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.

2365 lines
57 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\ip\rtrmgr\init.c
  5. Abstract:
  6. IP Router Manager code
  7. Revision History:
  8. Gurdeep Singh Pall 6/14/95 Created
  9. --*/
  10. #include "allinc.h"
  11. DWORD
  12. RtrMgrMIBEntryCreate(
  13. IN DWORD dwRoutingPid,
  14. IN DWORD dwEntrySize,
  15. IN LPVOID lpEntry
  16. );
  17. DWORD
  18. RtrMgrMIBEntryDelete(
  19. IN DWORD dwRoutingPid,
  20. IN DWORD dwEntrySize,
  21. IN LPVOID lpEntry
  22. );
  23. DWORD
  24. RtrMgrMIBEntryGet(
  25. IN DWORD dwRoutingPid,
  26. IN DWORD dwInEntrySize,
  27. IN LPVOID lpInEntry,
  28. IN OUT LPDWORD lpOutEntrySize,
  29. OUT LPVOID lpOutEntry
  30. );
  31. DWORD
  32. RtrMgrMIBEntryGetFirst(
  33. IN DWORD dwRoutingPid,
  34. IN DWORD dwInEntrySize,
  35. IN LPVOID lpInEntry,
  36. IN OUT LPDWORD lpOutEntrySize,
  37. OUT LPVOID lpOutEntry
  38. );
  39. DWORD
  40. RtrMgrMIBEntryGetNext(
  41. IN DWORD dwRoutingPid,
  42. IN DWORD dwInEntrySize,
  43. IN LPVOID lpInEntry,
  44. IN OUT LPDWORD lpOutEntrySize,
  45. OUT LPVOID lpOutEntry
  46. );
  47. DWORD
  48. RtrMgrMIBEntrySet(
  49. IN DWORD dwRoutingPid,
  50. IN DWORD dwEntrySize,
  51. IN LPVOID lpEntry
  52. );
  53. DWORD
  54. InitRouter(
  55. PRTR_INFO_BLOCK_HEADER pGlobalInfo
  56. )
  57. /*++
  58. Routine Description:
  59. Loads routing protocols, loads bootp agent, opens the approp. drivers,
  60. and starts the worker thread.
  61. Arguments:
  62. GlobalInfo passed in by DIM
  63. Return Value:
  64. NO_ERROR or some error code
  65. --*/
  66. {
  67. HANDLE hThread;
  68. DWORD dwResult, dwTid, i;
  69. PGLOBAL_INFO pInfo;
  70. PRTR_TOC_ENTRY pToc;
  71. IPSNMPInfo ipsiInfo;
  72. RTM_ENTITY_INFO entityInfo;
  73. PIP_NAT_GLOBAL_INFO pNatInfo;
  74. PMIB_IPFORWARDTABLE pInitRouteTable;
  75. PROUTE_LIST_ENTRY prl;
  76. MGM_CALLBACKS mgmCallbacks;
  77. ROUTER_MANAGER_CONFIG mgmConfig;
  78. TraceEnter("InitRouter");
  79. //
  80. // Initialize all the locks (MIB handlers and ICB_LIST/PROTOCOL_CB_LIST)
  81. // VERY IMPORTANT, since we break out of this and try and do a cleanup
  82. // which needs the lists and the locks, WE MUST initialize the lists
  83. // and the locks BEFORE the first abnormal exit from this function
  84. //
  85. for(i = 0; i < NUM_LOCKS; i++)
  86. {
  87. RtlInitializeResource(&g_LockTable[i]);
  88. }
  89. //
  90. // Init the list head for interfaces
  91. //
  92. InitializeListHead(&ICBList);
  93. //
  94. // Initialize ICB Hash lookup table and the Adapter to Interface Hash
  95. //
  96. for (i=0; i<ICB_HASH_TABLE_SIZE; i++)
  97. {
  98. InitializeListHead(&ICBHashLookup[i]);
  99. InitializeListHead(&ICBSeqNumLookup[i]);
  100. }
  101. InitHashTables();
  102. //
  103. // Initialize Routing protocol List
  104. //
  105. InitializeListHead(&g_leProtoCbList);
  106. //
  107. // Initialize the Router Discovery Timer Queue
  108. //
  109. InitializeListHead(&g_leTimerQueueHead);
  110. pToc = GetPointerToTocEntry(IP_GLOBAL_INFO, pGlobalInfo);
  111. if(!pToc or (pToc->InfoSize is 0))
  112. {
  113. LogErr0(NO_GLOBAL_INFO,
  114. ERROR_NO_DATA);
  115. Trace0(ERR,
  116. "InitRouter: No Global Info - can not start router");
  117. TraceLeave("InitRouter");
  118. return ERROR_CAN_NOT_COMPLETE;
  119. }
  120. pInfo = (PGLOBAL_INFO)GetInfoFromTocEntry(pGlobalInfo,
  121. pToc);
  122. if(pInfo is NULL)
  123. {
  124. LogErr0(NO_GLOBAL_INFO,
  125. ERROR_NO_DATA);
  126. Trace0(ERR,
  127. "InitRouter: No Global Info - can not start router");
  128. TraceLeave("InitRouter");
  129. return ERROR_CAN_NOT_COMPLETE;
  130. }
  131. #pragma warning(push)
  132. #pragma warning(disable:4296)
  133. if((pInfo->dwLoggingLevel > IPRTR_LOGGING_INFO) or
  134. (pInfo->dwLoggingLevel < IPRTR_LOGGING_NONE))
  135. #pragma warning(pop)
  136. {
  137. Trace1(ERR,
  138. "InitRouter: Global info has invalid logging level of %d",
  139. pInfo->dwLoggingLevel);
  140. g_dwLoggingLevel = IPRTR_LOGGING_INFO;
  141. }
  142. else
  143. {
  144. g_dwLoggingLevel = pInfo->dwLoggingLevel;
  145. }
  146. //
  147. // Allocate private heap
  148. //
  149. IPRouterHeap = HeapCreate(0, 5000, 0);
  150. if(IPRouterHeap is NULL)
  151. {
  152. dwResult = GetLastError() ;
  153. Trace1(ERR,
  154. "InitRouter: Error %d creating IPRouterHeap",
  155. dwResult) ;
  156. TraceLeave("InitRouter");
  157. return dwResult ;
  158. }
  159. //
  160. // Create the events needed to talk to the routing protocols,
  161. // DIM and WANARP
  162. //
  163. g_hRoutingProtocolEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  164. g_hStopRouterEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  165. g_hSetForwardingEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  166. g_hForwardingChangeEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  167. g_hDemandDialEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  168. g_hIpInIpEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  169. g_hStackChangeEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  170. g_hRtrDiscSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  171. g_hMHbeatSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  172. g_hMcMiscSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  173. g_hMzapSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  174. for(i = 0; i < NUM_MCAST_IRPS; i++)
  175. {
  176. g_hMcastEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
  177. }
  178. for(i = 0; i < NUM_ROUTE_CHANGE_IRPS; i++)
  179. {
  180. g_hRouteChangeEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
  181. }
  182. g_hRtrDiscTimer = CreateWaitableTimer(NULL,
  183. FALSE,
  184. NULL);
  185. g_hRasAdvTimer = CreateWaitableTimer(NULL,
  186. FALSE,
  187. NULL);
  188. g_hMzapTimer = CreateWaitableTimer(NULL,
  189. FALSE,
  190. NULL);
  191. if((g_hRoutingProtocolEvent is NULL) or
  192. (g_hStopRouterEvent is NULL) or
  193. (g_hSetForwardingEvent is NULL) or
  194. (g_hForwardingChangeEvent is NULL) or
  195. (g_hDemandDialEvent is NULL) or
  196. (g_hIpInIpEvent is NULL) or
  197. (g_hStackChangeEvent is NULL) or
  198. (g_hRtrDiscSocketEvent is NULL) or
  199. (g_hRtrDiscTimer is NULL) or
  200. (g_hRasAdvTimer is NULL) or
  201. (g_hMcMiscSocketEvent is NULL) or
  202. (g_hMzapSocketEvent is NULL) or
  203. (g_hMHbeatSocketEvent is NULL))
  204. {
  205. Trace0(ERR,
  206. "InitRouter: Couldnt create the needed events and timer");
  207. TraceLeave("InitRouter");
  208. return ERROR_CAN_NOT_COMPLETE;
  209. }
  210. for(i = 0; i < NUM_MCAST_IRPS; i++)
  211. {
  212. if(g_hMcastEvents[i] is NULL)
  213. {
  214. Trace0(ERR,
  215. "InitRouter: Couldnt create the mcast events");
  216. TraceLeave("InitRouter");
  217. return ERROR_CAN_NOT_COMPLETE;
  218. }
  219. }
  220. for(i = 0; i < NUM_ROUTE_CHANGE_IRPS; i++)
  221. {
  222. if(g_hRouteChangeEvents[i] is NULL)
  223. {
  224. Trace0(ERR,
  225. "InitRouter: Couldnt create the mcast events");
  226. TraceLeave("InitRouter");
  227. return ERROR_CAN_NOT_COMPLETE;
  228. }
  229. }
  230. Trace0(GLOBAL,
  231. "InitRouter: Created necessary events and timer");
  232. dwResult = MprConfigServerConnect(NULL,
  233. &g_hMprConfig);
  234. if(dwResult isnot NO_ERROR)
  235. {
  236. Trace1(ERR,
  237. "InitRouter: Error %d calling MprConfigServerConnect",
  238. dwResult);
  239. return dwResult;
  240. }
  241. g_sinAllSystemsAddr.sin_family = AF_INET;
  242. g_sinAllSystemsAddr.sin_addr.s_addr = ALL_SYSTEMS_MULTICAST_GROUP;
  243. g_sinAllSystemsAddr.sin_port = 0;
  244. g_pIpHeader = (PIP_HEADER)g_pdwIpAndIcmpBuf;
  245. g_wsaIpRcvBuf.buf = (PBYTE)g_pIpHeader;
  246. g_wsaIpRcvBuf.len = ICMP_RCV_BUFFER_LEN * sizeof(DWORD);
  247. g_wsaMcRcvBuf.buf = g_byMcMiscBuffer;
  248. g_wsaMcRcvBuf.len = sizeof(g_byMcMiscBuffer);
  249. //
  250. // Get all the routes that are in the stack and store them away
  251. //
  252. pInitRouteTable = NULL;
  253. InitializeListHead( &g_leStackRoutesToRestore );
  254. dwResult = AllocateAndGetIpForwardTableFromStack(&pInitRouteTable,
  255. FALSE,
  256. IPRouterHeap,
  257. 0);
  258. if(dwResult isnot NO_ERROR)
  259. {
  260. Trace1(ERR,
  261. "InitRouter: Couldnt get initial routes. Error %d",
  262. dwResult);
  263. }
  264. else
  265. {
  266. if(pInitRouteTable->dwNumEntries isnot 0)
  267. {
  268. TraceRoute0( ROUTE, "Init. table routes\n" );
  269. for ( i = 0; i < pInitRouteTable-> dwNumEntries; i++ )
  270. {
  271. if (pInitRouteTable->table[i].dwForwardProto !=
  272. MIB_IPPROTO_NETMGMT)
  273. {
  274. continue;
  275. }
  276. TraceRoute3(
  277. ROUTE, "%d.%d.%d.%d/%d.%d.%d.%d, type 0x%x",
  278. PRINT_IPADDR( pInitRouteTable-> table[i].dwForwardDest ),
  279. PRINT_IPADDR( pInitRouteTable-> table[i].dwForwardMask ),
  280. pInitRouteTable-> table[i].dwForwardType
  281. );
  282. //
  283. // Allocate and store route in a linked list
  284. //
  285. prl = HeapAlloc(
  286. IPRouterHeap, HEAP_ZERO_MEMORY,
  287. sizeof(ROUTE_LIST_ENTRY)
  288. );
  289. if (prl is NULL)
  290. {
  291. Trace2(
  292. ERR,
  293. "InitRouter: error %d allocating %d bytes "
  294. "for stack route entry",
  295. ERROR_NOT_ENOUGH_MEMORY,
  296. sizeof(ROUTE_LIST_ENTRY)
  297. );
  298. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  299. break;
  300. }
  301. InitializeListHead( &prl->leRouteList );
  302. prl->mibRoute = pInitRouteTable-> table[i];
  303. InsertTailList(
  304. &g_leStackRoutesToRestore, &prl->leRouteList
  305. );
  306. }
  307. if (dwResult isnot NO_ERROR)
  308. {
  309. while (!IsListEmpty(&g_leStackRoutesToRestore))
  310. {
  311. prl = (PROUTE_LIST_ENTRY) RemoveHeadList(
  312. &g_leStackRoutesToRestore
  313. );
  314. HeapFree(IPRouterHeap, 0, prl);
  315. }
  316. }
  317. }
  318. HeapFree(IPRouterHeap, 0, pInitRouteTable);
  319. pInitRouteTable = NULL;
  320. }
  321. //
  322. // The route table is created implicitly by RTM at the
  323. // time of the first registration call (see call below)
  324. //
  325. //
  326. // Setup common params for all registrations with RTMv2
  327. //
  328. entityInfo.RtmInstanceId = 0; // routerId;
  329. entityInfo.AddressFamily = AF_INET;
  330. entityInfo.EntityId.EntityInstanceId = 0;
  331. //
  332. // Register with RTM using the appropriate proto ids
  333. //
  334. //
  335. // This 1st registration is also used for performing
  336. // RTM operations common for all these registrations,
  337. // As an example it is used to get any changed dests.
  338. //
  339. entityInfo.EntityId.EntityProtocolId = PROTO_IP_LOCAL;
  340. dwResult = RtmRegisterEntity(&entityInfo,
  341. NULL,
  342. RtmEventCallback,
  343. FALSE,
  344. &g_rtmProfile,
  345. &g_hLocalRoute);
  346. if(dwResult isnot NO_ERROR)
  347. {
  348. Trace1(ERR,
  349. "InitRouter: RtmRegisterClient for local routes failed %d",
  350. dwResult) ;
  351. TraceLeave("InitRouter");
  352. return dwResult ;
  353. }
  354. // Also register for dest change notifications
  355. dwResult = RtmRegisterForChangeNotification(g_hLocalRoute,
  356. RTM_VIEW_MASK_UCAST,
  357. RTM_CHANGE_TYPE_FORWARDING,
  358. NULL,
  359. &g_hNotification);
  360. if (dwResult isnot NO_ERROR)
  361. {
  362. Trace1(ERR,
  363. "InitRouter: RtmRegisterForChangeNotificaition failed %d",
  364. dwResult) ;
  365. TraceLeave("InitRouter");
  366. return dwResult ;
  367. }
  368. //
  369. // Register more times for each type of route
  370. //
  371. entityInfo.EntityId.EntityProtocolId = PROTO_IP_NT_AUTOSTATIC;
  372. dwResult = RtmRegisterEntity(&entityInfo,
  373. NULL,
  374. NULL,
  375. FALSE,
  376. &g_rtmProfile,
  377. &g_hAutoStaticRoute);
  378. if(dwResult isnot NO_ERROR)
  379. {
  380. Trace1(ERR,
  381. "InitRouter: RtmRegisterClient for AutoStatic routes failed %d",
  382. dwResult) ;
  383. TraceLeave("InitRouter");
  384. return dwResult ;
  385. }
  386. entityInfo.EntityId.EntityProtocolId = PROTO_IP_NT_STATIC;
  387. dwResult = RtmRegisterEntity(&entityInfo,
  388. NULL,
  389. NULL,
  390. FALSE,
  391. &g_rtmProfile,
  392. &g_hStaticRoute);
  393. if(dwResult isnot NO_ERROR)
  394. {
  395. Trace1(ERR,
  396. "InitRouter: RtmRegisterClient for Static routes failed %d",
  397. dwResult) ;
  398. TraceLeave("InitRouter");
  399. return dwResult ;
  400. }
  401. entityInfo.EntityId.EntityProtocolId = PROTO_IP_NT_STATIC_NON_DOD;
  402. dwResult = RtmRegisterEntity(&entityInfo,
  403. NULL,
  404. NULL,
  405. FALSE,
  406. &g_rtmProfile,
  407. &g_hNonDodRoute);
  408. if(dwResult isnot NO_ERROR)
  409. {
  410. Trace1(ERR,
  411. "InitRouter: RtmRegisterClient for DOD routes failed %d",
  412. dwResult) ;
  413. TraceLeave("InitRouter");
  414. return dwResult ;
  415. }
  416. entityInfo.EntityId.EntityProtocolId = PROTO_IP_NETMGMT;
  417. dwResult = RtmRegisterEntity(&entityInfo,
  418. NULL,
  419. RtmEventCallback,
  420. FALSE,
  421. &g_rtmProfile,
  422. &g_hNetMgmtRoute);
  423. if(dwResult isnot NO_ERROR)
  424. {
  425. Trace1(ERR,
  426. "InitRouter: RtmRegisterClient for NetMgmt routes failed %d",
  427. dwResult) ;
  428. TraceLeave("InitRouter");
  429. return dwResult ;
  430. }
  431. // Also register for marked dest change notifications
  432. dwResult = RtmRegisterForChangeNotification(g_hNetMgmtRoute,
  433. RTM_VIEW_MASK_UCAST,
  434. RTM_CHANGE_TYPE_ALL |
  435. RTM_NOTIFY_ONLY_MARKED_DESTS,
  436. NULL,
  437. &g_hDefaultRouteNotification);
  438. if (dwResult isnot NO_ERROR)
  439. {
  440. Trace1(ERR,
  441. "InitRouter: RtmRegisterForChangeNotificaition failed %d",
  442. dwResult) ;
  443. TraceLeave("InitRouter");
  444. return dwResult ;
  445. }
  446. g_rgRtmHandles[0].dwProtoId = PROTO_IP_LOCAL;
  447. g_rgRtmHandles[0].hRouteHandle = g_hLocalRoute;
  448. g_rgRtmHandles[0].bStatic = FALSE;
  449. g_rgRtmHandles[1].dwProtoId = PROTO_IP_NT_AUTOSTATIC;
  450. g_rgRtmHandles[1].hRouteHandle = g_hAutoStaticRoute;
  451. g_rgRtmHandles[1].bStatic = TRUE;
  452. g_rgRtmHandles[2].dwProtoId = PROTO_IP_NT_STATIC;
  453. g_rgRtmHandles[2].hRouteHandle = g_hStaticRoute;
  454. g_rgRtmHandles[2].bStatic = TRUE;
  455. g_rgRtmHandles[3].dwProtoId = PROTO_IP_NT_STATIC_NON_DOD;
  456. g_rgRtmHandles[3].hRouteHandle = g_hNonDodRoute;
  457. g_rgRtmHandles[3].bStatic = TRUE;
  458. g_rgRtmHandles[4].dwProtoId = PROTO_IP_NETMGMT;
  459. g_rgRtmHandles[4].hRouteHandle = g_hNetMgmtRoute;
  460. g_rgRtmHandles[4].bStatic = FALSE;
  461. //
  462. // Initialize MGM
  463. //
  464. mgmConfig.dwLogLevel = g_dwLoggingLevel;
  465. mgmConfig.dwIfTableSize = MGM_IF_TABLE_SIZE;
  466. mgmConfig.dwGrpTableSize = MGM_GROUP_TABLE_SIZE;
  467. mgmConfig.dwSrcTableSize = MGM_SOURCE_TABLE_SIZE;
  468. mgmConfig.pfnAddMfeCallback = SetMfe;
  469. mgmConfig.pfnDeleteMfeCallback = DeleteMfe;
  470. mgmConfig.pfnGetMfeCallback = GetMfe;
  471. mgmConfig.pfnHasBoundaryCallback = RmHasBoundary;
  472. dwResult = MgmInitialize(&mgmConfig,
  473. &mgmCallbacks);
  474. if(dwResult isnot NO_ERROR)
  475. {
  476. Trace1(ERR,
  477. "InitRouter: Error %d initializing MGM\n",
  478. dwResult);
  479. TraceLeave("InitRouter");
  480. return dwResult;
  481. }
  482. //
  483. // Store callbacks into MGM
  484. //
  485. g_pfnMgmMfeDeleted = mgmCallbacks.pfnMfeDeleteIndication;
  486. g_pfnMgmNewPacket = mgmCallbacks.pfnNewPacketIndication;
  487. g_pfnMgmBlockGroups = mgmCallbacks.pfnBlockGroups;
  488. g_pfnMgmUnBlockGroups = mgmCallbacks.pfnUnBlockGroups;
  489. g_pfnMgmWrongIf = mgmCallbacks.pfnWrongIfIndication;
  490. if(OpenIPDriver() isnot NO_ERROR)
  491. {
  492. Trace0(ERR,
  493. "InitRouter: Couldnt open IP driver");
  494. TraceLeave("InitRouter");
  495. return ERROR_OPEN_FAILED;
  496. }
  497. //
  498. // Do the multicast initialization
  499. //
  500. dwResult = OpenMulticastDriver();
  501. if(dwResult isnot NO_ERROR)
  502. {
  503. Trace0(ERR,
  504. "InitRoute: Could not open IP Multicast device");
  505. //
  506. // not an error, just continue;
  507. //
  508. }
  509. else
  510. {
  511. //
  512. // Find if we are in multicast mode
  513. //
  514. dwResult = StartMulticast();
  515. if(dwResult isnot NO_ERROR)
  516. {
  517. Trace0(ERR,
  518. "InitRoute: Could not start multicast");
  519. }
  520. }
  521. if(!RouterRoleLanOnly)
  522. {
  523. if((dwResult = InitializeWanArp()) isnot NO_ERROR)
  524. {
  525. Trace0(ERR,
  526. "InitRouter: Couldnt open WanArp driver");
  527. TraceLeave("InitRouter");
  528. return dwResult;
  529. }
  530. }
  531. SetPriorityInfo(pGlobalInfo);
  532. SetScopeInfo(pGlobalInfo);
  533. if((dwResult = InitializeMibHandler()) isnot NO_ERROR)
  534. {
  535. Trace1(ERR,
  536. "InitRouter: InitializeMibHandler failed, returned %d",
  537. dwResult);
  538. TraceLeave("InitRouter");
  539. return dwResult;
  540. }
  541. //
  542. // Create Worker thread
  543. //
  544. hThread = CreateThread(NULL,
  545. 0,
  546. (PVOID) WorkerThread,
  547. pGlobalInfo,
  548. 0,
  549. &dwTid) ;
  550. if(hThread is NULL)
  551. {
  552. dwResult = GetLastError () ;
  553. Trace1(ERR,
  554. "InitRouter: CreateThread failed %d",
  555. dwResult);
  556. TraceLeave("InitRouter");
  557. return dwResult ;
  558. }
  559. else
  560. {
  561. CloseHandle(hThread);
  562. }
  563. dwResult = OpenIpIpKey();
  564. if(dwResult isnot NO_ERROR)
  565. {
  566. Trace1(ERR,
  567. "InitRouter: Error %d opening ipinip key",
  568. dwResult);
  569. return ERROR_CAN_NOT_COMPLETE;
  570. }
  571. //
  572. // We load are routing protocols after all our own initialization,
  573. // since we dont know how they will interact with us
  574. //
  575. ENTER_WRITER(ICB_LIST);
  576. ENTER_WRITER(PROTOCOL_CB_LIST);
  577. LoadRoutingProtocols (pGlobalInfo);
  578. EXIT_LOCK(PROTOCOL_CB_LIST);
  579. EXIT_LOCK(ICB_LIST);
  580. TraceLeave("InitRouter");
  581. return NO_ERROR;
  582. }
  583. DWORD
  584. LoadRoutingProtocols(
  585. PRTR_INFO_BLOCK_HEADER pGlobalInfo
  586. )
  587. /*++
  588. Routine Description:
  589. Loads and initializes all the routing protocols configured
  590. Called with ICBListLock and RoutingProcotoclCBListLock held
  591. Arguments
  592. GlobalInfo passed in by DIM
  593. Return Value:
  594. NO_ERROR or some error code
  595. --*/
  596. {
  597. DWORD i, j, dwSize, dwNumProtoEntries, dwResult;
  598. PPROTO_CB pNewProtocolCb;
  599. PWCHAR pwszDllNames ; // array of dll names
  600. MPR_PROTOCOL_0 *pmpProtocolInfo;
  601. PVOID pvInfo;
  602. BOOL bFound;
  603. TraceEnter("LoadRoutingProtocols");
  604. dwResult = MprSetupProtocolEnum(PID_IP,
  605. (PBYTE *)(&pmpProtocolInfo),
  606. &dwNumProtoEntries);
  607. if(dwResult isnot NO_ERROR)
  608. {
  609. Trace1(ERR,
  610. "LoadRoutingProtocols: Error %d loading protocol info from registry",
  611. dwResult);
  612. TraceLeave("LoadRoutingProtocols");
  613. return dwResult;
  614. }
  615. for(i=0; i < pGlobalInfo->TocEntriesCount; i++)
  616. {
  617. ULONG ulStructureVersion, ulStructureSize, ulStructureCount;
  618. DWORD dwType;
  619. //
  620. // Read each TOC and see if it is PROTO_TYPE_UCAST/MCAST
  621. // If it does it is a loadable protocol and we get its info
  622. // from the registry
  623. //
  624. dwType = TYPE_FROM_PROTO_ID(pGlobalInfo->TocEntry[i].InfoType);
  625. if((dwType < PROTO_TYPE_MS1) and
  626. (pGlobalInfo->TocEntry[i].InfoSize > 0))
  627. {
  628. bFound = FALSE;
  629. for(j = 0; j < dwNumProtoEntries; j ++)
  630. {
  631. if(pmpProtocolInfo[j].dwProtocolId is pGlobalInfo->TocEntry[i].InfoType)
  632. {
  633. //
  634. // well great, we have found it
  635. //
  636. bFound = TRUE;
  637. break;
  638. }
  639. }
  640. if(!bFound)
  641. {
  642. Trace1(ERR,
  643. "LoadRoutingProtocols: Couldnt find information for protocol ID %d",
  644. pGlobalInfo->TocEntry[i].InfoType);
  645. continue;
  646. }
  647. //
  648. // load library on the dll name provided
  649. //
  650. dwSize = (wcslen(pmpProtocolInfo[j].wszProtocol) +
  651. wcslen(pmpProtocolInfo[j].wszDLLName) + 2) * sizeof(WCHAR) +
  652. sizeof(PROTO_CB);
  653. pNewProtocolCb = HeapAlloc(IPRouterHeap,
  654. HEAP_ZERO_MEMORY,
  655. dwSize);
  656. if (pNewProtocolCb is NULL)
  657. {
  658. Trace2(ERR,
  659. "LoadRoutingProtocols: Error allocating %d bytes for %S",
  660. dwSize,
  661. pmpProtocolInfo[j].wszProtocol);
  662. continue ;
  663. }
  664. pvInfo = GetInfoFromTocEntry(pGlobalInfo,
  665. &(pGlobalInfo->TocEntry[i]));
  666. //ulStructureVersion = pGlobalInfo->TocEntry[i].InfoVersion;
  667. ulStructureVersion = 0x500;
  668. ulStructureSize = pGlobalInfo->TocEntry[i].InfoSize;
  669. ulStructureCount = pGlobalInfo->TocEntry[i].Count;
  670. dwResult = LoadProtocol(&(pmpProtocolInfo[j]),
  671. pNewProtocolCb,
  672. pvInfo,
  673. ulStructureVersion,
  674. ulStructureSize,
  675. ulStructureCount);
  676. if(dwResult isnot NO_ERROR)
  677. {
  678. Trace2(ERR,
  679. "LoadRoutingProtocols: %S failed to load: %d",
  680. pmpProtocolInfo[j].wszProtocol,
  681. dwResult);
  682. HeapFree (IPRouterHeap, 0, pNewProtocolCb) ;
  683. }
  684. else
  685. {
  686. pNewProtocolCb->posOpState = RTR_STATE_RUNNING ;
  687. //
  688. // Insert this routing protocol in the list of routing
  689. // protocols
  690. //
  691. InsertTailList(&g_leProtoCbList,
  692. &pNewProtocolCb->leList) ;
  693. Trace1(GLOBAL,
  694. "LoadRoutingProtocols: %S successfully initialized",
  695. pmpProtocolInfo[j].wszProtocol) ;
  696. TotalRoutingProtocols++ ;
  697. }
  698. }
  699. }
  700. MprSetupProtocolFree(pmpProtocolInfo);
  701. TraceLeave("LoadRoutingProtocols");
  702. return NO_ERROR ;
  703. }
  704. DWORD
  705. StartDriverAndOpenHandle(
  706. PCHAR pszServiceName,
  707. PWCHAR pwszDriverName,
  708. PHANDLE phDevice
  709. )
  710. /*++
  711. Routine Description:
  712. Creates a handle to the IP NAT service on the local machine
  713. Then tries to start the service. Loops till the service starts.
  714. Can potentially loop forever.
  715. Then creates a handle to the device.
  716. Arguments
  717. None
  718. Return Value:
  719. NO_ERROR or some error code
  720. --*/
  721. {
  722. NTSTATUS status;
  723. UNICODE_STRING nameString;
  724. IO_STATUS_BLOCK ioStatusBlock;
  725. OBJECT_ATTRIBUTES objectAttributes;
  726. SC_HANDLE schSCManager, schService;
  727. DWORD dwErr;
  728. SERVICE_STATUS ssStatus;
  729. BOOL bErr, bRet;
  730. ULONG ulCount;
  731. TraceEnter("StartDriver");
  732. schSCManager = OpenSCManager(NULL,
  733. NULL,
  734. SC_MANAGER_ALL_ACCESS);
  735. if (schSCManager is NULL)
  736. {
  737. dwErr = GetLastError();
  738. Trace2(ERR,
  739. "StartDriver: Error %d opening svc controller for %s",
  740. dwErr,
  741. pszServiceName);
  742. TraceLeave("StartDriver");
  743. return ERROR_OPEN_FAILED;
  744. }
  745. schService = OpenService(schSCManager,
  746. pszServiceName,
  747. SERVICE_ALL_ACCESS);
  748. if(schService is NULL)
  749. {
  750. dwErr = GetLastError();
  751. Trace2(ERR,
  752. "StartDriver: Error %d opening %s",
  753. dwErr,
  754. pszServiceName);
  755. CloseServiceHandle(schSCManager);
  756. TraceLeave("StartDriver");
  757. return ERROR_OPEN_FAILED;
  758. }
  759. __try
  760. {
  761. bRet = FALSE;
  762. bErr = QueryServiceStatus(schService,
  763. &ssStatus);
  764. if(!bErr)
  765. {
  766. dwErr = GetLastError();
  767. Trace2(ERR,
  768. "StartDriver: Error %d querying %s status to see if it is already running",
  769. dwErr,
  770. pszServiceName);
  771. __leave;
  772. }
  773. //
  774. // If the driver is running, we shut it down. This forces a
  775. // cleanup of all its internal data structures.
  776. //
  777. if(ssStatus.dwCurrentState isnot SERVICE_STOPPED)
  778. {
  779. if(!ControlService(schService,
  780. SERVICE_CONTROL_STOP,
  781. &ssStatus))
  782. {
  783. dwErr = GetLastError();
  784. Trace2(ERR,
  785. "StartDriver: %s was running at init time. Attempts to stop it caused error %d",
  786. pszServiceName,
  787. dwErr);
  788. }
  789. else
  790. {
  791. Sleep(1000);
  792. //
  793. // Now loop for 10 seconds waiting for the service to stop
  794. //
  795. ulCount = 0;
  796. while(ulCount < 5)
  797. {
  798. bErr = QueryServiceStatus(schService,
  799. &ssStatus);
  800. if(!bErr)
  801. {
  802. dwErr = GetLastError();
  803. break;
  804. }
  805. else
  806. {
  807. if (ssStatus.dwCurrentState is SERVICE_STOPPED)
  808. {
  809. break;
  810. }
  811. else
  812. {
  813. ulCount++;
  814. Sleep(2000);
  815. }
  816. }
  817. }
  818. if(ssStatus.dwCurrentState isnot SERVICE_STOPPED)
  819. {
  820. if(ulCount is 5)
  821. {
  822. dwErr = ERROR_SERVICE_REQUEST_TIMEOUT;
  823. }
  824. Trace2(ERR,
  825. "StartDriver: Error %d stopping %s which was running at init time",
  826. dwErr,
  827. pszServiceName);
  828. __leave;
  829. }
  830. }
  831. }
  832. //
  833. // Query the service status one more time to see
  834. // if it is now stopped (because it was never running
  835. // or because it was started and we managed to stop
  836. // it successfully
  837. //
  838. bErr = QueryServiceStatus(schService,
  839. &ssStatus);
  840. if(!bErr)
  841. {
  842. dwErr = GetLastError();
  843. Trace2(ERR,
  844. "StartDriver: Error %d querying %s status to see if it is stopped",
  845. dwErr,
  846. pszServiceName);
  847. __leave;
  848. }
  849. if(ssStatus.dwCurrentState is SERVICE_STOPPED)
  850. {
  851. //
  852. // Ok so at this time the service is stopped, lets start the
  853. // service
  854. //
  855. if(!StartService(schService, 0, NULL))
  856. {
  857. dwErr = GetLastError();
  858. Trace2(ERR,
  859. "StartDriver: Error %d starting %s",
  860. dwErr,
  861. pszServiceName);
  862. __leave;
  863. }
  864. //
  865. // Sleep for 1 second to avoid loop
  866. //
  867. Sleep(1000);
  868. ulCount = 0;
  869. //
  870. // We will wait for 30 seconds for the driver to start
  871. //
  872. while(ulCount < 6)
  873. {
  874. bErr = QueryServiceStatus(schService,
  875. &ssStatus);
  876. if(!bErr)
  877. {
  878. dwErr = GetLastError();
  879. break;
  880. }
  881. else
  882. {
  883. if (ssStatus.dwCurrentState is SERVICE_RUNNING)
  884. {
  885. break;
  886. }
  887. else
  888. {
  889. ulCount++;
  890. Sleep(5000);
  891. }
  892. }
  893. }
  894. if(ssStatus.dwCurrentState isnot SERVICE_RUNNING)
  895. {
  896. if(ulCount is 6)
  897. {
  898. dwErr = ERROR_SERVICE_REQUEST_TIMEOUT;
  899. }
  900. Trace2(ERR,
  901. "StartDriver: Error %d starting %s",
  902. dwErr,
  903. pszServiceName);
  904. __leave;
  905. }
  906. }
  907. //
  908. // Now the service is definitely up and running
  909. //
  910. RtlInitUnicodeString(&nameString,
  911. pwszDriverName);
  912. InitializeObjectAttributes(&objectAttributes,
  913. &nameString,
  914. OBJ_CASE_INSENSITIVE,
  915. NULL,
  916. NULL);
  917. status = NtCreateFile(phDevice,
  918. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  919. &objectAttributes,
  920. &ioStatusBlock,
  921. NULL,
  922. FILE_ATTRIBUTE_NORMAL,
  923. FILE_SHARE_READ | FILE_SHARE_WRITE,
  924. FILE_OPEN_IF,
  925. 0,
  926. NULL,
  927. 0);
  928. if(!NT_SUCCESS(status))
  929. {
  930. Trace2(ERR,
  931. "StartDriver: NtStatus %x creating handle to %S",
  932. status,
  933. pwszDriverName);
  934. __leave;
  935. }
  936. bRet = TRUE;
  937. }
  938. __finally
  939. {
  940. CloseServiceHandle(schSCManager);
  941. CloseServiceHandle(schService);
  942. TraceLeave("StartDriver");
  943. }
  944. if(!bRet) {
  945. return ERROR_OPEN_FAILED;
  946. } else {
  947. return NO_ERROR;
  948. }
  949. }
  950. DWORD
  951. OpenIPDriver(
  952. VOID
  953. )
  954. /*++
  955. Routine Description:
  956. Opens a handle to the IP Driver
  957. Arguments
  958. None
  959. Return Value:
  960. NO_ERROR or some error code
  961. --*/
  962. {
  963. NTSTATUS status;
  964. UNICODE_STRING nameString;
  965. IO_STATUS_BLOCK ioStatusBlock;
  966. OBJECT_ATTRIBUTES objectAttributes;
  967. DWORD dwResult = NO_ERROR;
  968. TraceEnter("OpenIPDriver");
  969. do
  970. {
  971. RtlInitUnicodeString(&nameString, DD_IP_DEVICE_NAME);
  972. InitializeObjectAttributes(&objectAttributes, &nameString,
  973. OBJ_CASE_INSENSITIVE, NULL, NULL);
  974. status = NtCreateFile(&g_hIpDevice,
  975. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  976. &objectAttributes,
  977. &ioStatusBlock,
  978. NULL,
  979. FILE_ATTRIBUTE_NORMAL,
  980. FILE_SHARE_READ | FILE_SHARE_WRITE,
  981. FILE_OPEN_IF,
  982. 0,
  983. NULL,
  984. 0);
  985. if(!NT_SUCCESS(status))
  986. {
  987. Trace1(ERR,
  988. "OpenIPDriver: Couldnt create IP driver handle. NtStatus %x",
  989. status);
  990. dwResult = ERROR_OPEN_FAILED;
  991. break;
  992. }
  993. //
  994. // Open change notification handle to TCPIP stack
  995. //
  996. ZeroMemory(&ioStatusBlock, sizeof(IO_STATUS_BLOCK));
  997. #if 1
  998. status = NtCreateFile(
  999. &g_hIpRouteChangeDevice,
  1000. GENERIC_EXECUTE,
  1001. &objectAttributes,
  1002. &ioStatusBlock,
  1003. NULL,
  1004. FILE_ATTRIBUTE_NORMAL,
  1005. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1006. FILE_OPEN_IF,
  1007. 0,
  1008. NULL,
  1009. 0
  1010. );
  1011. #else
  1012. g_hIpRouteChangeDevice = CreateFile(
  1013. TEXT("\\\\.\\Ip"),
  1014. GENERIC_EXECUTE,
  1015. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1016. NULL,
  1017. OPEN_EXISTING,
  1018. FILE_ATTRIBUTE_NORMAL |
  1019. FILE_ATTRIBUTE_OVERLAPPED,
  1020. NULL
  1021. );
  1022. if (g_hIpRouteChangeDevice is NULL)
  1023. #endif
  1024. if (!NT_SUCCESS(status))
  1025. {
  1026. Trace1(
  1027. ERR,
  1028. "OpenIPDriver: Couldnt create change notificatio handle."
  1029. "NtStatus %x",
  1030. status
  1031. );
  1032. dwResult = ERROR_OPEN_FAILED;
  1033. CloseHandle( g_hIpDevice );
  1034. g_hIpDevice = NULL;
  1035. }
  1036. g_IpNotifyData.Version = IPNotifySynchronization;
  1037. g_IpNotifyData.Add = 0;
  1038. } while( FALSE );
  1039. TraceLeave("OpenIPDriver");
  1040. return dwResult;
  1041. }
  1042. DWORD
  1043. OpenMulticastDriver(
  1044. VOID
  1045. )
  1046. {
  1047. NTSTATUS status;
  1048. UNICODE_STRING nameString;
  1049. IO_STATUS_BLOCK ioStatusBlock;
  1050. OBJECT_ATTRIBUTES objectAttributes;
  1051. DWORD i;
  1052. TraceEnter("OpenMulticastDriver");
  1053. RtlInitUnicodeString(&nameString,
  1054. DD_IPMCAST_DEVICE_NAME);
  1055. InitializeObjectAttributes(&objectAttributes,
  1056. &nameString,
  1057. OBJ_CASE_INSENSITIVE,
  1058. NULL,
  1059. NULL);
  1060. status = NtCreateFile(&g_hMcastDevice,
  1061. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  1062. &objectAttributes,
  1063. &ioStatusBlock,
  1064. NULL,
  1065. FILE_ATTRIBUTE_NORMAL,
  1066. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1067. FILE_OPEN_IF,
  1068. 0,
  1069. NULL,
  1070. 0);
  1071. if(status isnot STATUS_SUCCESS)
  1072. {
  1073. Trace2(MCAST,
  1074. "OpenMulticastDriver: Device Name %S could not be opened -> error code %d\n",
  1075. DD_IPMCAST_DEVICE_NAME,
  1076. status);
  1077. g_hMcastDevice = NULL;
  1078. return ERROR_OPEN_FAILED;
  1079. }
  1080. TraceLeave("OpenMulticastDriver");
  1081. return NO_ERROR;
  1082. }
  1083. DWORD
  1084. EnableNetbtBcastForwarding(
  1085. DWORD dwEnable
  1086. )
  1087. /*++
  1088. Routine description:
  1089. Sets the NETBT proxy mode to enable NETBT broadcast forwarding.
  1090. This enables RAS clients to resolve names (and consequently)
  1091. access resources on the networks (LANs) connected to the RAS
  1092. server without having WINS/DNS configured.
  1093. Arguements :
  1094. Return Value :
  1095. NO_ERROR
  1096. --*/
  1097. {
  1098. HKEY hkWanarpAdapter = NULL, hkNetbtParameters = NULL,
  1099. hkNetbtInterface = NULL;
  1100. DWORD dwSize = 0, dwResult, dwType = 0, dwMode = 0, dwFlags;
  1101. PBYTE pbBuffer = NULL;
  1102. PWCHAR pwcGuid;
  1103. WCHAR wszNetbtInterface[256] = L"\0";
  1104. TraceEnter("EnableNetbtBcastForwarding");
  1105. do
  1106. {
  1107. //
  1108. // Step I
  1109. // Query appropriate WANARP regsitry keys to find GUID
  1110. // corresponding to Internal (RAS server adapter)
  1111. //
  1112. dwResult = RegOpenKeyExW(
  1113. HKEY_LOCAL_MACHINE,
  1114. L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\NdisWanIP",
  1115. 0,
  1116. KEY_READ,
  1117. &hkWanarpAdapter
  1118. );
  1119. if (dwResult isnot NO_ERROR)
  1120. {
  1121. Trace1(
  1122. ERR,
  1123. "EnableNetbtBcastForwarding : error %d opening"
  1124. "NdisWanIP key\n",
  1125. dwResult
  1126. );
  1127. break;
  1128. }
  1129. //
  1130. // query size of buffer required.
  1131. //
  1132. dwResult = RegQueryValueExW(
  1133. hkWanarpAdapter,
  1134. L"IpConfig",
  1135. NULL,
  1136. &dwType,
  1137. (PBYTE)NULL,
  1138. &dwSize
  1139. );
  1140. if (dwResult isnot NO_ERROR)
  1141. {
  1142. Trace1(
  1143. ERR,
  1144. "EnableNetbtBcastForwarding : error %d querying"
  1145. "IPConfig value\n",
  1146. dwResult
  1147. );
  1148. break;
  1149. }
  1150. //
  1151. // Allocate buffer for value
  1152. //
  1153. pbBuffer = (PBYTE) HeapAlloc(
  1154. GetProcessHeap(),
  1155. 0,
  1156. dwSize
  1157. );
  1158. if ( pbBuffer == NULL )
  1159. {
  1160. dwResult = GetLastError();
  1161. Trace2(
  1162. ERR,
  1163. "EnableNetbtBcastForwarding : error %d allocating buffer of"
  1164. "size %d for IPConfig value",
  1165. dwResult, dwSize
  1166. );
  1167. break;
  1168. }
  1169. //
  1170. // query registry value of IPConfig
  1171. //
  1172. dwResult = RegQueryValueExW(
  1173. hkWanarpAdapter,
  1174. L"IpConfig",
  1175. NULL,
  1176. &dwType,
  1177. (PBYTE)pbBuffer,
  1178. &dwSize
  1179. );
  1180. if ( (dwResult isnot NO_ERROR) || (dwType != REG_MULTI_SZ) )
  1181. {
  1182. Trace1(
  1183. ERR,
  1184. "EnableNetbtBcastForwarding : error %d querying"
  1185. "IPConfig value\n",
  1186. dwResult
  1187. );
  1188. break;
  1189. }
  1190. //
  1191. // Extract the GUID of the Internal (RAS Server) adapter
  1192. //
  1193. pwcGuid = wcschr( (PWCHAR)pbBuffer, '{' );
  1194. Trace1(
  1195. INIT, "Internal adapter GUID is %lS",
  1196. pwcGuid
  1197. );
  1198. //
  1199. // Step II
  1200. //
  1201. // Save the old setting for NETBT PROXY mode. This will be restored
  1202. // when the RRAS server is stopped. and set the new PROXY mode
  1203. //
  1204. //
  1205. // open NETBT Key
  1206. //
  1207. dwResult = RegOpenKeyExW(
  1208. HKEY_LOCAL_MACHINE,
  1209. L"System\\CurrentControlSet\\Services\\Netbt\\Parameters",
  1210. 0,
  1211. KEY_READ | KEY_WRITE,
  1212. &hkNetbtParameters
  1213. );
  1214. if (dwResult isnot NO_ERROR)
  1215. {
  1216. Trace1(
  1217. ERR,
  1218. "EnableNetbtBcastForwarding : error %d opening"
  1219. "Netbt\\Parameters key\n",
  1220. dwResult
  1221. );
  1222. break;
  1223. }
  1224. //
  1225. // query EnableProxy mode
  1226. //
  1227. dwSize = sizeof( DWORD );
  1228. dwMode = 0;
  1229. dwResult = RegQueryValueExW(
  1230. hkNetbtParameters,
  1231. L"EnableProxy",
  1232. NULL,
  1233. &dwType,
  1234. (PBYTE)&dwMode,
  1235. &dwSize
  1236. );
  1237. if (dwResult isnot NO_ERROR)
  1238. {
  1239. //
  1240. // It is possible the key is not present esp. if this
  1241. // is the first time you are running RRAS or if the
  1242. // key has been manually deleted
  1243. // In this case assume proxy is set to 0 (disabled)
  1244. //
  1245. g_dwOldNetbtProxyMode = 0;
  1246. }
  1247. else
  1248. {
  1249. g_dwOldNetbtProxyMode = dwMode;
  1250. }
  1251. Trace1(
  1252. INIT,
  1253. "Netbt Proxy mode in registry is %d",
  1254. dwMode
  1255. );
  1256. //
  1257. // Set the NETBT proxy mode to enable/disable broadcast forwarding
  1258. //
  1259. //
  1260. // if NETBT broadcast fwdg is disabled, make sure
  1261. // the the EnableProxy setting matches that
  1262. //
  1263. if ( dwEnable == 0 )
  1264. {
  1265. //
  1266. // Netbt broadcast fwd'g is disabled
  1267. //
  1268. if ( dwMode == 2 )
  1269. {
  1270. //
  1271. // But the registry setting does not reflect this
  1272. //
  1273. g_dwOldNetbtProxyMode = 0;
  1274. dwMode = 0;
  1275. Trace1(
  1276. INIT,
  1277. "Forcing Netbt Proxy mode to be %d",
  1278. g_dwOldNetbtProxyMode
  1279. );
  1280. }
  1281. }
  1282. else
  1283. {
  1284. //
  1285. // Note: Need a #define value for netbt proxy mode
  1286. //
  1287. dwMode = 2;
  1288. }
  1289. Trace2(
  1290. INIT,
  1291. "Old Netbt Proxy mode is %d, New Nebt Proxy Mode is %d",
  1292. g_dwOldNetbtProxyMode, dwMode
  1293. );
  1294. dwResult = RegSetValueExW(
  1295. hkNetbtParameters,
  1296. L"EnableProxy",
  1297. 0,
  1298. REG_DWORD,
  1299. (PBYTE) &dwMode,
  1300. dwSize
  1301. );
  1302. if ( dwResult != NO_ERROR )
  1303. {
  1304. Trace1(
  1305. ERR,
  1306. "EnableNetbtBcastForwarding : error %d setting"
  1307. "EnableProxy value\n",
  1308. dwResult
  1309. );
  1310. break;
  1311. }
  1312. //
  1313. // Step III:
  1314. //
  1315. // Check for RASFlags under NETBT_TCPIP_{RAS_SERVER_GUID} key
  1316. //
  1317. //
  1318. // Open interface key under NETBT
  1319. //
  1320. wcscpy(
  1321. wszNetbtInterface,
  1322. L"System\\CurrentControlSet\\Services\\Netbt\\Parameters\\Interfaces\\Tcpip_"
  1323. );
  1324. wcscat(
  1325. wszNetbtInterface,
  1326. pwcGuid
  1327. );
  1328. dwResult = RegOpenKeyExW(
  1329. HKEY_LOCAL_MACHINE,
  1330. wszNetbtInterface,
  1331. 0,
  1332. KEY_READ | KEY_WRITE,
  1333. &hkNetbtInterface
  1334. );
  1335. if (dwResult isnot NO_ERROR)
  1336. {
  1337. Trace2(
  1338. ERR,
  1339. "EnableNetbtBcastForwarding : error %d opening"
  1340. "%ls key\n",
  1341. dwResult, wszNetbtInterface
  1342. );
  1343. break;
  1344. }
  1345. //
  1346. // query RASFlags value
  1347. //
  1348. // If present
  1349. // leave as is.
  1350. // else
  1351. // create and set it to 0x00000001 to disable NETBT
  1352. // broadcasts on WAN.
  1353. //
  1354. dwFlags = 0;
  1355. dwResult = RegQueryValueExW(
  1356. hkNetbtInterface,
  1357. L"RASFlags",
  1358. NULL,
  1359. &dwType,
  1360. (PBYTE)&dwFlags,
  1361. &dwSize
  1362. );
  1363. if (dwResult isnot NO_ERROR)
  1364. {
  1365. //
  1366. // It is possible the key is not present esp. if this
  1367. // is the first time you are running RRAS or if the
  1368. // key has been manually deleted
  1369. // In this case set RASFlags to 1 (default behavior).
  1370. //
  1371. dwFlags = 1;
  1372. dwResult = RegSetValueExW(
  1373. hkNetbtInterface,
  1374. L"RASFlags",
  1375. 0,
  1376. REG_DWORD,
  1377. (PBYTE) &dwFlags,
  1378. sizeof( DWORD )
  1379. );
  1380. if ( dwResult != NO_ERROR )
  1381. {
  1382. Trace1(
  1383. ERR,
  1384. "error %d setting RASFlags",
  1385. dwResult
  1386. );
  1387. }
  1388. }
  1389. else
  1390. {
  1391. //
  1392. // RASFlags value is already present. leave it as is.
  1393. //
  1394. Trace1(
  1395. INIT,
  1396. "RASFlags already present with value %d",
  1397. dwFlags
  1398. );
  1399. }
  1400. //
  1401. // Close NETBT keys. Doing so to avoid any contention issues
  1402. // with the NETBT.SYS driver trying to read them in the following
  1403. // function
  1404. //
  1405. RegCloseKey( hkNetbtParameters );
  1406. hkNetbtParameters = NULL;
  1407. RegCloseKey( hkNetbtInterface );
  1408. hkNetbtInterface = NULL;
  1409. dwResult = ForceNetbtRegistryRead();
  1410. } while (FALSE);
  1411. if ( hkWanarpAdapter )
  1412. {
  1413. RegCloseKey( hkWanarpAdapter );
  1414. }
  1415. if ( hkNetbtParameters )
  1416. {
  1417. RegCloseKey( hkNetbtParameters );
  1418. }
  1419. if ( hkNetbtInterface )
  1420. {
  1421. RegCloseKey( hkNetbtInterface );
  1422. }
  1423. if ( pbBuffer )
  1424. {
  1425. HeapFree( GetProcessHeap(), 0, pbBuffer );
  1426. }
  1427. TraceLeave("EnableNetbtBcastForwarding");
  1428. return dwResult;
  1429. }
  1430. DWORD
  1431. RestoreNetbtBcastForwardingMode(
  1432. VOID
  1433. )
  1434. /*++
  1435. Routine description:
  1436. Return the NETBT proxy mode setting to its original setting
  1437. Arguements :
  1438. Return Value :
  1439. --*/
  1440. {
  1441. DWORD dwResult, dwSize = 0;
  1442. HKEY hkNetbtParameters = NULL;
  1443. TraceEnter("RestoreNetbtBcastForwardingMode");
  1444. do
  1445. {
  1446. //
  1447. // open NETBT Key
  1448. //
  1449. dwResult = RegOpenKeyExW(
  1450. HKEY_LOCAL_MACHINE,
  1451. L"System\\CurrentControlSet\\Services\\Netbt\\Parameters",
  1452. 0,
  1453. KEY_READ | KEY_WRITE,
  1454. &hkNetbtParameters
  1455. );
  1456. if (dwResult isnot NO_ERROR)
  1457. {
  1458. Trace1(
  1459. ERR,
  1460. "EnableNetbtBcastForwarding : error %d opening"
  1461. "Netbt\\Parameters key\n",
  1462. dwResult
  1463. );
  1464. break;
  1465. }
  1466. //
  1467. // restore EnableProxy mode
  1468. //
  1469. dwSize = sizeof( DWORD );
  1470. dwResult = RegSetValueExW(
  1471. hkNetbtParameters,
  1472. L"EnableProxy",
  1473. 0,
  1474. REG_DWORD,
  1475. (PBYTE) &g_dwOldNetbtProxyMode,
  1476. dwSize
  1477. );
  1478. if ( dwResult != NO_ERROR )
  1479. {
  1480. Trace1(
  1481. ERR,
  1482. "EnableNetbtBcastForwarding : error %d setting"
  1483. "EnableProxy value\n",
  1484. dwResult
  1485. );
  1486. break;
  1487. }
  1488. dwResult = ForceNetbtRegistryRead();
  1489. } while (FALSE);
  1490. TraceLeave("RestoreNetbtBcastForwardingMode");
  1491. return dwResult;
  1492. }
  1493. DWORD
  1494. ForceNetbtRegistryRead(
  1495. VOID
  1496. )
  1497. /*++
  1498. Routine description:
  1499. Issue IOCTL to NETBT to re-read its registry setting.
  1500. Arguements :
  1501. Return Value :
  1502. --*/
  1503. {
  1504. DWORD dwErr = NO_ERROR;
  1505. NTSTATUS status;
  1506. UNICODE_STRING nameString;
  1507. IO_STATUS_BLOCK ioStatusBlock;
  1508. OBJECT_ATTRIBUTES objectAttributes;
  1509. HANDLE hNetbtDevice = NULL;
  1510. TraceEnter("ForceNetbtRegistryRead");
  1511. do
  1512. {
  1513. //
  1514. // Step I:
  1515. //
  1516. // Open NETBT driver
  1517. //
  1518. RtlInitUnicodeString(
  1519. &nameString,
  1520. L"\\Device\\NetbiosSmb"
  1521. );
  1522. InitializeObjectAttributes(
  1523. &objectAttributes,
  1524. &nameString,
  1525. OBJ_CASE_INSENSITIVE,
  1526. NULL,
  1527. NULL
  1528. );
  1529. status = NtCreateFile(
  1530. &hNetbtDevice,
  1531. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  1532. &objectAttributes,
  1533. &ioStatusBlock,
  1534. NULL,
  1535. FILE_ATTRIBUTE_NORMAL,
  1536. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1537. FILE_OPEN_IF,
  1538. 0,
  1539. NULL,
  1540. 0
  1541. );
  1542. if (!NT_SUCCESS(status))
  1543. {
  1544. Trace1(
  1545. ERR,
  1546. "ForceNetbtRegistryRead: Couldnt create NETBT driver handle. NtStatus %x",
  1547. status
  1548. );
  1549. dwErr = ERROR_OPEN_FAILED;
  1550. break;
  1551. }
  1552. //
  1553. // Issue IOCTL to re-read registry
  1554. //
  1555. status = NtDeviceIoControlFile(
  1556. hNetbtDevice,
  1557. NULL,
  1558. NULL,
  1559. NULL,
  1560. &ioStatusBlock,
  1561. IOCTL_NETBT_REREAD_REGISTRY,
  1562. NULL,
  1563. 0,
  1564. NULL,
  1565. 0
  1566. );
  1567. if (!NT_SUCCESS(status))
  1568. {
  1569. Trace1(
  1570. ERR,
  1571. "ForceNetbtRegistryRead: Failed IOCTL call to NETBT, status %x",
  1572. status
  1573. );
  1574. dwErr = ERROR_UNKNOWN;
  1575. break;
  1576. }
  1577. } while ( FALSE );
  1578. //
  1579. // Close NETBT driver
  1580. //
  1581. CloseHandle( hNetbtDevice );
  1582. TraceLeave("ForceNetbtRegistryRead");
  1583. return dwErr;
  1584. }
  1585. DWORD
  1586. InitializeMibHandler(
  1587. VOID
  1588. )
  1589. /*++
  1590. Routine Description:
  1591. Initalizes the heaps and Locks needed by the MIB handling code
  1592. Arguments:
  1593. None
  1594. Return Value:
  1595. NO_ERROR or some error code
  1596. --*/
  1597. {
  1598. DWORD i,dwResult, dwIpIfSize, dwMibSize;
  1599. BOOL fUpdate;
  1600. TraceEnter("InitializeMibHandler");
  1601. //
  1602. // Assert the size of MIB to stack mappings for which direct copy is
  1603. // being done
  1604. //
  1605. dwIpIfSize = IFE_FIXED_SIZE + MAX_IFDESCR_LEN;
  1606. dwMibSize = sizeof(MIB_IFROW) - FIELD_OFFSET(MIB_IFROW, dwIndex);
  1607. IpRtAssert(dwIpIfSize is dwMibSize);
  1608. IpRtAssert(sizeof(MIB_ICMP) is sizeof(ICMPSNMPInfo));
  1609. IpRtAssert(sizeof(MIB_UDPSTATS) is sizeof(UDPStats));
  1610. IpRtAssert(sizeof(MIB_UDPROW) is sizeof(UDPEntry));
  1611. IpRtAssert(sizeof(MIB_TCPSTATS) is sizeof(TCPStats));
  1612. IpRtAssert(sizeof(MIB_TCPROW) is sizeof(TCPConnTableEntry));
  1613. IpRtAssert(sizeof(MIB_IPSTATS) is sizeof(IPSNMPInfo));
  1614. IpRtAssert(sizeof(MIB_IPADDRROW) is sizeof(IPAddrEntry));
  1615. IpRtAssert(sizeof(MIB_IPNETROW) is sizeof(IPNetToMediaEntry));
  1616. g_dwStartTime = GetCurrentTime();
  1617. __try
  1618. {
  1619. //
  1620. // We dont initialize the locks since we do it in one shot at the
  1621. // beginning of StartRouter
  1622. //
  1623. //
  1624. // Now Create the heaps. Since only writers Alloc from the heap we
  1625. // are already guaranteed serialization, so lets not ask for it again
  1626. // Let all initial size be 1K, this doesnt really cost any thing
  1627. // since the memory is not committed
  1628. // We will just allocate a minimum size for the cache tables so
  1629. // that the startup doesnt barf
  1630. //
  1631. #define INIT_TABLE_SIZE 10
  1632. g_hIfHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
  1633. if(g_hIfHeap is NULL)
  1634. {
  1635. dwResult = GetLastError();
  1636. Trace1(ERR,
  1637. "InitializeMibHandler: Couldnt allocate IF Heap. Error %d",
  1638. dwResult);
  1639. __leave;
  1640. }
  1641. g_hUdpHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
  1642. if(g_hUdpHeap is NULL)
  1643. {
  1644. dwResult = GetLastError();
  1645. Trace1(ERR,
  1646. "InitializeMibHandler: Couldnt allocate UDP Heap. Error %d",
  1647. dwResult);
  1648. __leave;
  1649. }
  1650. g_UdpInfo.pUdpTable = HeapAlloc(g_hUdpHeap,
  1651. HEAP_NO_SERIALIZE,
  1652. SIZEOF_UDPTABLE(INIT_TABLE_SIZE));
  1653. if(g_UdpInfo.pUdpTable is NULL)
  1654. {
  1655. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1656. Trace0(ERR,
  1657. "InitializeMibHandler: Couldnt allocate UDP table");
  1658. __leave;
  1659. }
  1660. g_UdpInfo.dwTotalEntries = INIT_TABLE_SIZE;
  1661. g_hTcpHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
  1662. if(g_hTcpHeap is NULL)
  1663. {
  1664. dwResult = GetLastError();
  1665. Trace1(ERR,
  1666. "InitializeMibHandler: Couldnt allocate TCP Heap. Error %d",
  1667. dwResult);
  1668. __leave;
  1669. }
  1670. g_TcpInfo.pTcpTable = HeapAlloc(g_hTcpHeap,
  1671. HEAP_NO_SERIALIZE,
  1672. SIZEOF_TCPTABLE(INIT_TABLE_SIZE));
  1673. if(g_TcpInfo.pTcpTable is NULL)
  1674. {
  1675. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1676. Trace0(ERR,
  1677. "InitializeMibHandler: Couldnt allocate TCP table");
  1678. __leave;
  1679. }
  1680. g_TcpInfo.dwTotalEntries = INIT_TABLE_SIZE;
  1681. g_hIpAddrHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
  1682. if(g_hIpAddrHeap is NULL)
  1683. {
  1684. dwResult = GetLastError();
  1685. Trace1(ERR,
  1686. "InitializeMibHandler: Couldnt allocate IP Addr Heap. Error %d",
  1687. dwResult);
  1688. __leave;
  1689. }
  1690. g_IpInfo.pAddrTable = HeapAlloc(g_hIpAddrHeap,
  1691. HEAP_NO_SERIALIZE,
  1692. SIZEOF_IPADDRTABLE(INIT_TABLE_SIZE));
  1693. if(g_IpInfo.pAddrTable is NULL)
  1694. {
  1695. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1696. Trace0(ERR,
  1697. "InitializeMibHandler: Couldnt allocate IP Addr table.");
  1698. __leave;
  1699. }
  1700. g_IpInfo.dwTotalAddrEntries = INIT_TABLE_SIZE;
  1701. g_hIpForwardHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
  1702. if(g_hIpForwardHeap is NULL)
  1703. {
  1704. dwResult = GetLastError();
  1705. Trace1(ERR,
  1706. "InitializeMibHandler: Couldnt allocate IP Forward Heap. Error %d",
  1707. dwResult);
  1708. __leave;
  1709. }
  1710. g_IpInfo.pForwardTable = HeapAlloc(g_hIpForwardHeap,
  1711. HEAP_NO_SERIALIZE,
  1712. SIZEOF_IPFORWARDTABLE(INIT_TABLE_SIZE));
  1713. if(g_IpInfo.pForwardTable is NULL)
  1714. {
  1715. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1716. Trace0(ERR,
  1717. "InitializeMibHandler: Couldnt allocate IP Forward table");
  1718. __leave;
  1719. }
  1720. g_IpInfo.dwTotalForwardEntries = INIT_TABLE_SIZE;
  1721. g_hIpNetHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
  1722. if(g_hIpNetHeap is NULL)
  1723. {
  1724. dwResult = GetLastError();
  1725. Trace1(ERR,
  1726. "InitializeMibHandler: Couldnt allocate IP Net Heap. Error %d",
  1727. dwResult);
  1728. __leave;
  1729. }
  1730. g_IpInfo.pNetTable = HeapAlloc(g_hIpNetHeap,
  1731. HEAP_NO_SERIALIZE,
  1732. SIZEOF_IPNETTABLE(INIT_TABLE_SIZE));
  1733. if(g_IpInfo.pNetTable is NULL)
  1734. {
  1735. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1736. Trace0(ERR,
  1737. "InitializeMibHandler: Couldnt allocate IP Net table");
  1738. __leave;
  1739. }
  1740. g_IpInfo.dwTotalNetEntries = INIT_TABLE_SIZE;
  1741. //
  1742. // Now set up the caches
  1743. //
  1744. for(i = 0; i < NUM_CACHE; i++)
  1745. {
  1746. g_LastUpdateTable[i] = 0;
  1747. if(UpdateCache(i,&fUpdate) isnot NO_ERROR)
  1748. {
  1749. Trace1(ERR,
  1750. "InitializeMibHandler: Couldnt update %s Cache",
  1751. CacheToA(i));
  1752. //__leave;
  1753. }
  1754. }
  1755. dwResult = NO_ERROR;
  1756. }
  1757. __finally
  1758. {
  1759. TraceLeave("InitializeMibHandler");
  1760. }
  1761. return dwResult;
  1762. }