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.

296 lines
8.1 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include <winsock2.h>
  4. #include "utils.h"
  5. #define MAXIPSTRLEN 20
  6. //+----------------------------------------------------------------------------
  7. //
  8. // Function: IpAddressFromAbcdWsz
  9. //
  10. // Synopsis:Converts caller's a.b.c.d IP address string to a network byte order IP
  11. // address. 0 if formatted incorrectly.
  12. //
  13. // Arguments: IN const WCHAR* wszIpAddress - ip address in a.b.c.d unicode string
  14. //
  15. // Returns: DWORD - IPAddr, return INADDR_NONE on failure
  16. //
  17. // History: fengsun Created Header 12/8/98
  18. //
  19. //+----------------------------------------------------------------------------
  20. DWORD WINAPI IpAddressFromAbcdWsz(IN const WCHAR* wszIpAddress)
  21. {
  22. CHAR szIpAddress[MAXIPSTRLEN + 1];
  23. DWORD nboIpAddr;
  24. ASSERT(lstrlen(wszIpAddress) < MAXIPSTRLEN);
  25. WideCharToMultiByte(CP_ACP, 0, wszIpAddress, -1,
  26. szIpAddress, sizeof(szIpAddress), NULL, NULL);
  27. nboIpAddr = inet_addr(szIpAddress);
  28. return(nboIpAddr);
  29. }
  30. //+----------------------------------------------------------------------------
  31. //
  32. // Function: IpAddressToAbcdWsz
  33. //
  34. // Synopsis:
  35. // Converts IpAddr to a string in the a.b.c.d form and returns same in
  36. // caller's wszIpAddress buffer. The buffer should be at least
  37. // MAXIPSTRLEN + 1 characters long.
  38. //
  39. // Arguments: IPAddr IpAddress -
  40. // OUT WCHAR* wszIpAddress - buffer at least MAXIPSTRLEN
  41. //
  42. // Returns: void
  43. //
  44. // History: fengsun Created Header 12/21/98
  45. //
  46. //+----------------------------------------------------------------------------
  47. VOID
  48. WINAPI AbcdWszFromIpAddress(
  49. IN DWORD IpAddress,
  50. OUT WCHAR* wszIpAddress)
  51. {
  52. ASSERT(wszIpAddress);
  53. LPSTR AnsiAddressString = inet_ntoa( *(struct in_addr *)&IpAddress );
  54. ASSERT(AnsiAddressString);
  55. if (AnsiAddressString == NULL)
  56. {
  57. lstrcpyW(wszIpAddress, L"");
  58. return ;
  59. }
  60. MultiByteToWideChar(CP_ACP, 0, AnsiAddressString, -1 ,
  61. wszIpAddress, MAXIPSTRLEN + 1);
  62. }
  63. /*
  64. * Function: GetIPAddressOctets
  65. * Description: Turn an IP Address string into its 4 integer components.
  66. * Author: shouse 7.24.00
  67. */
  68. VOID GetIPAddressOctets (PCWSTR pszIpAddress, DWORD ardw[4]) {
  69. DWORD dwIpAddr = IpAddressFromAbcdWsz(pszIpAddress);
  70. const BYTE * bp = (const BYTE *)&dwIpAddr;
  71. ardw[0] = (DWORD)bp[0];
  72. ardw[1] = (DWORD)bp[1];
  73. ardw[2] = (DWORD)bp[2];
  74. ardw[3] = (DWORD)bp[3];
  75. }
  76. /*
  77. * Function: IsValidIPAddressSubnetMaskPair
  78. * Description: Checks for valid IP address/netmask pairs.
  79. * Author: Copied largely from net/config/netcfg/tcpipcfg/tcperror.cpp
  80. */
  81. BOOL IsValidIPAddressSubnetMaskPair (PCWSTR szIp, PCWSTR szSubnet) {
  82. BOOL fNoError = TRUE;
  83. DWORD ardwNetID[4];
  84. DWORD ardwHostID[4];
  85. DWORD ardwIp[4];
  86. DWORD ardwMask[4];
  87. GetIPAddressOctets(szIp, ardwIp);
  88. GetIPAddressOctets(szSubnet, ardwMask);
  89. INT nFirstByte = ardwIp[0] & 0xFF;
  90. // setup Net ID
  91. ardwNetID[0] = ardwIp[0] & ardwMask[0] & 0xFF;
  92. ardwNetID[1] = ardwIp[1] & ardwMask[1] & 0xFF;
  93. ardwNetID[2] = ardwIp[2] & ardwMask[2] & 0xFF;
  94. ardwNetID[3] = ardwIp[3] & ardwMask[3] & 0xFF;
  95. // setup Host ID
  96. ardwHostID[0] = ardwIp[0] & (~(ardwMask[0]) & 0xFF);
  97. ardwHostID[1] = ardwIp[1] & (~(ardwMask[1]) & 0xFF);
  98. ardwHostID[2] = ardwIp[2] & (~(ardwMask[2]) & 0xFF);
  99. ardwHostID[3] = ardwIp[3] & (~(ardwMask[3]) & 0xFF);
  100. // check each case
  101. if( ((nFirstByte & 0xF0) == 0xE0) || // Class D
  102. ((nFirstByte & 0xF0) == 0xF0) || // Class E
  103. (ardwNetID[0] == 127) || // NetID cannot be 127...
  104. ((ardwNetID[0] == 0) && // netid cannot be 0.0.0.0
  105. (ardwNetID[1] == 0) &&
  106. (ardwNetID[2] == 0) &&
  107. (ardwNetID[3] == 0)) ||
  108. // netid cannot be equal to sub-net mask
  109. ((ardwNetID[0] == ardwMask[0]) &&
  110. (ardwNetID[1] == ardwMask[1]) &&
  111. (ardwNetID[2] == ardwMask[2]) &&
  112. (ardwNetID[3] == ardwMask[3])) ||
  113. // hostid cannot be 0.0.0.0
  114. ((ardwHostID[0] == 0) &&
  115. (ardwHostID[1] == 0) &&
  116. (ardwHostID[2] == 0) &&
  117. (ardwHostID[3] == 0)) ||
  118. // hostid cannot be 255.255.255.255
  119. ((ardwHostID[0] == 0xFF) &&
  120. (ardwHostID[1] == 0xFF) &&
  121. (ardwHostID[2] == 0xFF) &&
  122. (ardwHostID[3] == 0xFF)) ||
  123. // test for all 255
  124. ((ardwIp[0] == 0xFF) &&
  125. (ardwIp[1] == 0xFF) &&
  126. (ardwIp[2] == 0xFF) &&
  127. (ardwIp[3] == 0xFF)))
  128. {
  129. fNoError = FALSE;
  130. }
  131. return fNoError;
  132. }
  133. /*
  134. * Function: IsContiguousSubnetMask
  135. * Description: Makes sure the netmask is contiguous
  136. * Author: Copied largely from net/config/netcfg/tcpipcfg/tcputil.cpp
  137. */
  138. BOOL IsContiguousSubnetMask (PCWSTR pszSubnet) {
  139. DWORD ardwSubnet[4];
  140. GetIPAddressOctets(pszSubnet, ardwSubnet);
  141. DWORD dwMask = (ardwSubnet[0] << 24) + (ardwSubnet[1] << 16)
  142. + (ardwSubnet[2] << 8) + ardwSubnet[3];
  143. DWORD i, dwContiguousMask;
  144. // Find out where the first '1' is in binary going right to left
  145. dwContiguousMask = 0;
  146. for (i = 0; i < sizeof(dwMask)*8; i++) {
  147. dwContiguousMask |= 1 << i;
  148. if (dwContiguousMask & dwMask)
  149. break;
  150. }
  151. // At this point, dwContiguousMask is 000...0111... If we inverse it,
  152. // we get a mask that can be or'd with dwMask to fill in all of
  153. // the holes.
  154. dwContiguousMask = dwMask | ~dwContiguousMask;
  155. // If the new mask is different, correct it here
  156. if (dwMask != dwContiguousMask)
  157. return FALSE;
  158. else
  159. return TRUE;
  160. }
  161. //+----------------------------------------------------------------------------
  162. //
  163. // Function: Params_ip2sub
  164. //
  165. // Description:
  166. //
  167. // Arguments: WSTR ip -
  168. // PWSTR sub -
  169. //
  170. // Returns: BOOL -
  171. //
  172. // History: fengsun Created Header 3/2/00
  173. //
  174. //+----------------------------------------------------------------------------
  175. BOOL ParamsGenerateSubnetMask (PWSTR ip, PWSTR sub) {
  176. DWORD b [4];
  177. swscanf (ip, L"%d.%d.%d.%d", b, b+1, b+2, b+3);
  178. if ((b [0] >= 1) && (b [0] <= 126)) {
  179. b [0] = 255;
  180. b [1] = 0;
  181. b [2] = 0;
  182. b [3] = 0;
  183. } else if ((b [0] >= 128) && (b [0] <= 191)) {
  184. b [0] = 255;
  185. b [1] = 255;
  186. b [2] = 0;
  187. b [3] = 0;
  188. } else if ((b [0] >= 192) && (b [0] <= 223)) {
  189. b [0] = 255;
  190. b [1] = 255;
  191. b [2] = 255;
  192. b [3] = 0;
  193. } else {
  194. b [0] = 0;
  195. b [1] = 0;
  196. b [2] = 0;
  197. b [3] = 0;
  198. };
  199. swprintf (sub, L"%d.%d.%d.%d",
  200. b [0], b [1], b [2], b [3]);
  201. return((b[0] + b[1] + b[2] + b[3]) > 0);
  202. }
  203. /*
  204. * Function: ParamsGenerateMAC
  205. * Description: Calculate the generated field in the structure
  206. * History: fengsun Created 3.27.00
  207. * shouse Modified 7.12.00
  208. */
  209. void ParamsGenerateMAC (const WCHAR * szClusterIP,
  210. OUT WCHAR * szClusterMAC,
  211. OUT WCHAR * szMulticastIP,
  212. BOOL fConvertMAC,
  213. BOOL fMulticast,
  214. BOOL fIGMP,
  215. BOOL fUseClusterIP) {
  216. DWORD dwIp;
  217. const BYTE * bp;
  218. if (!fConvertMAC) return;
  219. /* Unicast mode. */
  220. if (!fMulticast) {
  221. dwIp = IpAddressFromAbcdWsz(szClusterIP);
  222. bp = (const BYTE *)&dwIp;
  223. swprintf(szClusterMAC, L"02-bf-%02x-%02x-%02x-%02x", bp[0], bp[1], bp[2], bp[3]);
  224. return;
  225. }
  226. /* Multicast without IGMP. */
  227. if (!fIGMP) {
  228. dwIp = IpAddressFromAbcdWsz(szClusterIP);
  229. bp = (const BYTE *)&dwIp;
  230. swprintf(szClusterMAC, L"03-bf-%02x-%02x-%02x-%02x", bp[0], bp[1], bp[2], bp[3]);
  231. return;
  232. }
  233. /* Multicast with IGMP. */
  234. if (fUseClusterIP) {
  235. /* 239.255.x.x */
  236. dwIp = IpAddressFromAbcdWsz(szClusterIP);
  237. dwIp = 239 + (255 << 8) + (dwIp & 0xFFFF0000);
  238. AbcdWszFromIpAddress(dwIp, szMulticastIP);
  239. }
  240. dwIp = IpAddressFromAbcdWsz(szMulticastIP);
  241. bp = (const BYTE*)&dwIp;
  242. swprintf(szClusterMAC, L"01-00-5e-%02x-%02x-%02x", (bp[1] & 0x7f), bp[2], bp[3]);
  243. }