summaryrefslogtreecommitdiff
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
parentae39e102cb79ad85fa3c901d55d3081c478d2f80 (diff)
downloadglibc-a7eba295f0646a544e543131d16c5740a4875404.tar.gz
Handle scope IDs in resolv.conf.
-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;