+static const unsigned int *nfs_default_proto(void);
+#ifdef MOUNT_CONFIG
+static const unsigned int *nfs_default_proto()
+{
+ extern unsigned long config_default_proto;
+ /*
+ * If the default proto has been set and
+ * its not TCP, start with UDP
+ */
+ if (config_default_proto && config_default_proto != IPPROTO_TCP)
+ return probe_udp_first;
+
+ return probe_tcp_first;
+}
+#else
+static const unsigned int *nfs_default_proto()
+{
+ return probe_tcp_first;
+}
+#endif /* MOUNT_CONFIG */
+
+/**
+ * nfs_lookup - resolve hostname to an IPv4 or IPv6 socket address
+ * @hostname: pointer to C string containing DNS hostname to resolve
+ * @family: address family hint
+ * @sap: pointer to buffer to fill with socket address
+ * @len: IN: size of buffer to fill; OUT: size of socket address
+ *
+ * Returns 1 and places a socket address at @sap if successful;
+ * otherwise zero.
+ */
+int nfs_lookup(const char *hostname, const sa_family_t family,
+ struct sockaddr *sap, socklen_t *salen)
+{
+ struct addrinfo *gai_results;
+ struct addrinfo gai_hint = {
+#ifdef HAVE_DECL_AI_ADDRCONFIG
+ .ai_flags = AI_ADDRCONFIG,
+#endif /* HAVE_DECL_AI_ADDRCONFIG */
+ .ai_family = family,
+ };
+ socklen_t len = *salen;
+ int error, ret = 0;
+
+ *salen = 0;
+
+ error = getaddrinfo(hostname, NULL, &gai_hint, &gai_results);
+ switch (error) {
+ case 0:
+ break;
+ case EAI_SYSTEM:
+ nfs_error(_("%s: DNS resolution failed for %s: %s"),
+ progname, hostname, strerror(errno));
+ return ret;
+ default:
+ nfs_error(_("%s: DNS resolution failed for %s: %s"),
+ progname, hostname, gai_strerror(error));
+ return ret;
+ }
+
+ switch (gai_results->ai_addr->sa_family) {
+ case AF_INET:
+ case AF_INET6:
+ if (len >= gai_results->ai_addrlen) {
+ *salen = gai_results->ai_addrlen;
+ memcpy(sap, gai_results->ai_addr, *salen);
+ ret = 1;
+ }
+ break;
+ default:
+ /* things are really broken if we get here, so warn */
+ nfs_error(_("%s: unrecognized DNS resolution results for %s"),
+ progname, hostname);
+ break;
+ }
+
+ freeaddrinfo(gai_results);
+ return ret;
+}
+
+/**
+ * nfs_name_to_address - resolve hostname to an IPv4 or IPv6 socket address
+ * @hostname: pointer to C string containing DNS hostname to resolve
+ * @sap: pointer to buffer to fill with socket address
+ * @len: IN: size of buffer to fill; OUT: size of socket address
+ *
+ * Returns 1 and places a socket address at @sap if successful;
+ * otherwise zero.
+ */
+int nfs_name_to_address(const char *hostname,
+ struct sockaddr *sap, socklen_t *salen)
+{
+#ifdef IPV6_SUPPORTED
+ return nfs_lookup(hostname, AF_UNSPEC, sap, salen);
+#else /* !IPV6_SUPPORTED */
+ return nfs_lookup(hostname, AF_INET, sap, salen);
+#endif /* !IPV6_SUPPORTED */
+}
+