1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Test for bind 5 * PROGRAMMER: Peter Hater 6 */ 7 8 #include "ws2_32.h" 9 10 static CHAR LocalAddress[sizeof("255.255.255.255")]; 11 #define PORT 58888 12 13 static 14 VOID 15 TestBind(IN_ADDR Address) 16 { 17 const UCHAR b1 = Address.S_un.S_un_b.s_b1; 18 const UCHAR b2 = Address.S_un.S_un_b.s_b2; 19 const UCHAR b3 = Address.S_un.S_un_b.s_b3; 20 const UCHAR b4 = Address.S_un.S_un_b.s_b4; 21 22 int Error; 23 struct 24 { 25 INT Type; 26 INT Proto; 27 struct sockaddr_in Addr; 28 INT ExpectedResult; 29 INT ExpectedWSAResult; 30 struct sockaddr_in ExpectedAddr; 31 } Tests[] = 32 { 33 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } }, 34 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } }, 35 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} }, 0, 0, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} } }, 36 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL }, 37 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } }, 38 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } }, 39 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ b1, b2, b3, b4 }}} }, 0, 0, { AF_INET, 0, {{{ b1, b2, b3, b4 }}} } }, 40 { SOCK_STREAM, IPPROTO_TCP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL }, 41 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } }, 42 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} }, 0, 0, { AF_INET, PORT, {{{ 0x00, 0x00, 0x00, 0x00 }}} } }, 43 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} }, 0, 0, { AF_INET, PORT, {{{ b1, b2, b3, b4 }}} } }, 44 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, PORT, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL }, 45 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} }, 0, 0, { AF_INET, 0, {{{ 0x7f, 0x00, 0x00, 0x01 }}} } }, 46 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0x00, 0x00, 0x00, 0x00 }}} } }, 47 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ b1, b2, b3, b4 }}} }, 0, 0,{ AF_INET, 0, {{{ b1, b2, b3, b4 }}} } }, 48 { SOCK_DGRAM, IPPROTO_UDP, { AF_INET, 0, {{{ 0xff, 0xff, 0xff, 0xff }}} }, SOCKET_ERROR, WSAEADDRNOTAVAIL }, 49 }; 50 const INT TestCount = _countof(Tests); 51 INT i, AddrSize; 52 SOCKET Socket; 53 struct sockaddr_in Addr; 54 BOOL Broadcast = TRUE; 55 56 for (i = 0; i < TestCount; i++) 57 { 58 trace("%d: %s %d.%d.%d.%d:%d\n", i, Tests[i].Type == SOCK_STREAM ? "TCP" : "UDP", Tests[i].Addr.sin_addr.S_un.S_un_b.s_b1, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b2, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b3, Tests[i].Addr.sin_addr.S_un.S_un_b.s_b4, Tests[i].ExpectedAddr.sin_port); 59 Socket = socket(AF_INET, Tests[i].Type, Tests[i].Proto); 60 if (Socket == INVALID_SOCKET) 61 { 62 skip("Failed to create socket with error %d for test %d, skipping\n", WSAGetLastError(), i); 63 continue; 64 } 65 Error = bind(Socket, (const struct sockaddr *) &Tests[i].Addr, sizeof(Tests[i].Addr)); 66 ok(Error == Tests[i].ExpectedResult, "Error %d differs from expected %d for test %d\n", Error, Tests[i].ExpectedResult, i); 67 if (Error) 68 { 69 ok(WSAGetLastError() == Tests[i].ExpectedWSAResult, "Error %d differs from expected %d for test %d\n", WSAGetLastError(), Tests[i].ExpectedWSAResult, i); 70 } 71 else 72 { 73 AddrSize = sizeof(Addr); 74 Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize); 75 ok(Error == 0, "Unexpected error %d %d on getsockname for test %d\n", Error, WSAGetLastError(), i); 76 ok(AddrSize == sizeof(Addr), "Returned size %d differs from expected %d for test %d\n", AddrSize, sizeof(Addr), i); 77 ok(Addr.sin_addr.s_addr == Tests[i].ExpectedAddr.sin_addr.s_addr, "Expected address %lx differs from returned address %lx for test %d\n", Tests[i].ExpectedAddr.sin_addr.s_addr, Addr.sin_addr.s_addr, i); 78 if (Tests[i].ExpectedAddr.sin_port) 79 { 80 ok(Addr.sin_port == Tests[i].ExpectedAddr.sin_port, "Returned port %d differs from expected %d for test %d\n", Addr.sin_port, Tests[i].ExpectedAddr.sin_port, i); 81 } 82 else 83 { 84 ok(Addr.sin_port != 0, "Port remained zero for test %d\n", i); 85 } 86 } 87 Error = closesocket(Socket); 88 ok(Error == 0, "Unexpected error %d %d on closesocket for test %d\n", Error, WSAGetLastError(), i); 89 } 90 /* Check double bind */ 91 Socket = socket(AF_INET, Tests[0].Type, Tests[0].Proto); 92 ok(Socket != INVALID_SOCKET, "Failed to create socket with error %d for double bind test, next tests might be wrong\n", WSAGetLastError()); 93 Error = bind(Socket, (const struct sockaddr *) &Tests[0].Addr, sizeof(Tests[0].Addr)); 94 ok(Error == Tests[0].ExpectedResult, "Error %d differs from expected %d for double bind test\n", Error, Tests[0].ExpectedResult); 95 if (Error) 96 { 97 ok(WSAGetLastError() == Tests[i].ExpectedWSAResult, "Error %d differs from expected %d for double bind test\n", WSAGetLastError(), Tests[0].ExpectedWSAResult); 98 } 99 else 100 { 101 AddrSize = sizeof(Addr); 102 Error = getsockname(Socket, (struct sockaddr *) &Addr, &AddrSize); 103 ok(Error == 0, "Unexpected error %d %d on getsockname for double bind test\n", Error, WSAGetLastError()); 104 ok(AddrSize == sizeof(Addr), "Returned size %d differs from expected %d for double bind test\n", AddrSize, sizeof(Addr)); 105 ok(Addr.sin_addr.s_addr == Tests[0].ExpectedAddr.sin_addr.s_addr, "Expected address %lx differs from returned address %lx for double bind test\n", Tests[0].ExpectedAddr.sin_addr.s_addr, Addr.sin_addr.s_addr); 106 if (Tests[0].ExpectedAddr.sin_port) 107 { 108 ok(Addr.sin_port == Tests[0].ExpectedAddr.sin_port, "Returned port %d differs from expected %d for double bind test\n", Addr.sin_port, Tests[0].ExpectedAddr.sin_port); 109 } 110 else 111 { 112 ok(Addr.sin_port != 0, "Port remained zero for double bind test\n"); 113 } 114 Error = bind(Socket, (const struct sockaddr *) &Tests[2].Addr, sizeof(Tests[2].Addr)); 115 ok(Error == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL, "Unexpected result %d expected %d and wsa result %d expected %ld for double bind test\n", Error, SOCKET_ERROR, WSAGetLastError(), WSAEINVAL); 116 } 117 Error = closesocket(Socket); 118 ok(Error == 0, "Unexpected error %d %d on closesocket for double bind test\n", Error, WSAGetLastError()); 119 /* Check SO_BROADCAST and bind to broadcast address */ 120 Socket = socket(AF_INET, Tests[10].Type, Tests[10].Proto); 121 ok(Socket != INVALID_SOCKET, "Failed to create socket with error %d for broadcast test, next tests might be wrong\n", WSAGetLastError()); 122 Error = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST, (const char *) &Broadcast, sizeof(Broadcast)); 123 ok(Error == 0, "Unexpected error %d %d on setsockopt for broadcast test\n", Error, WSAGetLastError()); 124 Error = bind(Socket, (const struct sockaddr *) &Tests[10].Addr, sizeof(Tests[10].Addr)); 125 ok(Error == 0, "Unexpected error %d %d on bind for broadcast test\n", Error, WSAGetLastError()); 126 Error = closesocket(Socket); 127 ok(Error == 0, "Unexpected error %d %d on closesocket for broadcast test\n", Error, WSAGetLastError()); 128 } 129 130 START_TEST(bind) 131 { 132 WSADATA WsaData; 133 int Error; 134 CHAR LocalHostName[128]; 135 struct hostent *Hostent; 136 IN_ADDR Address = { 0 }; 137 SOCKET Socket; 138 struct sockaddr_in Addr = { AF_INET }; 139 140 /* not yet initialized */ 141 StartSeh() 142 Error = bind(INVALID_SOCKET, NULL, 0); 143 ok_dec(Error, -1); 144 EndSeh(STATUS_SUCCESS); 145 StartSeh() 146 Error = bind(INVALID_SOCKET, InvalidPointer, 0); 147 ok_dec(Error, -1); 148 EndSeh(STATUS_SUCCESS); 149 150 Error = WSAStartup(MAKEWORD(2, 2), &WsaData); 151 ok_dec(Error, 0); 152 153 /* initialize LocalAddress for tests */ 154 Error = gethostname(LocalHostName, sizeof(LocalHostName)); 155 ok_dec(Error, 0); 156 ok_dec(WSAGetLastError(), 0); 157 trace("Local host name is '%s'\n", LocalHostName); 158 Hostent = gethostbyname(LocalHostName); 159 ok(Hostent != NULL, "gethostbyname failed with %d\n", WSAGetLastError()); 160 if (Hostent && Hostent->h_addr_list[0] && Hostent->h_length == sizeof(IN_ADDR)) 161 { 162 memcpy(&Address, Hostent->h_addr_list[0], sizeof(Address)); 163 strcpy(LocalAddress, inet_ntoa(Address)); 164 } 165 trace("Local address is '%s'\n", LocalAddress); 166 ok(LocalAddress[0] != '\0', 167 "Could not determine local address. Following test results may be wrong.\n"); 168 169 /* parameter tests */ 170 StartSeh() 171 Error = bind(INVALID_SOCKET, NULL, 0); 172 ok_dec(Error, SOCKET_ERROR); 173 ok_dec(WSAGetLastError(), WSAENOTSOCK); 174 EndSeh(STATUS_SUCCESS); 175 StartSeh() 176 Error = bind(INVALID_SOCKET, InvalidPointer, 0); 177 ok_dec(Error, SOCKET_ERROR); 178 ok_dec(WSAGetLastError(), WSAENOTSOCK); 179 EndSeh(STATUS_SUCCESS); 180 StartSeh() 181 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 182 Error = bind(Socket, NULL, 0); 183 ok_dec(Error, SOCKET_ERROR); 184 ok_dec(WSAGetLastError(), WSAEFAULT); 185 closesocket(Socket); 186 EndSeh(STATUS_SUCCESS); 187 StartSeh() 188 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 189 Error = bind(Socket, InvalidPointer, 0); 190 ok_dec(Error, SOCKET_ERROR); 191 ok_dec(WSAGetLastError(), WSAEFAULT); 192 closesocket(Socket); 193 EndSeh(STATUS_SUCCESS); 194 StartSeh() 195 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 196 Error = bind(Socket, NULL, sizeof(Addr)); 197 ok_dec(Error, SOCKET_ERROR); 198 ok_dec(WSAGetLastError(), WSAEFAULT); 199 closesocket(Socket); 200 EndSeh(STATUS_SUCCESS); 201 StartSeh() 202 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 203 Error = bind(Socket, InvalidPointer, sizeof(Addr)); 204 ok_dec(Error, SOCKET_ERROR); 205 ok_dec(WSAGetLastError(), WSAEFAULT); 206 closesocket(Socket); 207 EndSeh(STATUS_SUCCESS); 208 StartSeh() 209 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 210 Error = bind(Socket, (const struct sockaddr *) &Addr, 0); 211 ok_dec(Error, SOCKET_ERROR); 212 ok_dec(WSAGetLastError(), WSAEFAULT); 213 closesocket(Socket); 214 EndSeh(STATUS_SUCCESS); 215 StartSeh() 216 Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 217 Error = bind(Socket, (const struct sockaddr *) &Addr, sizeof(Addr)-1); 218 ok_dec(Error, SOCKET_ERROR); 219 ok_dec(WSAGetLastError(), WSAEFAULT); 220 closesocket(Socket); 221 EndSeh(STATUS_SUCCESS); 222 223 TestBind(Address); 224 /* TODO: test IPv6 */ 225 226 Error = WSACleanup(); 227 ok_dec(Error, 0); 228 } 229