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.

1186 lines
31 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\ip\rtrmgr\info.c
  5. Abstract:
  6. All info structure related code lives here
  7. Revision History:
  8. Gurdeep Singh Pall 6/15/95 Created
  9. --*/
  10. #include "allinc.h"
  11. PRTR_TOC_ENTRY
  12. GetPointerToTocEntry(
  13. DWORD dwType,
  14. PRTR_INFO_BLOCK_HEADER pInfoHdr
  15. )
  16. /*++
  17. Routine Description
  18. Given a pointer to an InfoBlock, this returns a pointer to the
  19. TOC of a given type
  20. Locks
  21. None
  22. Arguments
  23. dwType InfoType for TOC
  24. pInfoHdr Pointer to the InfoBlock header
  25. Return Value
  26. NULL if the structure was not found
  27. Pointer to TOC other wise
  28. --*/
  29. {
  30. DWORD i;
  31. if(pInfoHdr is NULL)
  32. {
  33. return NULL;
  34. }
  35. for(i = 0; i < pInfoHdr->TocEntriesCount; i++)
  36. {
  37. if(pInfoHdr->TocEntry[i].InfoType is dwType)
  38. {
  39. return &(pInfoHdr->TocEntry[i]);
  40. }
  41. }
  42. return NULL;
  43. }
  44. DWORD
  45. GetSizeOfInterfaceConfig(
  46. PICB picb
  47. )
  48. /*++
  49. Routine Description
  50. This function figures out the size of interface configuration
  51. Locks
  52. ICB_LIST lock taken as READER
  53. Takes the PROTOCOL_CB_LIST lock as reader
  54. Arguments
  55. picb ICB for the interface
  56. Return Value
  57. None
  58. --*/
  59. {
  60. DWORD dwRoutProtInfoSize,dwRouteCount;
  61. PLIST_ENTRY pleNode;
  62. DWORD dwSize = 0, dwNumFilters;
  63. DWORD dwResult;
  64. DWORD dwInfoSize, i;
  65. ULONG ulStructureSize, ulStructureVersion, ulStructureCount;
  66. TraceEnter("GetSizeOfInterfaceConfig");
  67. //
  68. // Start with just the header (no TOC entry)
  69. //
  70. dwSize = FIELD_OFFSET(RTR_INFO_BLOCK_HEADER,
  71. TocEntry[0]);
  72. //
  73. // Static Routes:
  74. // Get the count, figure out the size needed to hold those, add the
  75. // size of a TOC and an ALIGN_SIZE added for alignment
  76. //
  77. dwRouteCount = GetNumStaticRoutes(picb);
  78. dwSize += (SIZEOF_ROUTEINFO(dwRouteCount) +
  79. sizeof(RTR_TOC_ENTRY) +
  80. ALIGN_SIZE);
  81. //
  82. // Router Discovery info
  83. //
  84. dwSize += (sizeof(RTR_DISC_INFO) +
  85. sizeof(RTR_TOC_ENTRY) +
  86. ALIGN_SIZE);
  87. //
  88. // Interface Status info
  89. //
  90. dwSize += (sizeof(INTERFACE_STATUS_INFO) +
  91. sizeof(RTR_TOC_ENTRY) +
  92. ALIGN_SIZE);
  93. #ifdef KSL_IPINIP
  94. //
  95. // If this is an ip in ip interface, add that info
  96. //
  97. if(picb->ritType is ROUTER_IF_TYPE_TUNNEL1)
  98. {
  99. dwSize += (sizeof(IPINIP_CONFIG_INFO) +
  100. sizeof(RTR_TOC_ENTRY) +
  101. ALIGN_SIZE);
  102. }
  103. #endif //KSL_IPINIP
  104. for(i = 0; i < NUM_INFO_CBS; i++)
  105. {
  106. if (!g_rgicInfoCb[i].pfnGetInterfaceInfo)
  107. continue;
  108. dwInfoSize = 0;
  109. dwResult = g_rgicInfoCb[i].pfnGetInterfaceInfo(picb,
  110. NULL,
  111. NULL,
  112. NULL,
  113. NULL,
  114. &dwInfoSize);
  115. if((dwResult isnot NO_ERROR) and
  116. (dwResult isnot ERROR_INSUFFICIENT_BUFFER))
  117. {
  118. //
  119. // The only errors which will tell us the size needed are
  120. // NO_ERROR and ERROR_INSUFFICIENT_BUFFER. Anything else means
  121. // we didnt get the right size
  122. //
  123. Trace2(ERR,
  124. "GetSizeOfInterfaceConfig: Error %d in GetIfInfo for %s\n",
  125. dwResult,
  126. g_rgicInfoCb[i].pszInfoName);
  127. continue;
  128. }
  129. dwSize += (dwInfoSize +
  130. sizeof(RTR_TOC_ENTRY) +
  131. ALIGN_SIZE);
  132. }
  133. //
  134. // Information for all routing protocols ON THIS interface
  135. //
  136. ENTER_READER(PROTOCOL_CB_LIST);
  137. for(pleNode = picb->leProtocolList.Flink;
  138. pleNode isnot &(picb->leProtocolList);
  139. pleNode = pleNode->Flink)
  140. {
  141. PIF_PROTO pProto;
  142. pProto = CONTAINING_RECORD(pleNode,IF_PROTO,leIfProtoLink);
  143. if(pProto->bPromiscuous)
  144. {
  145. //
  146. // This interface was added merely because of promiscuous mode
  147. //
  148. continue;
  149. }
  150. //
  151. // Call the routing protocol's GetInterfaceConfigInfo() entrypoint
  152. // with a NULL buffer. This will cause it to tell us the size of
  153. // its config
  154. //
  155. dwRoutProtInfoSize = 0;
  156. dwResult = (pProto->pActiveProto->pfnGetInterfaceInfo)(
  157. picb->dwIfIndex,
  158. NULL,
  159. &dwRoutProtInfoSize,
  160. &ulStructureVersion,
  161. &ulStructureSize,
  162. &ulStructureCount);
  163. if((dwResult isnot NO_ERROR) and
  164. (dwResult isnot ERROR_INSUFFICIENT_BUFFER))
  165. {
  166. //
  167. // The only errors which will tell us the size needed are
  168. // NO_ERROR and ERROR_INSUFFICIENT_BUFFER. Anything else means
  169. // we didnt get the right size
  170. //
  171. Trace2(ERR,
  172. "GetSizeOfInterfaceConfig: Error %d in GetIfInfo for %S\n",
  173. dwResult,
  174. pProto->pActiveProto->pwszDisplayName);
  175. continue;
  176. }
  177. dwSize += (dwRoutProtInfoSize +
  178. sizeof(RTR_TOC_ENTRY) +
  179. ALIGN_SIZE);
  180. }
  181. EXIT_LOCK(PROTOCOL_CB_LIST);
  182. //
  183. // If we have filters on this interface, add that info
  184. //
  185. if(picb->pInFilter)
  186. {
  187. dwNumFilters = picb->pInFilter->dwNumFilters;
  188. dwSize += (sizeof(RTR_TOC_ENTRY) +
  189. FIELD_OFFSET(FILTER_DESCRIPTOR, fiFilter[0]) +
  190. (dwNumFilters * sizeof(FILTER_INFO)) +
  191. ALIGN_SIZE);
  192. }
  193. if(picb->pOutFilter)
  194. {
  195. dwNumFilters = picb->pOutFilter->dwNumFilters;
  196. dwSize += (sizeof(RTR_TOC_ENTRY) +
  197. FIELD_OFFSET(FILTER_DESCRIPTOR, fiFilter[0]) +
  198. (dwNumFilters * sizeof(FILTER_INFO)) +
  199. ALIGN_SIZE);
  200. }
  201. //
  202. // Always report the fragmentation filter.
  203. //
  204. dwSize += (sizeof(IFFILTER_INFO) +
  205. sizeof(RTR_TOC_ENTRY) +
  206. ALIGN_SIZE);
  207. if(picb->pDemandFilter)
  208. {
  209. dwNumFilters = picb->pDemandFilter->dwNumFilters;
  210. dwSize += (sizeof(RTR_TOC_ENTRY) +
  211. FIELD_OFFSET(FILTER_DESCRIPTOR, fiFilter[0]) +
  212. (dwNumFilters * sizeof(FILTER_INFO)) +
  213. ALIGN_SIZE);
  214. }
  215. return dwSize;
  216. }
  217. DWORD
  218. GetInterfaceConfiguration(
  219. PICB picb,
  220. PRTR_INFO_BLOCK_HEADER pInfoHdrAndBuffer,
  221. DWORD dwInfoSize
  222. )
  223. {
  224. DWORD i,dwErr, dwRet;
  225. DWORD dwTocIndex;
  226. PBYTE pbyDataPtr , pbyEndPtr;
  227. DWORD dwNumTocEntries;
  228. LONG lSize;
  229. PLIST_ENTRY pleNode;
  230. TraceEnter("GetInterfaceConfiguration");
  231. dwRet = NO_ERROR;
  232. //
  233. // First calculate number of TOCs
  234. //
  235. //
  236. // for static routes, router discovery, interface info and frag info
  237. //
  238. dwNumTocEntries = TOCS_ALWAYS_IN_INTERFACE_INFO;
  239. //
  240. // One TOC for each filter that exists
  241. //
  242. if(picb->pInFilter)
  243. {
  244. dwNumTocEntries++;
  245. }
  246. if(picb->pOutFilter)
  247. {
  248. dwNumTocEntries++;
  249. }
  250. if(picb->pDemandFilter)
  251. {
  252. dwNumTocEntries++;
  253. }
  254. #ifdef KSL_IPINIP
  255. if(picb->ritType is ROUTER_IF_TYPE_TUNNEL1)
  256. {
  257. dwNumTocEntries++;
  258. }
  259. #endif //KSL_IPINIP
  260. for(i = 0; i < NUM_INFO_CBS; i++)
  261. {
  262. if (!g_rgicInfoCb[i].pfnGetInterfaceInfo)
  263. continue;
  264. lSize = 0;
  265. dwErr = g_rgicInfoCb[i].pfnGetInterfaceInfo(picb,
  266. NULL,
  267. &dwNumTocEntries,
  268. NULL,
  269. NULL,
  270. &lSize);
  271. }
  272. //
  273. // One TOC for each configured protocol
  274. //
  275. // *** Exclusion Begin ***
  276. ENTER_READER(PROTOCOL_CB_LIST);
  277. for(pleNode = picb->leProtocolList.Flink;
  278. pleNode isnot &(picb->leProtocolList);
  279. pleNode = pleNode->Flink)
  280. {
  281. PIF_PROTO pProto;
  282. pProto = CONTAINING_RECORD(pleNode,IF_PROTO,leIfProtoLink);
  283. if(pProto->bPromiscuous)
  284. {
  285. continue;
  286. }
  287. dwNumTocEntries++;
  288. }
  289. //
  290. // fill in RTR_INFO_BLOCK_HEADER
  291. //
  292. dwTocIndex = 0;
  293. pInfoHdrAndBuffer->Version = IP_ROUTER_MANAGER_VERSION;
  294. pInfoHdrAndBuffer->TocEntriesCount = dwNumTocEntries;
  295. pInfoHdrAndBuffer->Size = dwInfoSize;
  296. //
  297. // Data begins after TocEntry[dwNumTocEntries - 1]
  298. //
  299. pbyDataPtr = ((PBYTE) &(pInfoHdrAndBuffer->TocEntry[dwNumTocEntries]));
  300. //
  301. // Align to an 8byte boundary
  302. //
  303. ALIGN_POINTER(pbyDataPtr);
  304. pbyEndPtr = (PBYTE)pInfoHdrAndBuffer + dwInfoSize;
  305. //
  306. // So the size of buffer left for information is
  307. //
  308. lSize = (LONG)(pbyEndPtr - pbyDataPtr);
  309. //
  310. // fill in routing protocol info
  311. //
  312. for(pleNode = picb->leProtocolList.Flink;
  313. pleNode isnot &(picb->leProtocolList);
  314. pleNode = pleNode->Flink)
  315. {
  316. PIF_PROTO pProto;
  317. pProto = CONTAINING_RECORD(pleNode,IF_PROTO,leIfProtoLink);
  318. if(pProto->bPromiscuous)
  319. {
  320. //
  321. // This interface was added merely because of promiscuous mode
  322. //
  323. continue;
  324. }
  325. if(lSize <= 0)
  326. {
  327. Trace0(ERR,
  328. "GetInterfaceConfiguration: There is no more space left to fill in config info even though there are more protocols");
  329. break;
  330. }
  331. dwErr = GetInterfaceRoutingProtoInfo(
  332. picb,
  333. pProto->pActiveProto,
  334. &pInfoHdrAndBuffer->TocEntry[dwTocIndex++],
  335. pbyDataPtr,
  336. pInfoHdrAndBuffer,
  337. &lSize);
  338. if(dwErr isnot NO_ERROR)
  339. {
  340. Trace2(ERR,
  341. "GetInterfaceConfiguration: Info from %S. Error %d",
  342. pProto->pActiveProto->pwszDisplayName,
  343. dwErr);
  344. dwRet = ERROR_MORE_DATA;
  345. }
  346. else
  347. {
  348. pbyDataPtr += lSize;
  349. ALIGN_POINTER(pbyDataPtr);
  350. }
  351. lSize = (LONG)(pbyEndPtr - pbyDataPtr);
  352. }
  353. EXIT_LOCK(PROTOCOL_CB_LIST);
  354. if(lSize <= 0)
  355. {
  356. Trace0(ERR,
  357. "GetInterfaceConfiguration: There is no more space left to fill in config info");
  358. return ERROR_MORE_DATA;
  359. }
  360. for(i = 0; i < NUM_INFO_CBS; i++)
  361. {
  362. if (!g_rgicInfoCb[i].pfnGetInterfaceInfo)
  363. continue;
  364. dwErr = g_rgicInfoCb[i].pfnGetInterfaceInfo(picb,
  365. &pInfoHdrAndBuffer->TocEntry[dwTocIndex],
  366. &dwTocIndex,
  367. pbyDataPtr,
  368. pInfoHdrAndBuffer,
  369. &lSize);
  370. if(dwErr isnot NO_ERROR)
  371. {
  372. Trace2(ERR,
  373. "GetInterfaceConfiguration: Error %d getting %s info.",
  374. dwErr,
  375. g_rgicInfoCb[i].pszInfoName);
  376. if(dwErr isnot ERROR_NO_DATA)
  377. {
  378. dwRet = ERROR_MORE_DATA;
  379. }
  380. }
  381. else
  382. {
  383. pbyDataPtr += lSize;
  384. ALIGN_POINTER(pbyDataPtr);
  385. }
  386. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  387. }
  388. #ifdef KSL_IPINIP
  389. if(picb->ritType is ROUTER_IF_TYPE_TUNNEL1)
  390. {
  391. dwErr = GetInterfaceIpIpInfo(picb,
  392. &pInfoHdrAndBuffer->TocEntry[dwTocIndex++],
  393. pbyDataPtr,
  394. pInfoHdrAndBuffer,
  395. &lSize);
  396. if(dwErr isnot NO_ERROR)
  397. {
  398. Trace1(ERR,
  399. "GetInterfaceConfiguration: Couldnt ipip info. Error %d",
  400. dwErr);
  401. if(dwErr isnot ERROR_NO_DATA)
  402. {
  403. dwRet = ERROR_MORE_DATA;
  404. }
  405. }
  406. else
  407. {
  408. pbyDataPtr += lSize;
  409. ALIGN_POINTER(pbyDataPtr);
  410. }
  411. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  412. }
  413. #endif //KSL_IPINIP
  414. //
  415. // fill in route info
  416. //
  417. dwErr = GetInterfaceRouteInfo(picb,
  418. &pInfoHdrAndBuffer->TocEntry[dwTocIndex++],
  419. pbyDataPtr,
  420. pInfoHdrAndBuffer,
  421. &lSize);
  422. if(dwErr isnot NO_ERROR)
  423. {
  424. Trace1(ERR,
  425. "GetInterfaceConfiguration: Couldnt Interface route info. Error %d",
  426. dwErr);
  427. if(dwErr isnot ERROR_NO_DATA)
  428. {
  429. dwRet = ERROR_MORE_DATA;
  430. }
  431. }
  432. else
  433. {
  434. pbyDataPtr += lSize;
  435. ALIGN_POINTER(pbyDataPtr);
  436. }
  437. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  438. if(lSize <= 0)
  439. {
  440. Trace0(ERR,
  441. "GetInterfaceConfiguration: There is no more space left to fill in config info");
  442. return ERROR_MORE_DATA;
  443. }
  444. //
  445. // Fill in the status info
  446. //
  447. dwErr = GetInterfaceStatusInfo(picb,
  448. &pInfoHdrAndBuffer->TocEntry[dwTocIndex++],
  449. pbyDataPtr,
  450. pInfoHdrAndBuffer,
  451. &lSize);
  452. if(dwErr isnot NO_ERROR)
  453. {
  454. Trace1(ERR,
  455. "GetInterfaceConfiguration: Error %d getting Interface status",
  456. dwErr);
  457. if(dwErr isnot ERROR_NO_DATA)
  458. {
  459. dwRet = ERROR_MORE_DATA;
  460. }
  461. }
  462. else
  463. {
  464. pbyDataPtr += lSize;
  465. ALIGN_POINTER(pbyDataPtr);
  466. }
  467. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  468. if(lSize <= 0)
  469. {
  470. Trace0(ERR,
  471. "GetInterfaceConfiguration: There is no more space left to fill in config info");
  472. return ERROR_MORE_DATA;
  473. }
  474. //
  475. // Fill in the Router Discovery information
  476. //
  477. dwErr = GetInterfaceRouterDiscoveryInfo(
  478. picb,
  479. &pInfoHdrAndBuffer->TocEntry[dwTocIndex++],
  480. pbyDataPtr,
  481. pInfoHdrAndBuffer,
  482. &lSize);
  483. if(dwErr isnot NO_ERROR)
  484. {
  485. Trace1(ERR,
  486. "GetInterfaceConfiguration: Couldnt Interface router discovery info. Error %d",
  487. dwErr);
  488. if(dwErr isnot ERROR_NO_DATA)
  489. {
  490. dwRet = ERROR_MORE_DATA;
  491. }
  492. }
  493. else
  494. {
  495. pbyDataPtr += lSize;
  496. ALIGN_POINTER(pbyDataPtr);
  497. }
  498. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  499. if(lSize <= 0)
  500. {
  501. Trace0(ERR,
  502. "GetInterfaceConfiguration: There is no more space left to fill in config info");
  503. return ERROR_MORE_DATA;
  504. }
  505. if(picb->pInFilter)
  506. {
  507. dwErr = GetInFilters(picb,
  508. &pInfoHdrAndBuffer->TocEntry[dwTocIndex],
  509. pbyDataPtr,
  510. pInfoHdrAndBuffer,
  511. &lSize);
  512. if(dwErr is NO_ERROR)
  513. {
  514. dwTocIndex++;
  515. pbyDataPtr += lSize;
  516. ALIGN_POINTER(pbyDataPtr);
  517. }
  518. else
  519. {
  520. if(dwErr isnot ERROR_NO_DATA)
  521. {
  522. dwRet = ERROR_MORE_DATA;
  523. }
  524. }
  525. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  526. if(lSize <= 0)
  527. {
  528. Trace0(ERR,
  529. "GetInterfaceConfiguration: There is no more space left to fill in config info");
  530. return ERROR_MORE_DATA;
  531. }
  532. }
  533. if(picb->pOutFilter)
  534. {
  535. dwErr = GetOutFilters(picb,
  536. &pInfoHdrAndBuffer->TocEntry[dwTocIndex],
  537. pbyDataPtr,
  538. pInfoHdrAndBuffer,
  539. &lSize);
  540. if(dwErr is NO_ERROR)
  541. {
  542. dwTocIndex++;
  543. pbyDataPtr += lSize;
  544. ALIGN_POINTER(pbyDataPtr);
  545. }
  546. else
  547. {
  548. if(dwErr isnot ERROR_NO_DATA)
  549. {
  550. dwRet = ERROR_MORE_DATA;
  551. }
  552. }
  553. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  554. if(lSize <= 0)
  555. {
  556. Trace0(ERR,
  557. "GetInterfaceConfiguration: There is no more space left to fill in config info");
  558. return ERROR_MORE_DATA;
  559. }
  560. }
  561. if((picb->ritType isnot ROUTER_IF_TYPE_INTERNAL) and
  562. (picb->ritType isnot ROUTER_IF_TYPE_LOOPBACK) and
  563. (picb->ritType isnot ROUTER_IF_TYPE_CLIENT))
  564. {
  565. dwErr = GetGlobalFilterOnIf(picb,
  566. &pInfoHdrAndBuffer->TocEntry[dwTocIndex],
  567. pbyDataPtr,
  568. pInfoHdrAndBuffer,
  569. &lSize);
  570. if(dwErr is NO_ERROR)
  571. {
  572. dwTocIndex++;
  573. pbyDataPtr += lSize;
  574. ALIGN_POINTER(pbyDataPtr);
  575. }
  576. else
  577. {
  578. if(dwErr isnot ERROR_NO_DATA)
  579. {
  580. dwRet = ERROR_MORE_DATA;
  581. }
  582. }
  583. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  584. if(lSize <= 0)
  585. {
  586. Trace0(ERR,
  587. "GetInterfaceConfiguration: There is no more space left to fill in config info");
  588. return ERROR_MORE_DATA;
  589. }
  590. }
  591. if(picb->pDemandFilter)
  592. {
  593. dwErr = GetDemandFilters(picb,
  594. &pInfoHdrAndBuffer->TocEntry[dwTocIndex],
  595. pbyDataPtr,
  596. pInfoHdrAndBuffer,
  597. &lSize);
  598. if(dwErr is NO_ERROR)
  599. {
  600. dwTocIndex++;
  601. pbyDataPtr += lSize;
  602. ALIGN_POINTER(pbyDataPtr);
  603. }
  604. else
  605. {
  606. if(dwErr isnot ERROR_NO_DATA)
  607. {
  608. dwRet = ERROR_MORE_DATA;
  609. }
  610. }
  611. lSize = (LONG) (pbyEndPtr - pbyDataPtr);
  612. }
  613. if(pInfoHdrAndBuffer->TocEntriesCount != dwTocIndex)
  614. {
  615. pInfoHdrAndBuffer->TocEntriesCount = dwTocIndex;
  616. }
  617. return dwRet;
  618. }
  619. DWORD
  620. GetInterfaceRoutingProtoInfo(
  621. PICB picb,
  622. PPROTO_CB pProtoCbPtr,
  623. PRTR_TOC_ENTRY pToc,
  624. PBYTE pbyDataPtr,
  625. PRTR_INFO_BLOCK_HEADER pInfoHdrAndBuffer,
  626. PDWORD pdwSize
  627. )
  628. {
  629. ULONG ulStructureSize, ulStructureCount, ulStructureVersion;
  630. DWORD dwError = NO_ERROR;
  631. TraceEnter("GetInterfaceRoutingProtoInfo");
  632. dwError = (pProtoCbPtr->pfnGetInterfaceInfo)(picb->dwIfIndex,
  633. pbyDataPtr,
  634. pdwSize,
  635. &ulStructureVersion,
  636. &ulStructureSize,
  637. &ulStructureCount);
  638. if(dwError isnot NO_ERROR)
  639. {
  640. Trace1(ERR,
  641. "GetInterfaceRoutingProtoInfo: GetIfConfigInfo() failed for protocol %S",
  642. pProtoCbPtr->pwszDisplayName);
  643. return dwError;
  644. }
  645. //IpRtAssert(*pdwSize is (ulStructureSize * ulStructureCount));
  646. pToc->InfoSize = ulStructureSize;
  647. pToc->InfoType = pProtoCbPtr->dwProtocolId;
  648. pToc->Count = ulStructureCount;
  649. pToc->Offset = (ULONG)(pbyDataPtr - (PBYTE)pInfoHdrAndBuffer);
  650. //pToc->InfoVersion = ulStructureVersion;
  651. return NO_ERROR;
  652. }
  653. DWORD
  654. GetGlobalConfiguration(
  655. PRTR_INFO_BLOCK_HEADER pInfoHdrAndBuffer,
  656. DWORD dwInfoSize
  657. )
  658. {
  659. DWORD dwRoutProtInfoSize;
  660. PPROTO_CB pProtoCbPtr;
  661. DWORD dwNumTocEntries, i;
  662. DWORD dwTocIndex,dwResult;
  663. DWORD dwBufferRemaining,dwSize,dwIndex;
  664. PBYTE pbyDataPtr, pbyEndPtr;
  665. PLIST_ENTRY pleNode;
  666. PGLOBAL_INFO pGlobalInfo;
  667. ULONG ulStructureVersion, ulStructureSize, ulStructureCount;
  668. TraceEnter("GetGlobalConfiguration");
  669. //
  670. // First calculate number of TOCs
  671. //
  672. dwNumTocEntries = TotalRoutingProtocols + TOCS_ALWAYS_IN_GLOBAL_INFO;
  673. for(i = 0; i < NUM_INFO_CBS; i++)
  674. {
  675. if (!g_rgicInfoCb[i].pfnGetGlobalInfo)
  676. continue;
  677. dwSize = 0;
  678. dwResult = g_rgicInfoCb[i].pfnGetGlobalInfo(NULL,
  679. &dwNumTocEntries,
  680. NULL,
  681. NULL,
  682. &dwSize);
  683. }
  684. //
  685. // Fill Header, RTR_TOC_ENTRYs for global, priority and each of the protos
  686. //
  687. pInfoHdrAndBuffer->Version = IP_ROUTER_MANAGER_VERSION;
  688. pInfoHdrAndBuffer->TocEntriesCount = dwNumTocEntries;
  689. //
  690. // Fill in TOCs. Data starts after the last TOC
  691. //
  692. pbyDataPtr = (PBYTE)&(pInfoHdrAndBuffer->TocEntry[pInfoHdrAndBuffer->TocEntriesCount]);
  693. pbyEndPtr = (PBYTE)pInfoHdrAndBuffer + dwInfoSize;
  694. ALIGN_POINTER(pbyDataPtr);
  695. dwTocIndex = 0;
  696. dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr);
  697. //
  698. // Fill in Routing Protocol Priority infoblock
  699. //
  700. dwRoutProtInfoSize = dwBufferRemaining;
  701. dwResult = GetPriorityInfo(pbyDataPtr, &dwRoutProtInfoSize);
  702. //pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoVersion = dwRoutProtInfoSize;
  703. pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoSize = dwRoutProtInfoSize;
  704. pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoType = IP_PROT_PRIORITY_INFO;
  705. pInfoHdrAndBuffer->TocEntry[dwTocIndex].Count = 1;
  706. pInfoHdrAndBuffer->TocEntry[dwTocIndex].Offset =
  707. (ULONG)(pbyDataPtr - (PBYTE)pInfoHdrAndBuffer);
  708. dwTocIndex++;
  709. pbyDataPtr += dwRoutProtInfoSize;
  710. ALIGN_POINTER(pbyDataPtr);
  711. dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr);
  712. for(i = 0; i < NUM_INFO_CBS; i++)
  713. {
  714. if (!g_rgicInfoCb[i].pfnGetGlobalInfo)
  715. continue;
  716. dwSize = dwBufferRemaining;
  717. dwResult = g_rgicInfoCb[i].pfnGetGlobalInfo(
  718. &pInfoHdrAndBuffer->TocEntry[dwTocIndex],
  719. &dwTocIndex,
  720. pbyDataPtr,
  721. pInfoHdrAndBuffer,
  722. &dwSize);
  723. pbyDataPtr += dwSize;
  724. ALIGN_POINTER(pbyDataPtr);
  725. dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr);
  726. }
  727. dwSize = sizeof(GLOBAL_INFO);
  728. pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoSize = dwSize;
  729. pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoType = IP_GLOBAL_INFO;
  730. pInfoHdrAndBuffer->TocEntry[dwTocIndex].Count = 1;
  731. //pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoVersion = 1;
  732. pInfoHdrAndBuffer->TocEntry[dwTocIndex].Offset =
  733. (ULONG)(pbyDataPtr - (PBYTE) pInfoHdrAndBuffer);
  734. pGlobalInfo = (PGLOBAL_INFO)pbyDataPtr;
  735. //
  736. // unused
  737. //
  738. pGlobalInfo->bFilteringOn = 0;
  739. pGlobalInfo->dwLoggingLevel = g_dwLoggingLevel;
  740. dwTocIndex++;
  741. pbyDataPtr += dwSize;
  742. ALIGN_POINTER(pbyDataPtr);
  743. dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr);
  744. //
  745. // fill in global info for all routing protocols
  746. //
  747. for(pleNode = g_leProtoCbList.Flink;
  748. pleNode != &g_leProtoCbList;
  749. pleNode = pleNode->Flink)
  750. {
  751. pProtoCbPtr = CONTAINING_RECORD(pleNode,
  752. PROTO_CB,
  753. leList);
  754. if(pProtoCbPtr->posOpState isnot RTR_STATE_RUNNING)
  755. {
  756. //
  757. // if the protocol is in the process of stopping
  758. // skip it
  759. //
  760. continue;
  761. }
  762. dwRoutProtInfoSize = dwBufferRemaining;
  763. dwResult = (pProtoCbPtr->pfnGetGlobalInfo)(pbyDataPtr,
  764. &dwRoutProtInfoSize,
  765. &ulStructureVersion,
  766. &ulStructureSize,
  767. &ulStructureCount);
  768. if(dwResult isnot NO_ERROR)
  769. {
  770. Trace2(ERR,
  771. "GetGlobalConfiguration: Error %d getting global info from %s",
  772. dwResult,
  773. pProtoCbPtr->pwszDllName);
  774. continue;
  775. }
  776. // pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoVersion = ulStructureVersion;
  777. pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoSize =
  778. ulStructureSize;
  779. pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoType =
  780. pProtoCbPtr->dwProtocolId;
  781. pInfoHdrAndBuffer->TocEntry[dwTocIndex].Offset =
  782. (ULONG)(pbyDataPtr - (PBYTE)pInfoHdrAndBuffer);
  783. pInfoHdrAndBuffer->TocEntry[dwTocIndex].Count = ulStructureCount;
  784. dwTocIndex++;
  785. pbyDataPtr += dwRoutProtInfoSize;
  786. ALIGN_POINTER(pbyDataPtr);
  787. dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr);
  788. }
  789. pInfoHdrAndBuffer->Size = (ULONG) ((ULONG_PTR)pbyDataPtr - (ULONG_PTR)pInfoHdrAndBuffer);
  790. return NO_ERROR;
  791. }
  792. DWORD
  793. GetSizeOfGlobalInfo(
  794. VOID
  795. )
  796. {
  797. DWORD dwSize = 0, dwResult;
  798. DWORD dwRoutProtInfoSize;
  799. PICB picb;
  800. PPROTO_CB pProtoCbPtr;
  801. PLIST_ENTRY pleNode;
  802. DWORD dwInfoSize, i;
  803. ULONG ulStructureVersion, ulStructureSize, ulStructureCount;
  804. TraceEnter("GetSizeOfGlobalInfo");
  805. dwSize = sizeof(RTR_INFO_BLOCK_HEADER) - sizeof(RTR_TOC_ENTRY);
  806. //
  807. // get size of Routing Protocol Priority info
  808. //
  809. dwRoutProtInfoSize = 0;
  810. GetPriorityInfo(NULL,
  811. &dwRoutProtInfoSize);
  812. //
  813. // ALIGN_SIZE added for alignment
  814. //
  815. dwSize += (dwRoutProtInfoSize +
  816. sizeof(RTR_TOC_ENTRY) +
  817. ALIGN_SIZE);
  818. for(i = 0; i < NUM_INFO_CBS; i++)
  819. {
  820. if (!g_rgicInfoCb[i].pfnGetGlobalInfo)
  821. continue;
  822. dwInfoSize = 0;
  823. dwResult = g_rgicInfoCb[i].pfnGetGlobalInfo(NULL,
  824. NULL,
  825. NULL,
  826. NULL,
  827. &dwInfoSize);
  828. if((dwResult isnot NO_ERROR) and
  829. (dwResult isnot ERROR_INSUFFICIENT_BUFFER))
  830. {
  831. //
  832. // The only errors which will tell us the size needed are
  833. // NO_ERROR and ERROR_INSUFFICIENT_BUFFER. Anything else means
  834. // we didnt get the right size
  835. //
  836. Trace2(ERR,
  837. "GetSizeOfGlobalInfo: Error %d in GetGlobInfo for %s\n",
  838. dwResult,
  839. g_rgicInfoCb[i].pszInfoName);
  840. continue;
  841. }
  842. dwSize += (dwInfoSize +
  843. sizeof(RTR_TOC_ENTRY) +
  844. ALIGN_SIZE);
  845. }
  846. //
  847. // The names of the Dlls - part of Global Info
  848. //
  849. dwSize += (sizeof(GLOBAL_INFO) +
  850. sizeof(RTR_TOC_ENTRY) +
  851. ALIGN_SIZE);
  852. //
  853. // get size of infoblocks for all routing protocols
  854. //
  855. for(pleNode = g_leProtoCbList.Flink;
  856. pleNode isnot &g_leProtoCbList;
  857. pleNode = pleNode->Flink)
  858. {
  859. pProtoCbPtr = CONTAINING_RECORD(pleNode,
  860. PROTO_CB,
  861. leList);
  862. if(pProtoCbPtr->posOpState isnot RTR_STATE_RUNNING)
  863. {
  864. //
  865. // if the protocol is in the process of stopping
  866. // skip it
  867. //
  868. continue;
  869. }
  870. //
  871. // Call the routing protocol's GetGlobalConfigInfo() entrypoint
  872. // with NULL. This should return the buffer size needed
  873. //
  874. dwRoutProtInfoSize = 0;
  875. dwResult = (pProtoCbPtr->pfnGetGlobalInfo)(NULL,
  876. &dwRoutProtInfoSize,
  877. &ulStructureVersion,
  878. &ulStructureSize,
  879. &ulStructureCount);
  880. if((dwResult is NO_ERROR) or
  881. (dwResult is ERROR_INSUFFICIENT_BUFFER))
  882. {
  883. dwSize += (dwRoutProtInfoSize +
  884. sizeof(RTR_TOC_ENTRY) +
  885. ALIGN_SIZE);
  886. }
  887. }
  888. return dwSize;
  889. }