ReactOS 0.4.16-dev-338-g34e76ad
network.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Runtime Library
4 * PURPOSE: Network Address Translation implementation
5 * PROGRAMMER: Alex Ionescu (alexi@tinykrnl.org)
6 * Thomas Faber (thomas.faber@reactos.org)
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <rtl.h>
12#include <ntstrsafe.h>
13#define NDEBUG
14#include <debug.h>
15
16/* maximum length of an ipv4 address expressed as a string */
17#define IPV4_ADDR_STRING_MAX_LEN 16
18
19/* maximum length of an ipv4 port expressed as a string */
20#define IPV4_PORT_STRING_MAX_LEN 7 /* with the leading ':' */
21
22/* maximum length of an ipv6 string for RtlIpv6AddressToString */
23#define RTLIPV6A2S_MAX_LEN 46
24
25/* maximum length of an ipv6 string with scope and port for RtlIpv6AddressToStringEx */
26#define RTLIPV6A2SEX_MAX_LEN 65
27
28/* network to host order conversion for little endian machines */
29#define WN2H(w) (((w & 0xFF00) >> 8) | ((w & 0x00FF) << 8))
30
31/* PRIVATE FUNCTIONS **********************************************************/
32
33/* decode a string with given Base (8, 10 or 16) */
34static
39 _Out_ PCWSTR *Terminator,
41{
43 ULONG Result = 0;
44 ULONG Digit;
45
46 while (1)
47 {
48 Digit = towlower(*String);
49 if (isdigit(Digit) && (Base >= 10 || Digit <= L'7'))
50 Digit -= L'0';
51 else if (Digit >= L'a' && Digit <= L'f' && Base >= 16)
52 Digit -= (L'a' - 10);
53 else
54 break;
55
56 Status = RtlULongMult(Result, Base, &Result);
57 if (!NT_SUCCESS(Status))
58 {
60 break;
61 }
62
63 Status = RtlULongAdd(Result, Digit, &Result);
64 if (!NT_SUCCESS(Status))
65 {
67 break;
68 }
69 String++;
70 }
71
72 *Terminator = String;
73 *Out = Result;
74 return Status;
75}
76
77
78static
82 _In_ BOOLEAN Strict,
83 _Out_ PCWSTR *Terminator,
85{
86 ULONG Base = 10;
87
88 if (String[0] == L'0')
89 {
90 if (String[1] == L'x' || String[1] == L'X')
91 {
92 /* 0x/0X prefix -- hex */
93 String += 2;
94 Base = 16;
95 }
96 else if (String[1] >= L'0' && String[1] <= L'9')
97 {
98 /* 0 prefix -- octal */
99 String++;
100 Base = 8;
101 }
102 }
103
104 /* Strict forbids anything but decimal */
105 if (Strict && Base != 10)
106 {
107 *Terminator = String;
109 }
110 return RtlpStringToUlongBase(String, Base, Terminator, Out);
111}
112
113/* Worker function to extract the ipv4 part of a string. */
115NTAPI
118 _In_ BOOLEAN Strict,
119 _Out_ PCWSTR *Terminator,
120 _Out_writes_(4) ULONG *Values,
121 _Out_ INT *Parts)
122{
124 *Parts = 0;
125 do
126 {
127 Status = RtlpStringToUlong(String, Strict, &String, &Values[*Parts]);
128 (*Parts)++;
129
130 if (*String != L'.')
131 break;
132
133 /* Already four parts, but a dot follows? */
134 if (*Parts == 4)
135 {
137 break;
138 }
139 /* Skip the dot */
140 String++;
141 } while (NT_SUCCESS(Status));
142
143 *Terminator = String;
144 return Status;
145}
146
147/* PUBLIC FUNCTIONS ***********************************************************/
148
149/*
150 * @implemented
151 */
152PSTR
153NTAPI
155 _In_ const struct in_addr *Addr,
157{
159 PSTR End;
160
161 if (!S)
162 return (PSTR)~0;
163
166 &End,
167 NULL,
168 0,
169 "%u.%u.%u.%u",
170 Addr->S_un.S_un_b.s_b1,
171 Addr->S_un.S_un_b.s_b2,
172 Addr->S_un.S_un_b.s_b3,
173 Addr->S_un.S_un_b.s_b4);
175 if (!NT_SUCCESS(Status))
176 return (PSTR)~0;
177
178 return End;
179}
180
181/*
182 * @implemented
183 */
185NTAPI
187 _In_ const struct in_addr *Address,
189 _Out_writes_to_(*AddressStringLength, *AddressStringLength) PCHAR AddressString,
190 _Inout_ PULONG AddressStringLength)
191{
195 PSTR End;
196
197 if (!Address || !AddressString || !AddressStringLength)
199
202 &End,
203 NULL,
204 0,
205 Port ? "%u.%u.%u.%u:%u"
206 : "%u.%u.%u.%u",
207 Address->S_un.S_un_b.s_b1,
208 Address->S_un.S_un_b.s_b2,
209 Address->S_un.S_un_b.s_b3,
210 Address->S_un.S_un_b.s_b4,
211 WN2H(Port));
213 if (!NT_SUCCESS(Status))
215
216 Length = End - Buffer;
217 if (*AddressStringLength > Length)
218 {
219 Status = RtlStringCchCopyA(AddressString,
220 *AddressStringLength,
221 Buffer);
223 *AddressStringLength = Length + 1;
224 return STATUS_SUCCESS;
225 }
226
227 *AddressStringLength = Length + 1;
229}
230
231/*
232 * @implemented
233 */
234PWSTR
235NTAPI
237 _In_ const struct in_addr *Addr,
239{
241 PWSTR End;
242
243 if (!S)
244 return (PWSTR)~0;
245
248 &End,
249 NULL,
250 0,
251 L"%u.%u.%u.%u",
252 Addr->S_un.S_un_b.s_b1,
253 Addr->S_un.S_un_b.s_b2,
254 Addr->S_un.S_un_b.s_b3,
255 Addr->S_un.S_un_b.s_b4);
257 if (!NT_SUCCESS(Status))
258 return (PWSTR)~0;
259
260 return End;
261}
262
263/*
264 * @implemented
265 */
267NTAPI
269 _In_ const struct in_addr *Address,
271 _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWCHAR AddressString,
272 _Inout_ PULONG AddressStringLength)
273{
277 PWSTR End;
278
279 if (!Address || !AddressString || !AddressStringLength)
281
284 &End,
285 NULL,
286 0,
287 Port ? L"%u.%u.%u.%u:%u"
288 : L"%u.%u.%u.%u",
289 Address->S_un.S_un_b.s_b1,
290 Address->S_un.S_un_b.s_b2,
291 Address->S_un.S_un_b.s_b3,
292 Address->S_un.S_un_b.s_b4,
293 WN2H(Port));
295 if (!NT_SUCCESS(Status))
297
298 Length = End - AddressString;
299 if (*AddressStringLength > Length)
300 {
301 Status = RtlStringCchCopyW(AddressString,
302 *AddressStringLength,
303 Buffer);
305 *AddressStringLength = Length + 1;
306 return STATUS_SUCCESS;
307 }
308
309 *AddressStringLength = Length + 1;
311}
312
313/*
314 * @implemented
315 */
317NTAPI
320 _In_ BOOLEAN Strict,
321 _Out_ PCSTR *Terminator,
322 _Out_ struct in_addr *Addr)
323{
325 ANSI_STRING AddressA;
326 UNICODE_STRING AddressW;
327 PCWSTR TerminatorW = NULL;
328
329 Status = RtlInitAnsiStringEx(&AddressA, String);
330 if (!NT_SUCCESS(Status))
331 return Status;
332
333 Status = RtlAnsiStringToUnicodeString(&AddressW, &AddressA, TRUE);
334 if (!NT_SUCCESS(Status))
335 return Status;
336
338 Strict,
339 &TerminatorW,
340 Addr);
341
342 ASSERT(TerminatorW >= AddressW.Buffer);
343 *Terminator = String + (TerminatorW - AddressW.Buffer);
344
345 RtlFreeUnicodeString(&AddressW);
346
347 return Status;
348}
349
350/*
351 * @implemented
352 */
354NTAPI
356 _In_ PCSTR AddressString,
357 _In_ BOOLEAN Strict,
358 _Out_ struct in_addr *Address,
360{
362 ANSI_STRING AddressA;
363 UNICODE_STRING AddressW;
364
365 Status = RtlInitAnsiStringEx(&AddressA, AddressString);
366 if (!NT_SUCCESS(Status))
367 return Status;
368
369 Status = RtlAnsiStringToUnicodeString(&AddressW, &AddressA, TRUE);
370 if (!NT_SUCCESS(Status))
371 return Status;
372
373 Status = RtlIpv4StringToAddressExW(AddressW.Buffer, Strict, Address, Port);
374
375 RtlFreeUnicodeString(&AddressW);
376
377 return Status;
378}
379
380/*
381 * @implemented
382 */
384NTAPI
387 _In_ BOOLEAN Strict,
388 _Out_ PCWSTR *Terminator,
389 _Out_ struct in_addr *Addr)
390{
392 ULONG Values[4];
394 INT Parts = 0;
395 INT i;
396
398 Strict,
399 Terminator,
400 Values,
401 &Parts);
402 if (Strict && Parts < 4)
404
405 if (!NT_SUCCESS(Status))
406 return Status;
407
408 /* Combine the parts */
409 Result = Values[Parts - 1];
410 for (i = 0; i < Parts - 1; i++)
411 {
412 INT Shift = CHAR_BIT * (3 - i);
413
414 if (Values[i] > 0xFF || (Result & (0xFF << Shift)) != 0)
415 {
417 }
418 Result |= Values[i] << Shift;
419 }
420
421 Addr->S_un.S_addr = RtlUlongByteSwap(Result);
422 return Status;
423}
424
425/*
426* @implemented
427*/
429NTAPI
431 _In_ PCWSTR AddressString,
432 _In_ BOOLEAN Strict,
433 _Out_ struct in_addr *Address,
435{
436 PCWSTR CurrentChar;
437 ULONG ConvertedPort;
439
440 if (!AddressString || !Address || !Port)
442
443 Status = RtlIpv4StringToAddressW(AddressString,
444 Strict,
445 &CurrentChar,
446 Address);
447 if (!NT_SUCCESS(Status))
448 return Status;
449
450 if (!*CurrentChar)
451 {
452 *Port = 0;
453 return STATUS_SUCCESS;
454 }
455
456 if (*CurrentChar != L':')
458 ++CurrentChar;
459
460 Status = RtlpStringToUlong(CurrentChar,
461 FALSE,
462 &CurrentChar,
463 &ConvertedPort);
464 if (!NT_SUCCESS(Status))
465 return Status;
466
467 if (*CurrentChar || !ConvertedPort || ConvertedPort > 0xffff)
469
470 *Port = WN2H(ConvertedPort);
471 return STATUS_SUCCESS;
472}
473
474/*
475* @implemented
476*/
477PSTR
478NTAPI
480 _In_ const struct in6_addr *Addr,
482{
486
487 if (!S)
488 return (PSTR)~0;
489
490 Buffer[0] = 0;
492 if (Result == (PWSTR)~0)
493 return (PSTR)~0;
494
495 ASSERT(Result >= Buffer);
497
499 if (!NT_SUCCESS(Status))
500 return (PSTR)~0;
501
502 return S + strlen(S);
503}
504
505/*
506* @implemented
507*/
509NTAPI
511 _In_ const struct in6_addr *Address,
512 _In_ ULONG ScopeId,
514 _Out_writes_to_(*AddressStringLength, *AddressStringLength) PSTR AddressString,
515 _Inout_ PULONG AddressStringLength)
516{
519
520 if (!Address || !AddressString || !AddressStringLength)
522
523 Status = RtlIpv6AddressToStringExW(Address, ScopeId, Port, Buffer, AddressStringLength);
524 if (!NT_SUCCESS(Status))
525 return Status;
526
527 Status = RtlUnicodeToMultiByteN(AddressString, RTLIPV6A2SEX_MAX_LEN, NULL, Buffer, (*AddressStringLength + 1) * sizeof(WCHAR));
528 if (!NT_SUCCESS(Status))
530
531 return STATUS_SUCCESS;
532}
533
534/*
535* @implemented
536*/
537PWSTR
538NTAPI
540 _In_ const struct in6_addr *Addr,
542{
544 UINT Parts = 8, n;
545 BOOLEAN SkipOnce = TRUE;
546 PWSTR End;
547 size_t Remaining;
548
549 if (!S)
550 return (PWSTR)~0;
551
552 Remaining = RTLIPV6A2S_MAX_LEN;
553 /* does it look like an ipv4 address contained in an ipv6? http://tools.ietf.org/html/rfc2765 */
554 if (!Addr->s6_words[0] && !Addr->s6_words[1] && !Addr->s6_words[2] && !Addr->s6_words[3] && Addr->s6_words[6])
555 {
556 PWSTR Prefix = NULL;
557 if (Addr->s6_words[4] == 0xffff && !Addr->s6_words[5])
558 Prefix = L"ffff:0:";
559 else if (!Addr->s6_words[4] && Addr->s6_words[5] == 0xffff)
560 Prefix = L"ffff:";
561 else if (!Addr->s6_words[4] && !Addr->s6_words[5])
562 Prefix = L"";
563 if (Prefix != NULL)
564 {
566 Remaining,
567 &End,
568 NULL,
569 0,
570 L"::%ls%u.%u.%u.%u",
571 Prefix,
572 Addr->s6_bytes[12],
573 Addr->s6_bytes[13],
574 Addr->s6_bytes[14],
575 Addr->s6_bytes[15]);
577 if (!NT_SUCCESS(Status))
578 return (PWSTR)~0;
579 return End;
580 }
581 }
582
583 /* does it look like an ISATAP address? http://tools.ietf.org/html/rfc5214 */
584 if (!(Addr->s6_words[4] & 0xfffd) && Addr->s6_words[5] == 0xfe5e)
585 Parts = 6;
586
587 for (n = 0; n < Parts; ++n)
588 {
589 if (SkipOnce && ((n + 1) < Parts) && !Addr->s6_words[n] && !Addr->s6_words[n + 1])
590 {
591 SkipOnce = FALSE;
592 while (!Addr->s6_words[n + 1] && (n + 1) < Parts)
593 ++n;
594 *S++ = ':';
595 Remaining--;
596 if ((n + 1) >= Parts)
597 {
598 *S++ = ':';
599 Remaining--;
600 }
601 }
602 else
603 {
604 if (n)
605 {
606 *S++ = ':';
607 Remaining--;
608 }
610 Remaining,
611 &End,
612 &Remaining,
613 0,
614 L"%x",
615 WN2H(Addr->s6_words[n]));
617 if (!NT_SUCCESS(Status))
618 return (PWSTR)~0;
619 S = End;
620 }
621 }
622 if (Parts < 8)
623 {
625 Remaining,
626 &End,
627 NULL,
628 0,
629 L":%u.%u.%u.%u",
630 Addr->s6_bytes[12],
631 Addr->s6_bytes[13],
632 Addr->s6_bytes[14],
633 Addr->s6_bytes[15]);
635 if (!NT_SUCCESS(Status))
636 return (PWSTR)~0;
637
638 return End;
639 }
640 *S = UNICODE_NULL;
641 return S;
642}
643
644/*
645* @implemented
646*/
648NTAPI
650 _In_ const struct in6_addr *Address,
651 _In_ ULONG ScopeId,
653 _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWCHAR AddressString,
654 _Inout_ PULONG AddressStringLength)
655{
657 PWCHAR S = Buffer;
660 size_t Remaining;
661
662 if (!Address || !AddressString || !AddressStringLength)
664
665 if (Port)
666 *S++ = L'[';
667
669 ASSERT(S != (PCWSTR)~0);
670 if (S == (PCWSTR)~0)
672
673 ASSERT(S >= Buffer);
675 Remaining = RTL_NUMBER_OF(Buffer) - (S - Buffer);
677
678 if (ScopeId)
679 {
681 Remaining,
682 &S,
683 &Remaining,
684 0,
685 L"%%%u",
686 ScopeId);
688 if (!NT_SUCCESS(Status))
690 }
691
692 if (Port)
693 {
695 Remaining,
696 &S,
697 &Remaining,
698 0,
699 L"]:%u",
700 WN2H(Port));
702 if (!NT_SUCCESS(Status))
704 }
705
706 Length = S - Buffer;
708 if (*AddressStringLength > Length)
709 {
710 Status = RtlStringCchCopyW(AddressString, *AddressStringLength, Buffer);
712 *AddressStringLength = Length + 1;
713 return STATUS_SUCCESS;
714 }
715
716 *AddressStringLength = Length + 1;
718}
719
720/*
721* @implemented
722*/
724NTAPI
727 _Out_ PCSTR *Terminator,
728 _Out_ struct in6_addr *Addr)
729{
731 ANSI_STRING StringA;
733 PCWSTR TerminatorW = NULL;
734
735 Status = RtlInitAnsiStringEx(&StringA, String);
736 if (!NT_SUCCESS(Status))
737 return Status;
738
740 if (!NT_SUCCESS(Status))
741 return Status;
742
743 Status = RtlIpv6StringToAddressW(StringW.Buffer, &TerminatorW, Addr);
744 /* on windows the terminator is not always written, so we mimic that behavior. */
745 if (TerminatorW)
746 *Terminator = String + (TerminatorW - StringW.Buffer);
747
749 return Status;
750}
751
752/*
753* @implemented
754*/
756NTAPI
758 _In_ PCSTR AddressString,
759 _Out_ struct in6_addr *Address,
760 _Out_ PULONG ScopeId,
762{
764 ANSI_STRING AddressA;
765 UNICODE_STRING AddressW;
766
767 Status = RtlInitAnsiStringEx(&AddressA, AddressString);
768 if (!NT_SUCCESS(Status))
769 return Status;
770
771 Status = RtlAnsiStringToUnicodeString(&AddressW, &AddressA, TRUE);
772 if (!NT_SUCCESS(Status))
773 return Status;
774
775 Status = RtlIpv6StringToAddressExW(AddressW.Buffer, Address, ScopeId, Port);
776
777 RtlFreeUnicodeString(&AddressW);
778 return Status;
779}
780
781/*
782 * RtlIpv6StringToAddress[Ex]W implementation was imported from Wine 9.6 at 20/4/2024
783 *
784 * This library is free software; you can redistribute it and/or
785 * modify it under the terms of the GNU Lesser General Public
786 * License as published by the Free Software Foundation; either
787 * version 2.1 of the License, or (at your option) any later version.
788 *
789 * For full text of the license see COPYING.LIB in the root of this project.
790 *
791 * Copyright 2020 Alex Henrie
792 */
793
794static const int hex_table[] = {
795 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
796 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
797 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x20-0x2F */
798 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
799 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x40-0x4F */
800 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x50-0x5F */
801 -1, 10, 11, 12, 13, 14, 15 /* 0x60-0x66 */
802};
803
805{
806 int base = 10, d;
807 WCHAR c;
808 ULONG cur_value, prev_value = 0;
810
811 if (**str == '.')
812 {
813 *str += 1;
814 return FALSE;
815 }
816
817 if ((*str)[0] == '0')
818 {
819 if ((*str)[1] == 'x' || (*str)[1] == 'X')
820 {
821 *str += 2;
822 if (strict) return FALSE;
823 base = 16;
824 }
825 else if ((*str)[1] >= '0' && (*str)[1] <= '9')
826 {
827 *str += 1;
828 if (strict) return FALSE;
829 base = 8;
830 }
831 }
832
833 for (cur_value = 0; **str; *str += 1)
834 {
835 c = **str;
836 if (c >= ARRAYSIZE(hex_table)) break;
837 d = hex_table[c];
838 if (d == -1 || d >= base) break;
839 cur_value = cur_value * base + d;
840 success = TRUE;
841 if (cur_value < prev_value) return FALSE; /* overflow */
842 prev_value = cur_value;
843 }
844
845 if (success) *value = cur_value;
846 return success;
847}
848
850{
851 WCHAR *terminator;
852 if (**str >= ARRAYSIZE(hex_table) || hex_table[**str] == -1) return FALSE;
853 *value = min(wcstoul(*str, &terminator, base), 0x7FFFFFFF);
854 if (*terminator == '0') terminator++; /* "0x" but nothing valid after */
855 else if (terminator == *str) return FALSE;
856 *str = terminator;
857 return TRUE;
858}
859
861 const WCHAR **terminator, IN6_ADDR *address, ULONG *scope, USHORT *port)
862{
863 BOOL expecting_port = FALSE, has_0x = FALSE, too_big = FALSE;
864 int n_bytes = 0, n_ipv4_bytes = 0, gap = -1;
865 ULONG ip_component, scope_component = 0, port_component = 0;
866 const WCHAR *prev_str;
867
868 if (str[0] == '[')
869 {
870 if (!ex) goto error;
871 expecting_port = TRUE;
872 str++;
873 }
874
875 if (str[0] == ':')
876 {
877 if (str[1] != ':') goto error;
878 str++;
879 address->u.Word[0] = 0;
880 }
881
882 for (;;)
883 {
884 if (!n_ipv4_bytes && *str == ':')
885 {
886 /* double colon */
887 if (gap != -1) goto error;
888 str++;
889 prev_str = str;
890 gap = n_bytes;
891 if (n_bytes == 14 || !parse_ipv6_component(&str, 16, &ip_component)) break;
892 str = prev_str;
893 }
894 else
895 {
896 prev_str = str;
897 }
898
899 if (!n_ipv4_bytes && n_bytes <= (gap != -1 ? 10 : 12))
900 {
901 if (parse_ipv6_component(&str, 10, &ip_component) && *str == '.')
902 n_ipv4_bytes = 1;
903 str = prev_str;
904 }
905
906 if (n_ipv4_bytes)
907 {
908 /* IPv4 component */
909 if (!parse_ipv6_component(&str, 10, &ip_component)) goto error;
910 if (str - prev_str > 3 || ip_component > 255)
911 {
912 too_big = TRUE;
913 }
914 else
915 {
916 if (*str != '.' && (n_ipv4_bytes < 4 || (n_bytes < 15 && gap == -1))) goto error;
917 address->u.Byte[n_bytes] = ip_component;
918 n_bytes++;
919 }
920 if (n_ipv4_bytes == 4 || *str != '.') break;
921 n_ipv4_bytes++;
922 }
923 else
924 {
925 /* IPv6 component */
926 if (!parse_ipv6_component(&str, 16, &ip_component)) goto error;
927 if (prev_str[0] == '0' && (prev_str[1] == 'x' || prev_str[1] == 'X'))
928 {
929 /* Windows "feature": the last IPv6 component can start with "0x" and be longer than 4 digits */
930 if (terminator) *terminator = prev_str + 1; /* Windows says that the "x" is the terminator */
931 if (n_bytes < 14 && gap == -1) return STATUS_INVALID_PARAMETER;
932 address->u.Word[n_bytes/2] = RtlUshortByteSwap(ip_component);
933 n_bytes += 2;
934 has_0x = TRUE;
935 goto fill_gap;
936 }
937 if (*str != ':' && n_bytes < 14 && gap == -1) goto error;
938 if (str - prev_str > 4)
939 too_big = TRUE;
940 else
941 address->u.Word[n_bytes/2] = RtlUshortByteSwap(ip_component);
942 n_bytes += 2;
943 if (*str != ':' || (gap != -1 && str[1] == ':')) break;
944 }
945 if (n_bytes == (gap != -1 ? 14 : 16)) break;
946 if (too_big) return STATUS_INVALID_PARAMETER;
947 str++;
948 }
949
950 if (terminator) *terminator = str;
951 if (too_big) return STATUS_INVALID_PARAMETER;
952
953fill_gap:
954 if (gap == -1)
955 {
956 if (n_bytes < 16) goto error;
957 }
958 else
959 {
960 memmove(address->u.Byte + 16 - (n_bytes - gap), address->u.Byte + gap, n_bytes - gap);
961 memset(address->u.Byte + gap, 0, 16 - n_bytes);
962 }
963
964 if (ex)
965 {
966 if (has_0x) goto error;
967
968 if (*str == '%')
969 {
970 str++;
971 if (!parse_ipv4_component(&str, TRUE, &scope_component)) goto error;
972 }
973
974 if (expecting_port)
975 {
976 if (*str != ']') goto error;
977 str++;
978 if (*str == ':')
979 {
980 str++;
981 if (!parse_ipv4_component(&str, FALSE, &port_component)) goto error;
982 if (!port_component || port_component > 0xFFFF || *str) goto error;
983 port_component = RtlUshortByteSwap(port_component);
984 }
985 }
986 }
987
988 if (!terminator && *str) return STATUS_INVALID_PARAMETER;
989
990 if (scope) *scope = scope_component;
991 if (port) *port = port_component;
992
993 return STATUS_SUCCESS;
994
995error:
996 if (terminator) *terminator = str;
998}
999
1000/*
1001* @implemented
1002*/
1004NTAPI
1007 _Out_ PCWSTR *Terminator,
1008 _Out_ struct in6_addr *Addr)
1009{
1010 if (!String || !Terminator || !Addr)
1012
1013 return ipv6_string_to_address(String, FALSE, Terminator, Addr, NULL, NULL);
1014}
1015
1016/*
1017* @implemented
1018*/
1020NTAPI
1022 _In_ PCWSTR AddressString,
1023 _Out_ struct in6_addr *Address,
1024 _Out_ PULONG ScopeId,
1026{
1027 if (!AddressString || !Address || !ScopeId || !Port)
1029
1030 return ipv6_string_to_address(AddressString, TRUE, NULL, Address, ScopeId, Port);
1031}
1032
1033/* End of Wine implementation */
1034
1035/* EOF */
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
@ Out
#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 ARRAYSIZE(array)
Definition: filtermapper.c:47
#define RtlUlongByteSwap(_x)
Definition: compat.h:815
USHORT port
Definition: uri.c:228
#define CHAR_BIT
Definition: urlcache.c:62
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
GLdouble n
Definition: glext.h:7729
GLuint address
Definition: glext.h:9393
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
CPPORT Port[4]
Definition: headless.c:35
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI NTSTATUS WINAPI RtlInitAnsiStringEx(PANSI_STRING, PCSZ)
static const WCHAR StringW[]
Definition: global.c:49
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#define error(str)
Definition: mkdosfs.c:1605
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define ASSERT(a)
Definition: mode.c:44
static int strict
Definition: error.c:51
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2451
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteN(_Out_ PCHAR MbString, _In_ ULONG MbSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:107
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_to_(s, c)
Definition: no_sal2.h:188
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEAPI RtlStringCchCopyA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:110
NTSTRSAFEVAPI RtlStringCchPrintfExA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd, _Out_opt_ size_t *pcchRemaining, _In_ STRSAFE_DWORD dwFlags, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1218
NTSTRSAFEVAPI RtlStringCchPrintfExW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd, _Out_opt_ size_t *pcchRemaining, _In_ STRSAFE_DWORD dwFlags, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1246
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
const WCHAR * str
#define S(x)
Definition: test.h:220
#define memset(x, y, z)
Definition: compat.h:39
PWSTR NTAPI RtlIpv6AddressToStringW(_In_ const struct in6_addr *Addr, _Out_writes_(RTLIPV6A2S_MAX_LEN) PWSTR S)
Definition: network.c:539
NTSTATUS NTAPI RtlIpv4StringToAddressExA(_In_ PCSTR AddressString, _In_ BOOLEAN Strict, _Out_ struct in_addr *Address, _Out_ PUSHORT Port)
Definition: network.c:355
#define RTLIPV6A2S_MAX_LEN
Definition: network.c:23
#define IPV4_PORT_STRING_MAX_LEN
Definition: network.c:20
PSTR NTAPI RtlIpv4AddressToStringA(_In_ const struct in_addr *Addr, _Out_writes_(IPV4_ADDR_STRING_MAX_LEN) PCHAR S)
Definition: network.c:154
PWSTR NTAPI RtlIpv4AddressToStringW(_In_ const struct in_addr *Addr, _Out_writes_(IPV4_ADDR_STRING_MAX_LEN) PWCHAR S)
Definition: network.c:236
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
NTSTATUS NTAPI RtlIpv6StringToAddressExW(_In_ PCWSTR AddressString, _Out_ struct in6_addr *Address, _Out_ PULONG ScopeId, _Out_ PUSHORT Port)
Definition: network.c:1021
static NTSTATUS RtlpStringToUlongBase(_In_ PCWSTR String, _In_ ULONG Base, _Out_ PCWSTR *Terminator, _Out_ PULONG Out)
Definition: network.c:36
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
static NTSTATUS ipv6_string_to_address(const WCHAR *str, BOOL ex, const WCHAR **terminator, IN6_ADDR *address, ULONG *scope, USHORT *port)
Definition: network.c:860
static NTSTATUS RtlpStringToUlong(_In_ PCWSTR String, _In_ BOOLEAN Strict, _Out_ PCWSTR *Terminator, _Out_ PULONG Out)
Definition: network.c:80
NTSTATUS NTAPI RtlIpv4StringToAddressW(_In_ PCWSTR String, _In_ BOOLEAN Strict, _Out_ PCWSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:385
static const int hex_table[]
Definition: network.c:794
#define IPV4_ADDR_STRING_MAX_LEN
Definition: network.c:17
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
static BOOL parse_ipv4_component(const WCHAR **str, BOOL strict, ULONG *value)
Definition: network.c:804
static BOOL parse_ipv6_component(const WCHAR **str, int base, ULONG *value)
Definition: network.c:849
#define WN2H(w)
Definition: network.c:29
#define RTLIPV6A2SEX_MAX_LEN
Definition: network.c:26
NTSTATUS NTAPI RtlIpv6StringToAddressExA(_In_ PCSTR AddressString, _Out_ struct in6_addr *Address, _Out_ PULONG ScopeId, _Out_ PUSHORT Port)
Definition: network.c:757
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 RtlIpv4StringToAddressA(_In_ PCSTR String, _In_ BOOLEAN Strict, _Out_ PCSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:318
NTSTATUS NTAPI RtlIpv6StringToAddressW(_In_ PCWSTR String, _Out_ PCWSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:1005
PSTR NTAPI RtlIpv6AddressToStringA(_In_ const struct in6_addr *Addr, _Out_writes_(RTLIPV6A2S_MAX_LEN) PSTR S)
Definition: network.c:479
NTSTATUS NTAPI RtlIpv6StringToAddressA(_In_ PCSTR String, _Out_ PCSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:725
NTSTATUS NTAPI RtlpIpv4StringToAddressParserW(_In_ PCWSTR String, _In_ BOOLEAN Strict, _Out_ PCWSTR *Terminator, _Out_writes_(4) ULONG *Values, _Out_ INT *Parts)
Definition: network.c:116
NTSTATUS NTAPI RtlIpv4StringToAddressExW(_In_ PCWSTR AddressString, _In_ BOOLEAN Strict, _Out_ struct in_addr *Address, _Out_ PUSHORT Port)
Definition: network.c:430
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: movable.cpp:9
Definition: comerr.c:44
Definition: inet.h:67
Definition: tcpip.h:126
#define towlower(c)
Definition: wctype.h:97
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
int32_t INT
Definition: typedefs.h:58
uint16_t * PUSHORT
Definition: typedefs.h:56
const char * PCSTR
Definition: typedefs.h:52
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: pdh_main.c:94
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
#define success(from, fromstr, to, tostr)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_In_ ULONG Shift
Definition: rtlfuncs.h:2698
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3214
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1647
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175