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.

775 lines
15 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. if(pAddrPool1->hboLastIpAddr < pAddrPool2->hboLastIpAddr)
  226. {
  227. EnterCriticalSection(&RasStatCriticalSection);
  228. pAddrPool1->hboLastIpAddr = pAddrPool2->hboLastIpAddr;
  229. LeaveCriticalSection(&RasStatCriticalSection);
  230. }
  231. if( (pAddrPool1->pNext == NULL)
  232. && (pAddrPool2->pNext != NULL))
  233. {
  234. EnterCriticalSection(&RasStatCriticalSection);
  235. pAddrPool1->pNext = pAddrPool2->pNext;
  236. LeaveCriticalSection(&RasStatCriticalSection);
  237. pAddrPool2->pNext = NULL;
  238. return FALSE;
  239. }
  240. pAddrPool1 = pAddrPool1->pNext;
  241. pAddrPool2 = pAddrPool2->pNext;
  242. }
  243. }
  244. /*
  245. Returns:
  246. Notes:
  247. */
  248. DWORD
  249. RasStatAcquireAddress(
  250. IN HPORT hPort,
  251. OUT IPADDR* pnboIpAddr,
  252. OUT IPADDR* pnboIpMask
  253. )
  254. {
  255. IPADDR_NODE* pNode;
  256. DWORD dwErr = ERROR_NO_IP_ADDRESSES;
  257. TraceHlp("RasStatAcquireAddress");
  258. EnterCriticalSection(&RasStatCriticalSection);
  259. if (NULL == RasStatFreePool)
  260. {
  261. rasStatAllocateAddresses();
  262. if (NULL == RasStatFreePool)
  263. {
  264. TraceHlp("Out of addresses");
  265. goto LDone;
  266. }
  267. }
  268. // Move from Free pool to Alloc pool
  269. pNode = RasStatFreePool;
  270. RasStatFreePool = RasStatFreePool->pNext;
  271. pNode->pNext = RasStatAllocPool;
  272. RasStatAllocPool = pNode;
  273. TraceHlp("Acquired 0x%x", pNode->hboIpAddr);
  274. *pnboIpAddr = htonl(pNode->hboIpAddr);
  275. *pnboIpMask = htonl(HOST_MASK);
  276. pNode->hPort = hPort;
  277. dwErr = NO_ERROR;
  278. LDone:
  279. LeaveCriticalSection(&RasStatCriticalSection);
  280. return(dwErr);
  281. }
  282. /*
  283. Returns:
  284. VOID
  285. Notes:
  286. */
  287. VOID
  288. RasStatReleaseAddress(
  289. IN IPADDR nboIpAddr
  290. )
  291. {
  292. IPADDR_NODE* pNode;
  293. IPADDR_NODE** ppNode;
  294. IPADDR hboIpAddr;
  295. TraceHlp("RasStatReleaseAddress");
  296. EnterCriticalSection(&RasStatCriticalSection);
  297. hboIpAddr = ntohl(nboIpAddr);
  298. for (ppNode = &RasStatAllocPool;
  299. (pNode = *ppNode) != NULL;
  300. ppNode = &pNode->pNext)
  301. {
  302. if (pNode->hboIpAddr == hboIpAddr)
  303. {
  304. TraceHlp("Released 0x%x", nboIpAddr);
  305. // Unlink from alloc pool
  306. *ppNode = pNode->pNext;
  307. // Put at the end of the free pool, because we want to round-robin
  308. // the addresses.
  309. pNode->pNext = NULL;
  310. ppNode = &RasStatFreePool;
  311. while (NULL != *ppNode)
  312. {
  313. ppNode = &((*ppNode)->pNext);
  314. }
  315. *ppNode = pNode;
  316. goto LDone;
  317. }
  318. }
  319. TraceHlp("IpAddress 0x%x not present in alloc pool", nboIpAddr);
  320. LDone:
  321. LeaveCriticalSection(&RasStatCriticalSection);
  322. }
  323. /*
  324. Returns:
  325. VOID
  326. Notes:
  327. */
  328. VOID
  329. rasStatDeleteLists(
  330. VOID
  331. )
  332. {
  333. IPADDR_NODE* pNode;
  334. IPADDR_NODE* pNodeTemp;
  335. DWORD dwIndex;
  336. TraceHlp("rasStatDeleteLists");
  337. EnterCriticalSection(&RasStatCriticalSection);
  338. pNode = RasStatAllocPool;
  339. while (pNode != NULL)
  340. {
  341. pNodeTemp = pNode;
  342. pNode = pNode->pNext;
  343. LocalFree(pNodeTemp);
  344. }
  345. pNode = RasStatFreePool;
  346. while (pNode != NULL)
  347. {
  348. pNodeTemp = pNode;
  349. pNode = pNode->pNext;
  350. LocalFree(pNodeTemp);
  351. }
  352. RasStatAllocPool = NULL;
  353. RasStatFreePool = NULL;
  354. LeaveCriticalSection(&RasStatCriticalSection);
  355. }
  356. /*
  357. Returns:
  358. VOID
  359. Notes:
  360. */
  361. VOID
  362. rasStatAllocateAddresses(
  363. VOID
  364. )
  365. {
  366. DWORD dwNumAddressesToGet;
  367. IPADDR_NODE* pNode;
  368. IPADDR_NODE** ppNode;
  369. IPADDR hboIpAddr;
  370. TraceHlp("rasStatAllocateAddresses");
  371. EnterCriticalSection(&RasStatCriticalSection);
  372. ppNode = &RasStatFreePool;
  373. dwNumAddressesToGet = HelperRegVal.dwChunkSize;
  374. while (dwNumAddressesToGet > 0)
  375. {
  376. if (RasStatCurrentPool == NULL)
  377. {
  378. goto LDone;
  379. }
  380. hboIpAddr = RasStatCurrentPool->hboNextIpAddr;
  381. if (rasStatBadAddress(hboIpAddr))
  382. {
  383. TraceHlp("Discarding address 0x%x", hboIpAddr);
  384. goto LWhileEnd;
  385. }
  386. pNode = LocalAlloc(LPTR, sizeof(IPADDR_NODE));
  387. if (NULL == pNode)
  388. {
  389. TraceHlp("LocalAlloc failed and returned %d", GetLastError());
  390. goto LDone;
  391. }
  392. pNode->hboIpAddr = hboIpAddr;
  393. TraceHlp("Allocated address 0x%x", hboIpAddr);
  394. *ppNode = pNode;
  395. ppNode = &((*ppNode)->pNext);
  396. dwNumAddressesToGet--;
  397. LWhileEnd:
  398. if (RasStatCurrentPool->hboNextIpAddr ==
  399. RasStatCurrentPool->hboLastIpAddr)
  400. {
  401. RasStatCurrentPool = RasStatCurrentPool->pNext;
  402. }
  403. else
  404. {
  405. RasStatCurrentPool->hboNextIpAddr++;
  406. }
  407. }
  408. LDone:
  409. LeaveCriticalSection(&RasStatCriticalSection);
  410. }
  411. /*
  412. Returns:
  413. VOID
  414. Notes:
  415. */
  416. BOOL
  417. rasStatBadAddress(
  418. IPADDR hboIpAddr
  419. )
  420. {
  421. IPADDR hboSubnetMask;
  422. if ( INVALID_HBO_CLASS(hboIpAddr)
  423. || LOOPBACK_HBO_ADDR(hboIpAddr))
  424. {
  425. // Addresses >= 224.0.0.0 (0xE0000000) are invalid unicast addresses.
  426. // They are meant only for multicast use.
  427. return(TRUE);
  428. }
  429. // Reject 0.*.*.* also
  430. if ((hboIpAddr & 0xFF000000) == 0)
  431. {
  432. return(TRUE);
  433. }
  434. if (CLASSA_HBO_ADDR(hboIpAddr))
  435. {
  436. hboSubnetMask = CLASSA_HBO_ADDR_MASK;
  437. }
  438. else if (CLASSB_HBO_ADDR(hboIpAddr))
  439. {
  440. hboSubnetMask = CLASSB_HBO_ADDR_MASK;
  441. }
  442. else if (CLASSC_HBO_ADDR(hboIpAddr))
  443. {
  444. hboSubnetMask = CLASSC_HBO_ADDR_MASK;
  445. }
  446. else
  447. {
  448. return(TRUE);
  449. }
  450. // Reject subnet address
  451. if ((hboIpAddr & hboSubnetMask) == hboIpAddr)
  452. {
  453. return(TRUE);
  454. }
  455. // Reject broadcast address
  456. if ((hboIpAddr | ~hboSubnetMask) == hboIpAddr)
  457. {
  458. return(TRUE);
  459. }
  460. return(FALSE);
  461. }
  462. /*
  463. Returns:
  464. Notes:
  465. */
  466. VOID
  467. rasStatCreatePoolListFromOldValues(
  468. IN OUT ADDR_POOL** ppAddrPoolOut
  469. )
  470. {
  471. HKEY hKeyIpParam = NULL;
  472. CHAR* szIpAddress = NULL;
  473. CHAR* szIpMask = NULL;
  474. ADDR_POOL* pAddrPool = NULL;
  475. IPADDR hboFirstIpAddr;
  476. IPADDR hboLastIpAddr;
  477. IPADDR hboMask;
  478. LONG lErr;
  479. DWORD dwErr;
  480. TraceHlp("rasStatCreatePoolListFromOldValues");
  481. lErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_RAS_IP_PARAM_A, 0,
  482. KEY_READ, &hKeyIpParam);
  483. if (ERROR_SUCCESS != lErr)
  484. {
  485. TraceHlp("Couldn't open key %s: %d", REGKEY_RAS_IP_PARAM_A, lErr);
  486. goto LDone;
  487. }
  488. pAddrPool = LocalAlloc(LPTR, sizeof(ADDR_POOL));
  489. if (NULL == pAddrPool)
  490. {
  491. TraceHlp("Out of memory");
  492. goto LDone;
  493. }
  494. dwErr = RegQueryValueWithAllocA(hKeyIpParam, REGVAL_IPADDRESS_A,
  495. REG_SZ, &szIpAddress);
  496. if (NO_ERROR != dwErr)
  497. {
  498. TraceHlp("RegQueryValueWithAllocA(%s) failed: %d",
  499. REGVAL_IPADDRESS_A, dwErr);
  500. goto LDone;
  501. }
  502. hboFirstIpAddr = ntohl(inet_addr(szIpAddress));
  503. if (INADDR_NONE == hboFirstIpAddr)
  504. {
  505. TraceHlp("Bad value in %s", REGVAL_IPADDRESS_A);
  506. goto LDone;
  507. }
  508. dwErr = RegQueryValueWithAllocA(hKeyIpParam, REGVAL_IPMASK_A,
  509. REG_SZ, &szIpMask);
  510. if (NO_ERROR != dwErr)
  511. {
  512. TraceHlp("RegQueryValueWithAllocA(%s) failed: %d",
  513. REGVAL_IPMASK_A, dwErr);
  514. goto LDone;
  515. }
  516. hboMask = ntohl(inet_addr(szIpMask));
  517. if (INADDR_NONE == hboMask)
  518. {
  519. TraceHlp("Bad value in %s", REGVAL_IPMASK_A);
  520. goto LDone;
  521. }
  522. hboLastIpAddr = hboFirstIpAddr | (~hboMask);
  523. pAddrPool->hboFirstIpAddr = hboFirstIpAddr;
  524. pAddrPool->hboLastIpAddr = hboLastIpAddr;
  525. pAddrPool->hboNextIpAddr = hboFirstIpAddr;
  526. pAddrPool->hboMask = hboMask;
  527. TraceHlp("0x%x...0x%x/0x%x", hboFirstIpAddr, hboLastIpAddr, hboMask);
  528. *ppAddrPoolOut = pAddrPool;
  529. pAddrPool = NULL;
  530. LDone:
  531. if (NULL != hKeyIpParam)
  532. {
  533. RegCloseKey(hKeyIpParam);
  534. }
  535. LocalFree(szIpAddress);
  536. LocalFree(szIpMask);
  537. RasStatFreeAddrPool(pAddrPool);
  538. }
  539. /*
  540. Returns:
  541. Notes:
  542. */
  543. IPADDR
  544. rasStatMaskFromAddrPair(
  545. IN IPADDR hboFirstIpAddr,
  546. IN IPADDR hboLastIpAddr
  547. )
  548. {
  549. IPADDR hboTemp;
  550. IPADDR hboMask;
  551. IPADDR hboMaskTemp;
  552. DWORD dw;
  553. // This will put 1's where the bits have the same value
  554. hboTemp = ~(hboFirstIpAddr ^ hboLastIpAddr);
  555. // Now we look for the first 0 bit (looking from high bit to low bit)
  556. // This will give us our mask
  557. hboMask = 0;
  558. hboMaskTemp = 0;
  559. for (dw = 0; dw < sizeof(IPADDR) * 8; dw++)
  560. {
  561. hboMaskTemp >>= 1;
  562. hboMaskTemp |= 0x80000000;
  563. // Is there a zero bit?
  564. if ((hboMaskTemp & hboTemp) != hboMaskTemp)
  565. {
  566. // There is a zero, so we break out.
  567. break;
  568. }
  569. // If not, continue
  570. hboMask = hboMaskTemp;
  571. }
  572. return(hboMask);
  573. }