Windows: Fix implementation of lws_plat_inet_ntop()
authorPatrick Gansterer <paroga@paroga.com>
Tue, 15 Apr 2014 16:45:48 +0000 (18:45 +0200)
committerPatrick Gansterer <paroga@paroga.com>
Tue, 15 Apr 2014 16:45:48 +0000 (18:45 +0200)
We need to pass a sockaddr_in6 struct to WSAAddressToString() to have a
working implementation for IPV6. Also use the WideChar version to allow
compilation on Windows CE too.

lib/lws-plat-win.c

index 3c40d59..b33f79c 100644 (file)
@@ -311,30 +311,48 @@ lws_plat_open_file(const char* filename, unsigned long* filelen)
        return ret;
 }
 
-#ifdef LWS_USE_IPV6
-/* 
- * Windows doesn't have an "inet_ntop"
- * This came from http://memset.wordpress.com/2010/10/09/inet_ntop-for-win32/
- * suggested by Joakim Soderberg
- */
-
 LWS_VISIBLE const char *
 lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
 { 
-       struct sockaddr_in srcaddr;
-       DWORD rv;
-
-       memset(&srcaddr, 0, sizeof(struct sockaddr_in));
-       memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
+       WCHAR *buffer;
+       DWORD bufferlen = cnt;
+       BOOL ok = FALSE;
+
+       buffer = malloc(bufferlen);
+       if (!buffer) {
+               lwsl_err("Out of memory\n");
+               return NULL;
+       }
 
-       srcaddr.sin_family = af;
-       if (!WSAAddressToString((struct sockaddr*)&srcaddr,
-                           sizeof(struct sockaddr_in), 0, dst, (LPDWORD)&cnt))
-               return dst;
+       if (af == AF_INET) {
+               struct sockaddr_in srcaddr;
+               bzero(&srcaddr, sizeof(srcaddr));
+               srcaddr.sin_family = AF_INET;
+               memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
 
-       rv = WSAGetLastError();
-       lwsl_err("WSAAddressToString() : %d\n", rv);
+               if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
+                       ok = TRUE;
+#ifdef LWS_USE_IPV6
+       } else if (af == AF_INET6) {
+               struct sockaddr_in6 srcaddr;
+               bzero(&srcaddr, sizeof(srcaddr));
+               srcaddr.sin6_family = AF_INET6;
+               memcpy(&(srcaddr.sin6_addr), src, sizeof(srcaddr.sin6_addr));
+
+               if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
+                       ok = TRUE;
+#endif
+       } else
+               lwsl_err("Unsupported type\n");
+
+       if (!ok) {
+               int rv = WSAGetLastError();
+               lwsl_err("WSAAddressToString() : %d\n", rv);
+       } else {
+               if (WideCharToMultiByte(CP_ACP, 0, buffer, bufferlen, dst, cnt, 0, NULL) <= 0)
+                       ok = FALSE;
+       }
 
-       return NULL;
+       free(buffer);
+       return ok ? dst : NULL;
 }
-#endif
\ No newline at end of file