Handle scope IDs in resolv.conf.
authorUlrich Drepper <drepper@redhat.com>
Mon, 7 Apr 2008 17:20:25 +0000 (17:20 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 7 Apr 2008 17:20:25 +0000 (17:20 +0000)
resolv/res_init.c

index d1a5681..a284096 100644 (file)
@@ -69,22 +69,22 @@ static const char sccsid[] = "@(#)res_init.c        8.1 (Berkeley) 6/7/93";
 static const char rcsid[] = "$BINDId: res_init.c,v 8.16 2000/05/09 07:10:12 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
 #include <ctype.h>
+#include <netdb.h>
 #include <resolv.h>
 #include <stdio.h>
 #include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
 
 #include <not-cancel.h>
 
@@ -327,15 +327,41 @@ __res_vinit(res_state statp, int preinit) {
 
                         if ((el = strchr(cp, '\n')) != NULL)
                             *el = '\0';
+                       if ((el = strchr(cp, SCOPE_DELIMITER)) != NULL)
+                           *el = '\0';
                         if ((*cp != '\0') &&
                             (inet_pton(AF_INET6, cp, &a6) > 0)) {
                             struct sockaddr_in6 *sa6;
 
                             sa6 = malloc(sizeof(*sa6));
                             if (sa6 != NULL) {
-                                sa6->sin6_addr = a6;
                                 sa6->sin6_family = AF_INET6;
                                 sa6->sin6_port = htons(NAMESERVER_PORT);
+                               sa6->sin6_flowinfo = 0;
+                                sa6->sin6_addr = a6;
+
+                               if (__builtin_expect (el == NULL, 1))
+                                   sa6->sin6_scope_id = 0;
+                               else {
+                                   int try_numericscope = 1;
+                                   if (IN6_IS_ADDR_LINKLOCAL (&a6)
+                                       || IN6_IS_ADDR_MC_LINKLOCAL (&a6)) {
+                                       sa6->sin6_scope_id
+                                         = if_nametoindex (el + 1);
+                                       if (sa6->sin6_scope_id != 0)
+                                           try_numericscope = 0;
+                                   }
+
+                                   if (try_numericscope) {
+                                       char *end;
+                                       sa6->sin6_scope_id
+                                         = (uint32_t) strtoul (el + 1, &end,
+                                                               10);
+                                       if (*end != '\0')
+                                           sa6->sin6_scope_id = 0;
+                                   }
+                               }
+
                                statp->_u._ext.nsaddrs[nservall] = sa6;
                                statp->_u._ext.nssocks[nservall] = -1;
                                statp->_u._ext.nsmap[nservall] = MAXNS + 1;