Leaked source code of windows server 2003
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.

417 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: T C P E R R O R . C P P
  7. //
  8. // Contents:
  9. //
  10. // Notes:
  11. //
  12. // Author: tongl
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "tcperror.h"
  18. #include "tcputil.h"
  19. #include "tcpconst.h"
  20. #include "resource.h"
  21. IP_VALIDATION_ERR IsValidIpandSubnet(PCWSTR szIp, PCWSTR szSubnet)
  22. {
  23. IP_VALIDATION_ERR ret = ERR_NONE;
  24. DWORD dwAddr = IPStringToDword(szIp);
  25. DWORD dwMask = IPStringToDword(szSubnet);
  26. //The host ID cannot contain all 1's
  27. if ((dwMask | dwAddr) == 0xFFFFFFFF)
  28. {
  29. return ERR_HOST_ALL1;
  30. }
  31. if (((~dwMask) & dwAddr) == 0)
  32. {
  33. return ERR_HOST_ALL0;
  34. }
  35. if ((dwMask & dwAddr) == 0)
  36. {
  37. return ERR_SUBNET_ALL0;
  38. }
  39. DWORD ardwNetID[4];
  40. DWORD ardwIp[4];
  41. DWORD ardwMask[4];
  42. GetNodeNum(szIp, ardwIp);
  43. GetNodeNum(szSubnet, ardwMask);
  44. INT nFirstByte = ardwIp[0] & 0xFF ;
  45. // setup Net ID
  46. ardwNetID[0] = ardwIp[0] & ardwMask[0] & 0xFF;
  47. ardwNetID[1] = ardwIp[1] & ardwMask[1] & 0xFF;
  48. ardwNetID[2] = ardwIp[2] & ardwMask[2] & 0xFF;
  49. ardwNetID[3] = ardwIp[3] & ardwMask[3] & 0xFF;
  50. // setup Host ID
  51. DWORD ardwHostID[4];
  52. ardwHostID[0] = ardwIp[0] & (~(ardwMask[0]) & 0xFF);
  53. ardwHostID[1] = ardwIp[1] & (~(ardwMask[1]) & 0xFF);
  54. ardwHostID[2] = ardwIp[2] & (~(ardwMask[2]) & 0xFF);
  55. ardwHostID[3] = ardwIp[3] & (~(ardwMask[3]) & 0xFF);
  56. // check each case
  57. if( ((nFirstByte & 0xF0) == 0xE0) || // Class D
  58. ((nFirstByte & 0xF0) == 0xF0) || // Class E
  59. (ardwNetID[0] == 127) || // NetID cannot be 127...
  60. ((ardwNetID[0] == 0) && // netid cannot be 0.0.0.0
  61. (ardwNetID[1] == 0) &&
  62. (ardwNetID[2] == 0) &&
  63. (ardwNetID[3] == 0)) ||
  64. // netid cannot be equal to sub-net mask
  65. ((ardwNetID[0] == ardwMask[0]) &&
  66. (ardwNetID[1] == ardwMask[1]) &&
  67. (ardwNetID[2] == ardwMask[2]) &&
  68. (ardwNetID[3] == ardwMask[3])) ||
  69. // hostid cannot be 255.255.255.255
  70. ((ardwHostID[0] == 0xFF) &&
  71. (ardwHostID[1] == 0xFF) &&
  72. (ardwHostID[2] == 0xFF) &&
  73. (ardwHostID[3] == 0xFF)) ||
  74. // test for all 255
  75. ((ardwIp[0] == 0xFF) &&
  76. (ardwIp[1] == 0xFF) &&
  77. (ardwIp[2] == 0xFF) &&
  78. (ardwIp[3] == 0xFF)))
  79. {
  80. ret = ERR_INCORRECT_IP;
  81. }
  82. return ret;
  83. }
  84. // return IP_VALIDATION_ERR
  85. IP_VALIDATION_ERR ValidateIp(ADAPTER_INFO * const pAdapterInfo)
  86. {
  87. IP_VALIDATION_ERR result = ERR_NONE;
  88. IP_VALIDATION_ERR tmp = ERR_NONE;
  89. Assert(pAdapterInfo != NULL);
  90. // if enable DHCP is false;
  91. if (!pAdapterInfo->m_fEnableDhcp)
  92. {
  93. DWORD dwIpCount = pAdapterInfo->m_vstrIpAddresses.size();
  94. DWORD dwSubnetCount = pAdapterInfo->m_vstrSubnetMask.size();
  95. // check the first pair of IP and subnet
  96. VSTR_ITER iterIpBegin = pAdapterInfo->m_vstrIpAddresses.begin();
  97. VSTR_ITER iterIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
  98. VSTR_ITER iterIp = iterIpBegin;
  99. VSTR_ITER iterSubnetMaskBegin = pAdapterInfo->m_vstrSubnetMask.begin();
  100. VSTR_ITER iterSubnetMaskEnd = pAdapterInfo->m_vstrSubnetMask.end();
  101. VSTR_ITER iterSubnetMask = iterSubnetMaskBegin;
  102. BOOL fSwap = FALSE;
  103. // If ip address and subnet are both empty
  104. if((iterIp == iterIpEnd) && (iterSubnetMask == iterSubnetMaskEnd))
  105. {
  106. result = ERR_NO_IP;
  107. }
  108. else if (dwIpCount < dwSubnetCount)
  109. {
  110. //ensure count of IP is the same as count of subnet
  111. result = ERR_NO_IP;
  112. }
  113. else if (dwIpCount > dwSubnetCount)
  114. {
  115. result = ERR_NO_SUBNET;
  116. }
  117. else
  118. {
  119. for( ;
  120. iterIp != iterIpEnd || iterSubnetMask != iterSubnetMaskEnd ;
  121. ++iterIp, ++iterSubnetMask)
  122. {
  123. Assert(iterIp != iterIpEnd);
  124. if (iterIp == iterIpEnd)
  125. {
  126. result = ERR_NO_IP;
  127. break;
  128. }
  129. Assert(iterSubnetMask != iterSubnetMaskEnd);
  130. if (iterSubnetMask == iterSubnetMaskEnd)
  131. {
  132. result = ERR_NO_SUBNET;
  133. break;
  134. }
  135. if(**iterIp == L"" && !fSwap)
  136. {
  137. result = ERR_NO_IP;
  138. fSwap = TRUE;
  139. }
  140. else if(**iterSubnetMask == L"" && !fSwap)
  141. {
  142. result = ERR_NO_SUBNET;
  143. fSwap = TRUE;
  144. }
  145. else if(!IsContiguousSubnet((*iterSubnetMask)->c_str()))
  146. {
  147. result = ERR_UNCONTIGUOUS_SUBNET;
  148. fSwap = TRUE;
  149. }
  150. else if(ERR_NONE != (tmp = IsValidIpandSubnet((*iterIp)->c_str(), (*iterSubnetMask)->c_str())) && !fSwap)
  151. {
  152. result = tmp;
  153. fSwap = TRUE;
  154. }
  155. if(fSwap)
  156. {
  157. tstring * pstrTmp;
  158. pstrTmp = *iterIp;
  159. *iterIp = *iterIpBegin;
  160. *iterIpBegin = pstrTmp;
  161. pstrTmp = *iterSubnetMask;
  162. *iterSubnetMask = *iterSubnetMaskBegin;
  163. *iterSubnetMaskBegin = pstrTmp;
  164. break;
  165. }
  166. }
  167. }
  168. }
  169. return result;
  170. }
  171. // return >=0 : the adapter that has the duplicate address
  172. // return -1 : all is ok
  173. // Check from duplicate IP address between the adapter in pAdapterInfo and
  174. // any different, enabled, LAN adapters in the pvcardAdapterInfo list
  175. int CheckForDuplicates(const VCARD * pvcardAdapterInfo,
  176. ADAPTER_INFO * pAdapterInfo,
  177. tstring& strIp)
  178. {
  179. int nResult = -1;
  180. Assert(pvcardAdapterInfo != NULL);
  181. Assert(pAdapterInfo != NULL);
  182. Assert(!pAdapterInfo->m_fEnableDhcp);
  183. for(size_t i = 0; ((i < pvcardAdapterInfo->size()) && (nResult == -1)) ; ++i)
  184. {
  185. VSTR_ITER iterCompareIpBegin;
  186. VSTR_ITER iterCompareIpEnd;
  187. if ((*pvcardAdapterInfo)[i]->m_guidInstanceId ==
  188. pAdapterInfo->m_guidInstanceId)
  189. {
  190. // same adapter
  191. continue;
  192. }
  193. else
  194. {
  195. // different adapter
  196. // Skip the following:
  197. // 1) disabled adapter
  198. // 2) ndiswan adapter
  199. // 3) Dhcp enabled adapter
  200. // 4) RAS Fake adapters
  201. if(((*pvcardAdapterInfo)[i]->m_BindingState != BINDING_ENABLE) ||
  202. ((*pvcardAdapterInfo)[i]->m_fIsWanAdapter) ||
  203. ((*pvcardAdapterInfo)[i]->m_fEnableDhcp) ||
  204. ((*pvcardAdapterInfo)[i]->m_fIsRasFakeAdapter))
  205. continue;
  206. iterCompareIpBegin = (*pvcardAdapterInfo)[i]->m_vstrIpAddresses.begin();
  207. iterCompareIpEnd = (*pvcardAdapterInfo)[i]->m_vstrIpAddresses.end();
  208. }
  209. VSTR_ITER iterCompareIp = iterCompareIpBegin;
  210. for ( ; iterCompareIp != iterCompareIpEnd; ++iterCompareIp)
  211. {
  212. if(**iterCompareIp == strIp) // if duplicate IP address found
  213. {
  214. nResult = i;
  215. break;
  216. /*
  217. nCompareCount++;
  218. if (nCompareCount >= 1)
  219. {
  220. nResult = i;
  221. tstring * pstrTmp;
  222. // swap the Current Compared IP and Subnet Mask with the
  223. // first IP and first subnetmask that are duplicates
  224. pstrTmp = *iterIp;
  225. *iterIp = *iterIpBegin;
  226. *iterIpBegin = pstrTmp;
  227. pstrTmp = *iterSubnetMask;
  228. *iterSubnetMask = *iterSubnetMaskBegin;
  229. *iterSubnetMaskBegin = pstrTmp;
  230. break;
  231. }
  232. */
  233. }
  234. }
  235. }
  236. return nResult;
  237. }
  238. BOOL FHasDuplicateIp(ADAPTER_INFO * pAdapterInfo)
  239. {
  240. Assert(pAdapterInfo);
  241. Assert(!pAdapterInfo->m_fEnableDhcp);
  242. BOOL fDup = FALSE;
  243. VSTR_ITER iterIpBegin = pAdapterInfo->m_vstrIpAddresses.begin();
  244. VSTR_ITER iterIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
  245. VSTR_ITER iterIp = iterIpBegin;
  246. for( ; ((iterIp != iterIpEnd) && (!fDup)) ; ++iterIp)
  247. {
  248. // check only IP addresses one by one
  249. VSTR_ITER iterCompareIpBegin = iterIp+1;
  250. VSTR_ITER iterCompareIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
  251. VSTR_ITER iterCompareIp = iterCompareIpBegin;
  252. for ( ; iterCompareIp != iterCompareIpEnd; ++iterCompareIp)
  253. {
  254. if(**iterCompareIp == **iterIp) // if duplicate IP address found
  255. {
  256. fDup = TRUE;
  257. break;
  258. }
  259. }
  260. }
  261. return fDup;
  262. }
  263. //Check if the IP and the Gateway are in the same subnet
  264. BOOL FIpAndGatewayInSameSubNet(
  265. PCWSTR szIp,
  266. PCWSTR szMask,
  267. PCWSTR szGateway
  268. )
  269. {
  270. Assert(szIp);
  271. Assert(szMask);
  272. Assert(szGateway);
  273. BOOL fRet = TRUE;
  274. DWORD dwIp = IPStringToDword(szIp);
  275. DWORD dwMask = IPStringToDword(szMask);
  276. DWORD dwGateway = IPStringToDword(szGateway);
  277. DWORD dwNetID = dwIp & dwMask;
  278. DWORD dwGwNetID = dwGateway & dwMask;
  279. return (dwNetID == dwGwNetID);
  280. }
  281. //Check if all the fields of the IP address are valid
  282. //Arguments: szIp the IP address
  283. // fIsIpAddr whether the szIp is IP address (otherwise, it should be subnet mask)
  284. // if szIp is IP address, it's first field should be between 1 and 223,
  285. // and cannot be 127 (loopback address)
  286. BOOL FIsValidIpFields(PCWSTR szIp, BOOL fIsIpAddr)
  287. {
  288. BOOL fRet = TRUE;
  289. DWORD ardwIp[4];
  290. GetNodeNum(szIp, ardwIp);
  291. // if the address is IP, there are some special rules for its first field
  292. if (fIsIpAddr && (ardwIp[0] < c_iIPADDR_FIELD_1_LOW || ardwIp[0] > c_iIPADDR_FIELD_1_HIGH ||
  293. ardwIp[0] == c_iIPADDR_FIELD_1_LOOPBACK))
  294. {
  295. fRet = FALSE;
  296. }
  297. else
  298. {
  299. //if the address is IP, then we have already validate the first field. Otherwise, we need
  300. // valid the first field here.
  301. for (INT i = (fIsIpAddr) ? 1 : 0; i < 4; i++)
  302. {
  303. #pragma warning(push)
  304. #pragma warning(disable:4296)
  305. if (ardwIp[i] < (DWORD)c_iIpLow || ardwIp[i] > c_iIpHigh)
  306. {
  307. fRet = FALSE;
  308. break;
  309. }
  310. #pragma warning(pop)
  311. }
  312. }
  313. return fRet;
  314. }
  315. //Get the resource ID of the error message based on the IP validation err
  316. UINT GetIPValidationErrorMessageID(IP_VALIDATION_ERR err)
  317. {
  318. UINT uID = 0;
  319. switch(err)
  320. {
  321. case ERR_NONE:
  322. uID = 0;
  323. break;
  324. case ERR_HOST_ALL0:
  325. uID = IDS_INVALID_HOST_ALL_0;
  326. break;
  327. case ERR_HOST_ALL1:
  328. uID = IDS_INVALID_HOST_ALL_1;
  329. break;
  330. case ERR_SUBNET_ALL0:
  331. uID = IDS_INVALID_SUBNET_ALL_0;
  332. break;
  333. case ERR_INCORRECT_IP:
  334. uID = IDS_INCORRECT_IPADDRESS;
  335. break;
  336. case ERR_NO_IP:
  337. uID = IDS_INVALID_NO_IP;
  338. break;
  339. case ERR_NO_SUBNET:
  340. uID = IDS_INVALID_NOSUBNET;
  341. break;
  342. case ERR_UNCONTIGUOUS_SUBNET:
  343. uID = IDS_ERROR_UNCONTIGUOUS_SUBNET;
  344. break;
  345. default:
  346. uID = IDS_INCORRECT_IPADDRESS;
  347. break;
  348. }
  349. return uID;
  350. }