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.

1365 lines
27 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. rmnat.c
  5. Abstract:
  6. This module contains routines for the NAT module's interface
  7. to the IP router-manager. (See ROUTPROT.H for details).
  8. Author:
  9. Abolade Gbadegesin (aboladeg) 4-Mar-1998
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. COMPONENT_REFERENCE NatComponentReference;
  15. PIP_NAT_GLOBAL_INFO NatGlobalInfo = NULL;
  16. CRITICAL_SECTION NatGlobalInfoLock;
  17. HANDLE NatNotificationEvent;
  18. ULONG NatProtocolStopped = 0;
  19. const MPR_ROUTING_CHARACTERISTICS NatRoutingCharacteristics =
  20. {
  21. MS_ROUTER_VERSION,
  22. MS_IP_NAT,
  23. RF_ROUTING,
  24. NatRmStartProtocol,
  25. NatRmStartComplete,
  26. NatRmStopProtocol,
  27. NatRmGetGlobalInfo,
  28. NatRmSetGlobalInfo,
  29. NULL,
  30. NULL,
  31. NatRmAddInterface,
  32. NatRmDeleteInterface,
  33. NatRmInterfaceStatus,
  34. NatRmGetInterfaceInfo,
  35. NatRmSetInterfaceInfo,
  36. NatRmGetEventMessage,
  37. NULL,
  38. NatRmConnectClient,
  39. NatRmDisconnectClient,
  40. NULL,
  41. NULL,
  42. NatRmMibCreate,
  43. NatRmMibDelete,
  44. NatRmMibGet,
  45. NatRmMibSet,
  46. NatRmMibGetFirst,
  47. NatRmMibGetNext,
  48. NULL,
  49. NULL
  50. };
  51. SUPPORT_FUNCTIONS NatSupportFunctions;
  52. //
  53. // FORWARD DECLARATIONS
  54. //
  55. VOID
  56. NatCleanupModule(
  57. VOID
  58. )
  59. /*++
  60. Routine Description:
  61. This routine is invoked to cleanup the NAT module.
  62. Arguments:
  63. none.
  64. Return Value:
  65. none.
  66. Environment:
  67. Invoked from within a 'DllMain' routine on 'DLL_PROCESS_DETACH'.
  68. --*/
  69. {
  70. DeleteCriticalSection(&NatInterfaceLock);
  71. DeleteCriticalSection(&NatGlobalInfoLock);
  72. DeleteComponentReference(&NatComponentReference);
  73. } // NatCleanupModule
  74. VOID
  75. NatCleanupProtocol(
  76. VOID
  77. )
  78. /*++
  79. Routine Description:
  80. This routine is invoked to cleanup the NAT protocol-component
  81. after a 'StopProtocol'.
  82. Arguments:
  83. none.
  84. Return Value:
  85. none.
  86. Environment:
  87. Invoked from within an arbitrary context with no locks held.
  88. --*/
  89. {
  90. PROFILE("NatCleanupProtocol");
  91. //
  92. // Stop the NAT driver.
  93. //
  94. NatUnloadDriver(NULL);
  95. if (NatGlobalInfo) { NH_FREE(NatGlobalInfo); NatGlobalInfo = NULL; }
  96. //
  97. // Notify the router-manager.
  98. //
  99. InterlockedExchange(reinterpret_cast<LPLONG>(&NatProtocolStopped), 1);
  100. SetEvent(NatNotificationEvent);
  101. //
  102. // Reset the component reference
  103. //
  104. ResetComponentReference(&NatComponentReference);
  105. //
  106. // Return the component to the uninitialized mode,
  107. // whatever the original mode might have been.
  108. //
  109. NhResetComponentMode();
  110. //
  111. // Free up HNetCfgMgr pointers
  112. //
  113. if (NULL != NhGITp)
  114. {
  115. HRESULT hr;
  116. BOOLEAN ComInitialized = FALSE;
  117. //
  118. // Make sure COM is initialized
  119. //
  120. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE );
  121. if (SUCCEEDED(hr))
  122. {
  123. ComInitialized = TRUE;
  124. }
  125. else if (RPC_E_CHANGED_MODE == hr)
  126. {
  127. hr = S_OK;
  128. }
  129. if (SUCCEEDED(hr))
  130. {
  131. //
  132. // Release the CfgMgr from the GIT
  133. //
  134. NhGITp->RevokeInterfaceFromGlobal(NhCfgMgrCookie);
  135. NhCfgMgrCookie = 0;
  136. //
  137. // Release the GIT
  138. //
  139. NhGITp->Release();
  140. NhGITp = NULL;
  141. }
  142. if (TRUE == ComInitialized)
  143. {
  144. CoUninitialize();
  145. }
  146. }
  147. //
  148. // Remove our reference, if any, to IPRTRMGR.DLL
  149. //
  150. EnterCriticalSection(&NhLock);
  151. if (NhpRtrmgrDll) {
  152. FreeLibrary(NhpRtrmgrDll);
  153. NhpRtrmgrDll = NULL;
  154. }
  155. LeaveCriticalSection(&NhLock);
  156. NhStopEventLog();
  157. } // NatCleanupProtocol
  158. BOOLEAN
  159. NatInitializeModule(
  160. VOID
  161. )
  162. /*++
  163. Routine Description:
  164. This routine is invoked to initialize the NAT module.
  165. Arguments:
  166. none.
  167. Return Value:
  168. BOOLEAN - TRUE if initialization succeeded, FALSE otherwise
  169. Environment:
  170. Invoked in the context of a 'DllMain' routine on 'DLL_PROCESS_ATTACH'.
  171. --*/
  172. {
  173. InitializeListHead(&NatInterfaceList);
  174. if (InitializeComponentReference(
  175. &NatComponentReference, NatCleanupProtocol
  176. )) {
  177. return FALSE;
  178. }
  179. __try {
  180. InitializeCriticalSection(&NatGlobalInfoLock);
  181. }
  182. __except(EXCEPTION_EXECUTE_HANDLER) {
  183. DeleteComponentReference(&NatComponentReference);
  184. return FALSE;
  185. }
  186. __try {
  187. InitializeCriticalSection(&NatInterfaceLock);
  188. }
  189. __except (EXCEPTION_EXECUTE_HANDLER) {
  190. DeleteCriticalSection(&NatGlobalInfoLock);
  191. DeleteComponentReference(&NatComponentReference);
  192. return FALSE;
  193. }
  194. ZeroMemory(&NatSupportFunctions, sizeof(NatSupportFunctions));
  195. return TRUE;
  196. } // NatInitializeModule
  197. ULONG
  198. APIENTRY
  199. NatRmStartProtocol(
  200. HANDLE NotificationEvent,
  201. PSUPPORT_FUNCTIONS SupportFunctions,
  202. PVOID GlobalInfo,
  203. ULONG StructureVersion,
  204. ULONG StructureSize,
  205. ULONG StructureCount
  206. )
  207. /*++
  208. Routine Description:
  209. This routine is invoked to indicate the component's operation should begin.
  210. Arguments:
  211. NotificationEvent - event on which we notify the router-manager
  212. about asynchronous occurrences
  213. SupportFunctions - functions for initiating router-related operations
  214. GlobalInfo - configuration for the component
  215. Return Value:
  216. ULONG - Win32 status code.
  217. Environment:
  218. The routine runs in the context of an IP router-manager thread.
  219. --*/
  220. {
  221. ULONG Error = NO_ERROR;
  222. ULONG Size;
  223. PROFILE("NatRmStartProtocol");
  224. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  225. if (!GlobalInfo) { DEREFERENCE_NAT_AND_RETURN(ERROR_INVALID_PARAMETER); }
  226. NhStartEventLog();
  227. do {
  228. //
  229. // Copy the global configuration
  230. //
  231. EnterCriticalSection(&NatGlobalInfoLock);
  232. Size =
  233. FIELD_OFFSET(IP_NAT_GLOBAL_INFO, Header) +
  234. ((PIP_NAT_GLOBAL_INFO)GlobalInfo)->Header.Size;
  235. NatGlobalInfo = reinterpret_cast<PIP_NAT_GLOBAL_INFO>(NH_ALLOCATE(Size));
  236. if (!NatGlobalInfo) {
  237. LeaveCriticalSection(&NatGlobalInfoLock);
  238. NhTrace(
  239. TRACE_FLAG_INIT,
  240. "NatRmStartProtocol: cannot allocate global info"
  241. );
  242. NhErrorLog(
  243. IP_NAT_LOG_ALLOCATION_FAILED,
  244. 0,
  245. "%d",
  246. Size
  247. );
  248. Error = ERROR_NOT_ENOUGH_MEMORY;
  249. break;
  250. }
  251. CopyMemory(NatGlobalInfo, GlobalInfo, Size);
  252. LeaveCriticalSection(&NatGlobalInfoLock);
  253. //
  254. // Save the notification event and the support functions
  255. //
  256. NatNotificationEvent = NotificationEvent;
  257. EnterCriticalSection(&NatInterfaceLock);
  258. if (!SupportFunctions) {
  259. ZeroMemory(&NatSupportFunctions, sizeof(NatSupportFunctions));
  260. } else {
  261. CopyMemory(
  262. &NatSupportFunctions,
  263. SupportFunctions,
  264. sizeof(*SupportFunctions)
  265. );
  266. }
  267. LeaveCriticalSection(&NatInterfaceLock);
  268. //
  269. // Attempt to load and start the NAT driver.
  270. //
  271. Error = NatLoadDriver(
  272. &NatFileHandle,
  273. reinterpret_cast<PIP_NAT_GLOBAL_INFO>(GlobalInfo)
  274. );
  275. NhUpdateApplicationSettings();
  276. NatInstallApplicationSettings();
  277. InterlockedExchange(reinterpret_cast<LPLONG>(&NatProtocolStopped), 0);
  278. } while (FALSE);
  279. if (NO_ERROR != Error) {
  280. NhStopEventLog();
  281. }
  282. DEREFERENCE_NAT_AND_RETURN(Error);
  283. } // NatRmStartProtocol
  284. ULONG
  285. APIENTRY
  286. NatRmStartComplete(
  287. VOID
  288. )
  289. /*++
  290. Routine Description:
  291. This routine is invoked when the router has finished adding the initial
  292. configuration
  293. Arguments:
  294. none.
  295. Return Value:
  296. ULONG - Win32 status code
  297. Environment:
  298. The routine runs in the context of an IP router-manager thread.
  299. --*/
  300. {
  301. return NO_ERROR;
  302. } // NatRmStartComplete
  303. ULONG
  304. APIENTRY
  305. NatRmStopProtocol(
  306. VOID
  307. )
  308. /*++
  309. Routine Description:
  310. This routine is invoked to stop the protocol.
  311. Arguments:
  312. none.
  313. Return Value:
  314. ULONG - Win32 status code
  315. Environment:
  316. The routine runs in the context of an IP router-manager thread.
  317. --*/
  318. {
  319. PLIST_ENTRY Link;
  320. PNAT_APP_ENTRY pAppEntry;
  321. //
  322. // Reference the module to make sure it's running
  323. //
  324. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  325. NatStopConnectionManagement();
  326. EnterCriticalSection(&NhLock);
  327. //
  328. // Free application list
  329. //
  330. NhFreeApplicationSettings();
  331. LeaveCriticalSection(&NhLock);
  332. //
  333. // Close our handle to the driver, thus cancelling all outstanding I/O.
  334. //
  335. EnterCriticalSection(&NatInterfaceLock);
  336. NtClose(NatFileHandle);
  337. NatFileHandle = NULL;
  338. LeaveCriticalSection(&NatInterfaceLock);
  339. //
  340. // Drop the initial reference to cause a cleanup
  341. //
  342. ReleaseInitialComponentReference(&NatComponentReference);
  343. return DEREFERENCE_NAT() ? NO_ERROR : ERROR_PROTOCOL_STOP_PENDING;
  344. } // NatRmStopProtocol
  345. ULONG
  346. APIENTRY
  347. NatRmAddInterface(
  348. PWCHAR Name,
  349. ULONG Index,
  350. NET_INTERFACE_TYPE Type,
  351. ULONG MediaType,
  352. USHORT AccessType,
  353. USHORT ConnectionType,
  354. PVOID InterfaceInfo,
  355. ULONG StructureVersion,
  356. ULONG StructureSize,
  357. ULONG StructureCount
  358. )
  359. /*++
  360. Routine Description:
  361. This routine is invoked to add an interface to the component.
  362. Arguments:
  363. Name - the name of the interface (unused)
  364. Index - the index of the interface
  365. Type - the type of the interface
  366. InterfaceInfo - the configuration information for the interface
  367. Return Value:
  368. ULONG - Win32 status code.
  369. Environment:
  370. The routine runs in the context of an IP router-manager thread.
  371. --*/
  372. {
  373. ULONG Error;
  374. PROFILE("NatRmAddInterface");
  375. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  376. Error =
  377. NatCreateInterface(
  378. Index,
  379. Type,
  380. (PIP_NAT_INTERFACE_INFO)InterfaceInfo
  381. );
  382. DEREFERENCE_NAT_AND_RETURN(Error);
  383. } // NatRmAddInterface
  384. ULONG
  385. APIENTRY
  386. NatRmDeleteInterface(
  387. ULONG Index
  388. )
  389. /*++
  390. Routine Description:
  391. This routine is invoked to delete an interface from the component.
  392. Arguments:
  393. Index - the index of the interface
  394. Return Value:
  395. ULONG - Win32 status code
  396. Environment:
  397. The routine runs in the context of an IP router-manager thread.
  398. --*/
  399. {
  400. ULONG Error;
  401. PROFILE("NatRmDeleteInterface");
  402. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  403. Error =
  404. NatDeleteInterface(
  405. Index
  406. );
  407. DEREFERENCE_NAT_AND_RETURN(Error);
  408. } // NatRmDeleteInterface
  409. ULONG
  410. APIENTRY
  411. NatRmGetEventMessage(
  412. OUT ROUTING_PROTOCOL_EVENTS* Event,
  413. OUT MESSAGE* Result
  414. )
  415. /*++
  416. Routine Description:
  417. This routine is invoked to retrieve an event message from the component.
  418. The only event message we generate is the 'ROUTER_STOPPED' message.
  419. Arguments:
  420. Event - receives the generated event
  421. Result - receives the associated result
  422. Return Value:
  423. ULONG - Win32 status code.
  424. --*/
  425. {
  426. PROFILE("NatRmGetEventMessage");
  427. if (InterlockedExchange(reinterpret_cast<LPLONG>(&NatProtocolStopped), 0)) {
  428. *Event = ROUTER_STOPPED;
  429. return NO_ERROR;
  430. }
  431. return ERROR_NO_MORE_ITEMS;
  432. } // NatRmGetEventMessage
  433. ULONG
  434. APIENTRY
  435. NatRmGetInterfaceInfo(
  436. ULONG Index,
  437. PVOID InterfaceInfo,
  438. IN OUT PULONG InterfaceInfoSize,
  439. IN OUT PULONG StructureVersion,
  440. IN OUT PULONG StructureSize,
  441. IN OUT PULONG StructureCount
  442. )
  443. /*++
  444. Routine Description:
  445. This routine is invoked to retrieve the component's per-interface
  446. configuration.
  447. Arguments:
  448. Index - the index of the interface to be queried
  449. InterfaceInfo - receives the query results
  450. InterfaceInfoSize - receives the amount of data retrieved
  451. Return Value:
  452. ULONG - Win32 status code.
  453. --*/
  454. {
  455. ULONG Error;
  456. PROFILE("NatRmGetInterfaceInfo");
  457. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  458. Error =
  459. NatQueryInterface(
  460. Index,
  461. (PIP_NAT_INTERFACE_INFO)InterfaceInfo,
  462. InterfaceInfoSize
  463. );
  464. *StructureSize = *InterfaceInfoSize;
  465. if (StructureCount) {*StructureCount = 1;}
  466. DEREFERENCE_NAT_AND_RETURN(Error);
  467. } // NatRmGetInterfaceInfo
  468. ULONG
  469. APIENTRY
  470. NatRmSetInterfaceInfo(
  471. ULONG Index,
  472. PVOID InterfaceInfo,
  473. ULONG StructureVersion,
  474. ULONG StructureSize,
  475. ULONG StructureCount
  476. )
  477. /*++
  478. Routine Description:
  479. This routine is invoked to change the component's per-interface
  480. configuration.
  481. Arguments:
  482. Index - the index of the interface to be updated
  483. InterfaceInfo - supplies the new configuration
  484. Return Value:
  485. ULONG - Win32 status code.
  486. --*/
  487. {
  488. ULONG Error;
  489. PROFILE("NatRmSetInterfaceInfo");
  490. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  491. Error =
  492. NatConfigureInterface(
  493. Index,
  494. (PIP_NAT_INTERFACE_INFO)InterfaceInfo
  495. );
  496. DEREFERENCE_NAT_AND_RETURN(Error);
  497. } // NatRmSetInterfaceInfo
  498. ULONG
  499. APIENTRY
  500. NatRmInterfaceStatus(
  501. ULONG Index,
  502. BOOL InterfaceActive,
  503. ULONG StatusType,
  504. PVOID StatusInfo
  505. )
  506. /*++
  507. Routine Description:
  508. This routine is invoked to bind/unbind, enable/disable an interface
  509. Arguments:
  510. Index - the interface to be bound
  511. InterfaceActive - whether the interface is active
  512. StatusType - type of status being changed (bind or enabled)
  513. StatusInfo - Info pertaining to the state being changed
  514. Return Value:
  515. ULONG - Win32 Status code
  516. Environment:
  517. The routine runs in the context of an IP router-manager thread.
  518. --*/
  519. {
  520. ULONG Error = NO_ERROR;
  521. switch(StatusType) {
  522. case RIS_INTERFACE_ADDRESS_CHANGE: {
  523. PIP_ADAPTER_BINDING_INFO BindInfo =
  524. (PIP_ADAPTER_BINDING_INFO)StatusInfo;
  525. if (BindInfo->AddressCount) {
  526. Error = NatRmBindInterface(Index, StatusInfo);
  527. } else {
  528. Error = NatRmUnbindInterface(Index);
  529. }
  530. break;
  531. }
  532. case RIS_INTERFACE_ENABLED: {
  533. Error = NatRmEnableInterface(Index);
  534. break;
  535. }
  536. case RIS_INTERFACE_DISABLED: {
  537. Error = NatRmDisableInterface(Index);
  538. break;
  539. }
  540. }
  541. return Error;
  542. } // NatRmInterfaceStatus
  543. ULONG
  544. NatRmBindInterface(
  545. ULONG Index,
  546. PVOID BindingInfo
  547. )
  548. /*++
  549. Routine Description:
  550. This routine is invoked to bind an interface to its IP address(es).
  551. Arguments:
  552. Index - the interface to be bound
  553. BindingInfo - the addressing information
  554. Return Value:
  555. ULONG - Win32 status code.
  556. Environment:
  557. The routine runs in the context of an IP router-manager thread.
  558. --*/
  559. {
  560. ULONG Error;
  561. PROFILE("NatRmBindInterface");
  562. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  563. Error =
  564. NatBindInterface(
  565. Index,
  566. NULL,
  567. (PIP_ADAPTER_BINDING_INFO)BindingInfo,
  568. (ULONG)-1
  569. );
  570. DEREFERENCE_NAT_AND_RETURN(Error);
  571. } // NatRmBindInterface
  572. ULONG
  573. NatRmUnbindInterface(
  574. ULONG Index
  575. )
  576. /*++
  577. Routine Description:
  578. This routine is invoked to unbind an interface from its IP address(es).
  579. Arguments:
  580. Index - the interface to be unbound
  581. Return Value:
  582. ULONG - Win32 status code.
  583. Environment:
  584. The routine runs in the context of an IP router-manager thread.
  585. --*/
  586. {
  587. ULONG Error;
  588. PROFILE("NatRmUnbindInterface");
  589. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  590. Error =
  591. NatUnbindInterface(
  592. Index,
  593. NULL
  594. );
  595. DEREFERENCE_NAT_AND_RETURN(Error);
  596. } // NatRmUnbindInterface
  597. ULONG
  598. NatRmEnableInterface(
  599. ULONG Index
  600. )
  601. /*++
  602. Routine Description:
  603. This routine is invoked to enable operation on an interface.
  604. The NAT ignores the invocation.
  605. Arguments:
  606. none unused.
  607. Return Value:
  608. NO_ERROR.
  609. Environment:
  610. The routine runs in the context of an IP router-manager thread.
  611. --*/
  612. {
  613. PROFILE("NatRmEnableInterface");
  614. return NO_ERROR;
  615. } // NatRmEnableInterface
  616. ULONG
  617. NatRmDisableInterface(
  618. ULONG Index
  619. )
  620. /*++
  621. Routine Description:
  622. This routine is invoked to disable operation on an interface.
  623. The NAT ignores the invocation.
  624. Arguments:
  625. none unused.
  626. Return Value:
  627. NO_ERROR.
  628. Environment:
  629. The routine runs in the context of an IP router-manager thread.
  630. --*/
  631. {
  632. PROFILE("NatRmDisableInterface");
  633. return NO_ERROR;
  634. } // NatRmDisableInterface
  635. ULONG
  636. APIENTRY
  637. NatRmGetGlobalInfo(
  638. PVOID GlobalInfo,
  639. IN OUT PULONG GlobalInfoSize,
  640. IN OUT PULONG StructureVersion,
  641. IN OUT PULONG StructureSize,
  642. IN OUT PULONG StructureCount
  643. )
  644. /*++
  645. Routine Description:
  646. This routine is invoked to retrieve the configuration for the component.
  647. Arguments:
  648. GlobalInfo - receives the configuration
  649. GlobalInfoSize - receives the size of the configuration
  650. Return Value:
  651. ULONG - Win32 status code
  652. Environment:
  653. The routine runs in the context of an IP router-manager thread.
  654. --*/
  655. {
  656. ULONG Size;
  657. PROFILE("NatRmGetGlobalInfo");
  658. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  659. if (!GlobalInfoSize || (*GlobalInfoSize && !GlobalInfo)) {
  660. DEREFERENCE_NAT_AND_RETURN(ERROR_INVALID_PARAMETER);
  661. } else if (!NatGlobalInfo) {
  662. *GlobalInfoSize = 0;
  663. DEREFERENCE_NAT_AND_RETURN(NO_ERROR);
  664. }
  665. EnterCriticalSection(&NatGlobalInfoLock);
  666. Size =
  667. FIELD_OFFSET(IP_NAT_GLOBAL_INFO, Header) + NatGlobalInfo->Header.Size;
  668. if (*GlobalInfoSize < Size) {
  669. LeaveCriticalSection(&NatGlobalInfoLock);
  670. *StructureSize = *GlobalInfoSize = Size;
  671. if (StructureCount) {*StructureCount = 1;}
  672. DEREFERENCE_NAT_AND_RETURN(ERROR_INSUFFICIENT_BUFFER);
  673. }
  674. CopyMemory(GlobalInfo, NatGlobalInfo, Size);
  675. LeaveCriticalSection(&NatGlobalInfoLock);
  676. *StructureSize = *GlobalInfoSize = Size;
  677. if (StructureCount) {*StructureCount =1;}
  678. DEREFERENCE_NAT_AND_RETURN(NO_ERROR);
  679. } // NatRmGetGlobalInfo
  680. ULONG
  681. APIENTRY
  682. NatRmSetGlobalInfo(
  683. PVOID GlobalInfo,
  684. ULONG StructureVersion,
  685. ULONG StructureSize,
  686. ULONG StructureCount
  687. )
  688. /*++
  689. Routine Description:
  690. This routine is invoked to change the configuration for the component.
  691. Arguments:
  692. GlobalInfo - the new configuration
  693. Return Value:
  694. ULONG - Win32 status code
  695. Environment:
  696. The routine runs in the context of an IP router-manager thread.
  697. --*/
  698. {
  699. ULONG Error;
  700. PIP_NAT_GLOBAL_INFO NewInfo;
  701. ULONG Size;
  702. PROFILE("NatRmSetGlobalInfo");
  703. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  704. if (!GlobalInfo) { DEREFERENCE_NAT_AND_RETURN(ERROR_INVALID_PARAMETER); }
  705. Size =
  706. FIELD_OFFSET(IP_NAT_GLOBAL_INFO, Header) +
  707. ((PIP_NAT_GLOBAL_INFO)GlobalInfo)->Header.Size;
  708. NewInfo = reinterpret_cast<PIP_NAT_GLOBAL_INFO>(NH_ALLOCATE(Size));
  709. if (!NewInfo) {
  710. NhTrace(
  711. TRACE_FLAG_INIT,
  712. "NatRmSetGlobalInfo: error reallocating global info"
  713. );
  714. NhErrorLog(
  715. IP_NAT_LOG_ALLOCATION_FAILED,
  716. 0,
  717. "%d",
  718. Size
  719. );
  720. DEREFERENCE_NAT_AND_RETURN(ERROR_NOT_ENOUGH_MEMORY);
  721. }
  722. CopyMemory(NewInfo, GlobalInfo, Size);
  723. Error =
  724. NatConfigureDriver(
  725. NewInfo
  726. );
  727. if (Error) {
  728. NH_FREE(NewInfo);
  729. } else {
  730. EnterCriticalSection(&NatGlobalInfoLock);
  731. NH_FREE(NatGlobalInfo);
  732. NatGlobalInfo = NewInfo;
  733. LeaveCriticalSection(&NatGlobalInfoLock);
  734. }
  735. NatRemoveApplicationSettings();
  736. NhUpdateApplicationSettings();
  737. NatInstallApplicationSettings();
  738. DEREFERENCE_NAT_AND_RETURN(Error);
  739. } // NatRmSetGlobalInfo
  740. ULONG
  741. APIENTRY
  742. NatRmMibCreate(
  743. ULONG InputDataSize,
  744. PVOID InputData
  745. )
  746. {
  747. return ERROR_NOT_SUPPORTED;
  748. }
  749. ULONG
  750. APIENTRY
  751. NatRmMibDelete(
  752. ULONG InputDataSize,
  753. PVOID InputData
  754. )
  755. {
  756. return ERROR_NOT_SUPPORTED;
  757. }
  758. ULONG
  759. APIENTRY
  760. NatRmMibGet(
  761. ULONG InputDataSize,
  762. PVOID InputData,
  763. OUT PULONG OutputDataSize,
  764. OUT PVOID OutputData
  765. )
  766. /*++
  767. Routine Description:
  768. The NAT exposes two items to the MIB; its per-interface statistics,
  769. and its per-interface mapping table.
  770. Arguments:
  771. InputDataSize - the MIB query data size
  772. InputData - specifies the MIB object to be retrieved
  773. OutputDataSize - the MIB response data size
  774. OutputData - receives the MIB object retrieved
  775. Return Value:
  776. ULONG - Win32 status code.
  777. --*/
  778. {
  779. ULONG Error;
  780. ULONG Index;
  781. PIP_NAT_MIB_QUERY Oidp;
  782. PROFILE("NatRmMibGet");
  783. REFERENCE_NAT_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
  784. if (InputDataSize < sizeof(*Oidp) || !OutputDataSize) {
  785. Error = ERROR_INVALID_PARAMETER;
  786. } else {
  787. Oidp = (PIP_NAT_MIB_QUERY)InputData;
  788. switch(Oidp->Oid) {
  789. case IP_NAT_INTERFACE_STATISTICS_OID: {
  790. if (*OutputDataSize <
  791. sizeof(*Oidp) + sizeof(IP_NAT_INTERFACE_STATISTICS)) {
  792. *OutputDataSize =
  793. sizeof(*Oidp) + sizeof(IP_NAT_INTERFACE_STATISTICS);
  794. Error = ERROR_INSUFFICIENT_BUFFER;
  795. } else {
  796. Index = Oidp->Index[0];
  797. Oidp = (PIP_NAT_MIB_QUERY)OutputData;
  798. Oidp->Oid = IP_NAT_INTERFACE_STATISTICS_OID;
  799. *OutputDataSize -= sizeof(*Oidp);
  800. Error =
  801. NatQueryStatisticsInterface(
  802. Index,
  803. (PIP_NAT_INTERFACE_STATISTICS)Oidp->Data,
  804. OutputDataSize
  805. );
  806. *OutputDataSize += sizeof(*Oidp);
  807. }
  808. break;
  809. }
  810. case IP_NAT_INTERFACE_MAPPING_TABLE_OID: {
  811. if (OutputData && *OutputDataSize < sizeof(*Oidp)
  812. + sizeof(IP_NAT_ENUMERATE_SESSION_MAPPINGS)) {
  813. *OutputDataSize = 0;
  814. OutputData = NULL;
  815. }
  816. PIP_NAT_ENUMERATE_SESSION_MAPPINGS EnumerateTable = NULL;
  817. Index = Oidp->Index[0];
  818. Oidp = (PIP_NAT_MIB_QUERY)OutputData;
  819. if (Oidp) {
  820. Oidp->Oid = IP_NAT_INTERFACE_MAPPING_TABLE_OID;
  821. EnumerateTable =
  822. (PIP_NAT_ENUMERATE_SESSION_MAPPINGS)Oidp->Data;
  823. }
  824. if (*OutputDataSize) { *OutputDataSize -= sizeof(*Oidp); }
  825. Error =
  826. NatQueryInterfaceMappingTable(
  827. Index,
  828. EnumerateTable,
  829. OutputDataSize
  830. );
  831. *OutputDataSize += sizeof(*Oidp);
  832. break;
  833. }
  834. case IP_NAT_MAPPING_TABLE_OID: {
  835. if (OutputData && *OutputDataSize < sizeof(*Oidp)
  836. + sizeof(IP_NAT_ENUMERATE_SESSION_MAPPINGS)) {
  837. *OutputDataSize = 0;
  838. OutputData = NULL;
  839. }
  840. PIP_NAT_ENUMERATE_SESSION_MAPPINGS EnumerateTable = NULL;
  841. Oidp = (PIP_NAT_MIB_QUERY)OutputData;
  842. if (Oidp) {
  843. Oidp->Oid = IP_NAT_MAPPING_TABLE_OID;
  844. EnumerateTable =
  845. (PIP_NAT_ENUMERATE_SESSION_MAPPINGS)Oidp->Data;
  846. }
  847. if (*OutputDataSize) { *OutputDataSize -= sizeof(*Oidp); }
  848. Error =
  849. NatQueryMappingTable(
  850. EnumerateTable,
  851. OutputDataSize
  852. );
  853. *OutputDataSize += sizeof(*Oidp);
  854. break;
  855. }
  856. default: {
  857. NhTrace(
  858. TRACE_FLAG_NAT,
  859. "NatRmMibGet: oid %d invalid",
  860. Oidp->Oid
  861. );
  862. Error = ERROR_INVALID_PARAMETER;
  863. break;
  864. }
  865. }
  866. }
  867. DEREFERENCE_NAT_AND_RETURN(Error);
  868. }
  869. ULONG
  870. APIENTRY
  871. NatRmMibSet(
  872. ULONG InputDataSize,
  873. PVOID InputData
  874. )
  875. {
  876. return ERROR_NOT_SUPPORTED;
  877. }
  878. ULONG
  879. APIENTRY
  880. NatRmMibGetFirst(
  881. ULONG InputDataSize,
  882. PVOID InputData,
  883. OUT PULONG OutputDataSize,
  884. OUT PVOID OutputData
  885. )
  886. {
  887. return ERROR_NOT_SUPPORTED;
  888. }
  889. ULONG
  890. APIENTRY
  891. NatRmMibGetNext(
  892. ULONG InputDataSize,
  893. PVOID InputData,
  894. OUT PULONG OutputDataSize,
  895. OUT PVOID OutputData
  896. )
  897. {
  898. return ERROR_NOT_SUPPORTED;
  899. }
  900. ULONG
  901. APIENTRY
  902. NatRmConnectClient(
  903. ULONG Index,
  904. PVOID ClientAddress
  905. )
  906. /*++
  907. Routine Description:
  908. This routine is called upon establishment of an incoming connection
  909. by a RAS client.
  910. We automatically enable NAT access for incoming clients who connect
  911. over direct-cable/infra-red connections.
  912. Arguments:
  913. Index - unused
  914. ClientAddress - unused
  915. Return Value:
  916. ULONG - Win32 status code.
  917. --*/
  918. {
  919. ULONG Error;
  920. PROFILE("NatRmConnectClient");
  921. return NO_ERROR;
  922. }
  923. ULONG
  924. APIENTRY
  925. NatRmDisconnectClient(
  926. ULONG Index,
  927. PVOID ClientAddress
  928. )
  929. /*++
  930. Routine Description:
  931. This routine is called upon disconnection of a RAS client.
  932. It cleans up NAT access if it was enabled for the disconnected client.
  933. Arguments:
  934. Index - unused
  935. ClientAddress - unused
  936. Return Value:
  937. ULONG - Win32 status code.
  938. --*/
  939. {
  940. ULONG Error;
  941. PROFILE("NatRmDisconnectClient");
  942. return NO_ERROR;
  943. }