Handle IPv4 addresses in Windows inet_ntop

Hrvoje Niksic <[email protected]> Tue, 09 Aug 2005 14:45:28 +0200
Newsgroups gmane.comp.web.wget.patches
Message-ID <[email protected]>
Since we have a nearly-complete inet_ntop implementation, it's a shame
for it not to handle IPv4 addresses.  This patch trivially adds them,
allowing the option for print_address to eventually always use
inet_ntop for address printing when IPv6 is enabled.

I haven't had a chance to test this on Windows yet; please let me know
if it breaks something.


2005-08-09  Hrvoje Niksic  <[email protected]>

	* mswindows.c (inet_ntop): Also handle IPv4 addresses for
	completeness.

Index: src/mswindows.c
===================================================================
--- src/mswindows.c	(revision 2008)
+++ src/mswindows.c	(working copy)
@@ -799,23 +799,40 @@
 }
 
 #ifdef ENABLE_IPV6
-/* An IPv6-only inet_ntop that prints with WSAAddressToString.  (Wget
-   uses inet_ntoa for IPv4 addresses -- see print_address.)  Prototype
-   complies with POSIX 1003.1-2004.  */
+/* An inet_ntop implementation that uses WSAAddressToString.
+   Prototype complies with POSIX 1003.1-2004.  This is only used under
+   IPv6 because Wget prints IPv4 addresses using inet_ntoa.  */
 
 const char *
 inet_ntop (int af, const void *src, char *dst, socklen_t cnt)
 {
-  struct sockaddr_in6 sin6;
+  /* struct sockaddr can't accomodate struct sockaddr_in6. */
+  union {
+    struct sockaddr_in6 sin6;
+    struct sockaddr_in sin;
+  } sa;
   DWORD dstlen = cnt;
+  size_t srcsize;
 
-  assert (af == AF_INET6);
-  xzero (sin6);
-  sin6.sin6_family = AF_INET6;
-  sin6.sin6_addr = *(struct in6_addr *) src;
-  if (WSAAddressToString ((struct sockaddr *) &sin6, sizeof (sin6),
-                          NULL, dst, &dstlen) != 0)
+  xzero (sa);
+  switch (af)
     {
+    case AF_INET:
+      sa.sin.sin_family = AF_INET;
+      sa.sin.sin_addr = *(struct in_addr *) src;
+      srcsize = sizeof (sa.sin);
+      break;
+    case AF_INET6:
+      sa.sin6.sin6_family = AF_INET6;
+      sa.sin6.sin6_addr = *(struct in6_addr *) src;
+      srcsize = sizeof (sa.sin6);
+      break;
+    default:
+      abort ();
+    }
+
+  if (WSAAddressToString ((struct sockaddr *) &sa, srcsize, NULL, dst, &dstlen) != 0)
+    {
       errno = WSAGetLastError();
       return NULL;
     }