about summary refs log tree commit diff
path: root/resolv/res_init.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-04-07 17:20:25 +0000
committerUlrich Drepper <drepper@redhat.com>2008-04-07 17:20:25 +0000
commita7eba295f0646a544e543131d16c5740a4875404 (patch)
treea44a366c89f4237a6f33043762ce115ff6a9cb7a /resolv/res_init.c
parentae39e102cb79ad85fa3c901d55d3081c478d2f80 (diff)
downloadglibc-a7eba295f0646a544e543131d16c5740a4875404.tar.gz
glibc-a7eba295f0646a544e543131d16c5740a4875404.tar.xz
glibc-a7eba295f0646a544e543131d16c5740a4875404.zip
Handle scope IDs in resolv.conf.
Diffstat (limited to 'resolv/res_init.c')
-rw-r--r--resolv/res_init.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/resolv/res_init.c b/resolv/res_init.c
index d1a5681a93..a2840968f3 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -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;