ws2_32: Add tests and implement inet_pton
Bruno Jesus
00cpxxx at gmail.com
Mon Nov 3 15:16:14 CST 2014
Special thanks to Erich Hoover.
Fixes https://bugs.winehq.org/show_bug.cgi?id=36713
-------------- next part --------------
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 0bcce40..b3db306 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -6911,6 +6911,40 @@ PCSTR WINAPI WS_inet_ntop( INT family, PVOID addr, PSTR buffer, SIZE_T len )
}
/***********************************************************************
+* inet_pton (WS2_32.@)
+*/
+INT WINAPI WS_inet_pton( INT family, PCSTR addr, PVOID buffer)
+{
+#ifdef HAVE_INET_PTON
+ int unixaf, ret;
+
+ TRACE("family %d, addr '%s', buffer (%p)\n", family, addr ? addr : "(null)", buffer);
+
+ if (!addr || !buffer)
+ {
+ SetLastError(WSAEFAULT);
+ return SOCKET_ERROR;
+ }
+
+ unixaf = convert_af_w2u(family);
+ if (unixaf != AF_INET && unixaf != AF_INET6)
+ {
+ SetLastError(WSAEAFNOSUPPORT);
+ return SOCKET_ERROR;
+ }
+
+ ret = inet_pton(unixaf, addr, buffer);
+ if (ret == -1) SetLastError(wsaErrno());
+ return ret;
+#else
+ FIXME( "not supported on this platform\n" );
+ WSASetLastError( WSAEAFNOSUPPORT );
+ return SOCKET_ERROR;
+#endif
+}
+
+
+/***********************************************************************
* WSAStringToAddressA (WS2_32.80)
*/
INT WINAPI WSAStringToAddressA(LPSTR AddressString,
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 0ad6e8a..0c39545 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -67,6 +67,7 @@ static int (WINAPI *pgetaddrinfo)(LPCSTR,LPCSTR,const struct addrinfo *,struct
static void (WINAPI *pFreeAddrInfoW)(PADDRINFOW);
static int (WINAPI *pGetAddrInfoW)(LPCWSTR,LPCWSTR,const ADDRINFOW *,PADDRINFOW *);
static PCSTR (WINAPI *pInetNtop)(INT,LPVOID,LPSTR,ULONG);
+static int (WINAPI *pInetPton)(INT,LPSTR,LPVOID);
static int (WINAPI *pWSALookupServiceBeginW)(LPWSAQUERYSETW,DWORD,LPHANDLE);
static int (WINAPI *pWSALookupServiceEnd)(HANDLE);
static int (WINAPI *pWSALookupServiceNextW)(HANDLE,DWORD,LPDWORD,LPWSAQUERYSETW);
@@ -1139,6 +1140,7 @@ static void Init (void)
pFreeAddrInfoW = (void *)GetProcAddress(hws2_32, "FreeAddrInfoW");
pGetAddrInfoW = (void *)GetProcAddress(hws2_32, "GetAddrInfoW");
pInetNtop = (void *)GetProcAddress(hws2_32, "inet_ntop");
+ pInetPton = (void *)GetProcAddress(hws2_32, "inet_pton");
pWSALookupServiceBeginW = (void *)GetProcAddress(hws2_32, "WSALookupServiceBeginW");
pWSALookupServiceEnd = (void *)GetProcAddress(hws2_32, "WSALookupServiceEnd");
pWSALookupServiceNextW = (void *)GetProcAddress(hws2_32, "WSALookupServiceNextW");
@@ -3987,6 +3989,117 @@ static void test_addr_to_print(void)
pdst = pInetNtop(AF_INET6, (void*)&in6.s6_addr, dst6, 18);
ok(pdst != NULL, "The pointer should be returned (%p)\n", pdst);
}
+static void test_inet_pton(void)
+{
+ struct TEST_DATA
+ {
+ int family, ret;
+ DWORD err;
+ const char *printable, *collapsed, *raw_data;
+ } tests[] = {
+ {AF_UNSPEC, -1, WSAEFAULT, /* Test 0 */
+ NULL, NULL, NULL},
+ {AF_INET, -1, WSAEFAULT,
+ NULL, NULL, NULL},
+ {AF_INET6, -1, WSAEFAULT,
+ NULL, NULL, NULL},
+ {AF_UNSPEC, -1, WSAEAFNOSUPPORT,
+ "127.0.0.1", NULL, NULL},
+ {AF_INET, 1, 0,
+ "127.0.0.1", "127.0.0.1",
+ "\x7f\x00\x00\x01"},
+ {AF_INET6, 0, 0,
+ "127.0.0.1", "127.0.0.1", NULL},
+ {AF_INET, 0, 0,
+ "::1/128", NULL, NULL},
+ {AF_INET6, 0, 0,
+ "::1/128", NULL, NULL},
+ {AF_UNSPEC, -1, WSAEAFNOSUPPORT,
+ "broken", NULL, NULL},
+ {AF_INET, 0, 0,
+ "broken", NULL, NULL},
+ {AF_INET6, 0, 0, /* Test 10 */
+ "broken", NULL, NULL},
+ {AF_UNSPEC, -1, WSAEAFNOSUPPORT,
+ "177.32.45.20", NULL, NULL},
+ {AF_INET, 1, 0,
+ "177.32.45.20", "177.32.45.20",
+ "\xb1\x20\x2d\x14"},
+ {AF_INET6, 0, 0,
+ "177.32.45.20", NULL, NULL},
+ {AF_INET, 0, 0,
+ "2607:f0d0:1002:51::4", NULL, NULL},
+ {AF_INET6, 1, 0,
+ "2607:f0d0:1002:51::4", "2607:f0d0:1002:51::4",
+ "\x26\x07\xf0\xd0\x10\x02\x00\x51\x00\x00\x00\x00\x00\x00\x00\x04"},
+ {AF_INET, 0, 0,
+ "::177.32.45.20", NULL, NULL},
+ {AF_INET6, 1, 0,
+ "::177.32.45.20", "::177.32.45.20",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x20\x2d\x14"},
+ {AF_INET, 0, 0,
+ "fe80::0202:b3ff:fe1e:8329", NULL, NULL},
+ {AF_INET6, 1, 0,
+ "fe80::0202:b3ff:fe1e:8329", "fe80::202:b3ff:fe1e:8329",
+ "\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x02\xb3\xff\xfe\x1e\x83\x29"},
+ {AF_INET6, 1, 0, /* Test 20 */
+ "fe80::202:b3ff:fe1e:8329", "fe80::202:b3ff:fe1e:8329",
+ "\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x02\xb3\xff\xfe\x1e\x83\x29"},
+ {AF_INET, 0, 0,
+ "a", NULL, NULL},
+ {AF_INET, 0, 0,
+ "a.b", NULL, NULL},
+ {AF_INET, 0, 0,
+ "a.b.c", NULL, NULL},
+ {AF_INET, 0, 0,
+ "a.b.c.d", NULL, NULL},
+ {AF_INET6, 1, 0,
+ "2001:cdba:0000:0000:0000:0000:3257:9652", "2001:cdba::3257:9652",
+ "\x20\x01\xcd\xba\x00\x00\x00\x00\x00\x00\x00\x00\x32\x57\x96\x52"},
+ {AF_INET6, 1, 0,
+ "2001:cdba::3257:9652", "2001:cdba::3257:9652",
+ "\x20\x01\xcd\xba\x00\x00\x00\x00\x00\x00\x00\x00\x32\x57\x96\x52"},
+ {AF_INET6, 1, 0,
+ "2001:cdba:0:0:0:0:3257:9652", "2001:cdba::3257:9652",
+ "\x20\x01\xcd\xba\x00\x00\x00\x00\x00\x00\x00\x00\x32\x57\x96\x52"}
+ };
+ int i, ret;
+ DWORD err;
+ char buffer[64],str[64];
+ const char *ptr;
+
+ /* InetNtop and InetPton became available in Vista and Win2008 */
+ if (!pInetNtop || !pInetPton)
+ {
+ win_skip("InetNtop and/or InetPton not present, not executing tests\n");
+ return;
+ }
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ {
+ WSASetLastError(0xdeadbeef);
+ ret = pInetPton(tests[i].family, (char *)tests[i].printable, buffer);
+ ok (ret == tests[i].ret, "Test [%d]: Expected %d, got %d\n", i, tests[i].ret, ret);
+ if (tests[i].ret == -1)
+ {
+ err = WSAGetLastError();
+ ok (tests[i].err == err, "Test [%d]: Expected 0x%x, got 0x%x\n", i, tests[i].err, err);
+ }
+ if (tests[i].ret != 1) continue;
+ ok (memcmp(buffer, tests[i].raw_data,
+ tests[i].family == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr)) == 0,
+ "Test [%d]: Expected binary data differs\n", i);
+
+ /* Test the result from Pton with Ntop */
+ strcpy (str, "deadbeef");
+ ptr = pInetNtop(tests[i].family, buffer, str, sizeof(str));
+ ok (ptr != NULL, "Test [%d]: Failed with NULL\n", i);
+ ok (ptr == str, "Test [%d]: Pointers differ (%p != %p)\n", i, ptr, str);
+ if (!ptr) continue;
+ ok (strcmp(ptr, tests[i].collapsed) == 0, "Test [%d]: Expected '%s', got '%s'\n",
+ i, tests[i].collapsed, ptr);
+ }
+}
static void test_ioctlsocket(void)
{
@@ -7739,6 +7852,7 @@ START_TEST( sock )
Init();
test_inet_ntoa();
+ test_inet_pton();
test_set_getsockopt();
test_so_reuseaddr();
test_ip_pktinfo();
diff --git a/dlls/ws2_32/ws2_32.spec b/dlls/ws2_32/ws2_32.spec
index 0811b74..f7c6c2d 100644
--- a/dlls/ws2_32/ws2_32.spec
+++ b/dlls/ws2_32/ws2_32.spec
@@ -121,3 +121,4 @@
@ stdcall getaddrinfo(str str ptr ptr) WS_getaddrinfo
@ stdcall getnameinfo(ptr long ptr long ptr long long) WS_getnameinfo
@ stdcall inet_ntop(long ptr ptr long) WS_inet_ntop
+@ stdcall inet_pton(long ptr ptr) WS_inet_pton
More information about the wine-patches
mailing list