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.

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