dlls/iphlpapi/tests/iphlpapi.c: output more readable information, add test for valid & connectable address for DNS entry

Peter Balzer Peter535 at hab-verschlafen.de
Wed Nov 24 21:10:28 CST 2010


 The interface list has many (IP) addresses in it, which were only dumped as
 pointer, making it hard to see the actual interface configuration.

Therefore:
- expanded output for addresses into readable (IP) addresses
- added helpers to test for valid address & valid connectable address
- added test for valid & (todo_wine'd) connectable DNS server

This is to motivate a patch that will avoid adding (IPv6) DNS server addresses
from __res (set via resolv.conf) as invalid (IP) DNS servers (because it breaks the
the DNS lookup system as a whole).
---
 dlls/iphlpapi/tests/iphlpapi.c |  143 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 134 insertions(+), 9 deletions(-)

diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c
index f48470c..ec0c0b2 100644
--- a/dlls/iphlpapi/tests/iphlpapi.c
+++ b/dlls/iphlpapi/tests/iphlpapi.c
@@ -36,6 +36,7 @@
 
 #include <stdarg.h>
 #include "winsock2.h"
+#include "ws2ipdef.h"
 #include "windef.h"
 #include "winbase.h"
 #include "iphlpapi.h"
@@ -815,11 +816,120 @@ static void testWin2KFunctions(void)
     testGetPerAdapterInfo();
 }
 
+static char ptrstrnull[] = "(null)";
+
+static char *debustr_unixsocket_sockaddr(struct sockaddr *sa, u_char withport, char *space, int len)
+{
+    if (!space)
+        return NULL;
+
+    if (!sa)
+        snprintf(space, len, ptrstrnull);
+    else
+    {
+        if (sa->sa_family == AF_INET)
+        {
+            struct sockaddr_in *in = (struct sockaddr_in *)sa;
+            u_char *bytes = (u_char *)&in->sin_addr;
+            if (withport)
+                snprintf(space, len, "%i.%i.%i.%i:%i", bytes[0], bytes[1], bytes[2], bytes[3], ntohs(in->sin_port));
+            else
+                snprintf(space, len, "%i.%i.%i.%i", bytes[0], bytes[1], bytes[2], bytes[3]);
+        }
+        else
+            snprintf(space, len, "{ family %i, ... }", sa->sa_family);
+    }
+
+    return space;
+}
+
+static char *debustr_winsock_sockaddr(SOCKET_ADDRESS *saptr, u_char withport, char *space, int len)
+{
+    int len_used;
+
+    if (!space)
+        return NULL;
+
+    if (!saptr)
+        snprintf(space, len, ptrstrnull);
+    else
+    {
+        if (!saptr->lpSockaddr)
+            snprintf(space, len, "(%s)", ptrstrnull);
+        else if (saptr->iSockaddrLength < sizeof(struct sockaddr))
+            snprintf(space, len, "?? (too short: %i bytes, required %i bytes)",
+                    saptr->iSockaddrLength,    sizeof(struct sockaddr));
+        else
+        {
+            debustr_unixsocket_sockaddr(saptr->lpSockaddr, withport, space, len);
+            len_used = strlen(space);
+            snprintf(space + len_used, len - len_used, " (len %i)", saptr->iSockaddrLength);
+        }
+    }
+
+    return space;
+}
+
+static void CheckAddressRecordConnectable(const char *Info, SOCKET_ADDRESS *saptr)
+{
+    if (saptr->lpSockaddr->sa_family == AF_INET)
+    {
+        /* size is always sufficient for ipv4 to cast from sockaddr to sockaddr_in */
+        struct WS(sockaddr_in) *in = (struct WS(sockaddr_in) *)saptr->lpSockaddr;
+
+        /* if this is supposed to be a address to connect to, it must not be INADDR_ANY */
+        ok(in->sin_addr.s_addr != INADDR_ANY, "%s must not be INADDR_ANY.\n", Info);
+    }
+    else if (saptr->lpSockaddr->sa_family == AF_INET6)
+    {
+        struct WS(sockaddr_in6) *in6 = (struct WS(sockaddr_in6) *)saptr->lpSockaddr;
+
+        /* if this is supposed to be a address to connect to, it must not be IN6ADDR_ANY */
+        struct WS(in6_addr) in6_addr_any;
+        memset(&in6_addr_any, 0, sizeof(struct WS(in6_addr)));
+        ok(!memcmp(&in6->sin6_addr, &in6_addr_any, sizeof(struct WS(in6_addr))),
+                "%s must not be IN6ADDR_ANY.\n", Info);
+    }
+}
+
+static int CheckAddressRecordValid(const char *Info, SOCKET_ADDRESS *saptr)
+{
+    if (!saptr || !saptr->lpSockaddr)
+        return 0;
+
+    ok(saptr->iSockaddrLength >= sizeof(struct WS(sockaddr)),
+            "%s is too short (%i, need %i for basic struct sockaddr).\n",
+            Info, saptr->iSockaddrLength, sizeof(struct WS(sockaddr)));
+    if (saptr->iSockaddrLength < sizeof(struct WS(sockaddr)))
+        return 0;
+
+    ok(saptr->lpSockaddr->sa_family, "%s has unset address family %d.\n", Info, saptr->lpSockaddr->sa_family);
+    if (!saptr->lpSockaddr->sa_family)
+        return 0;
+
+    if (saptr->lpSockaddr->sa_family == AF_INET)
+        return 1;
+    else if (saptr->lpSockaddr->sa_family == AF_INET6)
+    {
+        ok(saptr->iSockaddrLength >= sizeof(struct WS(sockaddr_in6)),
+                "%s is too short (%i, need %i for family AF_INET6).\n", Info,
+                saptr->iSockaddrLength, sizeof(struct WS(sockaddr_in6)));
+        return (saptr->iSockaddrLength >= sizeof(struct WS(sockaddr_in6)));
+    }
+    else /* could we get crazy stuff like IPX or Appletalk or ... here? */
+    {
+        ok(0, "%s: don't know how to handle address family %d.\n", Info, saptr->lpSockaddr->sa_family);
+        return 0;
+    }
+}
+
 static void test_GetAdaptersAddresses(void)
 {
     ULONG ret, size;
     IP_ADAPTER_ADDRESSES *aa;
     IP_ADAPTER_UNICAST_ADDRESS *ua;
+    int i, pos;
+    char scratch[64];
 
     if (!gGetAdaptersAddresses)
     {
@@ -839,6 +949,7 @@ static void test_GetAdaptersAddresses(void)
     ret = gGetAdaptersAddresses(AF_UNSPEC, 0, NULL, aa, &size);
     ok(!ret, "expected ERROR_SUCCESS got %u\n", ret);
 
+    trace("AdaptersAddresses:     %p\n", aa);
     while (!ret && winetest_debug > 1 && aa)
     {
         trace("Length:                %u\n", S(U(*aa)).Length);
@@ -852,8 +963,7 @@ static void test_GetAdaptersAddresses(void)
             trace("\tLength:                  %u\n", S(U(*ua)).Length);
             trace("\tFlags:                   0x%08x\n", S(U(*ua)).Flags);
             trace("\tNext:                    %p\n", ua->Next);
-            trace("\tAddress.lpSockaddr:      %p\n", ua->Address.lpSockaddr);
-            trace("\tAddress.iSockaddrLength: %d\n", ua->Address.iSockaddrLength);
+            trace("\tAddress:                 %s\n", debustr_winsock_sockaddr(&ua->Address, 0, scratch, sizeof(scratch)));
             trace("\tPrefixOrigin:            %u\n", ua->PrefixOrigin);
             trace("\tSuffixOrigin:            %u\n", ua->SuffixOrigin);
             trace("\tDadState:                %u\n", ua->DadState);
@@ -863,14 +973,29 @@ static void test_GetAdaptersAddresses(void)
             trace("\n");
             ua = ua->Next;
         }
-        trace("FirstAnycastAddress:   %p\n", aa->FirstAnycastAddress);
-        trace("FirstMulticastAddress: %p\n", aa->FirstMulticastAddress);
-        trace("FirstDnsServerAddress: %p\n", aa->FirstDnsServerAddress);
-        trace("DnsSuffix:             %p\n", aa->DnsSuffix);
-        trace("Description:           %p\n", aa->Description);
-        trace("FriendlyName:          %p\n", aa->FriendlyName);
-        trace("PhysicalAddress:       %02x\n", aa->PhysicalAddress[0]);
+        trace("FirstAnycastAddress:   %s\n", !aa->FirstAnycastAddress ? ptrstrnull :
+                debustr_winsock_sockaddr(&aa->FirstAnycastAddress->Address, 0, scratch, sizeof(scratch)));
+        trace("FirstMulticastAddress: %s\n", !aa->FirstMulticastAddress ? ptrstrnull :
+                debustr_winsock_sockaddr(&aa->FirstMulticastAddress->Address, 0, scratch, sizeof(scratch)));
+        trace("FirstDnsServerAddress: %s\n", !aa->FirstDnsServerAddress ? ptrstrnull :
+                debustr_winsock_sockaddr(&aa->FirstDnsServerAddress->Address, 1, scratch, sizeof(scratch)));
+        /* CheckAddressValidity tests will trigger a todo if the first entry in resolv.conf is IPv6, e.g. ::1 (IN6ADDR_LOOPBACK) */
+        if (aa->FirstDnsServerAddress)
+            if (CheckAddressRecordValid("FirstDnsServerAddress", &aa->FirstDnsServerAddress->Address))
+                todo_wine CheckAddressRecordConnectable("FirstDnsServerAddress", &aa->FirstDnsServerAddress->Address);
+        trace("DnsSuffix:             %s\n", wine_dbgstr_w(aa->DnsSuffix));
+        trace("Description:           %s\n", wine_dbgstr_w(aa->Description));
+        trace("FriendlyName:          %s\n", wine_dbgstr_w(aa->FriendlyName));
+
         trace("PhysicalAddressLength: %u\n", aa->PhysicalAddressLength);
+        if (aa->PhysicalAddressLength)
+        {
+                pos = 0;
+                for(i = 0; i < aa->PhysicalAddressLength; i++)
+                        pos += sprintf(&scratch[pos], i ? ":%02x" : "%02x", aa->PhysicalAddress[i]);
+                trace("PhysicalAddress:       %s\n", scratch);
+        }
+
         trace("Flags:                 0x%08x\n", aa->Flags);
         trace("Mtu:                   %u\n", aa->Mtu);
         trace("IfType:                %u\n", aa->IfType);
-- 
1.7.2.3

-- 
Neu: GMX De-Mail - Einfach wie E-Mail, sicher wie ein Brief!  
Jetzt De-Mail-Adresse reservieren: http://portal.gmx.net/de/go/demail



More information about the wine-patches mailing list