2003-03-29 Thorsten Kukuk * sysdeps/posix/getaddrinfo.c: Add support for AI_V4MAPPED/AI_ALL as described by POSIX and in rfc3493 * resolv/netdb.h: Add AI_V4MAPPED/AI_ALL --- resolv/netdb.h 2002-08-11 09:57:16.000000000 +0200 +++ resolv/netdb.h 2003-03-30 19:47:20.000000000 +0200 @@ -424,6 +424,8 @@ # define AI_PASSIVE 0x0001 /* Socket address is intended for `bind'. */ # define AI_CANONNAME 0x0002 /* Request for canonical name. */ # define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */ +# define AI_V4MAPPED 0x0008 /* IPv4-mapped addresses are acceptable. */ +# define AI_ALL 0x0010 /* Return both IPv4 and IPv6 addresses. */ /* Error values for `getaddrinfo' function. */ # define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */ --- sysdeps/posix/getaddrinfo.c 2002-12-21 14:39:05.000000000 +0100 +++ sysdeps/posix/getaddrinfo.c 2003-03-30 19:51:35.000000000 +0200 @@ -52,6 +52,9 @@ #include #include +/* Get implementation for some internal functions. */ +#include + #define GAIH_OKIFUNSPEC 0x0100 #define GAIH_EAI ~(GAIH_OKIFUNSPEC) @@ -368,6 +371,7 @@ struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv; struct gaih_addrtuple *at = NULL; int rc; + int v4mapped = (req->ai_family == AF_INET6) && (req->ai_flags & AI_V4MAPPED); if (req->ai_protocol || req->ai_socktype) { @@ -488,7 +492,7 @@ if (inet_pton (AF_INET, name, at->addr) > 0) { - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped) at->family = AF_INET; else return -EAI_ADDRFAMILY; @@ -609,7 +613,10 @@ gethosts (AF_INET6, struct in6_addr); no_inet6_data = no_data; } - else if (req->ai_family == AF_INET) + + if (req->ai_family == AF_INET || + (v4mapped && (no_inet6_data != 0 || h == NULL + || (req->ai_flags & AI_ALL)))) gethosts (AF_INET, struct in_addr); if (no_data != 0 && no_inet6_data != 0) @@ -745,7 +751,7 @@ else namelen = 0; - if (at2->family == AF_INET6) + if (at2->family == AF_INET6 || v4mapped) { family = AF_INET6; socklen = sizeof (struct sockaddr_in6); @@ -779,8 +785,13 @@ (struct sockaddr_in6 *) (*pai)->ai_addr; sin6p->sin6_flowinfo = 0; - memcpy (&sin6p->sin6_addr, - at2->addr, sizeof (struct in6_addr)); + if (at2->family == AF_INET6) + memcpy (&sin6p->sin6_addr, + at2->addr, sizeof (struct in6_addr)); + else + map_v4v6_address ((char *)&at2->addr, + (char *)&sin6p->sin6_addr); + sin6p->sin6_port = st2->port; sin6p->sin6_scope_id = at2->scopeid; } @@ -844,7 +854,8 @@ if (hints == NULL) hints = &default_hints; - if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)) + if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST| + AI_V4MAPPED|AI_ALL)) return EAI_BADFLAGS; if ((hints->ai_flags & AI_CANONNAME) && name == NULL)