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.

369 lines
10 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. // check the first pair of IP and subnet
  94. VSTR_ITER iterIpBegin = pAdapterInfo->m_vstrIpAddresses.begin();
  95. VSTR_ITER iterIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
  96. VSTR_ITER iterIp = iterIpBegin;
  97. VSTR_ITER iterSubnetMaskBegin = pAdapterInfo->m_vstrSubnetMask.begin();
  98. VSTR_ITER iterSubnetMaskEnd = pAdapterInfo->m_vstrSubnetMask.end();
  99. VSTR_ITER iterSubnetMask = iterSubnetMaskBegin;
  100. BOOL fSwap = FALSE;
  101. // If ip address and subnet are both empty
  102. if((iterIp == iterIpEnd) && (iterSubnetMask == iterSubnetMaskEnd))
  103. {
  104. result = ERR_NO_IP;
  105. }
  106. else
  107. {
  108. for( ;
  109. iterIp != iterIpEnd || iterSubnetMask != iterSubnetMaskEnd ;
  110. ++iterIp, ++iterSubnetMask)
  111. {
  112. if((iterIp == iterIpEnd || **iterIp == L"") && !fSwap)
  113. {
  114. result = ERR_NO_IP;
  115. fSwap = TRUE;
  116. }
  117. else if((iterSubnetMask == iterSubnetMaskEnd || **iterSubnetMask == L"") && !fSwap)
  118. {
  119. result = ERR_NO_SUBNET;
  120. fSwap = TRUE;
  121. }
  122. else if(!IsContiguousSubnet((*iterSubnetMask)->c_str()))
  123. {
  124. result = ERR_UNCONTIGUOUS_SUBNET;
  125. fSwap = TRUE;
  126. }
  127. else if(ERR_NONE != (tmp = IsValidIpandSubnet((*iterIp)->c_str(), (*iterSubnetMask)->c_str())) && !fSwap)
  128. {
  129. result = tmp;
  130. fSwap = TRUE;
  131. }
  132. if(fSwap)
  133. {
  134. tstring * pstrTmp;
  135. pstrTmp = *iterIp;
  136. *iterIp = *iterIpBegin;
  137. *iterIpBegin = pstrTmp;
  138. pstrTmp = *iterSubnetMask;
  139. *iterSubnetMask = *iterSubnetMaskBegin;
  140. *iterSubnetMaskBegin = pstrTmp;
  141. break;
  142. }
  143. }
  144. }
  145. }
  146. return result;
  147. }
  148. // return >=0 : the adapter that has the duplicate address
  149. // return -1 : all is ok
  150. // Check from duplicate IP address between the adapter in pAdapterInfo and
  151. // any different, enabled, LAN adapters in the pvcardAdapterInfo list
  152. int CheckForDuplicates(const VCARD * pvcardAdapterInfo,
  153. ADAPTER_INFO * pAdapterInfo,
  154. tstring& strIp)
  155. {
  156. int nResult = -1;
  157. Assert(pvcardAdapterInfo != NULL);
  158. Assert(pAdapterInfo != NULL);
  159. Assert(!pAdapterInfo->m_fEnableDhcp);
  160. for(size_t i = 0; ((i < pvcardAdapterInfo->size()) && (nResult == -1)) ; ++i)
  161. {
  162. VSTR_ITER iterCompareIpBegin;
  163. VSTR_ITER iterCompareIpEnd;
  164. if ((*pvcardAdapterInfo)[i]->m_guidInstanceId ==
  165. pAdapterInfo->m_guidInstanceId)
  166. {
  167. // same adapter
  168. continue;
  169. }
  170. else
  171. {
  172. // different adapter
  173. // Skip the following:
  174. // 1) disabled adapter
  175. // 2) ndiswan adapter
  176. // 3) Dhcp enabled adapter
  177. // 4) RAS Fake adapters
  178. if(((*pvcardAdapterInfo)[i]->m_BindingState != BINDING_ENABLE) ||
  179. ((*pvcardAdapterInfo)[i]->m_fIsWanAdapter) ||
  180. ((*pvcardAdapterInfo)[i]->m_fEnableDhcp) ||
  181. ((*pvcardAdapterInfo)[i]->m_fIsRasFakeAdapter))
  182. continue;
  183. iterCompareIpBegin = (*pvcardAdapterInfo)[i]->m_vstrIpAddresses.begin();
  184. iterCompareIpEnd = (*pvcardAdapterInfo)[i]->m_vstrIpAddresses.end();
  185. }
  186. VSTR_ITER iterCompareIp = iterCompareIpBegin;
  187. for ( ; iterCompareIp != iterCompareIpEnd; ++iterCompareIp)
  188. {
  189. if(**iterCompareIp == strIp) // if duplicate IP address found
  190. {
  191. nResult = i;
  192. break;
  193. /*
  194. nCompareCount++;
  195. if (nCompareCount >= 1)
  196. {
  197. nResult = i;
  198. tstring * pstrTmp;
  199. // swap the Current Compared IP and Subnet Mask with the
  200. // first IP and first subnetmask that are duplicates
  201. pstrTmp = *iterIp;
  202. *iterIp = *iterIpBegin;
  203. *iterIpBegin = pstrTmp;
  204. pstrTmp = *iterSubnetMask;
  205. *iterSubnetMask = *iterSubnetMaskBegin;
  206. *iterSubnetMaskBegin = pstrTmp;
  207. break;
  208. }
  209. */
  210. }
  211. }
  212. }
  213. return nResult;
  214. }
  215. BOOL FHasDuplicateIp(ADAPTER_INFO * pAdapterInfo)
  216. {
  217. Assert(pAdapterInfo);
  218. Assert(!pAdapterInfo->m_fEnableDhcp);
  219. BOOL fDup = FALSE;
  220. VSTR_ITER iterIpBegin = pAdapterInfo->m_vstrIpAddresses.begin();
  221. VSTR_ITER iterIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
  222. VSTR_ITER iterIp = iterIpBegin;
  223. for( ; ((iterIp != iterIpEnd) && (!fDup)) ; ++iterIp)
  224. {
  225. // check only IP addresses one by one
  226. VSTR_ITER iterCompareIpBegin = iterIp+1;
  227. VSTR_ITER iterCompareIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
  228. VSTR_ITER iterCompareIp = iterCompareIpBegin;
  229. for ( ; iterCompareIp != iterCompareIpEnd; ++iterCompareIp)
  230. {
  231. if(**iterCompareIp == **iterIp) // if duplicate IP address found
  232. {
  233. fDup = TRUE;
  234. break;
  235. }
  236. }
  237. }
  238. return fDup;
  239. }
  240. //Check if all the fields of the IP address are valid
  241. //Arguments: szIp the IP address
  242. // fIsIpAddr whether the szIp is IP address (otherwise, it should be subnet mask)
  243. // if szIp is IP address, it's first field should be between 1 and 223,
  244. // and cannot be 127 (loopback address)
  245. BOOL FIsValidIpFields(PCWSTR szIp, BOOL fIsIpAddr)
  246. {
  247. BOOL fRet = TRUE;
  248. DWORD ardwIp[4];
  249. GetNodeNum(szIp, ardwIp);
  250. // if the address is IP, there are some special rules for its first field
  251. if (fIsIpAddr && (ardwIp[0] < c_iIPADDR_FIELD_1_LOW || ardwIp[0] > c_iIPADDR_FIELD_1_HIGH ||
  252. ardwIp[0] == c_iIPADDR_FIELD_1_LOOPBACK))
  253. {
  254. fRet = FALSE;
  255. }
  256. else
  257. {
  258. //if the address is IP, then we have already validate the first field. Otherwise, we need
  259. // valid the first field here.
  260. for (INT i = (fIsIpAddr) ? 1 : 0; i < 4; i++)
  261. {
  262. #pragma warning(push)
  263. #pragma warning(disable:4296)
  264. if (ardwIp[i] < (DWORD)c_iIpLow || ardwIp[i] > c_iIpHigh)
  265. {
  266. fRet = FALSE;
  267. break;
  268. }
  269. #pragma warning(pop)
  270. }
  271. }
  272. return fRet;
  273. }
  274. //Get the resource ID of the error message based on the IP validation err
  275. UINT GetIPValidationErrorMessageID(IP_VALIDATION_ERR err)
  276. {
  277. UINT uID = 0;
  278. switch(err)
  279. {
  280. case ERR_NONE:
  281. uID = 0;
  282. break;
  283. case ERR_HOST_ALL0:
  284. uID = IDS_INVALID_HOST_ALL_0;
  285. break;
  286. case ERR_HOST_ALL1:
  287. uID = IDS_INVALID_HOST_ALL_1;
  288. break;
  289. case ERR_SUBNET_ALL0:
  290. uID = IDS_INVALID_SUBNET_ALL_0;
  291. break;
  292. case ERR_INCORRECT_IP:
  293. uID = IDS_INCORRECT_IPADDRESS;
  294. break;
  295. case ERR_NO_IP:
  296. uID = IDS_INVALID_NO_IP;
  297. break;
  298. case ERR_NO_SUBNET:
  299. uID = IDS_INVALID_NOSUBNET;
  300. break;
  301. case ERR_UNCONTIGUOUS_SUBNET:
  302. uID = IDS_ERROR_UNCONTIGUOUS_SUBNET;
  303. break;
  304. default:
  305. uID = IDS_INCORRECT_IPADDRESS;
  306. break;
  307. }
  308. return uID;
  309. }