Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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