diff --git a/configure b/configure index 5056a203c1c..16678d3138c 100755 --- a/configure +++ b/configure @@ -14792,6 +14792,20 @@ _ACEOF fi +ac_fn_c_check_member "$LINENO" "struct __res_state" "_u._ext.nscount6" "ac_cv_member_struct___res_state__u__ext_nscount6" "#ifdef HAVE_RESOLV_H +#include +#endif +" +if test "x$ac_cv_member_struct___res_state__u__ext_nscount6" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT___RES_STATE__U__EXT_NSCOUNT6 1 +_ACEOF + + +fi + + ac_fn_c_check_member "$LINENO" "ns_msg" "_msg_ptr" "ac_cv_member_ns_msg__msg_ptr" "#ifdef HAVE_SYS_TYPES_H #include #endif diff --git a/configure.ac b/configure.ac index 66b4dd6b0ea..96af2994bf3 100644 --- a/configure.ac +++ b/configure.ac @@ -2344,6 +2344,12 @@ AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id],,, #include #endif]) +dnl Check for _u._ext.nscount6 +AC_CHECK_MEMBERS([struct __res_state._u._ext.nscount6],,, +[#ifdef HAVE_RESOLV_H +#include +#endif]) + dnl Check for ns_msg ptr member AC_CHECK_MEMBERS([ns_msg._msg_ptr],,, [#ifdef HAVE_SYS_TYPES_H diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index fe247388697..5f795ec1f56 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -933,25 +933,46 @@ static ULONG adapterAddressesFromIndex(ULONG family, ULONG flags, IF_INDEX index return ERROR_SUCCESS; } -static int get_dns_servers( SOCKADDR_STORAGE *servers, int num ) +static int get_dns_servers( SOCKADDR_STORAGE *servers, int num, BOOL ip4_only ) { - int i; + int i, ip6_count = 0; SOCKADDR_STORAGE *addr; initialise_resolver(); - /* AF_INET6 not yet enumerated */ +#ifdef HAVE_STRUCT___RES_STATE__U__EXT_NSCOUNT6 + ip6_count = _res._u._ext.nscount6; +#endif + if (!servers || !num) { num = _res.nscount; + if (ip4_only) num -= ip6_count; return num; } for (i = 0, addr = servers; addr < (servers + num) && i < _res.nscount; i++) { - *(struct sockaddr_in *)addr = _res.nsaddr_list[i]; - memset( (char *)addr + sizeof(struct sockaddr_in), 0, - sizeof(SOCKADDR_STORAGE) - sizeof(struct sockaddr_in) ); +#ifdef HAVE_STRUCT___RES_STATE__U__EXT_NSCOUNT6 + if (_res._u._ext.nsaddrs[i]) + { + SOCKADDR_IN6 *s = (SOCKADDR_IN6 *)addr; + if (ip4_only) continue; + s->sin6_family = WS_AF_INET6; + s->sin6_port = _res._u._ext.nsaddrs[i]->sin6_port; + s->sin6_flowinfo = _res._u._ext.nsaddrs[i]->sin6_flowinfo; + memcpy( &s->sin6_addr, &_res._u._ext.nsaddrs[i]->sin6_addr, sizeof(IN6_ADDR) ); + s->sin6_scope_id = _res._u._ext.nsaddrs[i]->sin6_scope_id; + memset( (char *)s + sizeof(SOCKADDR_IN6), 0, + sizeof(SOCKADDR_STORAGE) - sizeof(SOCKADDR_IN6) ); + } + else +#endif + { + *(struct sockaddr_in *)addr = _res.nsaddr_list[i]; + memset( (char *)addr + sizeof(struct sockaddr_in), 0, + sizeof(SOCKADDR_STORAGE) - sizeof(struct sockaddr_in) ); + } addr++; } return addr - servers; @@ -959,7 +980,7 @@ static int get_dns_servers( SOCKADDR_STORAGE *servers, int num ) static ULONG get_dns_server_addresses(PIP_ADAPTER_DNS_SERVER_ADDRESS address, ULONG *len) { - int num = get_dns_servers( NULL, 0 ); + int num = get_dns_servers( NULL, 0, FALSE ); DWORD size; size = num * (sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) + sizeof(SOCKADDR_STORAGE)); @@ -975,12 +996,15 @@ static ULONG get_dns_server_addresses(PIP_ADAPTER_DNS_SERVER_ADDRESS address, UL SOCKADDR_STORAGE *sock_addrs = (SOCKADDR_STORAGE *)(address + num); int i; - get_dns_servers( sock_addrs, num ); + get_dns_servers( sock_addrs, num, FALSE ); for (i = 0; i < num; i++, addr = addr->Next) { addr->u.s.Length = sizeof(*addr); - addr->Address.iSockaddrLength = sizeof(SOCKADDR_IN); + if (sock_addrs[i].ss_family == WS_AF_INET6) + addr->Address.iSockaddrLength = sizeof(SOCKADDR_IN6); + else + addr->Address.iSockaddrLength = sizeof(SOCKADDR_IN); addr->Address.lpSockaddr = (SOCKADDR *)(sock_addrs + i); if (i == num - 1) addr->Next = NULL; @@ -1637,7 +1661,7 @@ static DWORD get_dns_server_list(PIP_ADDR_STRING list, PIP_ADDR_STRING firstDynamic, DWORD *len) { DWORD size; - int num = get_dns_servers( NULL, 0 ); + int num = get_dns_servers( NULL, 0, TRUE ); size = num * sizeof(IP_ADDR_STRING); if (!list || *len < size) { @@ -1650,7 +1674,7 @@ static DWORD get_dns_server_list(PIP_ADDR_STRING list, int i; SOCKADDR_STORAGE *addr = HeapAlloc( GetProcessHeap(), 0, num * sizeof(SOCKADDR_STORAGE) ); - get_dns_servers( addr, num ); + get_dns_servers( addr, num, TRUE ); for (i = 0, ptr = list; i < num; i++, ptr = ptr->Next) { toIPAddressString(((struct sockaddr_in *)(addr + i))->sin_addr.s_addr, diff --git a/include/config.h.in b/include/config.h.in index 44b34ce373d..2ab1081a3f0 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -912,6 +912,9 @@ /* Define to 1 if the system has the type `struct xinpgen'. */ #undef HAVE_STRUCT_XINPGEN +/* Define to 1 if `_u._ext.nscount6' is a member of `struct __res_state'. */ +#undef HAVE_STRUCT___RES_STATE__U__EXT_NSCOUNT6 + /* Define to 1 if you have the `symlink' function. */ #undef HAVE_SYMLINK