Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
4.7 KiB

  1. //=============================================================================
  2. // Copyright (c) Microsoft Corporation
  3. // Abstract:
  4. // This module implements string-address conversion functions.
  5. //=============================================================================
  6. #include "precomp.h"
  7. #pragma hdrstop
  8. WCHAR *
  9. FormatIPv6Address(
  10. IN IN6_ADDR *Address,
  11. IN DWORD dwScopeId
  12. )
  13. /*++
  14. Routine Description:
  15. Converts an IPv6 address to a string in a static buffer.
  16. Arguments:
  17. Address - Supplies the IPv6 address.
  18. dwScopeId - Supplies the scope identifier.
  19. Returns:
  20. Pointer to static buffer holding address literal string.
  21. --*/
  22. {
  23. static WCHAR Buffer[128];
  24. ULONG buflen = sizeof(Buffer);
  25. SOCKADDR_IN6 sin6;
  26. ZeroMemory(&sin6, sizeof(sin6));
  27. sin6.sin6_family = AF_INET6;
  28. sin6.sin6_scope_id = dwScopeId;
  29. sin6.sin6_addr = *Address;
  30. if (WSAAddressToString((SOCKADDR *) &sin6,
  31. sizeof sin6,
  32. NULL, // LPWSAPROTOCOL_INFO
  33. Buffer,
  34. &buflen) == SOCKET_ERROR) {
  35. wcscpy(Buffer, L"???");
  36. }
  37. return Buffer;
  38. }
  39. WCHAR *
  40. FormatIPv6Prefix(
  41. IN IN6_ADDR *Address,
  42. IN ULONG Length
  43. )
  44. {
  45. static WCHAR Buffer[128];
  46. swprintf(Buffer, L"%s/%d", FormatIPv6Address(Address, 0), Length);
  47. return Buffer;
  48. }
  49. WCHAR *
  50. FormatIPv4Address(
  51. IN IN_ADDR *Address
  52. )
  53. {
  54. static WCHAR Buffer[128];
  55. ULONG buflen = sizeof(Buffer);
  56. SOCKADDR_IN sin;
  57. ZeroMemory(&sin, sizeof(sin));
  58. sin.sin_family = AF_INET;
  59. sin.sin_addr = *Address;
  60. if (WSAAddressToString((SOCKADDR *) &sin,
  61. sizeof sin,
  62. NULL, // LPWSAPROTOCOL_INFO
  63. Buffer,
  64. &buflen) == SOCKET_ERROR) {
  65. wcscpy(Buffer, L"<invalid>");
  66. }
  67. return Buffer;
  68. }
  69. WCHAR *
  70. FormatLinkLayerAddress(
  71. IN ULONG Length,
  72. IN UCHAR *Addr
  73. )
  74. {
  75. static WCHAR Buffer[128];
  76. switch (Length) {
  77. case 6: {
  78. int i, digit;
  79. WCHAR *s = Buffer;
  80. for (i = 0; i < 6; i++) {
  81. if (i != 0)
  82. *s++ = '-';
  83. digit = Addr[i] >> 4;
  84. if (digit < 10)
  85. *s++ = digit + '0';
  86. else
  87. *s++ = digit - 10 + 'a';
  88. digit = Addr[i] & 0xf;
  89. if (digit < 10)
  90. *s++ = digit + '0';
  91. else
  92. *s++ = digit - 10 + 'a';
  93. }
  94. *s = '\0';
  95. break;
  96. }
  97. case 4:
  98. //
  99. // IPv4 Address (6-over-4 link)
  100. //
  101. wcscpy(Buffer, FormatIPv4Address((struct in_addr *)Addr));
  102. break;
  103. case 0:
  104. default:
  105. //
  106. // Null or loop-back address
  107. //
  108. Buffer[0] = '\0';
  109. break;
  110. }
  111. return Buffer;
  112. }
  113. DWORD
  114. GetIpv4Address(
  115. IN PWCHAR pwszArgument,
  116. OUT IN_ADDR *pipAddress
  117. )
  118. /*++
  119. Routine Description:
  120. Gets the IPv4 address from the string.
  121. Arguments:
  122. pwszArgument argument specifing an ip address
  123. pipAddress ip address
  124. Return Value:
  125. NO_ERROR if success
  126. Failure code o/w
  127. --*/
  128. {
  129. NTSTATUS ntStatus;
  130. PWCHAR Terminator;
  131. //
  132. // Parse unicode IPv4 address with "strict" semantics (full dotted-decimal
  133. // only). There's no other function that does this today other than
  134. // the Rtl function below.
  135. //
  136. ntStatus = RtlIpv4StringToAddressW(pwszArgument, TRUE, &Terminator,
  137. pipAddress);
  138. if (!NT_SUCCESS(ntStatus) || (*Terminator != 0)) {
  139. return ERROR_INVALID_PARAMETER;
  140. }
  141. return NO_ERROR;
  142. }
  143. DWORD
  144. GetIpv6Prefix(
  145. IN PWCHAR pwszArgument,
  146. OUT IN6_ADDR *pipAddress,
  147. OUT DWORD *dwPrefixLength
  148. )
  149. {
  150. NTSTATUS ntStatus;
  151. PWCHAR Terminator;
  152. DWORD Length = 0;
  153. ntStatus = RtlIpv6StringToAddressW(pwszArgument, &Terminator,
  154. pipAddress);
  155. if (!NT_SUCCESS(ntStatus) || (*Terminator++ != L'/')) {
  156. return ERROR_INVALID_PARAMETER;
  157. }
  158. while (iswdigit(*Terminator)) {
  159. Length = (Length * 10) + (*Terminator++ - L'0');
  160. }
  161. if (*Terminator != 0) {
  162. return ERROR_INVALID_PARAMETER;
  163. }
  164. *dwPrefixLength = Length;
  165. return NO_ERROR;
  166. }
  167. DWORD
  168. GetIpv6Address(
  169. IN PWCHAR pwszArgument,
  170. OUT IN6_ADDR *pipAddress
  171. )
  172. {
  173. NTSTATUS ntStatus;
  174. PWCHAR Terminator;
  175. ntStatus = RtlIpv6StringToAddressW(pwszArgument, &Terminator,
  176. pipAddress);
  177. if (!NT_SUCCESS(ntStatus) || (*Terminator != 0)) {
  178. return ERROR_INVALID_PARAMETER;
  179. }
  180. return NO_ERROR;
  181. }