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.

293 lines
8.1 KiB

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