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.

758 lines
14 KiB

  1. /*
  2. Copyright (c) 1998, Microsoft Corporation, all rights reserved
  3. Description:
  4. */
  5. #include "rasstat_.h"
  6. /*
  7. Returns:
  8. Notes:
  9. */
  10. DWORD
  11. RasStatInitialize(
  12. VOID
  13. )
  14. {
  15. TraceHlp("RasStatInitialize");
  16. EnterCriticalSection(&RasStatCriticalSection);
  17. RasStatAllocPool = NULL;
  18. RasStatFreePool = NULL;
  19. RasStatCurrentPool = HelperRegVal.pAddrPool;
  20. LeaveCriticalSection(&RasStatCriticalSection);
  21. return(NO_ERROR);
  22. }
  23. /*
  24. Returns:
  25. VOID
  26. Notes:
  27. */
  28. VOID
  29. RasStatUninitialize(
  30. VOID
  31. )
  32. {
  33. ADDR_POOL* pAddrPool;
  34. TraceHlp("RasStatUninitialize");
  35. EnterCriticalSection(&RasStatCriticalSection);
  36. rasStatDeleteLists();
  37. RasStatCurrentPool = HelperRegVal.pAddrPool;
  38. pAddrPool = HelperRegVal.pAddrPool;
  39. while (pAddrPool != NULL)
  40. {
  41. pAddrPool->hboNextIpAddr = pAddrPool->hboFirstIpAddr;
  42. pAddrPool = pAddrPool->pNext;
  43. }
  44. LeaveCriticalSection(&RasStatCriticalSection);
  45. }
  46. /*
  47. Returns:
  48. VOID
  49. Notes:
  50. */
  51. VOID
  52. RasStatSetRoutes(
  53. IN IPADDR nboServerIpAddress,
  54. IN BOOL fSet
  55. )
  56. {
  57. ADDR_POOL* pAddrPool;
  58. IPADDR nboAddress;
  59. IPADDR nboMask;
  60. TraceHlp("RasStatSetRoutes");
  61. pAddrPool = HelperRegVal.pAddrPool;
  62. while (pAddrPool != NULL)
  63. {
  64. nboAddress = htonl(pAddrPool->hboFirstIpAddr & pAddrPool->hboMask);
  65. nboMask = htonl(pAddrPool->hboMask);
  66. RasTcpSetRoute(
  67. nboAddress,
  68. nboServerIpAddress,
  69. nboMask,
  70. nboServerIpAddress,
  71. fSet,
  72. 1,
  73. FALSE);
  74. pAddrPool = pAddrPool->pNext;
  75. }
  76. }
  77. /*
  78. Returns:
  79. Notes:
  80. */
  81. VOID
  82. RasStatCreatePoolList(
  83. IN OUT ADDR_POOL** ppAddrPoolOut
  84. )
  85. {
  86. HKEY hKeyAddrPool = NULL;
  87. HKEY hKey;
  88. LONG lErr;
  89. CHAR aszSubKey[10];
  90. DWORD dwIndex;
  91. BOOL fExitWhile;
  92. DWORD dwType;
  93. DWORD dwValue;
  94. DWORD dwSize;
  95. IPADDR hboFirstIpAddr;
  96. IPADDR hboLastIpAddr;
  97. IPADDR hboMask;
  98. ADDR_POOL* pAddrPool = NULL;
  99. ADDR_POOL** ppAddrPool = NULL;
  100. ADDR_POOL* pAddrPoolTemp;
  101. TraceHlp("RasStatCreatePoolList");
  102. lErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_ADDR_POOL_A, 0,
  103. KEY_READ, &hKeyAddrPool);
  104. if (ERROR_SUCCESS != lErr)
  105. {
  106. rasStatCreatePoolListFromOldValues(ppAddrPoolOut);
  107. goto LDone;
  108. }
  109. ppAddrPool = &pAddrPool;
  110. dwIndex = 0;
  111. fExitWhile = FALSE;
  112. while (!fExitWhile)
  113. {
  114. hKey = NULL;
  115. sprintf(aszSubKey, "%d", dwIndex);
  116. lErr = RegOpenKeyEx(hKeyAddrPool, aszSubKey, 0, KEY_READ,
  117. &hKey);
  118. if (ERROR_SUCCESS != lErr)
  119. {
  120. TraceHlp("Couldn't open key %s in key :%ld", aszSubKey, lErr );
  121. fExitWhile = TRUE;
  122. goto LWhileEnd;
  123. }
  124. dwSize = sizeof(dwValue);
  125. lErr = RegQueryValueEx(hKey, REGVAL_FROM_A, NULL, &dwType,
  126. (BYTE*)&dwValue, &dwSize);
  127. if ( (ERROR_SUCCESS != lErr)
  128. || (REG_DWORD != dwType))
  129. {
  130. TraceHlp("Couldn't read value %s in key %s: %d",
  131. REGVAL_FROM_A, aszSubKey, lErr);
  132. goto LWhileEnd;
  133. }
  134. hboFirstIpAddr = dwValue;
  135. dwSize = sizeof(dwValue);
  136. lErr = RegQueryValueEx(hKey, REGVAL_TO_A, NULL, &dwType,
  137. (BYTE*)&dwValue, &dwSize);
  138. if ( (ERROR_SUCCESS != lErr)
  139. || (REG_DWORD != dwType))
  140. {
  141. TraceHlp("Couldn't read value %s in key %s: %d",
  142. REGVAL_TO_A, aszSubKey, lErr);
  143. goto LWhileEnd;
  144. }
  145. hboLastIpAddr = dwValue;
  146. hboMask = rasStatMaskFromAddrPair(hboFirstIpAddr, hboLastIpAddr);
  147. pAddrPoolTemp = LocalAlloc(LPTR, sizeof(ADDR_POOL));
  148. if (NULL == pAddrPoolTemp)
  149. {
  150. TraceHlp("Out of memory");
  151. fExitWhile = TRUE;
  152. goto LWhileEnd;
  153. }
  154. pAddrPoolTemp->hboFirstIpAddr = hboFirstIpAddr;
  155. pAddrPoolTemp->hboLastIpAddr = hboLastIpAddr;
  156. pAddrPoolTemp->hboNextIpAddr = hboFirstIpAddr;
  157. pAddrPoolTemp->hboMask = hboMask;
  158. TraceHlp("0x%x...0x%x/0x%x", hboFirstIpAddr, hboLastIpAddr, hboMask);
  159. *ppAddrPool = pAddrPoolTemp;
  160. ppAddrPool = &(pAddrPoolTemp->pNext);
  161. LWhileEnd:
  162. if (NULL != hKey)
  163. {
  164. RegCloseKey(hKey);
  165. }
  166. dwIndex++;
  167. }
  168. *ppAddrPoolOut = pAddrPool;
  169. pAddrPool = NULL;
  170. LDone:
  171. if (NULL != hKeyAddrPool)
  172. {
  173. RegCloseKey(hKeyAddrPool);
  174. }
  175. RasStatFreeAddrPool(pAddrPool);
  176. }
  177. /*
  178. Returns:
  179. VOID
  180. Description:
  181. */
  182. VOID
  183. RasStatFreeAddrPool(
  184. IN ADDR_POOL* pAddrPool
  185. )
  186. {
  187. ADDR_POOL* pAddrPoolTemp;
  188. while (pAddrPool != NULL)
  189. {
  190. pAddrPoolTemp = pAddrPool;
  191. pAddrPool = pAddrPool->pNext;
  192. LocalFree(pAddrPoolTemp);
  193. }
  194. }
  195. /*
  196. Returns:
  197. TRUE: The 2 static address pools are different
  198. FALSE: The 2 static address pools are identical
  199. Description:
  200. */
  201. BOOL
  202. RasStatAddrPoolsDiffer
  203. (
  204. IN ADDR_POOL* pAddrPool1,
  205. IN ADDR_POOL* pAddrPool2
  206. )
  207. {
  208. while (TRUE)
  209. {
  210. if ( (NULL == pAddrPool1)
  211. && (NULL == pAddrPool2))
  212. {
  213. return(FALSE);
  214. }
  215. if ( (NULL == pAddrPool1)
  216. || (NULL == pAddrPool2))
  217. {
  218. return(TRUE);
  219. }
  220. if ( (pAddrPool1->hboFirstIpAddr != pAddrPool2->hboFirstIpAddr)
  221. || (pAddrPool1->hboLastIpAddr != pAddrPool2->hboLastIpAddr))
  222. {
  223. return(TRUE);
  224. }
  225. pAddrPool1 = pAddrPool1->pNext;
  226. pAddrPool2 = pAddrPool2->pNext;
  227. }
  228. }
  229. /*
  230. Returns:
  231. Notes:
  232. */
  233. DWORD
  234. RasStatAcquireAddress(
  235. IN HPORT hPort,
  236. OUT IPADDR* pnboIpAddr,
  237. OUT IPADDR* pnboIpMask
  238. )
  239. {
  240. IPADDR_NODE* pNode;
  241. DWORD dwErr = ERROR_NO_IP_ADDRESSES;
  242. TraceHlp("RasStatAcquireAddress");
  243. EnterCriticalSection(&RasStatCriticalSection);
  244. if (NULL == RasStatFreePool)
  245. {
  246. rasStatAllocateAddresses();
  247. if (NULL == RasStatFreePool)
  248. {
  249. TraceHlp("Out of addresses");
  250. goto LDone;
  251. }
  252. }
  253. // Move from Free pool to Alloc pool
  254. pNode = RasStatFreePool;
  255. RasStatFreePool = RasStatFreePool->pNext;
  256. pNode->pNext = RasStatAllocPool;
  257. RasStatAllocPool = pNode;
  258. TraceHlp("Acquired 0x%x", pNode->hboIpAddr);
  259. *pnboIpAddr = htonl(pNode->hboIpAddr);
  260. *pnboIpMask = htonl(HOST_MASK);
  261. pNode->hPort = hPort;
  262. dwErr = NO_ERROR;
  263. LDone:
  264. LeaveCriticalSection(&RasStatCriticalSection);
  265. return(dwErr);
  266. }
  267. /*
  268. Returns:
  269. VOID
  270. Notes:
  271. */
  272. VOID
  273. RasStatReleaseAddress(
  274. IN IPADDR nboIpAddr
  275. )
  276. {
  277. IPADDR_NODE* pNode;
  278. IPADDR_NODE** ppNode;
  279. IPADDR hboIpAddr;
  280. TraceHlp("RasStatReleaseAddress");
  281. EnterCriticalSection(&RasStatCriticalSection);
  282. hboIpAddr = ntohl(nboIpAddr);
  283. for (ppNode = &RasStatAllocPool;
  284. (pNode = *ppNode) != NULL;
  285. ppNode = &pNode->pNext)
  286. {
  287. if (pNode->hboIpAddr == hboIpAddr)
  288. {
  289. TraceHlp("Released 0x%x", nboIpAddr);
  290. // Unlink from alloc pool
  291. *ppNode = pNode->pNext;
  292. // Put at the end of the free pool, because we want to round-robin
  293. // the addresses.
  294. pNode->pNext = NULL;
  295. ppNode = &RasStatFreePool;
  296. while (NULL != *ppNode)
  297. {
  298. ppNode = &((*ppNode)->pNext);
  299. }
  300. *ppNode = pNode;
  301. goto LDone;
  302. }
  303. }
  304. TraceHlp("IpAddress 0x%x not present in alloc pool", nboIpAddr);
  305. LDone:
  306. LeaveCriticalSection(&RasStatCriticalSection);
  307. }
  308. /*
  309. Returns:
  310. VOID
  311. Notes:
  312. */
  313. VOID
  314. rasStatDeleteLists(
  315. VOID
  316. )
  317. {
  318. IPADDR_NODE* pNode;
  319. IPADDR_NODE* pNodeTemp;
  320. DWORD dwIndex;
  321. TraceHlp("rasStatDeleteLists");
  322. EnterCriticalSection(&RasStatCriticalSection);
  323. pNode = RasStatAllocPool;
  324. while (pNode != NULL)
  325. {
  326. pNodeTemp = pNode;
  327. pNode = pNode->pNext;
  328. LocalFree(pNodeTemp);
  329. }
  330. pNode = RasStatFreePool;
  331. while (pNode != NULL)
  332. {
  333. pNodeTemp = pNode;
  334. pNode = pNode->pNext;
  335. LocalFree(pNodeTemp);
  336. }
  337. RasStatAllocPool = NULL;
  338. RasStatFreePool = NULL;
  339. LeaveCriticalSection(&RasStatCriticalSection);
  340. }
  341. /*
  342. Returns:
  343. VOID
  344. Notes:
  345. */
  346. VOID
  347. rasStatAllocateAddresses(
  348. VOID
  349. )
  350. {
  351. DWORD dwNumAddressesToGet;
  352. IPADDR_NODE* pNode;
  353. IPADDR_NODE** ppNode;
  354. IPADDR hboIpAddr;
  355. TraceHlp("rasStatAllocateAddresses");
  356. EnterCriticalSection(&RasStatCriticalSection);
  357. ppNode = &RasStatFreePool;
  358. dwNumAddressesToGet = HelperRegVal.dwChunkSize;
  359. while (dwNumAddressesToGet > 0)
  360. {
  361. if (RasStatCurrentPool == NULL)
  362. {
  363. goto LDone;
  364. }
  365. hboIpAddr = RasStatCurrentPool->hboNextIpAddr;
  366. if (rasStatBadAddress(hboIpAddr))
  367. {
  368. TraceHlp("Discarding address 0x%x", hboIpAddr);
  369. goto LWhileEnd;
  370. }
  371. pNode = LocalAlloc(LPTR, sizeof(IPADDR_NODE));
  372. if (NULL == pNode)
  373. {
  374. TraceHlp("LocalAlloc failed and returned %d", GetLastError());
  375. goto LDone;
  376. }
  377. pNode->hboIpAddr = hboIpAddr;
  378. TraceHlp("Allocated address 0x%x", hboIpAddr);
  379. *ppNode = pNode;
  380. ppNode = &((*ppNode)->pNext);
  381. dwNumAddressesToGet--;
  382. LWhileEnd:
  383. if (RasStatCurrentPool->hboNextIpAddr ==
  384. RasStatCurrentPool->hboLastIpAddr)
  385. {
  386. RasStatCurrentPool = RasStatCurrentPool->pNext;
  387. }
  388. else
  389. {
  390. RasStatCurrentPool->hboNextIpAddr++;
  391. }
  392. }
  393. LDone:
  394. LeaveCriticalSection(&RasStatCriticalSection);
  395. }
  396. /*
  397. Returns:
  398. VOID
  399. Notes:
  400. */
  401. BOOL
  402. rasStatBadAddress(
  403. IPADDR hboIpAddr
  404. )
  405. {
  406. IPADDR hboSubnetMask;
  407. if ( INVALID_HBO_CLASS(hboIpAddr)
  408. || LOOPBACK_HBO_ADDR(hboIpAddr))
  409. {
  410. // Addresses >= 224.0.0.0 (0xE0000000) are invalid unicast addresses.
  411. // They are meant only for multicast use.
  412. return(TRUE);
  413. }
  414. // Reject 0.*.*.* also
  415. if ((hboIpAddr & 0xFF000000) == 0)
  416. {
  417. return(TRUE);
  418. }
  419. if (CLASSA_HBO_ADDR(hboIpAddr))
  420. {
  421. hboSubnetMask = CLASSA_HBO_ADDR_MASK;
  422. }
  423. else if (CLASSB_HBO_ADDR(hboIpAddr))
  424. {
  425. hboSubnetMask = CLASSB_HBO_ADDR_MASK;
  426. }
  427. else if (CLASSC_HBO_ADDR(hboIpAddr))
  428. {
  429. hboSubnetMask = CLASSC_HBO_ADDR_MASK;
  430. }
  431. else
  432. {
  433. return(TRUE);
  434. }
  435. // Reject subnet address
  436. if ((hboIpAddr & hboSubnetMask) == hboIpAddr)
  437. {
  438. return(TRUE);
  439. }
  440. // Reject broadcast address
  441. if ((hboIpAddr | ~hboSubnetMask) == hboIpAddr)
  442. {
  443. return(TRUE);
  444. }
  445. return(FALSE);
  446. }
  447. /*
  448. Returns:
  449. Notes:
  450. */
  451. VOID
  452. rasStatCreatePoolListFromOldValues(
  453. IN OUT ADDR_POOL** ppAddrPoolOut
  454. )
  455. {
  456. HKEY hKeyIpParam = NULL;
  457. CHAR* szIpAddress = NULL;
  458. CHAR* szIpMask = NULL;
  459. ADDR_POOL* pAddrPool = NULL;
  460. IPADDR hboFirstIpAddr;
  461. IPADDR hboLastIpAddr;
  462. IPADDR hboMask;
  463. LONG lErr;
  464. DWORD dwErr;
  465. TraceHlp("rasStatCreatePoolListFromOldValues");
  466. lErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_RAS_IP_PARAM_A, 0,
  467. KEY_READ, &hKeyIpParam);
  468. if (ERROR_SUCCESS != lErr)
  469. {
  470. TraceHlp("Couldn't open key %s: %d", REGKEY_RAS_IP_PARAM_A, lErr);
  471. goto LDone;
  472. }
  473. pAddrPool = LocalAlloc(LPTR, sizeof(ADDR_POOL));
  474. if (NULL == pAddrPool)
  475. {
  476. TraceHlp("Out of memory");
  477. goto LDone;
  478. }
  479. dwErr = RegQueryValueWithAllocA(hKeyIpParam, REGVAL_IPADDRESS_A,
  480. REG_SZ, &szIpAddress);
  481. if (NO_ERROR != dwErr)
  482. {
  483. TraceHlp("RegQueryValueWithAllocA(%s) failed: %d",
  484. REGVAL_IPADDRESS_A, dwErr);
  485. goto LDone;
  486. }
  487. hboFirstIpAddr = ntohl(inet_addr(szIpAddress));
  488. if (INADDR_NONE == hboFirstIpAddr)
  489. {
  490. TraceHlp("Bad value in %s", REGVAL_IPADDRESS_A);
  491. goto LDone;
  492. }
  493. dwErr = RegQueryValueWithAllocA(hKeyIpParam, REGVAL_IPMASK_A,
  494. REG_SZ, &szIpMask);
  495. if (NO_ERROR != dwErr)
  496. {
  497. TraceHlp("RegQueryValueWithAllocA(%s) failed: %d",
  498. REGVAL_IPMASK_A, dwErr);
  499. goto LDone;
  500. }
  501. hboMask = ntohl(inet_addr(szIpMask));
  502. if (INADDR_NONE == hboMask)
  503. {
  504. TraceHlp("Bad value in %s", REGVAL_IPMASK_A);
  505. goto LDone;
  506. }
  507. hboLastIpAddr = hboFirstIpAddr | (~hboMask);
  508. pAddrPool->hboFirstIpAddr = hboFirstIpAddr;
  509. pAddrPool->hboLastIpAddr = hboLastIpAddr;
  510. pAddrPool->hboNextIpAddr = hboFirstIpAddr;
  511. pAddrPool->hboMask = hboMask;
  512. TraceHlp("0x%x...0x%x/0x%x", hboFirstIpAddr, hboLastIpAddr, hboMask);
  513. *ppAddrPoolOut = pAddrPool;
  514. pAddrPool = NULL;
  515. LDone:
  516. if (NULL != hKeyIpParam)
  517. {
  518. RegCloseKey(hKeyIpParam);
  519. }
  520. LocalFree(szIpAddress);
  521. LocalFree(szIpMask);
  522. RasStatFreeAddrPool(pAddrPool);
  523. }
  524. /*
  525. Returns:
  526. Notes:
  527. */
  528. IPADDR
  529. rasStatMaskFromAddrPair(
  530. IN IPADDR hboFirstIpAddr,
  531. IN IPADDR hboLastIpAddr
  532. )
  533. {
  534. IPADDR hboTemp;
  535. IPADDR hboMask;
  536. IPADDR hboMaskTemp;
  537. DWORD dw;
  538. // This will put 1's where the bits have the same value
  539. hboTemp = ~(hboFirstIpAddr ^ hboLastIpAddr);
  540. // Now we look for the first 0 bit (looking from high bit to low bit)
  541. // This will give us our mask
  542. hboMask = 0;
  543. hboMaskTemp = 0;
  544. for (dw = 0; dw < sizeof(IPADDR) * 8; dw++)
  545. {
  546. hboMaskTemp >>= 1;
  547. hboMaskTemp |= 0x80000000;
  548. // Is there a zero bit?
  549. if ((hboMaskTemp & hboTemp) != hboMaskTemp)
  550. {
  551. // There is a zero, so we break out.
  552. break;
  553. }
  554. // If not, continue
  555. hboMask = hboMaskTemp;
  556. }
  557. return(hboMask);
  558. }