ReactOS 0.4.16-dev-598-gc07fba4
addrconv.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/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 */
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
79again:
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 */
158CHAR FAR*
159WSAAPI
161{
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 */
173 {
174 DPRINT("MANUAL LOAD\n");
175
176 /* Only fail if the error wasn't related to a missing WSAStartup */
178 {
179 /* Fail */
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 */
189 return NULL;
190 }
191
192 /* Try the prolog again */
193 ManualLoad = TRUE;
195 {
196 /* Failed again... */
197 WSACleanup();
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 */
226ULONG
227WSAAPI
228htonl(IN ULONG hostlong)
229{
230 return DH2N(hostlong);
231}
232
233/*
234 * @implemented
235 */
236USHORT
237WSAAPI
238htons(IN USHORT hostshort)
239{
240 return WH2N(hostshort);
241}
242
243/*
244 * @implemented
245 */
246ULONG
247WSAAPI
248ntohl(IN ULONG netlong)
249{
250 return DN2H(netlong);
251}
252
253/*
254 * @implemented
255 */
256USHORT
257WSAAPI
258ntohs(IN USHORT netshort)
259{
260 return WN2H(netshort);
261}
262
263/*
264 * @implemented
265 */
266INT
267WSAAPI
269 IN ULONG hostlong,
270 OUT ULONG FAR* lpnetlong)
271{
273 PWSSOCKET Socket;
274 DPRINT("WSAHtonl: %p, %lx, %p\n", s, hostlong, lpnetlong);
275
276 /* Check for WSAStartup */
278 {
279 /* Make sure we got a parameter */
280 if (!lpnetlong)
281 {
282 /* Fail */
284 return SOCKET_ERROR;
285 }
286
287 /* Get the Socket Context */
288 if ((Socket = WsSockGetSocket(s)))
289 {
290 /* Check which byte order to use */
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 */
313 }
314 }
315
316 /* Return with error */
318 return SOCKET_ERROR;
319}
320
321/*
322 * @implemented
323 */
324INT
325WSAAPI
327 IN USHORT hostshort,
328 OUT USHORT FAR* lpnetshort)
329{
331 PWSSOCKET Socket;
332 DPRINT("WSAHtons: %p, %lx, %p\n", s, hostshort, lpnetshort);
333
334 /* Check for WSAStartup */
336 {
337 /* Make sure we got a parameter */
338 if (!lpnetshort)
339 {
340 /* Fail */
342 return SOCKET_ERROR;
343 }
344
345 /* Get the Socket Context */
346 if ((Socket = WsSockGetSocket(s)))
347 {
348 /* Check which byte order to use */
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 */
371 }
372 }
373
374 /* Return with error */
376 return SOCKET_ERROR;
377}
378
379/*
380 * @implemented
381 */
382INT
383WSAAPI
385 IN ULONG netlong,
386 OUT ULONG FAR* lphostlong)
387{
389 PWSSOCKET Socket;
390 DPRINT("WSANtohl: %p, %lx, %p\n", s, netlong, lphostlong);
391
392 /* Check for WSAStartup */
394 {
395 /* Make sure we got a parameter */
396 if (!lphostlong)
397 {
398 /* Fail */
400 return SOCKET_ERROR;
401 }
402
403 /* Get the Socket Context */
404 if ((Socket = WsSockGetSocket(s)))
405 {
406 /* Check which byte order to use */
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 */
429 }
430 }
431
432 /* Return with error */
434 return SOCKET_ERROR;
435}
436
437/*
438 * @implemented
439 */
440INT
441WSAAPI
443 IN USHORT netshort,
444 OUT USHORT FAR* lphostshort)
445{
447 PWSSOCKET Socket;
448 DPRINT("WSANtohs: %p, %lx, %p\n", s, netshort, lphostshort);
449
450 /* Check for WSAStartup */
452 {
453 /* Make sure we got a parameter */
454 if (!lphostshort)
455 {
456 /* Fail */
458 return SOCKET_ERROR;
459 }
460
461 /* Get the Socket Context */
462 if ((Socket = WsSockGetSocket(s)))
463 {
464 /* Check which byte order to use */
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 */
487 }
488 }
489
490 /* Return with error */
492 return SOCKET_ERROR;
493}
494
495PCSTR
496WSAAPI
499 _In_ const VOID *pAddr,
500 _Out_writes_(StringBufSize) PSTR pStringBuf,
501 _In_ size_t StringBufSize)
502{
504 ULONG BufSize = StringBufSize;
505
506 switch (Family)
507 {
508 case AF_INET:
509 Status = RtlIpv4AddressToStringExA(pAddr, 0, pStringBuf, &BufSize);
510 break;
511 case AF_INET6:
512 Status = RtlIpv6AddressToStringExA(pAddr, 0, 0, pStringBuf, &BufSize);
513 break;
514 default:
516 return NULL;
517 }
518
519 if (!NT_SUCCESS(Status))
520 {
522 return NULL;
523 }
524
525 return pStringBuf;
526}
527
528PCWSTR
529WSAAPI
532 _In_ const VOID *pAddr,
533 _Out_writes_(StringBufSize) PWSTR pStringBuf,
534 _In_ size_t StringBufSize)
535{
537 ULONG BufSize = StringBufSize;
538
539 switch (Family)
540 {
541 case AF_INET:
542 Status = RtlIpv4AddressToStringExW(pAddr, 0, pStringBuf, &BufSize);
543 break;
544 case AF_INET6:
545 Status = RtlIpv6AddressToStringExW(pAddr, 0, 0, pStringBuf, &BufSize);
546 break;
547 default:
549 return NULL;
550 }
551
552 if (!NT_SUCCESS(Status))
553 {
555 return NULL;
556 }
557
558 return pStringBuf;
559}
560
561INT
562WSAAPI
565 _In_ PCSTR pszAddrString,
566 _Out_writes_bytes_(sizeof(IN_ADDR6)) PVOID pAddrBuf)
567{
569 PCSTR ch;
570
571 if (!pszAddrString || !pAddrBuf)
572 {
574 return -1;
575 }
576
577 switch (Family)
578 {
579 case AF_INET:
580 Status = RtlIpv4StringToAddressA(pszAddrString, TRUE, &ch, pAddrBuf);
581 break;
582 case AF_INET6:
583 Status = RtlIpv6StringToAddressA(pszAddrString, &ch, pAddrBuf);
584 break;
585 default:
587 return -1;
588 }
589
590 if (!NT_SUCCESS(Status) || (*ch != 0))
591 {
592 return 0;
593 }
594
595 return 1;
596}
597
598INT
599WSAAPI
602 _In_ PCWSTR pszAddrString,
603 _Out_writes_bytes_(sizeof(IN_ADDR6)) PVOID pAddrBuf)
604{
606 PCWSTR ch;
607
608 if (!pszAddrString || !pAddrBuf)
609 {
611 return -1;
612 }
613
614 switch (Family)
615 {
616 case AF_INET:
617 Status = RtlIpv4StringToAddressW(pszAddrString, TRUE, &ch, pAddrBuf);
618 break;
619 case AF_INET6:
620 Status = RtlIpv6StringToAddressW(pszAddrString, &ch, pAddrBuf);
621 break;
622 default:
624 return -1;
625 }
626
627 if (!NT_SUCCESS(Status) || (*ch != 0))
628 {
629 SetLastError(WSAEINVAL); /* Only unicode version sets this error */
630 return 0;
631 }
632
633 return 1;
634}
#define BufSize
Definition: FsRtlTunnel.c:28
std::map< E_STRING, PART_TEST > parts
Definition: LocaleTests.cpp:67
#define isspace(c)
Definition: acclib.h:69
#define islower(c)
Definition: acclib.h:72
#define isdigit(c)
Definition: acclib.h:68
#define isxdigit(c)
Definition: acclib.h:70
CHAR FAR *WSAAPI inet_ntoa(IN IN_ADDR in)
Definition: addrconv.c:160
PCSTR WSAAPI inet_ntop(_In_ INT Family, _In_ const VOID *pAddr, _Out_writes_(StringBufSize) PSTR pStringBuf, _In_ size_t StringBufSize)
Definition: addrconv.c:497
PCWSTR WSAAPI InetNtopW(_In_ INT Family, _In_ const VOID *pAddr, _Out_writes_(StringBufSize) PWSTR pStringBuf, _In_ size_t StringBufSize)
Definition: addrconv.c:530
#define DH2N(dw)
Definition: addrconv.c:28
INT WSAAPI InetPtonW(_In_ INT Family, _In_ PCWSTR pszAddrString, _Out_writes_bytes_(sizeof(IN_ADDR6)) PVOID pAddrBuf)
Definition: addrconv.c:600
INT WSAAPI WSANtohs(IN SOCKET s, IN USHORT netshort, OUT USHORT FAR *lphostshort)
Definition: addrconv.c:442
INT WSAAPI WSAHtons(IN SOCKET s, IN USHORT hostshort, OUT USHORT FAR *lpnetshort)
Definition: addrconv.c:326
INT WSAAPI WSANtohl(IN SOCKET s, IN ULONG netlong, OUT ULONG FAR *lphostlong)
Definition: addrconv.c:384
ULONG WSAAPI inet_addr(IN CONST CHAR FAR *cp)
Definition: addrconv.c:71
#define WN2H(w)
Definition: addrconv.c:35
INT WSAAPI inet_pton(_In_ INT Family, _In_ PCSTR pszAddrString, _Out_writes_bytes_(sizeof(IN_ADDR6)) PVOID pAddrBuf)
Definition: addrconv.c:563
#define WH2N(w)
Definition: addrconv.c:40
#define DN2H(dw)
Definition: addrconv.c:21
INT WSAAPI WSAHtonl(IN SOCKET s, IN ULONG hostlong, OUT ULONG FAR *lpnetlong)
Definition: addrconv.c:268
LONG NTSTATUS
Definition: precomp.h:26
#define INADDR_NONE
Definition: tcp.c:42
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define SetLastError(x)
Definition: compat.h:752
#define FAR
Definition: zlib.h:34
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
unsigned long u_long
Definition: linux.h:269
#define AF_INET
Definition: tcpip.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER pAddr
Status
Definition: gdiplustypes.h:25
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLuint in
Definition: glext.h:9616
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
_itoa
Definition: stdlib.h:642
#define c
Definition: ke_i.h:80
#define INADDR_ANY
Definition: inet.h:80
POINT cp
Definition: magnifier.c:59
#define htons(x)
Definition: module.h:215
#define ntohl(x)
Definition: module.h:205
#define ntohs(x)
Definition: module.h:210
#define htonl(x)
Definition: module.h:214
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
NTSYSAPI NTSTATUS NTAPI RtlIpv6StringToAddressW(_In_ PCWSTR String, _Out_ PCWSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:1005
NTSYSAPI NTSTATUS NTAPI RtlIpv6AddressToStringExW(_In_ const struct in6_addr *Address, _In_ ULONG ScopeId, _In_ USHORT Port, _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWCHAR AddressString, _Inout_ PULONG AddressStringLength)
Definition: network.c:649
NTSTATUS NTAPI RtlIpv4AddressToStringExW(_In_ const struct in_addr *Address, _In_ USHORT Port, _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWCHAR AddressString, _Inout_ PULONG AddressStringLength)
Definition: network.c:268
NTSYSAPI NTSTATUS NTAPI RtlIpv4AddressToStringExA(_In_ const struct in_addr *Address, _In_ USHORT Port, _Out_writes_to_(*AddressStringLength, *AddressStringLength) PCHAR AddressString, _Inout_ PULONG AddressStringLength)
Definition: network.c:186
NTSYSAPI NTSTATUS NTAPI RtlIpv6AddressToStringExA(_In_ const struct in6_addr *Address, _In_ ULONG ScopeId, _In_ USHORT Port, _Out_writes_to_(*AddressStringLength, *AddressStringLength) PSTR AddressString, _Inout_ PULONG AddressStringLength)
Definition: network.c:510
NTSYSAPI NTSTATUS NTAPI RtlIpv4StringToAddressA(_In_ PCSTR String, _In_ BOOLEAN Strict, _Out_ PCSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:318
NTSYSAPI NTSTATUS NTAPI RtlIpv6StringToAddressA(_In_ PCSTR String, _Out_ PCSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:725
NTSYSAPI NTSTATUS NTAPI RtlIpv4StringToAddressW(_In_ PCWSTR String, _In_ BOOLEAN Strict, _Out_ PCWSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:385
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define CONST
Definition: pedump.c:81
unsigned short USHORT
Definition: pedump.c:61
static int Family
Definition: ping.c:62
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
#define DPRINT
Definition: sndvol32.h:73
WSAPROTOCOL_INFOW ProtocolInfo
Definition: ws2_32p.h:91
PTCATALOG_ENTRY CatalogEntry
Definition: ws2_32p.h:200
Definition: tcpip.h:126
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define WSANOTINITIALISED
Definition: winerror.h:1987
#define WSAEINVAL
Definition: winerror.h:1946
#define WSAENOTSOCK
Definition: winerror.h:1951
#define WSAEAFNOSUPPORT
Definition: winerror.h:1960
#define WSAEFAULT
Definition: winerror.h:1945
#define LITTLEENDIAN
Definition: winsock2.h:458
#define WSAAPI
Definition: winsock2.h:605
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define AF_INET6
Definition: winsock.h:369
FORCEINLINE DWORD WsQuickProlog(VOID)
Definition: ws2_32p.h:892
VOID WSAAPI WsSockDereference(IN PWSSOCKET Socket)
Definition: dsocket.c:205
INT WSAAPI WsApiProlog(OUT PWSPROCESS *Process, OUT PWSTHREAD *Thread)
Definition: wsautil.c:91
PWSSOCKET WSAAPI WsSockGetSocket(IN SOCKET Handle)
Definition: dsocket.c:140
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175