s4:lib/socket: don't use gethostbyname2()
[sfrench/samba-autobuild/.git] / source4 / lib / socket / socket_ip.c
index bca0aab9249d253de0804cc1eb9909f86663f593..cdb75fe0218d945714f520ebc8f505126db6b4bf 100644 (file)
@@ -549,19 +549,36 @@ _PUBLIC_ const struct socket_ops *socket_ipv4_ops(enum socket_type type)
 
 static struct in6_addr interpret_addr6(const char *name)
 {
-       struct hostent *he;
-       
-       if (name == NULL) return in6addr_any;
+       char addr[INET6_ADDRSTRLEN];
+       struct in6_addr dest6;
+       const char *sp = name;
+       char *p = strchr_m(sp, '%');
+       int ret;
+
+       if (sp == NULL) return in6addr_any;
 
-       if (strcasecmp(name, "localhost") == 0) {
-               name = "::1";
+       if (strcasecmp(sp, "localhost") == 0) {
+               sp = "::1";
        }
 
-       he = gethostbyname2(name, PF_INET6);
+       /*
+        * Cope with link-local.
+        * This is IP:v6:addr%ifname.
+        */
+
+       if (p && (p > sp) && (if_nametoindex(p+1) != 0)) {
+               strlcpy(addr, sp,
+                       MIN(PTR_DIFF(p,sp)+1,
+                               sizeof(addr)));
+               sp = addr;
+       }
 
-       if (he == NULL) return in6addr_any;
+       ret = inet_pton(AF_INET6, sp, &dest6);
+       if (ret > 0) {
+               return dest6;
+       }
 
-       return *((struct in6_addr *)he->h_addr);
+       return in6addr_any;
 }
 
 static NTSTATUS ipv6_init(struct socket_context *sock)