Move the horrible hack for link local addresses out of namequery.c
authorJeremy Allison <jra@samba.org>
Fri, 26 Oct 2007 23:03:20 +0000 (16:03 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 26 Oct 2007 23:03:20 +0000 (16:03 -0700)
and into util_sock.c. is_ipaddress() now copes with link:local:v6%ifname
addresses, as does interpret_string_addr().
Jeremy
(This used to be commit a3f7db3d30ced566c8340696914f1be3293a9c5b)

source3/lib/util_sock.c
source3/libsmb/namequery.c

index 80d4af8cdb63a6d20a1bd1968a5096bab57f452e..91da4074582b5a3d7b6e21c24ee75340d972c076 100644 (file)
@@ -53,11 +53,27 @@ bool is_ipaddress(const char *str)
        int ret = -1;
 
 #if defined(HAVE_IPV6)
-       struct in6_addr dest6;
+       if (strchr_m(str, ':')) {
+               char addr[INET6_ADDRSTRLEN];
+               struct in6_addr dest6;
+               const char *sp = str;
+               char *p = strchr_m(str, '%');
 
-       ret = inet_pton(AF_INET6, str, &dest6);
-       if (ret > 0) {
-               return true;
+               /*
+                * Cope with link-local.
+                * This is IP:v6:addr%ifname.
+                */
+
+               if (p && (p > str) && (if_nametoindex(p+1) != 0)) {
+                       strlcpy(addr, str,
+                               MIN(PTR_DIFF(p,str)+1,
+                                       sizeof(addr)));
+                       sp = addr;
+               }
+               ret = inet_pton(AF_INET6, addr, &dest6);
+               if (ret > 0) {
+                       return true;
+               }
        }
 #endif
        return is_ipaddress_v4(str);
@@ -200,7 +216,27 @@ bool interpret_string_addr(struct sockaddr_storage *pss,
                const char *str,
                int flags)
 {
+       char addr[INET6_ADDRSTRLEN];
        struct addrinfo *res = NULL;
+#if defined(HAVE_IPV6)
+       unsigned int scope_id = 0;
+
+       if (strchr_m(str, ':')) {
+               char *p = strchr_m(str, '%');
+
+               /*
+                * Cope with link-local.
+                * This is IP:v6:addr%ifname.
+                */
+
+               if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) {
+                       strlcpy(addr, str,
+                               MIN(PTR_DIFF(p,str)+1,
+                                       sizeof(addr)));
+                       str = addr;
+               }
+       }
+#endif
 
        zero_addr(pss, AF_INET);
 
@@ -212,6 +248,17 @@ bool interpret_string_addr(struct sockaddr_storage *pss,
        }
        /* Copy the first sockaddr. */
        memcpy(pss, res->ai_addr, res->ai_addrlen);
+
+#if defined(HAVE_IPV6)
+       if (pss->ss_family == AF_INET6 && scope_id) {
+               struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss;
+               if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) &&
+                               ps6->sin6_scope_id == 0) {
+                       ps6->sin6_scope_id = scope_id;
+               }
+       }
+#endif
+
        freeaddrinfo(res);
        return true;
 }
index 90e6be6a909ec530beb8c65e1c1b0e5df5a3ff66..34fe09b8c2988e475d4af827daefb09b1656de83 100644 (file)
@@ -1594,32 +1594,6 @@ bool resolve_name(const char *name,
        char *sitename = NULL;
        int count = 0;
 
-#if defined(HAVE_IPV6)
-       unsigned int if_idx = 0;
-       const char *p = strchr_m(name, '%');
-
-       if (p && (if_idx = if_nametoindex(p+1)) != 0) {
-               char *newname = SMB_STRDUP(name);
-               if (!newname) {
-                       return false;
-               }
-               newname[PTR_DIFF(p,name)] = '\0';
-               if (is_ipaddress(newname) &&
-                               interpret_string_addr(return_ss,
-                                       newname, AI_NUMERICHOST)) {
-                       struct sockaddr_in6 *psa6 =
-                               (struct sockaddr_in6 *)&return_ss;
-                       if (psa6->sin6_scope_id == 0 &&
-                                       IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
-                               psa6->sin6_scope_id = if_idx;
-                       }
-                       SAFE_FREE(newname);
-                       return true;
-               }
-               SAFE_FREE(newname);
-       }
-#endif
-
        if (is_ipaddress(name)) {
                return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
        }