(LINE_PARSER): Support IPv6-style addresses for IPv4 queries if they
authordrepper <drepper>
Mon, 20 Nov 2006 03:26:24 +0000 (03:26 +0000)
committerdrepper <drepper>
Mon, 20 Nov 2006 03:26:24 +0000 (03:26 +0000)
can be mapped.

nss/nss_files/files-hosts.c

index 8d1a8ee..6daafde 100644 (file)
@@ -1,5 +1,5 @@
 /* Hosts file parser in nss_files module.
-   Copyright (C) 1996-2001, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2001, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -55,14 +55,30 @@ LINE_PARSER
    STRING_FIELD (addr, isspace, 1);
 
    /* Parse address.  */
-   if (inet_pton (af, addr, entdata->host_addr) <= 0
-       && (af != AF_INET6 || (flags & AI_V4MAPPED) == 0
-          || inet_pton (AF_INET, addr, entdata->host_addr) <= 0
-          || (map_v4v6_address ((char *) entdata->host_addr,
-                                (char *) entdata->host_addr),
-              0)))
-     /* Illegal address: ignore line.  */
-     return 0;
+   if (inet_pton (af, addr, entdata->host_addr) <= 0)
+     {
+       if (af == AF_INET6 && (flags & AI_V4MAPPED) != 0
+          && inet_pton (AF_INET, addr, entdata->host_addr) > 0)
+        map_v4v6_address ((char *) entdata->host_addr,
+                          (char *) entdata->host_addr);
+       else if (af == AF_INET
+               && inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
+        {
+          if (IN6_IS_ADDR_V4MAPPED (entdata->host_addr))
+            memcpy (entdata->host_addr, entdata->host_addr + 12, INADDRSZ);
+          else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr))
+            {
+              in_addr_t localhost = htonl (INADDR_LOOPBACK);
+              memcpy (entdata->host_addr, &localhost, sizeof (localhost));
+            }
+          else
+            /* Illegal address: ignore line.  */
+            return 0;
+        }
+       else
+        /* Illegal address: ignore line.  */
+        return 0;
+     }
 
    /* We always return entries of the requested form.  */
    result->h_addrtype = af;