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