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.

1811 lines
47 KiB

  1. #include "precomp.h"
  2. WCHAR g_wszRtrMgrDLL[] = L"%SystemRoot%\\system32\\IPRTRMGR.DLL";
  3. DWORD g_dwIfState = MIB_IF_ADMIN_STATUS_UP;
  4. BOOL g_bDiscEnable = FALSE;
  5. #define IP_KEY L"Ip"
  6. #undef EXTRA_DEBUG
  7. DWORD
  8. ValidateInterfaceInfo(
  9. IN LPCWSTR pwszIfName,
  10. OUT RTR_INFO_BLOCK_HEADER **ppInfo, OPTIONAL
  11. OUT PDWORD pdwIfType, OPTIONAL
  12. OUT INTERFACE_STORE **ppIfStore OPTIONAL
  13. )
  14. {
  15. PRTR_INFO_BLOCK_HEADER pOldInfo = NULL;
  16. DWORD dwErr, dwIfType, dwTmpSize;
  17. BOOL bFound = FALSE;
  18. LIST_ENTRY *ple;
  19. PINTERFACE_STORE pii;
  20. if(ppInfo)
  21. {
  22. *ppInfo = NULL;
  23. }
  24. if(ppIfStore)
  25. {
  26. *ppIfStore = NULL;
  27. }
  28. //
  29. // If the current mode is commit, get info from config/router
  30. //
  31. if(g_bCommit)
  32. {
  33. dwErr = GetInterfaceInfo(pwszIfName,
  34. ppInfo,
  35. NULL,
  36. pdwIfType);
  37. return dwErr;
  38. }
  39. //
  40. // Uncommit mode. Try to find the interface in the list
  41. //
  42. bFound = FALSE;
  43. for(ple = g_leIfListHead.Flink;
  44. ple != &g_leIfListHead;
  45. ple = ple->Flink)
  46. {
  47. pii = CONTAINING_RECORD(ple, INTERFACE_STORE, le);
  48. if (_wcsicmp(pii->pwszIfName, pwszIfName) == 0)
  49. {
  50. bFound = TRUE;
  51. break;
  52. }
  53. }
  54. if(!bFound ||
  55. !pii->bValid)
  56. {
  57. //
  58. // the required one was not found, or it was not valid
  59. // Need to get the info for both cases
  60. //
  61. dwErr = GetInterfaceInfo(pwszIfName,
  62. &pOldInfo,
  63. NULL,
  64. &dwIfType);
  65. if (dwErr isnot NO_ERROR)
  66. {
  67. return dwErr;
  68. }
  69. }
  70. if(bFound)
  71. {
  72. if(!pii->bValid)
  73. {
  74. //
  75. // Update
  76. //
  77. pii->pibhInfo = pOldInfo;
  78. pii->bValid = TRUE;
  79. pii->dwIfType = dwIfType;
  80. }
  81. }
  82. else
  83. {
  84. //
  85. // No entry for the interface in the list.
  86. //
  87. pii = HeapAlloc(GetProcessHeap(),
  88. 0,
  89. sizeof(INTERFACE_STORE));
  90. if(pii == NULL)
  91. {
  92. FREE_BUFFER(pOldInfo);
  93. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
  94. return ERROR_NOT_ENOUGH_MEMORY;
  95. }
  96. pii->pwszIfName =
  97. HeapAlloc(GetProcessHeap(),
  98. 0,
  99. (wcslen(pwszIfName) + 1) * sizeof(WCHAR));
  100. if(pii->pwszIfName == NULL)
  101. {
  102. FREE_BUFFER(pOldInfo);
  103. HeapFree(GetProcessHeap(),
  104. 0,
  105. pii);
  106. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
  107. return ERROR_NOT_ENOUGH_MEMORY;
  108. }
  109. InsertHeadList(&g_leIfListHead, &(pii->le));
  110. wcscpy(pii->pwszIfName, pwszIfName);
  111. pii->pibhInfo = pOldInfo;
  112. pii->bValid = TRUE;
  113. pii->dwIfType = dwIfType;
  114. }
  115. if(ppIfStore)
  116. {
  117. *ppIfStore = pii;
  118. }
  119. if(pdwIfType)
  120. {
  121. *pdwIfType = pii->dwIfType;
  122. }
  123. if(ppInfo)
  124. {
  125. *ppInfo = pii->pibhInfo;
  126. }
  127. return NO_ERROR;
  128. }
  129. DWORD
  130. ValidateGlobalInfo(
  131. OUT RTR_INFO_BLOCK_HEADER **ppInfo
  132. )
  133. {
  134. DWORD dwErr;
  135. //
  136. // If the current mode is commit, get info from config/router
  137. //
  138. if(g_bCommit)
  139. {
  140. dwErr = GetGlobalInfo(ppInfo);
  141. return dwErr;
  142. }
  143. //
  144. // Uncommit mode. Check if the info in g_tiTransport is valid
  145. //
  146. if(g_tiTransport.bValid)
  147. {
  148. *ppInfo = g_tiTransport.pibhInfo;
  149. }
  150. else
  151. {
  152. //
  153. // Get the info from config/router and store in g_tiTransport
  154. // Mark the info to be valid.
  155. //
  156. dwErr = GetGlobalInfo(ppInfo);
  157. if (dwErr isnot NO_ERROR)
  158. {
  159. return dwErr;
  160. }
  161. g_tiTransport.pibhInfo = *ppInfo;
  162. g_tiTransport.bValid = TRUE;
  163. }
  164. return NO_ERROR;
  165. }
  166. DWORD
  167. GetGlobalInfo(
  168. OUT PRTR_INFO_BLOCK_HEADER *ppibhInfo
  169. )
  170. /*++
  171. Routine Description:
  172. Gets global transport information from registry or router.
  173. Arguments:
  174. bMprConfig - Info from Registry or info from router
  175. ppibhInfo - ptr to header
  176. Return Value:
  177. NO_ERROR, ERROR_INVALID_PARAMETER, ERROR_ROUTER_STOPPED
  178. --*/
  179. {
  180. HANDLE hTransport = (HANDLE) NULL;
  181. DWORD dwRes, dwSize;
  182. PRTR_INFO_BLOCK_HEADER pibhInfo = (PRTR_INFO_BLOCK_HEADER ) NULL;
  183. if(ppibhInfo == NULL)
  184. {
  185. return ERROR_INVALID_PARAMETER;
  186. }
  187. do
  188. {
  189. if (IsRouterRunning())
  190. {
  191. //
  192. // Retrieve global protocol information from router
  193. //
  194. dwRes = MprAdminTransportGetInfo(g_hMprAdmin,
  195. PID_IP,
  196. (LPBYTE*) &pibhInfo,
  197. &dwSize,
  198. NULL,
  199. NULL);
  200. if ( dwRes != NO_ERROR )
  201. {
  202. break;
  203. }
  204. if ( pibhInfo == (PRTR_INFO_BLOCK_HEADER) NULL )
  205. {
  206. dwRes = ERROR_INVALID_PARAMETER;
  207. break;
  208. }
  209. //
  210. // unfortunately, the memory allocation mechanisms
  211. // are different between the apis that access the registry
  212. // and those that access that the running router. To make
  213. // the source of the info transparent to the caller, we
  214. // need to copy this info out.
  215. //
  216. *ppibhInfo = HeapAlloc(GetProcessHeap(),
  217. 0,
  218. dwSize);
  219. if ( *ppibhInfo == NULL)
  220. {
  221. dwRes = GetLastError();
  222. break;
  223. }
  224. CopyMemory(*ppibhInfo,
  225. pibhInfo,
  226. dwSize);
  227. MprAdminBufferFree(pibhInfo);
  228. }
  229. else
  230. {
  231. //
  232. // router not running, get info from registry
  233. //
  234. dwRes = MprConfigTransportGetHandle(g_hMprConfig,
  235. PID_IP,
  236. &hTransport);
  237. if ( dwRes != NO_ERROR )
  238. {
  239. break;
  240. }
  241. dwRes = MprConfigTransportGetInfo(g_hMprConfig,
  242. hTransport,
  243. (LPBYTE*) &pibhInfo,
  244. &dwSize,
  245. NULL,
  246. NULL,
  247. NULL);
  248. if ( dwRes != NO_ERROR )
  249. {
  250. break;
  251. }
  252. if(( pibhInfo == (PRTR_INFO_BLOCK_HEADER) NULL )
  253. or (dwSize < sizeof(RTR_INFO_BLOCK_HEADER)))
  254. {
  255. dwRes = ERROR_TRANSPORT_NOT_PRESENT;
  256. break;
  257. }
  258. //
  259. // HACKHACK: we know that MprConfigXxx apis allocate from
  260. // process heap, so we can return the same block
  261. //
  262. *ppibhInfo = pibhInfo;
  263. }
  264. } while(FALSE);
  265. return dwRes;
  266. }
  267. DWORD
  268. SetGlobalInfo(
  269. IN PRTR_INFO_BLOCK_HEADER pibhInfo
  270. )
  271. /*++
  272. Routine Description:
  273. Sets global transport information to both the registry and the router
  274. Arguments:
  275. pibhInfo - ptr to header
  276. Return Value:
  277. NO_ERROR, ERROR_ROUTER_STOPPED
  278. --*/
  279. {
  280. DWORD dwARes = NO_ERROR,
  281. dwCRes = NO_ERROR;
  282. HANDLE hTransport;
  283. UINT i;
  284. PRTR_INFO_BLOCK_HEADER pibhNewInfo, pibhOldInfo;
  285. //
  286. // Create a new info block with all 0-length blocks removed
  287. // since we don't want to write them to the registry,
  288. // we only need to send them to the router which we
  289. // will do with the original info block below.
  290. //
  291. pibhOldInfo = NULL;
  292. pibhNewInfo = pibhInfo;
  293. for (i=0; (dwCRes is NO_ERROR) && (i<pibhInfo->TocEntriesCount); i++)
  294. {
  295. if (pibhInfo->TocEntry[i].InfoSize is 0)
  296. {
  297. pibhOldInfo = pibhNewInfo;
  298. dwCRes = MprInfoBlockRemove(pibhOldInfo,
  299. pibhOldInfo->TocEntry[i].InfoType,
  300. &pibhNewInfo);
  301. if (pibhOldInfo isnot pibhInfo)
  302. {
  303. FREE_BUFFER(pibhOldInfo);
  304. }
  305. }
  306. }
  307. if (dwCRes is NO_ERROR)
  308. {
  309. dwCRes = MprConfigTransportGetHandle(g_hMprConfig,
  310. PID_IP,
  311. &hTransport);
  312. }
  313. if (dwCRes is NO_ERROR)
  314. {
  315. dwCRes = MprConfigTransportSetInfo(g_hMprConfig,
  316. hTransport,
  317. (LPBYTE) pibhNewInfo,
  318. pibhNewInfo->Size,
  319. NULL,
  320. 0,
  321. NULL);
  322. }
  323. if (pibhNewInfo isnot pibhInfo)
  324. {
  325. FREE_BUFFER(pibhNewInfo);
  326. }
  327. //
  328. // Even if we failed to write to the registry, we still want
  329. // to write to the router.
  330. //
  331. // We use the original format when writing to the router, since it
  332. // needs to see the 0-length blocks in order to delete config info.
  333. //
  334. if(IsRouterRunning())
  335. {
  336. dwARes = MprAdminTransportSetInfo(g_hMprAdmin,
  337. PID_IP,
  338. (LPBYTE) pibhInfo,
  339. pibhInfo->Size,
  340. NULL,
  341. 0);
  342. }
  343. return (dwARes isnot NO_ERROR)? dwARes : dwCRes;
  344. }
  345. DWORD
  346. GetInterfaceInfo(
  347. IN LPCWSTR pwszIfName,
  348. OUT RTR_INFO_BLOCK_HEADER **ppibhInfo, OPTIONAL
  349. OUT PMPR_INTERFACE_0 pMprIfInfo, OPTIONAL
  350. OUT PDWORD pdwIfType OPTIONAL
  351. )
  352. /*++
  353. Routine Description:
  354. Gets global transport information from registry or router.
  355. If one of the out information is not required, then the parameter
  356. can be NULL.
  357. Arguments:
  358. pwszIfName - Interface Name
  359. bMprConfig - Info from Registry or info from router
  360. ppibhInfo - ptr to header
  361. pMprIfInfo - ptr to interface info
  362. pdwIfType - Type of interface
  363. Return Value:
  364. NO_ERROR,
  365. ERROR_NO_SUCH_INTERFACE
  366. ERROR_TRANSPORT_NOT_PRESENT
  367. --*/
  368. {
  369. PMPR_INTERFACE_0 pMprIf = NULL;
  370. PRTR_INFO_BLOCK_HEADER pibh;
  371. HANDLE hInterface,hIfTransport;
  372. DWORD dwRes, dwSize;
  373. if(((ULONG_PTR)ppibhInfo | (ULONG_PTR)pMprIfInfo | (ULONG_PTR)pdwIfType) ==
  374. (ULONG_PTR)NULL)
  375. {
  376. return NO_ERROR;
  377. }
  378. do
  379. {
  380. if(IsRouterRunning())
  381. {
  382. //
  383. // Get info from the router
  384. //
  385. dwRes = MprAdminInterfaceGetHandle(g_hMprAdmin,
  386. (LPWSTR)pwszIfName,
  387. &hInterface,
  388. FALSE);
  389. if( dwRes != NO_ERROR )
  390. {
  391. break;
  392. }
  393. if(pMprIfInfo || pdwIfType)
  394. {
  395. dwRes = MprAdminInterfaceGetInfo(g_hMprAdmin,
  396. hInterface,
  397. 0,
  398. (LPBYTE *) &pMprIf);
  399. if ( dwRes != NO_ERROR )
  400. {
  401. break;
  402. }
  403. if (pMprIf == NULL)
  404. {
  405. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  406. break;
  407. }
  408. if(pMprIfInfo)
  409. {
  410. //
  411. // structure copy
  412. //
  413. *pMprIfInfo= *pMprIf;
  414. }
  415. if(pdwIfType)
  416. {
  417. *pdwIfType = pMprIf->dwIfType;
  418. }
  419. MprAdminBufferFree(pMprIf);
  420. }
  421. if(ppibhInfo)
  422. {
  423. dwRes = MprAdminInterfaceTransportGetInfo(g_hMprAdmin,
  424. hInterface,
  425. PID_IP,
  426. (LPBYTE*) &pibh,
  427. &dwSize);
  428. if(dwRes != NO_ERROR)
  429. {
  430. break;
  431. }
  432. if(pibh == (PRTR_INFO_BLOCK_HEADER) NULL)
  433. {
  434. dwRes = ERROR_TRANSPORT_NOT_PRESENT;
  435. break;
  436. }
  437. //
  438. // The info returned to the user must be from
  439. // process heap. Admin calls use MIDL allocation, so
  440. // copy out info
  441. //
  442. *ppibhInfo = HeapAlloc(GetProcessHeap(),
  443. 0,
  444. dwSize);
  445. if(*ppibhInfo == NULL)
  446. {
  447. dwRes = GetLastError();
  448. break;
  449. }
  450. CopyMemory(*ppibhInfo,
  451. pibh,
  452. dwSize);
  453. MprAdminBufferFree(pibh);
  454. }
  455. }
  456. else
  457. {
  458. //
  459. // Router not running, get info from the registry
  460. //
  461. dwRes = MprConfigInterfaceGetHandle(g_hMprConfig,
  462. (LPWSTR)pwszIfName,
  463. &hInterface);
  464. if(dwRes != NO_ERROR)
  465. {
  466. break;
  467. }
  468. if(pMprIfInfo || pdwIfType)
  469. {
  470. dwRes = MprConfigInterfaceGetInfo(g_hMprConfig,
  471. hInterface,
  472. 0,
  473. (LPBYTE *) &pMprIf,
  474. &dwSize);
  475. if(dwRes != NO_ERROR)
  476. {
  477. break;
  478. }
  479. if (pMprIf == NULL)
  480. {
  481. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  482. break;
  483. }
  484. if(pdwIfType)
  485. {
  486. *pdwIfType = pMprIf->dwIfType;
  487. }
  488. if(pMprIfInfo)
  489. {
  490. *pMprIfInfo = *pMprIf;
  491. }
  492. MprConfigBufferFree(pMprIf);
  493. }
  494. if (ppibhInfo)
  495. {
  496. dwRes = MprConfigInterfaceTransportGetHandle(g_hMprConfig,
  497. hInterface,
  498. PID_IP,
  499. &hIfTransport);
  500. if(dwRes != NO_ERROR)
  501. {
  502. break;
  503. }
  504. dwRes = MprConfigInterfaceTransportGetInfo(g_hMprConfig,
  505. hInterface,
  506. hIfTransport,
  507. (LPBYTE*) &pibh,
  508. &dwSize);
  509. if(dwRes != NO_ERROR)
  510. {
  511. break;
  512. }
  513. if((pibh == (PRTR_INFO_BLOCK_HEADER) NULL)
  514. or (dwSize < sizeof(RTR_INFO_BLOCK_HEADER)))
  515. {
  516. dwRes = ERROR_TRANSPORT_NOT_PRESENT;
  517. break;
  518. }
  519. //
  520. // Again, since this is also allocated from process heap
  521. //
  522. *ppibhInfo = pibh;
  523. }
  524. }
  525. } while (FALSE);
  526. return dwRes;
  527. }
  528. DWORD
  529. MakeIPGlobalInfo( LPBYTE* ppBuff )
  530. {
  531. DWORD dwSize = 0,
  532. dwRes = (DWORD) -1;
  533. LPBYTE pbDataPtr = (LPBYTE) NULL;
  534. PRTR_TOC_ENTRY pTocEntry = (PRTR_TOC_ENTRY) NULL;
  535. PGLOBAL_INFO pGlbInfo = NULL;
  536. PPRIORITY_INFO pPriorInfo = NULL;
  537. PRTR_INFO_BLOCK_HEADER pIBH = (PRTR_INFO_BLOCK_HEADER) NULL;
  538. //
  539. // Alocate for minimal global Information
  540. //
  541. dwSize = sizeof( RTR_INFO_BLOCK_HEADER ) + sizeof(GLOBAL_INFO) +
  542. sizeof( RTR_TOC_ENTRY ) + SIZEOF_PRIORITY_INFO(7) +
  543. 2 * ALIGN_SIZE;
  544. pIBH = (PRTR_INFO_BLOCK_HEADER) HeapAlloc( GetProcessHeap(), 0, dwSize );
  545. if ( pIBH == (PRTR_INFO_BLOCK_HEADER) NULL )
  546. {
  547. DisplayMessage( g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
  548. *ppBuff = (LPBYTE) NULL;
  549. return ERROR_NOT_ENOUGH_MEMORY;
  550. }
  551. //
  552. // init. infobase fields
  553. //
  554. *ppBuff = (LPBYTE) pIBH;
  555. pIBH-> Version = RTR_INFO_BLOCK_VERSION;
  556. pIBH-> TocEntriesCount = 2;
  557. pIBH-> Size = dwSize;
  558. pbDataPtr = (LPBYTE) &( pIBH-> TocEntry[ pIBH-> TocEntriesCount ] );
  559. ALIGN_POINTER( pbDataPtr );
  560. //
  561. // make IP rtr mgr global info.
  562. //
  563. pTocEntry = &(pIBH-> TocEntry[ 0 ]);
  564. pTocEntry-> InfoType = IP_GLOBAL_INFO;
  565. pTocEntry-> Count = 1;
  566. pTocEntry-> Offset = (ULONG)(pbDataPtr - (PBYTE) pIBH);
  567. pTocEntry-> InfoSize = sizeof(GLOBAL_INFO);
  568. pGlbInfo = (PGLOBAL_INFO) pbDataPtr;
  569. pGlbInfo-> bFilteringOn = TRUE;
  570. pGlbInfo-> dwLoggingLevel = IPRTR_LOGGING_ERROR;
  571. pbDataPtr += pTocEntry->Count * pTocEntry-> InfoSize;
  572. ALIGN_POINTER( pbDataPtr );
  573. //
  574. // make IP rtr priority. Info
  575. //
  576. pTocEntry = &(pIBH-> TocEntry[ 1 ]);
  577. pTocEntry-> InfoType = IP_PROT_PRIORITY_INFO;
  578. pTocEntry-> Count = 1;
  579. pTocEntry-> Offset = (DWORD)(pbDataPtr - (PBYTE) pIBH);
  580. pTocEntry-> InfoSize = SIZEOF_PRIORITY_INFO(7);
  581. pPriorInfo = (PPRIORITY_INFO) pbDataPtr;
  582. pPriorInfo-> dwNumProtocols = 7;
  583. pPriorInfo-> ppmProtocolMetric[ 0 ].dwProtocolId = PROTO_IP_LOCAL;
  584. pPriorInfo-> ppmProtocolMetric[ 0 ].dwMetric = 1;
  585. pPriorInfo-> ppmProtocolMetric[ 1 ].dwProtocolId = PROTO_IP_NT_STATIC;
  586. pPriorInfo-> ppmProtocolMetric[ 1 ].dwMetric = 3;
  587. pPriorInfo-> ppmProtocolMetric[ 2 ].dwProtocolId = PROTO_IP_NT_STATIC_NON_DOD;
  588. pPriorInfo-> ppmProtocolMetric[ 2 ].dwMetric = 5;
  589. pPriorInfo-> ppmProtocolMetric[ 3 ].dwProtocolId = PROTO_IP_NT_AUTOSTATIC;
  590. pPriorInfo-> ppmProtocolMetric[ 3 ].dwMetric = 7;
  591. pPriorInfo-> ppmProtocolMetric[ 4 ].dwProtocolId = PROTO_IP_NETMGMT;
  592. pPriorInfo-> ppmProtocolMetric[ 4 ].dwMetric = 10;
  593. pPriorInfo-> ppmProtocolMetric[ 5 ].dwProtocolId = PROTO_IP_OSPF;
  594. pPriorInfo-> ppmProtocolMetric[ 5 ].dwMetric = 110;
  595. pPriorInfo-> ppmProtocolMetric[ 6 ].dwProtocolId = PROTO_IP_RIP;
  596. pPriorInfo-> ppmProtocolMetric[ 6 ].dwMetric = 120;
  597. return NO_ERROR;
  598. }
  599. DWORD
  600. MakeIPInterfaceInfo(
  601. LPBYTE* ppBuff,
  602. DWORD dwIfType
  603. )
  604. {
  605. DWORD dwSize = (DWORD) -1;
  606. DWORD dwTocEntries = 2;
  607. LPBYTE pbDataPtr = (LPBYTE) NULL;
  608. PRTR_TOC_ENTRY pTocEntry = (PRTR_TOC_ENTRY) NULL;
  609. #if 0
  610. PRTR_DISC_INFO pRtrDisc = (PRTR_DISC_INFO) NULL;
  611. #endif
  612. PINTERFACE_STATUS_INFO pifStat = (PINTERFACE_STATUS_INFO) NULL;
  613. PRTR_INFO_BLOCK_HEADER pIBH = (PRTR_INFO_BLOCK_HEADER) NULL;
  614. PIPINIP_CONFIG_INFO pIpIpCfg;
  615. //
  616. // Allocate for minimal interface Info.
  617. // a TOC entry is allocated for IP_ROUTE_INFO, but no route info
  618. // block is created, since initially there are no static routes.
  619. //
  620. dwSize = sizeof( RTR_INFO_BLOCK_HEADER ) +
  621. sizeof( RTR_TOC_ENTRY ) + sizeof( INTERFACE_STATUS_INFO ) +
  622. 2 * ALIGN_SIZE;
  623. #if 0
  624. if (dwIfType is ROUTER_IF_TYPE_DEDICATED)
  625. {
  626. dwSize += sizeof( RTR_TOC_ENTRY )
  627. + sizeof( RTR_DISC_INFO )
  628. + ALIGN_SIZE;
  629. dwTocEntries++;
  630. }
  631. #endif
  632. pIBH = (PRTR_INFO_BLOCK_HEADER) HeapAlloc( GetProcessHeap(), 0, dwSize );
  633. if ( pIBH == (PRTR_INFO_BLOCK_HEADER) NULL )
  634. {
  635. *ppBuff = (LPBYTE) NULL;
  636. DisplayMessage( g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
  637. return ERROR_NOT_ENOUGH_MEMORY;
  638. }
  639. *ppBuff = (LPBYTE) pIBH;
  640. pIBH-> Version = RTR_INFO_BLOCK_VERSION;
  641. pIBH-> TocEntriesCount = dwTocEntries;
  642. pIBH-> Size = dwSize;
  643. pbDataPtr = (LPBYTE) &( pIBH-> TocEntry[ pIBH-> TocEntriesCount ] );
  644. ALIGN_POINTER( pbDataPtr );
  645. //
  646. // Create empty route info block
  647. //
  648. pTocEntry = (PRTR_TOC_ENTRY) &( pIBH-> TocEntry[ 0 ] );
  649. pTocEntry-> InfoType = IP_ROUTE_INFO;
  650. pTocEntry-> InfoSize = sizeof( MIB_IPFORWARDROW );
  651. pTocEntry-> Count = 0;
  652. pTocEntry-> Offset = (ULONG) (pbDataPtr - (PBYTE) pIBH);
  653. pbDataPtr += pTocEntry-> Count * pTocEntry-> InfoSize;
  654. ALIGN_POINTER( pbDataPtr );
  655. //
  656. // Create interface status block.
  657. //
  658. pTocEntry = (PRTR_TOC_ENTRY) &( pIBH-> TocEntry[ 1 ] );
  659. pTocEntry-> InfoType = IP_INTERFACE_STATUS_INFO;
  660. pTocEntry-> InfoSize = sizeof( INTERFACE_STATUS_INFO );
  661. pTocEntry-> Count = 1;
  662. pTocEntry-> Offset = (ULONG) (pbDataPtr - (LPBYTE) pIBH);
  663. pifStat = (PINTERFACE_STATUS_INFO) pbDataPtr;
  664. pifStat-> dwAdminStatus = g_dwIfState;
  665. pbDataPtr += pTocEntry-> Count * pTocEntry-> InfoSize;
  666. ALIGN_POINTER( pbDataPtr );
  667. #if 0
  668. if (dwIfType is ROUTER_IF_TYPE_DEDICATED)
  669. {
  670. //
  671. // Create Router Disc. Info.
  672. //
  673. pTocEntry = (PRTR_TOC_ENTRY) &( pIBH-> TocEntry[ 2 ]);
  674. pTocEntry-> InfoType = IP_ROUTER_DISC_INFO;
  675. pTocEntry-> InfoSize = sizeof( RTR_DISC_INFO );
  676. pTocEntry-> Count = 1;
  677. pTocEntry-> Offset = (ULONG) (pbDataPtr - (LPBYTE) pIBH);
  678. pRtrDisc = (PRTR_DISC_INFO) pbDataPtr;
  679. pRtrDisc-> bAdvertise = TRUE;
  680. pRtrDisc-> wMaxAdvtInterval = g_wMaxAdvtInterval;
  681. pRtrDisc-> wMinAdvtInterval = g_wMinAdvtInterval;
  682. pRtrDisc-> wAdvtLifetime = g_wAdvtLifeTime;
  683. pRtrDisc-> lPrefLevel = g_lPrefLevel;
  684. pbDataPtr += pTocEntry-> Count * pTocEntry-> InfoSize;
  685. ALIGN_POINTER( pbDataPtr );
  686. }
  687. #endif
  688. return NO_ERROR;
  689. }
  690. DWORD
  691. AddInterfaceInfo(
  692. IN LPCWSTR pwszIfName
  693. )
  694. {
  695. DWORD dwRes = (DWORD) -1,
  696. dwIfType,
  697. dwSize = 0;
  698. BOOL bAddRtrMgr = FALSE;
  699. HANDLE hInterface = (HANDLE) NULL,
  700. hTransport = (HANDLE) NULL,
  701. hIfAdmin = (HANDLE) NULL,
  702. hIfTransport = (HANDLE) NULL;
  703. PRTR_INFO_BLOCK_HEADER pibhTmp = (PRTR_INFO_BLOCK_HEADER) NULL;
  704. #ifdef EXTRA_DEBUG
  705. PRINT(L"AddInterfaceInfo:");
  706. PRINT(pwszIfName);
  707. #endif
  708. do
  709. {
  710. PMPR_INTERFACE_0 pmiIfInfo;
  711. //
  712. // verify interface name.
  713. //
  714. dwRes = MprConfigInterfaceGetHandle( g_hMprConfig,
  715. (LPWSTR)pwszIfName,
  716. &hInterface );
  717. if ( dwRes != NO_ERROR )
  718. {
  719. DisplayMessage( g_hModule, MSG_NO_INTERFACE, pwszIfName );
  720. break;
  721. }
  722. // Make sure interface exists
  723. dwRes = MprConfigInterfaceGetInfo(g_hMprConfig,
  724. hInterface,
  725. 0,
  726. (BYTE **)&pmiIfInfo,
  727. &dwSize);
  728. if( dwRes != NO_ERROR )
  729. {
  730. DisplayError( NULL, dwRes );
  731. break;
  732. }
  733. dwIfType = pmiIfInfo->dwIfType;
  734. // Here's a hack due apparently due to the inability of
  735. // the current stack to do Foo-over-IP tunnels, so adding
  736. // an ipip tunnel both creates the tunnel and enables IP
  737. // on it.
  738. if(dwIfType is ROUTER_IF_TYPE_TUNNEL1)
  739. {
  740. MprConfigBufferFree(pmiIfInfo);
  741. dwRes = ERROR_INVALID_PARAMETER;
  742. DisplayMessage(g_hModule, MSG_IP_IF_IS_TUNNEL);
  743. break;
  744. }
  745. MprConfigBufferFree(pmiIfInfo);
  746. //
  747. // Is IP RtrMgr present on this router.
  748. //
  749. // if specified IP router manager is absent,
  750. // we shall need to add global info for this
  751. // router manager "before" we add the interface
  752. // information
  753. //
  754. //
  755. // Try to get a handle to the rtr mgr.
  756. //
  757. dwRes = MprConfigTransportGetHandle(g_hMprConfig,
  758. PID_IP,
  759. &hTransport);
  760. if ( dwRes != NO_ERROR )
  761. {
  762. if ( dwRes == ERROR_UNKNOWN_PROTOCOL_ID )
  763. {
  764. bAddRtrMgr = TRUE;
  765. }
  766. else
  767. {
  768. DisplayError( NULL, dwRes );
  769. break;
  770. }
  771. }
  772. //
  773. // if handle is available, try to retrieve global info.
  774. // if not available we shall need to add the global info.
  775. //
  776. if ( !bAddRtrMgr )
  777. {
  778. dwRes = MprConfigTransportGetInfo(g_hMprConfig,
  779. hTransport,
  780. (LPBYTE*) &pibhTmp,
  781. &dwSize,
  782. NULL,
  783. NULL,
  784. NULL);
  785. if ( dwRes != NO_ERROR )
  786. {
  787. DisplayError( NULL, dwRes );
  788. break;
  789. }
  790. if ( pibhTmp == (PRTR_INFO_BLOCK_HEADER) NULL )
  791. {
  792. bAddRtrMgr = TRUE;
  793. }
  794. else
  795. {
  796. MprConfigBufferFree( pibhTmp );
  797. pibhTmp = NULL;
  798. }
  799. }
  800. //
  801. // If IP is already present on router, see if IP was already
  802. // added to the interface. If so, complain.
  803. //
  804. if ( !bAddRtrMgr )
  805. {
  806. dwRes = MprConfigInterfaceTransportGetHandle(g_hMprConfig,
  807. hInterface,
  808. PID_IP,
  809. &hIfTransport);
  810. if ( dwRes == NO_ERROR )
  811. {
  812. dwRes = ERROR_INVALID_PARAMETER;
  813. // was SetInterfaceInRouterConfig(); to update
  814. break;
  815. }
  816. }
  817. //
  818. // If IP RtrMgr is not present, add global info.
  819. //
  820. if ( bAddRtrMgr )
  821. {
  822. dwRes = MakeIPGlobalInfo( (LPBYTE *)&pibhTmp );
  823. if ( dwRes != NO_ERROR )
  824. {
  825. break;
  826. }
  827. dwRes = MprConfigTransportCreate( g_hMprConfig,
  828. PID_IP,
  829. IP_KEY,
  830. (LPBYTE) pibhTmp,
  831. pibhTmp-> Size,
  832. NULL,
  833. 0,
  834. g_wszRtrMgrDLL,
  835. &hTransport );
  836. if ( dwRes != NO_ERROR )
  837. {
  838. DisplayError( NULL, dwRes );
  839. break;
  840. }
  841. HeapFree( GetProcessHeap(), 0, pibhTmp );
  842. }
  843. pibhTmp = (PRTR_INFO_BLOCK_HEADER) NULL;
  844. //
  845. // Add IP Rtr Mgr. information for the interface
  846. //
  847. dwRes = MakeIPInterfaceInfo( (LPBYTE*) &pibhTmp, dwIfType);
  848. if ( dwRes != NO_ERROR )
  849. {
  850. break;
  851. }
  852. dwRes = MprConfigInterfaceTransportAdd( g_hMprConfig,
  853. hInterface,
  854. PID_IP,
  855. IP_KEY,
  856. (LPBYTE) pibhTmp,
  857. pibhTmp-> Size,
  858. &hIfTransport );
  859. if ( dwRes != NO_ERROR )
  860. {
  861. DisplayError( NULL, dwRes );
  862. break;
  863. }
  864. if(IsRouterRunning())
  865. {
  866. dwRes = MprAdminInterfaceGetHandle(g_hMprAdmin,
  867. (LPWSTR)pwszIfName,
  868. &hIfAdmin,
  869. FALSE);
  870. if ( dwRes != NO_ERROR )
  871. {
  872. break;
  873. }
  874. dwRes = MprAdminInterfaceTransportAdd( g_hMprAdmin,
  875. hIfAdmin,
  876. PID_IP,
  877. (LPBYTE) pibhTmp,
  878. pibhTmp->Size );
  879. if ( dwRes != NO_ERROR )
  880. {
  881. DisplayMessage( g_hModule, ERROR_ADMIN, dwRes );
  882. break;
  883. }
  884. break;
  885. }
  886. } while( FALSE );
  887. //
  888. // Free all allocations
  889. //
  890. if ( pibhTmp ) { HeapFree( GetProcessHeap(), 0, pibhTmp ); }
  891. return dwRes;
  892. }
  893. DWORD
  894. DeleteInterfaceInfo(
  895. IN LPCWSTR pwszIfName
  896. )
  897. {
  898. DWORD dwRes, dwIfType = 0, dwErr;
  899. HANDLE hIfTransport, hInterface;
  900. do
  901. {
  902. dwRes = MprConfigInterfaceGetHandle(g_hMprConfig,
  903. (LPWSTR)pwszIfName,
  904. &hInterface);
  905. if ( dwRes != NO_ERROR )
  906. {
  907. break;
  908. }
  909. //
  910. // Get the type of the interface
  911. //
  912. dwErr = GetInterfaceInfo(pwszIfName,
  913. NULL,
  914. NULL,
  915. &dwIfType);
  916. if(dwErr != NO_ERROR)
  917. {
  918. break;
  919. }
  920. dwRes = MprConfigInterfaceTransportGetHandle(g_hMprConfig,
  921. hInterface,
  922. PID_IP,
  923. &hIfTransport);
  924. if ( dwRes != NO_ERROR )
  925. {
  926. break;
  927. }
  928. dwRes = MprConfigInterfaceTransportRemove(g_hMprConfig,
  929. hInterface,
  930. hIfTransport);
  931. //
  932. // If its an ip in ip tunnel, clear out its name and delete from the
  933. // router
  934. //
  935. if(dwIfType == ROUTER_IF_TYPE_TUNNEL1)
  936. {
  937. dwRes = MprConfigInterfaceDelete(g_hMprConfig,
  938. hInterface);
  939. if(dwRes == NO_ERROR)
  940. {
  941. GUID Guid;
  942. dwRes = ConvertStringToGuid(pwszIfName,
  943. (USHORT)(wcslen(pwszIfName) * sizeof(WCHAR)),
  944. &Guid);
  945. if(dwRes != NO_ERROR)
  946. {
  947. break;
  948. }
  949. MprSetupIpInIpInterfaceFriendlyNameDelete(g_pwszRouter,
  950. &Guid);
  951. }
  952. }
  953. if(IsRouterRunning())
  954. {
  955. dwRes = MprAdminInterfaceGetHandle(g_hMprAdmin,
  956. (LPWSTR)pwszIfName,
  957. &hInterface,
  958. FALSE);
  959. if ( dwRes != NO_ERROR )
  960. {
  961. break;
  962. }
  963. dwRes = MprAdminInterfaceTransportRemove(g_hMprAdmin,
  964. hInterface,
  965. PID_IP);
  966. if(dwIfType == ROUTER_IF_TYPE_TUNNEL1)
  967. {
  968. dwRes = MprAdminInterfaceDelete(g_hMprAdmin,
  969. hInterface);
  970. }
  971. break;
  972. }
  973. } while (FALSE);
  974. return dwRes;
  975. }
  976. DWORD
  977. SetInterfaceInfo(
  978. IN PRTR_INFO_BLOCK_HEADER pibhInfo,
  979. IN LPCWSTR pwszIfName
  980. )
  981. /*++
  982. Routine Description:
  983. Sets interface transport information in registry or router.
  984. Arguments:
  985. pwszIfName - Interface Name
  986. pibhInfo - ptr to header
  987. Return Value:
  988. NO_ERROR, ERROR_ROUTER_STOPPED
  989. --*/
  990. {
  991. DWORD dwARes = NO_ERROR,
  992. dwCRes = NO_ERROR;
  993. HANDLE hIfTransport, hInterface;
  994. UINT i;
  995. PRTR_INFO_BLOCK_HEADER pibhNewInfo, pibhOldInfo;
  996. //
  997. // Create a new info block with all 0-length blocks removed
  998. // since we don't want to write them to the registry,
  999. // we only need to send them to the router which we
  1000. // will do with the original info block below.
  1001. //
  1002. pibhNewInfo = pibhInfo;
  1003. pibhOldInfo = NULL;
  1004. for (i=0; (dwCRes is NO_ERROR) && (i<pibhInfo->TocEntriesCount); i++)
  1005. {
  1006. if (pibhInfo->TocEntry[i].InfoSize is 0)
  1007. {
  1008. pibhOldInfo = pibhNewInfo;
  1009. dwCRes = MprInfoBlockRemove(pibhOldInfo,
  1010. pibhInfo->TocEntry[i].InfoType,
  1011. &pibhNewInfo);
  1012. if (pibhOldInfo isnot pibhInfo)
  1013. {
  1014. FREE_BUFFER(pibhOldInfo);
  1015. }
  1016. }
  1017. }
  1018. if (dwCRes is NO_ERROR)
  1019. {
  1020. dwCRes = MprConfigInterfaceGetHandle(g_hMprConfig,
  1021. (LPWSTR)pwszIfName,
  1022. &hInterface);
  1023. }
  1024. if (dwCRes is NO_ERROR)
  1025. {
  1026. dwCRes = MprConfigInterfaceTransportGetHandle(g_hMprConfig,
  1027. hInterface,
  1028. PID_IP,
  1029. &hIfTransport);
  1030. }
  1031. if (dwCRes is NO_ERROR)
  1032. {
  1033. dwCRes = MprConfigInterfaceTransportSetInfo(g_hMprConfig,
  1034. hInterface,
  1035. hIfTransport,
  1036. (LPBYTE) pibhNewInfo,
  1037. pibhNewInfo->Size);
  1038. }
  1039. if (pibhNewInfo isnot pibhInfo)
  1040. {
  1041. FREE_BUFFER(pibhNewInfo);
  1042. }
  1043. //
  1044. // Even if we failed to write to the registry, we still want
  1045. // to write to the router.
  1046. //
  1047. // We use the original format when writing to the router, since it
  1048. // needs to see the 0-length blocks in order to delete config info.
  1049. //
  1050. if(IsRouterRunning())
  1051. {
  1052. dwARes = MprAdminInterfaceGetHandle(g_hMprAdmin,
  1053. (LPWSTR)pwszIfName,
  1054. &hInterface,
  1055. FALSE);
  1056. if (dwARes is NO_ERROR)
  1057. {
  1058. dwARes = MprAdminInterfaceTransportSetInfo(g_hMprAdmin,
  1059. hInterface,
  1060. PID_IP,
  1061. (LPBYTE) pibhInfo,
  1062. pibhInfo->Size);
  1063. }
  1064. }
  1065. return (dwARes isnot NO_ERROR)? dwARes : dwCRes;
  1066. }
  1067. DWORD
  1068. WINAPI
  1069. IpCommit(
  1070. IN DWORD dwAction
  1071. )
  1072. {
  1073. PINTERFACE_STORE pii;
  1074. PLIST_ENTRY ple, pleTmp;
  1075. BOOL bCommit, bFlush = FALSE;
  1076. switch(dwAction)
  1077. {
  1078. case NETSH_COMMIT:
  1079. {
  1080. if (g_bCommit == TRUE)
  1081. {
  1082. return NO_ERROR;
  1083. }
  1084. g_bCommit = TRUE;
  1085. break;
  1086. }
  1087. case NETSH_UNCOMMIT:
  1088. {
  1089. g_bCommit = FALSE;
  1090. return NO_ERROR;
  1091. }
  1092. case NETSH_SAVE:
  1093. {
  1094. if (g_bCommit)
  1095. {
  1096. return NO_ERROR;
  1097. }
  1098. break;
  1099. }
  1100. case NETSH_FLUSH:
  1101. {
  1102. //
  1103. // Action is a flush. If current state is commit, then
  1104. // nothing to be done.
  1105. if (g_bCommit)
  1106. {
  1107. return NO_ERROR;
  1108. }
  1109. bFlush = TRUE;
  1110. break;
  1111. }
  1112. default:
  1113. {
  1114. return NO_ERROR;
  1115. }
  1116. }
  1117. //
  1118. // Switched to commit mode. So set all valid info in the
  1119. // strutures. Free memory and invalidate the info.
  1120. //
  1121. if((g_tiTransport.bValid && g_tiTransport.pibhInfo) &&
  1122. !bFlush)
  1123. {
  1124. SetGlobalInfo(g_tiTransport.pibhInfo);
  1125. }
  1126. g_tiTransport.bValid = FALSE;
  1127. if(g_tiTransport.pibhInfo)
  1128. {
  1129. FREE_BUFFER(g_tiTransport.pibhInfo);
  1130. g_tiTransport.pibhInfo = NULL;
  1131. }
  1132. //
  1133. // Set the interface info
  1134. //
  1135. while(!IsListEmpty(&g_leIfListHead))
  1136. {
  1137. ple = RemoveHeadList(&g_leIfListHead);
  1138. pii = CONTAINING_RECORD(ple,
  1139. INTERFACE_STORE,
  1140. le);
  1141. if ((pii->bValid && pii->pibhInfo) &&
  1142. !bFlush)
  1143. {
  1144. // Set the info in config
  1145. SetInterfaceInfo(pii->pibhInfo,
  1146. pii->pwszIfName);
  1147. }
  1148. pii->bValid = FALSE;
  1149. if(pii->pibhInfo)
  1150. {
  1151. FREE_BUFFER(pii->pibhInfo);
  1152. pii->pibhInfo = NULL;
  1153. }
  1154. if(pii->pwszIfName)
  1155. {
  1156. HeapFree(GetProcessHeap(),
  1157. 0,
  1158. pii->pwszIfName);
  1159. pii->pwszIfName = NULL;
  1160. }
  1161. //
  1162. // Free the list entry
  1163. //
  1164. HeapFree(GetProcessHeap(),
  1165. 0,
  1166. pii);
  1167. }
  1168. return NO_ERROR;
  1169. }
  1170. DWORD
  1171. CreateInterface(
  1172. IN LPCWSTR pwszFriendlyName,
  1173. IN LPCWSTR pwszGuidName,
  1174. IN DWORD dwIfType,
  1175. IN BOOL bCreateRouterIf
  1176. )
  1177. {
  1178. DWORD i, dwErr, dwType, dwSize;
  1179. HANDLE hIfCfg, hIfAdmin, hIfTransport;
  1180. PBYTE pbyData;
  1181. PRTR_INFO_BLOCK_HEADER pInfo;
  1182. PINTERFACE_STATUS_INFO pStatus;
  1183. #if 0
  1184. PRTR_DISC_INFO pDisc;
  1185. #endif
  1186. //
  1187. // The only type we can create in the router is TUNNEL1
  1188. //
  1189. if(dwIfType != ROUTER_IF_TYPE_TUNNEL1)
  1190. {
  1191. ASSERT(FALSE);
  1192. return ERROR_INVALID_PARAMETER;
  1193. }
  1194. hIfAdmin = NULL;
  1195. hIfCfg = NULL;
  1196. if(bCreateRouterIf)
  1197. {
  1198. MPR_INTERFACE_0 IfInfo;
  1199. //
  1200. // The caller wants us to create an interface in the router, also
  1201. //
  1202. wcsncpy(IfInfo.wszInterfaceName,
  1203. pwszGuidName,
  1204. MAX_INTERFACE_NAME_LEN);
  1205. IfInfo.fEnabled = TRUE;
  1206. IfInfo.dwIfType = dwIfType;
  1207. IfInfo.wszInterfaceName[MAX_INTERFACE_NAME_LEN] = UNICODE_NULL;
  1208. dwErr = MprConfigInterfaceCreate(g_hMprConfig,
  1209. 0,
  1210. (PBYTE)&IfInfo,
  1211. &hIfCfg);
  1212. if(dwErr isnot NO_ERROR)
  1213. {
  1214. DisplayError(NULL,
  1215. dwErr);
  1216. return dwErr;
  1217. }
  1218. //
  1219. // if router service is running add the interface
  1220. // to it too.
  1221. //
  1222. if(IsRouterRunning())
  1223. {
  1224. dwErr = MprAdminInterfaceCreate(g_hMprAdmin,
  1225. 0,
  1226. (PBYTE)&IfInfo,
  1227. &hIfAdmin);
  1228. if(dwErr isnot NO_ERROR)
  1229. {
  1230. DisplayError(NULL,
  1231. dwErr);
  1232. MprConfigInterfaceDelete(g_hMprConfig,
  1233. hIfCfg);
  1234. return dwErr;
  1235. }
  1236. }
  1237. }
  1238. else
  1239. {
  1240. //
  1241. // The interface existed in the router but not in IP
  1242. //
  1243. dwErr = MprConfigInterfaceGetHandle(g_hMprConfig,
  1244. (LPWSTR)pwszGuidName,
  1245. &hIfCfg);
  1246. if(dwErr isnot NO_ERROR)
  1247. {
  1248. DisplayError(NULL,
  1249. dwErr);
  1250. return dwErr;
  1251. }
  1252. if(IsRouterRunning())
  1253. {
  1254. dwErr = MprAdminInterfaceGetHandle(g_hMprAdmin,
  1255. (LPWSTR)pwszGuidName,
  1256. &hIfAdmin,
  1257. FALSE);
  1258. if(dwErr isnot NO_ERROR)
  1259. {
  1260. DisplayError(NULL,
  1261. dwErr);
  1262. return dwErr;
  1263. }
  1264. }
  1265. }
  1266. //
  1267. // At this point we have an interface which doesnt have IP on it
  1268. // We have the handles to config and admin (if router is running)
  1269. // Set the default information for the interface
  1270. //
  1271. dwSize = FIELD_OFFSET(RTR_INFO_BLOCK_HEADER, TocEntry[0]);
  1272. dwSize += (sizeof(INTERFACE_STATUS_INFO) +
  1273. sizeof(RTR_TOC_ENTRY) +
  1274. ALIGN_SIZE);
  1275. #if 0
  1276. dwSize += (sizeof(RTR_DISC_INFO) +
  1277. sizeof(RTR_TOC_ENTRY) +
  1278. ALIGN_SIZE);
  1279. #endif
  1280. pInfo = HeapAlloc(GetProcessHeap(),
  1281. 0,
  1282. dwSize);
  1283. if(pInfo is NULL)
  1284. {
  1285. DisplayError(NULL,
  1286. ERROR_NOT_ENOUGH_MEMORY);
  1287. if(bCreateRouterIf)
  1288. {
  1289. MprConfigInterfaceDelete(g_hMprConfig,
  1290. hIfCfg);
  1291. }
  1292. return ERROR_NOT_ENOUGH_MEMORY;
  1293. }
  1294. pInfo->Version = IP_ROUTER_MANAGER_VERSION;
  1295. pInfo->TocEntriesCount = 1;
  1296. pInfo->Size = dwSize;
  1297. //
  1298. // Make data point to N+1th entry
  1299. //
  1300. pbyData = (PBYTE)&(pInfo->TocEntry[1]);
  1301. ALIGN_POINTER(pbyData);
  1302. pStatus = (PINTERFACE_STATUS_INFO)pbyData;
  1303. pStatus->dwAdminStatus = IF_ADMIN_STATUS_UP;
  1304. pInfo->TocEntry[0].InfoSize = sizeof(INTERFACE_STATUS_INFO);
  1305. pInfo->TocEntry[0].InfoType = IP_INTERFACE_STATUS_INFO;
  1306. pInfo->TocEntry[0].Count = 1;
  1307. pInfo->TocEntry[0].Offset = (ULONG)(pbyData - (PBYTE)pInfo);
  1308. pbyData = (PBYTE)((ULONG_PTR)pbyData + sizeof(INTERFACE_STATUS_INFO));
  1309. ALIGN_POINTER(pbyData);
  1310. #if 0
  1311. pDisc = (PRTR_DISC_INFO)pbyData;
  1312. pDisc->wMaxAdvtInterval =
  1313. DEFAULT_MAX_ADVT_INTERVAL;
  1314. pDisc->wMinAdvtInterval =
  1315. (WORD)(DEFAULT_MIN_ADVT_INTERVAL_RATIO * DEFAULT_MAX_ADVT_INTERVAL);
  1316. pDisc->wAdvtLifetime =
  1317. DEFAULT_ADVT_LIFETIME_RATIO * DEFAULT_MAX_ADVT_INTERVAL;
  1318. pDisc->bAdvertise = FALSE;
  1319. pDisc->lPrefLevel = DEFAULT_PREF_LEVEL;
  1320. pInfo->TocEntry[1].InfoSize = sizeof(RTR_DISC_INFO);
  1321. pInfo->TocEntry[1].InfoType = IP_ROUTER_DISC_INFO;
  1322. pInfo->TocEntry[1].Count = 1;
  1323. pInfo->TocEntry[1].Offset = (ULONG)(pbyData - (PBYTE)pInfo);
  1324. #endif
  1325. dwErr = MprConfigInterfaceTransportAdd(g_hMprConfig,
  1326. hIfCfg,
  1327. PID_IP,
  1328. IP_KEY,
  1329. (PBYTE) pInfo,
  1330. dwSize,
  1331. &hIfTransport);
  1332. if(dwErr isnot NO_ERROR)
  1333. {
  1334. HeapFree(GetProcessHeap(),
  1335. 0,
  1336. pInfo);
  1337. DisplayMessage(g_hModule,
  1338. EMSG_CANT_CREATE_IF,
  1339. pwszFriendlyName,
  1340. dwErr);
  1341. if(bCreateRouterIf)
  1342. {
  1343. MprConfigInterfaceDelete(g_hMprConfig,
  1344. hIfCfg);
  1345. }
  1346. return dwErr;
  1347. }
  1348. if(hIfAdmin isnot NULL)
  1349. {
  1350. dwErr = MprAdminInterfaceTransportAdd(g_hMprAdmin,
  1351. hIfAdmin,
  1352. PID_IP,
  1353. (PBYTE) pInfo,
  1354. dwSize);
  1355. if(dwErr isnot NO_ERROR)
  1356. {
  1357. DisplayMessage(g_hModule,
  1358. EMSG_CANT_CREATE_IF,
  1359. pwszFriendlyName,
  1360. dwErr);
  1361. MprConfigInterfaceTransportRemove(g_hMprConfig,
  1362. hIfCfg,
  1363. hIfTransport);
  1364. if(bCreateRouterIf)
  1365. {
  1366. MprConfigInterfaceDelete(g_hMprConfig,
  1367. hIfCfg);
  1368. }
  1369. }
  1370. }
  1371. HeapFree(GetProcessHeap(),
  1372. 0,
  1373. pInfo);
  1374. return NO_ERROR;
  1375. }
  1376. DWORD
  1377. GetInterfaceClass(
  1378. IN LPCWSTR pwszIfName,
  1379. OUT PDWORD pdwIfClass
  1380. )
  1381. /*++
  1382. Description:
  1383. Determine whether an interface is of class Loopback, P2P,
  1384. Subnet, or NBMA. Currently there is no global way to do this,
  1385. so we test for some enumerated types and assume everything else
  1386. is Subnet.
  1387. Returns:
  1388. IFCLASS_xxx (see info.h)
  1389. --*/
  1390. {
  1391. DWORD dwErr, dwType;
  1392. dwErr = GetInterfaceInfo(pwszIfName,
  1393. NULL,
  1394. NULL,
  1395. &dwType);
  1396. if (dwErr)
  1397. {
  1398. return dwErr;
  1399. }
  1400. switch (dwType) {
  1401. case ROUTER_IF_TYPE_FULL_ROUTER : *pdwIfClass = IFCLASS_P2P; break;
  1402. case ROUTER_IF_TYPE_INTERNAL : *pdwIfClass = IFCLASS_NBMA; break;
  1403. case ROUTER_IF_TYPE_LOOPBACK : *pdwIfClass = IFCLASS_LOOPBACK; break;
  1404. case ROUTER_IF_TYPE_TUNNEL1 : *pdwIfClass = IFCLASS_P2P; break;
  1405. case ROUTER_IF_TYPE_DIALOUT : *pdwIfClass = IFCLASS_P2P; break;
  1406. default: *pdwIfClass = IFCLASS_BROADCAST; break;
  1407. }
  1408. return NO_ERROR;
  1409. }