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.

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