[WS2_32] Add some parameters check for getsockname. Use value size for size check...
[reactos.git] / reactos / dll / win32 / ws2_32 / src / addrconv.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32_new/src/addrconv.c
5 * PURPOSE: Address and Port Conversion Support
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ws2_32.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* DEFINES *******************************************************************/
17
18 #ifndef BE
19
20 /* DWORD network to host byte order conversion for little endian machines */
21 #define DN2H(dw) \
22 ((((dw) & 0xFF000000L) >> 24) | \
23 (((dw) & 0x00FF0000L) >> 8) | \
24 (((dw) & 0x0000FF00L) << 8) | \
25 (((dw) & 0x000000FFL) << 24))
26
27 /* DWORD host to network byte order conversion for little endian machines */
28 #define DH2N(dw) \
29 ((((dw) & 0xFF000000L) >> 24) | \
30 (((dw) & 0x00FF0000L) >> 8) | \
31 (((dw) & 0x0000FF00L) << 8) | \
32 (((dw) & 0x000000FFL) << 24))
33
34 /* WORD network to host order conversion for little endian machines */
35 #define WN2H(w) \
36 ((((w) & 0xFF00) >> 8) | \
37 (((w) & 0x00FF) << 8))
38
39 /* WORD host to network byte order conversion for little endian machines */
40 #define WH2N(w) \
41 ((((w) & 0xFF00) >> 8) | \
42 (((w) & 0x00FF) << 8))
43
44 #else /* BE */
45
46 /* DWORD network to host byte order conversion for big endian machines */
47 #define DN2H(dw) \
48 (dw)
49
50 /* DWORD host to network byte order conversion big endian machines */
51 #define DH2N(dw) \
52 (dw)
53
54 /* WORD network to host order conversion for big endian machines */
55 #define WN2H(w) \
56 (w)
57
58 /* WORD host to network byte order conversion for big endian machines */
59 #define WH2N(w) \
60 (w)
61
62 #endif /* BE */
63
64 /* FUNCTIONS *****************************************************************/
65
66 /*
67 * @implemented
68 */
69 ULONG
70 WSAAPI
71 inet_addr(IN CONST CHAR FAR* cp)
72 {
73 register u_long val, base, n;
74 register unsigned char c;
75 u_long parts[4], *pp = parts;
76 if (!cp) return INADDR_ANY;
77 if (!isdigit(*cp)) return INADDR_NONE;
78
79 again:
80 /*
81 * Collect number up to ``.''.
82 * Values are specified as for C:
83 * 0x=hex, 0=octal, other=decimal.
84 */
85 val = 0; base = 10;
86 if (*cp == '0') {
87 if (*++cp == 'x' || *cp == 'X')
88 base = 16, cp++;
89 else
90 base = 8;
91 }
92 while ((c = *cp)) {
93 if (isdigit(c)) {
94 val = (val * base) + (c - '0');
95 cp++;
96 continue;
97 }
98 if (base == 16 && isxdigit(c)) {
99 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
100 cp++;
101 continue;
102 }
103 break;
104 }
105 if (*cp == '.') {
106 /*
107 * Internet format:
108 * a.b.c.d
109 * a.b.c (with c treated as 16-bits)
110 * a.b (with b treated as 24 bits)
111 */
112 if (pp >= parts + 4) return (INADDR_NONE);
113 *pp++ = val;
114 cp++;
115 goto again;
116 }
117 /*
118 * Check for trailing characters.
119 */
120 if (*cp && !isspace((UCHAR)*cp)) return (INADDR_NONE);
121
122 *pp++ = val;
123 /*
124 * Concoct the address according to
125 * the number of parts specified.
126 */
127 n = (u_long)(pp - parts);
128 switch (n) {
129
130 case 1: /* a -- 32 bits */
131 val = parts[0];
132 break;
133
134 case 2: /* a.b -- 8.24 bits */
135 val = (parts[0] << 24) | (parts[1] & 0xffffff);
136 break;
137
138 case 3: /* a.b.c -- 8.8.16 bits */
139 val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
140 (parts[2] & 0xffff);
141 break;
142
143 case 4: /* a.b.c.d -- 8.8.8.8 bits */
144 val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
145 ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
146 break;
147
148 default:
149 return (INADDR_NONE);
150 }
151 val = htonl(val);
152 return (val);
153 }
154
155 /*
156 * @implemented
157 */
158 CHAR FAR*
159 WSAAPI
160 inet_ntoa(IN IN_ADDR in)
161 {
162 PWSPROCESS Process;
163 PWSTHREAD Thread;
164 INT ErrorCode;
165 WSADATA WsaData;
166 BOOL ManualLoad = FALSE;
167 CHAR b[10];
168 PCHAR p;
169 DPRINT("inet_ntoa: %lx\n", in);
170
171 /* Enter prolog */
172 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
173 {
174 DPRINT("MANUAL LOAD\n");
175
176 /* Only fail if the error wasn't related to a missing WSAStartup */
177 if (ErrorCode != WSANOTINITIALISED)
178 {
179 /* Fail */
180 SetLastError(ErrorCode);
181 return NULL;
182 }
183
184 /* Apps aren't expected to call WSAStartup for this API, so we will */
185 if ((ErrorCode = WSAStartup(MAKEWORD(2,2), &WsaData)) != ERROR_SUCCESS)
186 {
187 /* We failed */
188 SetLastError(ErrorCode);
189 return NULL;
190 }
191
192 /* Try the prolog again */
193 ManualLoad = TRUE;
194 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
195 {
196 /* Failed again... */
197 WSACleanup();
198 SetLastError(ErrorCode);
199 return NULL;
200 }
201 }
202
203 p = Thread->Buffer;
204 _itoa(in.S_un.S_addr & 0xFF, b, 10);
205 strcpy(p, b);
206 _itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10);
207 strcat(p, ".");
208 strcat(p, b);
209 _itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10);
210 strcat(p, ".");
211 strcat(p, b);
212 _itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10);
213 strcat(p, ".");
214 strcat(p, b);
215
216 /* Cleanup the manual load */
217 if (ManualLoad) WSACleanup();
218
219 /* Return the buffer */
220 return p;
221 }
222
223 /*
224 * @implemented
225 */
226 ULONG
227 WSAAPI
228 htonl(IN ULONG hostlong)
229 {
230 return DH2N(hostlong);
231 }
232
233 /*
234 * @implemented
235 */
236 USHORT
237 WSAAPI
238 htons(IN USHORT hostshort)
239 {
240 return WH2N(hostshort);
241 }
242
243 /*
244 * @implemented
245 */
246 ULONG
247 WSAAPI
248 ntohl(IN ULONG netlong)
249 {
250 return DN2H(netlong);
251 }
252
253 /*
254 * @implemented
255 */
256 USHORT
257 WSAAPI
258 ntohs(IN USHORT netshort)
259 {
260 return WN2H(netshort);
261 }
262
263 /*
264 * @implemented
265 */
266 INT
267 WSAAPI
268 WSAHtonl(IN SOCKET s,
269 IN ULONG hostlong,
270 OUT ULONG FAR* lpnetlong)
271 {
272 INT ErrorCode;
273 PWSSOCKET Socket;
274 DPRINT("WSAHtonl: %p, %lx, %p\n", s, hostlong, lpnetlong);
275
276 /* Check for WSAStartup */
277 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
278 {
279 /* Make sure we got a parameter */
280 if (!lpnetlong)
281 {
282 /* Fail */
283 SetLastError(WSAEFAULT);
284 return SOCKET_ERROR;
285 }
286
287 /* Get the Socket Context */
288 if ((Socket = WsSockGetSocket(s)))
289 {
290 /* Check which byte order to use */
291 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder ==
292 LITTLEENDIAN)
293 {
294 /* No conversion needed */
295 *lpnetlong = hostlong;
296 }
297 else
298 {
299 /* Use a swap */
300 *lpnetlong = DN2H(hostlong);
301 }
302
303 /* Dereference the socket */
304 WsSockDereference(Socket);
305
306 /* Return success */
307 return ERROR_SUCCESS;
308 }
309 else
310 {
311 /* Set the error code */
312 ErrorCode = WSAENOTSOCK;
313 }
314 }
315
316 /* Return with error */
317 SetLastError(ErrorCode);
318 return SOCKET_ERROR;
319 }
320
321 /*
322 * @implemented
323 */
324 INT
325 WSAAPI
326 WSAHtons(IN SOCKET s,
327 IN USHORT hostshort,
328 OUT USHORT FAR* lpnetshort)
329 {
330 INT ErrorCode;
331 PWSSOCKET Socket;
332 DPRINT("WSAHtons: %p, %lx, %p\n", s, hostshort, lpnetshort);
333
334 /* Check for WSAStartup */
335 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
336 {
337 /* Make sure we got a parameter */
338 if (!lpnetshort)
339 {
340 /* Fail */
341 SetLastError(WSAEFAULT);
342 return SOCKET_ERROR;
343 }
344
345 /* Get the Socket Context */
346 if ((Socket = WsSockGetSocket(s)))
347 {
348 /* Check which byte order to use */
349 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder ==
350 LITTLEENDIAN)
351 {
352 /* No conversion needed */
353 *lpnetshort = hostshort;
354 }
355 else
356 {
357 /* Use a swap */
358 *lpnetshort = WN2H(hostshort);
359 }
360
361 /* Dereference the socket */
362 WsSockDereference(Socket);
363
364 /* Return success */
365 return ERROR_SUCCESS;
366 }
367 else
368 {
369 /* Set the error code */
370 ErrorCode = WSAENOTSOCK;
371 }
372 }
373
374 /* Return with error */
375 SetLastError(ErrorCode);
376 return SOCKET_ERROR;
377 }
378
379 /*
380 * @implemented
381 */
382 INT
383 WSAAPI
384 WSANtohl(IN SOCKET s,
385 IN ULONG netlong,
386 OUT ULONG FAR* lphostlong)
387 {
388 INT ErrorCode;
389 PWSSOCKET Socket;
390 DPRINT("WSANtohl: %p, %lx, %p\n", s, netlong, lphostlong);
391
392 /* Check for WSAStartup */
393 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
394 {
395 /* Make sure we got a parameter */
396 if (!lphostlong)
397 {
398 /* Fail */
399 SetLastError(WSAEFAULT);
400 return SOCKET_ERROR;
401 }
402
403 /* Get the Socket Context */
404 if ((Socket = WsSockGetSocket(s)))
405 {
406 /* Check which byte order to use */
407 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder ==
408 LITTLEENDIAN)
409 {
410 /* No conversion needed */
411 *lphostlong = netlong;
412 }
413 else
414 {
415 /* Use a swap */
416 *lphostlong = DN2H(netlong);
417 }
418
419 /* Dereference the socket */
420 WsSockDereference(Socket);
421
422 /* Return success */
423 return ERROR_SUCCESS;
424 }
425 else
426 {
427 /* Set the error code */
428 ErrorCode = WSAENOTSOCK;
429 }
430 }
431
432 /* Return with error */
433 SetLastError(ErrorCode);
434 return SOCKET_ERROR;
435 }
436
437 /*
438 * @implemented
439 */
440 INT
441 WSAAPI
442 WSANtohs(IN SOCKET s,
443 IN USHORT netshort,
444 OUT USHORT FAR* lphostshort)
445 {
446 INT ErrorCode;
447 PWSSOCKET Socket;
448 DPRINT("WSANtohs: %p, %lx, %p\n", s, netshort, lphostshort);
449
450 /* Check for WSAStartup */
451 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
452 {
453 /* Make sure we got a parameter */
454 if (!lphostshort)
455 {
456 /* Fail */
457 SetLastError(WSAEFAULT);
458 return SOCKET_ERROR;
459 }
460
461 /* Get the Socket Context */
462 if ((Socket = WsSockGetSocket(s)))
463 {
464 /* Check which byte order to use */
465 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder ==
466 LITTLEENDIAN)
467 {
468 /* No conversion needed */
469 *lphostshort = netshort;
470 }
471 else
472 {
473 /* Use a swap */
474 *lphostshort = WN2H(netshort);
475 }
476
477 /* Dereference the socket */
478 WsSockDereference(Socket);
479
480 /* Return success */
481 return ERROR_SUCCESS;
482 }
483 else
484 {
485 /* Set the error code */
486 ErrorCode = WSAENOTSOCK;
487 }
488 }
489
490 /* Return with error */
491 SetLastError(ErrorCode);
492 return SOCKET_ERROR;
493 }
494