ReactOS  0.4.14-dev-55-g2da92ac
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) */
34 static
38  _In_ ULONG Base,
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 
78 static
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 /* Tell us what possible base the string could be in, 10 or 16 by looking at the characters.
114  Invalid characters break the operation */
115 static
116 ULONG
118 {
119  ULONG Len = 0;
120  *Base = 0;
121  for (Len = 0; S[Len]; ++Len)
122  {
123  if (iswascii(S[Len]) && isdigit(S[Len]))
124  *Base = max(*Base, 10);
125  else if (iswascii(S[Len]) && isxdigit(S[Len]))
126  *Base = 16;
127  else
128  break;
129  }
130  return Len;
131 }
132 
133 /* Worker function to extract the ipv4 part of a string. */
134 NTSTATUS
135 NTAPI
138  _In_ BOOLEAN Strict,
139  _Out_ PCWSTR *Terminator,
140  _Out_writes_(4) ULONG *Values,
141  _Out_ INT *Parts)
142 {
144  *Parts = 0;
145  do
146  {
147  Status = RtlpStringToUlong(String, Strict, &String, &Values[*Parts]);
148  (*Parts)++;
149 
150  if (*String != L'.')
151  break;
152 
153  /* Already four parts, but a dot follows? */
154  if (*Parts == 4)
155  {
157  break;
158  }
159  /* Skip the dot */
160  String++;
161  } while (NT_SUCCESS(Status));
162 
163  *Terminator = String;
164  return Status;
165 }
166 
167 /* PUBLIC FUNCTIONS ***********************************************************/
168 
169 /*
170  * @implemented
171  */
172 PSTR
173 NTAPI
175  _In_ const struct in_addr *Addr,
177 {
179  PSTR End;
180 
181  if (!S)
182  return (PSTR)~0;
183 
186  &End,
187  NULL,
188  0,
189  "%u.%u.%u.%u",
190  Addr->S_un.S_un_b.s_b1,
191  Addr->S_un.S_un_b.s_b2,
192  Addr->S_un.S_un_b.s_b3,
193  Addr->S_un.S_un_b.s_b4);
195  if (!NT_SUCCESS(Status))
196  return (PSTR)~0;
197 
198  return End;
199 }
200 
201 /*
202  * @implemented
203  */
204 NTSTATUS
205 NTAPI
207  _In_ const struct in_addr *Address,
208  _In_ USHORT Port,
209  _Out_writes_to_(*AddressStringLength, *AddressStringLength) PCHAR AddressString,
210  _Inout_ PULONG AddressStringLength)
211 {
214  ULONG Length;
215  PSTR End;
216 
217  if (!Address || !AddressString || !AddressStringLength)
219 
222  &End,
223  NULL,
224  0,
225  Port ? "%u.%u.%u.%u:%u"
226  : "%u.%u.%u.%u",
227  Address->S_un.S_un_b.s_b1,
228  Address->S_un.S_un_b.s_b2,
229  Address->S_un.S_un_b.s_b3,
230  Address->S_un.S_un_b.s_b4,
231  WN2H(Port));
233  if (!NT_SUCCESS(Status))
235 
236  Length = End - Buffer;
237  if (*AddressStringLength > Length)
238  {
239  Status = RtlStringCchCopyA(AddressString,
240  *AddressStringLength,
241  Buffer);
243  *AddressStringLength = Length + 1;
244  return STATUS_SUCCESS;
245  }
246 
247  *AddressStringLength = Length + 1;
249 }
250 
251 /*
252  * @implemented
253  */
254 PWSTR
255 NTAPI
257  _In_ const struct in_addr *Addr,
259 {
261  PWSTR End;
262 
263  if (!S)
264  return (PWSTR)~0;
265 
268  &End,
269  NULL,
270  0,
271  L"%u.%u.%u.%u",
272  Addr->S_un.S_un_b.s_b1,
273  Addr->S_un.S_un_b.s_b2,
274  Addr->S_un.S_un_b.s_b3,
275  Addr->S_un.S_un_b.s_b4);
277  if (!NT_SUCCESS(Status))
278  return (PWSTR)~0;
279 
280  return End;
281 }
282 
283 /*
284  * @implemented
285  */
286 NTSTATUS
287 NTAPI
289  _In_ const struct in_addr *Address,
290  _In_ USHORT Port,
291  _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWCHAR AddressString,
292  _Inout_ PULONG AddressStringLength)
293 {
296  ULONG Length;
297  PWSTR End;
298 
299  if (!Address || !AddressString || !AddressStringLength)
301 
304  &End,
305  NULL,
306  0,
307  Port ? L"%u.%u.%u.%u:%u"
308  : L"%u.%u.%u.%u",
309  Address->S_un.S_un_b.s_b1,
310  Address->S_un.S_un_b.s_b2,
311  Address->S_un.S_un_b.s_b3,
312  Address->S_un.S_un_b.s_b4,
313  WN2H(Port));
315  if (!NT_SUCCESS(Status))
317 
318  Length = End - AddressString;
319  if (*AddressStringLength > Length)
320  {
321  Status = RtlStringCchCopyW(AddressString,
322  *AddressStringLength,
323  Buffer);
325  *AddressStringLength = Length + 1;
326  return STATUS_SUCCESS;
327  }
328 
329  *AddressStringLength = Length + 1;
331 }
332 
333 /*
334  * @implemented
335  */
336 NTSTATUS
337 NTAPI
339  _In_ PCSTR String,
340  _In_ BOOLEAN Strict,
341  _Out_ PCSTR *Terminator,
342  _Out_ struct in_addr *Addr)
343 {
345  ANSI_STRING AddressA;
346  UNICODE_STRING AddressW;
347  PCWSTR TerminatorW = NULL;
348 
349  Status = RtlInitAnsiStringEx(&AddressA, String);
350  if (!NT_SUCCESS(Status))
351  return Status;
352 
353  Status = RtlAnsiStringToUnicodeString(&AddressW, &AddressA, TRUE);
354  if (!NT_SUCCESS(Status))
355  return Status;
356 
358  Strict,
359  &TerminatorW,
360  Addr);
361 
362  ASSERT(TerminatorW >= AddressW.Buffer);
363  *Terminator = String + (TerminatorW - AddressW.Buffer);
364 
365  RtlFreeUnicodeString(&AddressW);
366 
367  return Status;
368 }
369 
370 /*
371  * @implemented
372  */
373 NTSTATUS
374 NTAPI
376  _In_ PCSTR AddressString,
377  _In_ BOOLEAN Strict,
378  _Out_ struct in_addr *Address,
380 {
382  ANSI_STRING AddressA;
383  UNICODE_STRING AddressW;
384 
385  Status = RtlInitAnsiStringEx(&AddressA, AddressString);
386  if (!NT_SUCCESS(Status))
387  return Status;
388 
389  Status = RtlAnsiStringToUnicodeString(&AddressW, &AddressA, TRUE);
390  if (!NT_SUCCESS(Status))
391  return Status;
392 
393  Status = RtlIpv4StringToAddressExW(AddressW.Buffer, Strict, Address, Port);
394 
395  RtlFreeUnicodeString(&AddressW);
396 
397  return Status;
398 }
399 
400 /*
401  * @implemented
402  */
403 NTSTATUS
404 NTAPI
407  _In_ BOOLEAN Strict,
408  _Out_ PCWSTR *Terminator,
409  _Out_ struct in_addr *Addr)
410 {
412  ULONG Values[4];
413  ULONG Result;
414  INT Parts = 0;
415  INT i;
416 
418  Strict,
419  Terminator,
420  Values,
421  &Parts);
422  if (Strict && Parts < 4)
424 
425  if (!NT_SUCCESS(Status))
426  return Status;
427 
428  /* Combine the parts */
429  Result = Values[Parts - 1];
430  for (i = 0; i < Parts - 1; i++)
431  {
432  INT Shift = CHAR_BIT * (3 - i);
433 
434  if (Values[i] > 0xFF || (Result & (0xFF << Shift)) != 0)
435  {
437  }
438  Result |= Values[i] << Shift;
439  }
440 
441  Addr->S_un.S_addr = RtlUlongByteSwap(Result);
442  return Status;
443 }
444 
445 /*
446 * @implemented
447 */
448 NTSTATUS
449 NTAPI
451  _In_ PCWSTR AddressString,
452  _In_ BOOLEAN Strict,
453  _Out_ struct in_addr *Address,
455 {
456  PCWSTR CurrentChar;
457  ULONG ConvertedPort;
459 
460  if (!AddressString || !Address || !Port)
462 
463  Status = RtlIpv4StringToAddressW(AddressString,
464  Strict,
465  &CurrentChar,
466  Address);
467  if (!NT_SUCCESS(Status))
468  return Status;
469 
470  if (!*CurrentChar)
471  {
472  *Port = 0;
473  return STATUS_SUCCESS;
474  }
475 
476  if (*CurrentChar != L':')
478  ++CurrentChar;
479 
480  Status = RtlpStringToUlong(CurrentChar,
481  FALSE,
482  &CurrentChar,
483  &ConvertedPort);
484  if (!NT_SUCCESS(Status))
485  return Status;
486 
487  if (*CurrentChar || !ConvertedPort || ConvertedPort > 0xffff)
489 
490  *Port = WN2H(ConvertedPort);
491  return STATUS_SUCCESS;
492 }
493 
494 /*
495 * @implemented
496 */
497 PSTR
498 NTAPI
500  _In_ const struct in6_addr *Addr,
502 {
504  PWSTR Result;
506 
507  if (!S)
508  return (PSTR)~0;
509 
510  Buffer[0] = 0;
512  if (Result == (PWSTR)~0)
513  return (PSTR)~0;
514 
515  ASSERT(Result >= Buffer);
517 
519  if (!NT_SUCCESS(Status))
520  return (PSTR)~0;
521 
522  return S + strlen(S);
523 }
524 
525 /*
526 * @implemented
527 */
528 NTSTATUS
529 NTAPI
531  _In_ const struct in6_addr *Address,
532  _In_ ULONG ScopeId,
533  _In_ USHORT Port,
534  _Out_writes_to_(*AddressStringLength, *AddressStringLength) PSTR AddressString,
535  _Inout_ PULONG AddressStringLength)
536 {
539 
540  if (!Address || !AddressString || !AddressStringLength)
542 
543  Status = RtlIpv6AddressToStringExW(Address, ScopeId, Port, Buffer, AddressStringLength);
544  if (!NT_SUCCESS(Status))
545  return Status;
546 
547  Status = RtlUnicodeToMultiByteN(AddressString, RTLIPV6A2SEX_MAX_LEN, NULL, Buffer, (*AddressStringLength + 1) * sizeof(WCHAR));
548  if (!NT_SUCCESS(Status))
550 
551  return STATUS_SUCCESS;
552 }
553 
554 /*
555 * @implemented
556 */
557 PWSTR
558 NTAPI
560  _In_ const struct in6_addr *Addr,
562 {
564  UINT Parts = 8, n;
565  BOOLEAN SkipOnce = TRUE;
566  PWSTR End;
567  size_t Remaining;
568 
569  if (!S)
570  return (PWSTR)~0;
571 
572  Remaining = RTLIPV6A2S_MAX_LEN;
573  /* does it look like an ipv4 address contained in an ipv6? http://tools.ietf.org/html/rfc2765 */
574  if (!Addr->s6_words[0] && !Addr->s6_words[1] && !Addr->s6_words[2] && !Addr->s6_words[3] && Addr->s6_words[6])
575  {
576  PWSTR Prefix = NULL;
577  if (Addr->s6_words[4] == 0xffff && !Addr->s6_words[5])
578  Prefix = L"ffff:0:";
579  else if (!Addr->s6_words[4] && Addr->s6_words[5] == 0xffff)
580  Prefix = L"ffff:";
581  else if (!Addr->s6_words[4] && !Addr->s6_words[5])
582  Prefix = L"";
583  if (Prefix != NULL)
584  {
586  Remaining,
587  &End,
588  NULL,
589  0,
590  L"::%ls%u.%u.%u.%u",
591  Prefix,
592  Addr->s6_bytes[12],
593  Addr->s6_bytes[13],
594  Addr->s6_bytes[14],
595  Addr->s6_bytes[15]);
597  if (!NT_SUCCESS(Status))
598  return (PWSTR)~0;
599  return End;
600  }
601  }
602 
603  /* does it look like an ISATAP address? http://tools.ietf.org/html/rfc5214 */
604  if (!(Addr->s6_words[4] & 0xfffd) && Addr->s6_words[5] == 0xfe5e)
605  Parts = 6;
606 
607  for (n = 0; n < Parts; ++n)
608  {
609  if (SkipOnce && ((n + 1) < Parts) && !Addr->s6_words[n] && !Addr->s6_words[n + 1])
610  {
611  SkipOnce = FALSE;
612  while (!Addr->s6_words[n + 1] && (n + 1) < Parts)
613  ++n;
614  *S++ = ':';
615  Remaining--;
616  if ((n + 1) >= Parts)
617  {
618  *S++ = ':';
619  Remaining--;
620  }
621  }
622  else
623  {
624  if (n)
625  {
626  *S++ = ':';
627  Remaining--;
628  }
630  Remaining,
631  &End,
632  &Remaining,
633  0,
634  L"%x",
635  WN2H(Addr->s6_words[n]));
637  if (!NT_SUCCESS(Status))
638  return (PWSTR)~0;
639  S = End;
640  }
641  }
642  if (Parts < 8)
643  {
645  Remaining,
646  &End,
647  NULL,
648  0,
649  L":%u.%u.%u.%u",
650  Addr->s6_bytes[12],
651  Addr->s6_bytes[13],
652  Addr->s6_bytes[14],
653  Addr->s6_bytes[15]);
655  if (!NT_SUCCESS(Status))
656  return (PWSTR)~0;
657 
658  return End;
659  }
660  *S = UNICODE_NULL;
661  return S;
662 }
663 
664 /*
665 * @implemented
666 */
667 NTSTATUS
668 NTAPI
670  _In_ const struct in6_addr *Address,
671  _In_ ULONG ScopeId,
672  _In_ USHORT Port,
673  _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWCHAR AddressString,
674  _Inout_ PULONG AddressStringLength)
675 {
677  PWCHAR S = Buffer;
679  ULONG Length;
680  size_t Remaining;
681 
682  if (!Address || !AddressString || !AddressStringLength)
684 
685  if (Port)
686  *S++ = L'[';
687 
689  ASSERT(S != (PCWSTR)~0);
690  if (S == (PCWSTR)~0)
692 
693  ASSERT(S >= Buffer);
694  ASSERT(S <= Buffer + RTLIPV6A2S_MAX_LEN + 1);
695  Remaining = RTL_NUMBER_OF(Buffer) - (S - Buffer);
697 
698  if (ScopeId)
699  {
701  Remaining,
702  &S,
703  &Remaining,
704  0,
705  L"%%%u",
706  ScopeId);
708  if (!NT_SUCCESS(Status))
710  }
711 
712  if (Port)
713  {
715  Remaining,
716  &S,
717  &Remaining,
718  0,
719  L"]:%u",
720  WN2H(Port));
722  if (!NT_SUCCESS(Status))
724  }
725 
726  Length = S - Buffer;
728  if (*AddressStringLength > Length)
729  {
730  Status = RtlStringCchCopyW(AddressString, *AddressStringLength, Buffer);
732  *AddressStringLength = Length + 1;
733  return STATUS_SUCCESS;
734  }
735 
736  *AddressStringLength = Length + 1;
738 }
739 
740 /*
741 * @implemented
742 */
743 NTSTATUS
744 NTAPI
746  _In_ PCSTR String,
747  _Out_ PCSTR *Terminator,
748  _Out_ struct in6_addr *Addr)
749 {
751  ANSI_STRING StringA;
753  PCWSTR TerminatorW = NULL;
754 
755  Status = RtlInitAnsiStringEx(&StringA, String);
756  if (!NT_SUCCESS(Status))
757  return Status;
758 
760  if (!NT_SUCCESS(Status))
761  return Status;
762 
763  Status = RtlIpv6StringToAddressW(StringW.Buffer, &TerminatorW, Addr);
764  /* on windows the terminator is not always written, so we mimic that behavior. */
765  if (TerminatorW)
766  *Terminator = String + (TerminatorW - StringW.Buffer);
767 
769  return Status;
770 }
771 
772 /*
773 * @implemented
774 */
775 NTSTATUS
776 NTAPI
778  _In_ PCSTR AddressString,
779  _Out_ struct in6_addr *Address,
780  _Out_ PULONG ScopeId,
782 {
784  ANSI_STRING AddressA;
785  UNICODE_STRING AddressW;
786 
787  Status = RtlInitAnsiStringEx(&AddressA, AddressString);
788  if (!NT_SUCCESS(Status))
789  return Status;
790 
791  Status = RtlAnsiStringToUnicodeString(&AddressW, &AddressA, TRUE);
792  if (!NT_SUCCESS(Status))
793  return Status;
794 
795  Status = RtlIpv6StringToAddressExW(AddressW.Buffer, Address, ScopeId, Port);
796 
797  RtlFreeUnicodeString(&AddressW);
798  return Status;
799 }
800 
801 /*
802 * @implemented
803 */
804 NTSTATUS
805 NTAPI
808  _Out_ PCWSTR *Terminator,
809  _Out_ struct in6_addr *Addr)
810 {
811  INT n, j;
812  INT StartSkip = -1, Parts = 0;
813  ULONG Base, Len;
815  enum { None, Number, Colon, DoubleColon } Last = None;
816  BOOLEAN SkipoutLastHex = FALSE;
817 
818  if (!String || !Terminator || !Addr)
820 
821  for (n = 0; n < 8;)
822  {
824  if (Len == 0)
825  {
826  /* not a number, and no ':' or already encountered an ':' */
827  if (String[0] != ':' || Last == Colon)
828  break;
829 
830  /* double colon, 1 or more fields set to 0. mark the position, and move on. */
831  if (StartSkip == -1 && String[1] == ':')
832  {
833  /* this case was observed in windows, but it does not seem correct. */
834  if (!n)
835  {
836  Addr->s6_words[n++] = 0;
837  Addr->s6_words[n++] = 0;
838  }
839  StartSkip = n;
840  String += 2;
841  Last = DoubleColon;
842  }
843  else if (String[1] == ':' || Last != Number)
844  {
845  /* a double colon after we already encountered one, or a the last parsed item was not a number. */
846  break;
847  }
848  else
849  {
850  ++String;
851  Last = Colon;
852  }
853  }
854  else if (Len > 4)
855  {
856  /* it seems that when encountering more than 4 chars, the terminator is not updated,
857  unless the previously encountered item is a double colon.... */
859  if (Last != DoubleColon)
860  return Status;
861  String += Len;
862  break;
863  }
864  else
865  {
866  ULONG Value;
867  if (String[Len] == '.' && n <= 6)
868  {
869  ULONG Values[4];
870  INT PartsV4 = 0;
871  /* this could be an ipv4 address inside an ipv6 address http://tools.ietf.org/html/rfc2765 */
872  Last = Number;
873  Status = RtlpIpv4StringToAddressParserW(String, TRUE, &String, Values, &PartsV4);
874  for(j = 0; j < PartsV4; ++j)
875  {
876  if (Values[j] > 255)
877  {
879  if (j != 3)
880  return Status;
881  break;
882  }
883  if ((j == PartsV4 - 1) &&
884  (j < 3 ||
885  (*String == ':' && StartSkip == -1) ||
886  (StartSkip == -1 && n < 6) ||
888  {
890  break;
891  }
892  Addr->s6_bytes[n * 2 + j] = Values[j] & 0xff;
893  }
894  /* mark enough parts as converted in case we are the last item to be converted */
895  n += 2;
896  /* mark 2 parts as converted in case we are not the last item, and we encountered a double colon. */
897  Parts+=2;
898  break;
899  }
900 
901  if (String[Len] != ':' && n < 7 && StartSkip == -1)
902  {
903  /* if we decoded atleast some numbers, update the terminator to point to the first invalid char */
904  if (Base)
905  String += Len;
907  break;
908  }
909 
910  if (Len == 1 && towlower(String[Len]) == 'x' && String[0] == '0')
911  {
912  Len = RtlpClassifyChars(String + 2, &Base);
913  if (Len > 0 && Len <= 4)
914  {
915  *Terminator = String + 1;
916  String += 2;
917  SkipoutLastHex = TRUE;
918  }
919  }
920 
922  if (!NT_SUCCESS(Status))
923  break;
924 
925  if (StartSkip != -1)
926  Parts++;
927  Addr->s6_words[n++] = WN2H(Value);
928  Last = Number;
929  if (SkipoutLastHex)
930  break;
931  }
932  }
933 
934  if (StartSkip != -1 && Status != STATUS_INVALID_PARAMETER && Last != Colon)
935  {
936  /* we found a '::' somewhere, so expand that. */
937  memmove(&Addr->s6_words[8-Parts], &Addr->s6_words[StartSkip], Parts * sizeof(Addr->s6_words[0]));
938  memset(&Addr->s6_words[StartSkip], 0, (8-StartSkip-Parts) * sizeof(Addr->s6_words[0]));
939  n = 8;
940  }
941 
942  /* we have already set the terminator */
943  if (SkipoutLastHex)
944  return n < 8 ? STATUS_INVALID_PARAMETER : Status;
945  *Terminator = String;
946  return n < 8 ? STATUS_INVALID_PARAMETER : Status;
947 }
948 
949 /*
950 * @implemented
951 */
952 NTSTATUS
953 NTAPI
955  _In_ PCWSTR AddressString,
956  _Out_ struct in6_addr *Address,
957  _Out_ PULONG ScopeId,
959 {
961  ULONG ConvertedPort = 0, ConvertedScope = 0;
962  if (!AddressString || !Address || !ScopeId || !Port)
964 
965  if (*AddressString == '[')
966  {
967  ConvertedPort = 1;
968  ++AddressString;
969  }
970  Status = RtlIpv6StringToAddressW(AddressString, &AddressString, Address);
971  if (!NT_SUCCESS(Status))
973 
974  if (*AddressString == '%')
975  {
976  ++AddressString;
977  Status = RtlpStringToUlongBase(AddressString, 10, &AddressString, &ConvertedScope);
978  if (!NT_SUCCESS(Status))
980  }
981  else if (*AddressString && !(ConvertedPort && *AddressString == ']'))
982  {
984  }
985 
986  if (ConvertedPort)
987  {
988  if (*AddressString++ !=']')
990  if (*AddressString ==':')
991  {
992  ULONG Base = 10;
993  if (*++AddressString == '0')
994  {
995  if (towlower(*++AddressString) != 'x')
997  ++AddressString;
998  Base = 16;
999  }
1000  Status = RtlpStringToUlongBase(AddressString, Base, &AddressString, &ConvertedPort);
1001  if (!NT_SUCCESS(Status) || ConvertedPort > 0xffff)
1002  return STATUS_INVALID_PARAMETER;
1003  }
1004  else
1005  {
1006  ConvertedPort = 0;
1007  }
1008  }
1009 
1010  if (*AddressString == 0)
1011  {
1012  *ScopeId = ConvertedScope;
1013  *Port = WN2H(ConvertedPort);
1014  return STATUS_SUCCESS;
1015  }
1016  return STATUS_INVALID_PARAMETER;
1017 }
1018 
1019 /* EOF */
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
signed char * PCHAR
Definition: retypes.h:7
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
CPPORT Port[4]
Definition: headless.c:34
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define max(a, b)
Definition: svc.c:63
static NTSTATUS RtlpStringToUlongBase(_In_ PCWSTR String, _In_ ULONG Base, _Out_ PCWSTR *Terminator, _Out_ PULONG Out)
Definition: network.c:36
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:530
#define TRUE
Definition: types.h:120
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
NTSTATUS NTAPI RtlIpv4StringToAddressExW(_In_ PCWSTR AddressString, _In_ BOOLEAN Strict, _Out_ struct in_addr *Address, _Out_ PUSHORT Port)
Definition: network.c:450
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI RtlIpv4StringToAddressA(_In_ PCSTR String, _In_ BOOLEAN Strict, _Out_ PCSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:338
uint16_t * PWSTR
Definition: typedefs.h:54
NTSYSAPI NTSTATUS WINAPI RtlInitAnsiStringEx(PANSI_STRING, PCSZ)
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
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:288
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
GLdouble n
Definition: glext.h:7729
#define S(x)
Definition: test.h:190
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:206
#define CHAR_BIT
Definition: urlcache.c:57
PSTR NTAPI RtlIpv6AddressToStringA(_In_ const struct in6_addr *Addr, _Out_writes_(RTLIPV6A2S_MAX_LEN) PSTR S)
Definition: network.c:499
static WCHAR String[]
Definition: stringtable.c:55
uint16_t * PWCHAR
Definition: typedefs.h:54
Definition: movable.cpp:7
#define _Out_writes_to_(size, count)
Definition: no_sal2.h:378
PWSTR NTAPI RtlIpv4AddressToStringW(_In_ const struct in_addr *Addr, _Out_writes_(IPV4_ADDR_STRING_MAX_LEN) PWCHAR S)
Definition: network.c:256
int32_t INT
Definition: typedefs.h:56
static ULONG RtlpClassifyChars(PCWSTR S, PULONG Base)
Definition: network.c:117
#define _Out_writes_(size)
Definition: no_sal2.h:367
NTSTATUS NTAPI RtlIpv4StringToAddressW(_In_ PCWSTR String, _In_ BOOLEAN Strict, _Out_ PCWSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:405
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define RTLIPV6A2SEX_MAX_LEN
Definition: network.c:26
#define UNICODE_NULL
#define None
Definition: i386-dis.c:444
NTSTATUS NTAPI RtlpIpv4StringToAddressParserW(_In_ PCWSTR String, _In_ BOOLEAN Strict, _Out_ PCWSTR *Terminator, _Out_writes_(4) ULONG *Values, _Out_ INT *Parts)
Definition: network.c:136
unsigned char BOOLEAN
#define iswascii(_c)
Definition: ctype.h:675
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
_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:426
#define _Out_
Definition: no_sal2.h:323
PSTR NTAPI RtlIpv4AddressToStringA(_In_ const struct in_addr *Addr, _Out_writes_(IPV4_ADDR_STRING_MAX_LEN) PCHAR S)
Definition: network.c:174
Definition: bufpool.h:45
#define isdigit(c)
Definition: acclib.h:68
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 GLint GLint j
Definition: glfuncs.h:250
NTSTATUS NTAPI RtlIpv6StringToAddressExA(_In_ PCSTR AddressString, _Out_ struct in6_addr *Address, _Out_ PULONG ScopeId, _Out_ PUSHORT Port)
Definition: network.c:777
NTSTATUS NTAPI RtlIpv6StringToAddressA(_In_ PCSTR String, _Out_ PCSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:745
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI RtlIpv6StringToAddressW(_In_ PCWSTR String, _Out_ PCWSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:806
Definition: tcpip.h:125
#define Len
Definition: deflate.h:82
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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:669
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeToMultiByteN(PCHAR MbString, ULONG MbSize, PULONG ResultSize, PCWCH UnicodeString, ULONG UnicodeSize)
static const WCHAR L[]
Definition: oid.c:1250
#define IPV4_ADDR_STRING_MAX_LEN
Definition: network.c:17
#define RtlUlongByteSwap(_x)
Definition: compat.h:465
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
Status
Definition: gdiplustypes.h:24
static const WCHAR StringW[]
Definition: global.c:47
#define _In_
Definition: no_sal2.h:204
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTATUS NTAPI RtlIpv6StringToAddressExW(_In_ PCWSTR AddressString, _Out_ struct in6_addr *Address, _Out_ PULONG ScopeId, _Out_ PUSHORT Port)
Definition: network.c:954
unsigned short USHORT
Definition: pedump.c:61
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define WN2H(w)
Definition: network.c:29
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
signed char * PSTR
Definition: retypes.h:7
_In_ ULONG Shift
Definition: rtlfuncs.h:2683
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
#define isxdigit(c)
Definition: acclib.h:70
static NTSTATUS RtlpStringToUlong(_In_ PCWSTR String, _In_ BOOLEAN Strict, _Out_ PCWSTR *Terminator, _Out_ PULONG Out)
Definition: network.c:80
unsigned int ULONG
Definition: retypes.h:1
#define towlower(c)
Definition: wctype.h:97
NTSTRSAFEAPI RtlStringCchCopyA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:110
const char * PCSTR
Definition: typedefs.h:51
PWSTR NTAPI RtlIpv6AddressToStringW(_In_ const struct in6_addr *Addr, _Out_writes_(RTLIPV6A2S_MAX_LEN) PWSTR S)
Definition: network.c:559
#define RTLIPV6A2S_MAX_LEN
Definition: network.c:23
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define memset(x, y, z)
Definition: compat.h:39
NTSTATUS NTAPI RtlIpv4StringToAddressExA(_In_ PCSTR AddressString, _In_ BOOLEAN Strict, _Out_ struct in_addr *Address, _Out_ PUSHORT Port)
Definition: network.c:375
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
unsigned short * PUSHORT
Definition: retypes.h:2
#define IPV4_PORT_STRING_MAX_LEN
Definition: network.c:20
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