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.

1107 lines
28 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. sample\rmapi.c
  5. Abstract:
  6. The file contains IP router manager API implementations.
  7. --*/
  8. #include "pchsample.h"
  9. #pragma hdrstop
  10. DWORD
  11. WINAPI
  12. StartProtocol (
  13. IN HANDLE NotificationEvent,
  14. IN PSUPPORT_FUNCTIONS SupportFunctions,
  15. IN LPVOID GlobalInfo,
  16. IN ULONG StructureVersion,
  17. IN ULONG StructureSize,
  18. IN ULONG StructureCount
  19. )
  20. /*++
  21. Routine Description
  22. After the protocol has been registered, the IP Router Manager calls
  23. this function to tell the protocol to start. Most of the startup code
  24. is executed here.
  25. Arguments
  26. NotificationEvent Event to Set if the IP Router Manager needs to
  27. be notified to take any action on our behalf
  28. SupportFunctions Some functions exported by IP Router Manager
  29. GlobalInfo Our global configuration which was setup by our
  30. setup/admin DLL
  31. Return Value
  32. NO_ERROR Success
  33. Error Code o/w
  34. --*/
  35. {
  36. DWORD dwErr = NO_ERROR;
  37. TRACE3(ENTER, "Entering StartProtocol 0x%08x 0x%08x 0x%08x",
  38. NotificationEvent, SupportFunctions, GlobalInfo);
  39. do // breakout loop
  40. {
  41. // validate parameters
  42. if (!NotificationEvent or
  43. !SupportFunctions or
  44. !GlobalInfo)
  45. {
  46. dwErr = ERROR_INVALID_PARAMETER;
  47. break;
  48. }
  49. dwErr = CM_StartProtocol(NotificationEvent,
  50. SupportFunctions,
  51. GlobalInfo);
  52. } while(FALSE);
  53. TRACE1(LEAVE, "Leaving StartProtocol: %u", dwErr);
  54. return dwErr;
  55. }
  56. DWORD
  57. WINAPI
  58. StartComplete (
  59. VOID
  60. )
  61. {
  62. TRACE0(ENTER, "Entering StartComplete");
  63. TRACE0(LEAVE, "Leaving StartComplete");
  64. return NO_ERROR;
  65. }
  66. DWORD
  67. WINAPI
  68. StopProtocol (
  69. VOID
  70. )
  71. /*++
  72. Routine Description
  73. This function is called by the IP Router Manager to tell the protocol
  74. to stop. We set the protocol state to IPSAMPLE_STATUS_STOPPING to
  75. prevent us from servicing any more requests and wait for all pending
  76. threads to finish. Meanwhile we return PENDING to the IP Router
  77. Manager.
  78. Arguments
  79. None
  80. Return Value
  81. ERROR_PROTOCOL_STOP_PENDING Success
  82. Error Code o/w
  83. --*/
  84. {
  85. DWORD dwErr = NO_ERROR;
  86. TRACE0(ENTER, "Entering StopProtocol");
  87. dwErr = CM_StopProtocol();
  88. TRACE1(LEAVE, "Leaving StopProtocol: %u", dwErr);
  89. return dwErr;
  90. }
  91. DWORD
  92. WINAPI
  93. GetGlobalInfo (
  94. IN PVOID GlobalInfo,
  95. IN OUT PULONG BufferSize,
  96. OUT PULONG StructureVersion,
  97. OUT PULONG StructureSize,
  98. OUT PULONG StructureCount
  99. )
  100. /*++
  101. Routine Description
  102. The function is called by the IP Router Manager, usually because of a
  103. query by the admin utility. We see if we have space enough to return
  104. our global config. If we do, we return it, otherwise we return the size
  105. needed.
  106. Arguments
  107. GlobalInfo Pointer to allocated buffer to store our config
  108. BufferSize Size of config.
  109. Return Value
  110. NO_ERROR Success
  111. ERROR_INSUFFICIENT_BUFFER If the size of the buffer is too small
  112. Error Code o/w
  113. --*/
  114. {
  115. DWORD dwErr = NO_ERROR;
  116. TRACE2(ENTER, "Entering GetGlobalInfo: 0x%08x 0x%08x",
  117. GlobalInfo, BufferSize);
  118. do // breakout loop
  119. {
  120. // validate parameters
  121. if (!BufferSize)
  122. {
  123. dwErr = ERROR_INVALID_PARAMETER;
  124. break;
  125. }
  126. dwErr = CM_GetGlobalInfo(GlobalInfo,
  127. BufferSize,
  128. StructureVersion,
  129. StructureSize,
  130. StructureCount);
  131. } while(FALSE);
  132. TRACE1(LEAVE, "Leaving GetGlobalInfo: %u", dwErr);
  133. return dwErr;
  134. }
  135. DWORD
  136. WINAPI
  137. SetGlobalInfo (
  138. IN PVOID GlobalInfo,
  139. IN ULONG StructureVersion,
  140. IN ULONG StructureSize,
  141. IN ULONG StructureCount
  142. )
  143. /*++
  144. Routine Description
  145. Called by the IP Router Manager usually in response to an admin utility
  146. changing the global config. We verify the info and set it.
  147. Arguments
  148. GlobalInfo Our globals configuration
  149. Return Value
  150. NO_ERROR Success
  151. Error Code o/w
  152. --*/
  153. {
  154. DWORD dwErr = NO_ERROR;
  155. TRACE1(ENTER, "Entering SetGlobalInfo: 0x%08x", GlobalInfo);
  156. do // breakout loop
  157. {
  158. // validate parameters
  159. if (!GlobalInfo)
  160. {
  161. dwErr = ERROR_INVALID_PARAMETER;
  162. break;
  163. }
  164. dwErr = CM_SetGlobalInfo(GlobalInfo);
  165. } while(FALSE);
  166. TRACE1(LEAVE, "Leaving SetGlobalInfo: %u", dwErr);
  167. return NO_ERROR;
  168. }
  169. DWORD
  170. WINAPI
  171. AddInterface (
  172. IN LPWSTR InterfaceName,
  173. IN ULONG InterfaceIndex,
  174. IN NET_INTERFACE_TYPE InterfaceType,
  175. IN DWORD MediaType,
  176. IN WORD AccessType,
  177. IN WORD ConnectionType,
  178. IN PVOID InterfaceInfo,
  179. IN ULONG StructureVersion,
  180. IN ULONG StructureSize,
  181. IN ULONG StructureCount
  182. )
  183. /*++
  184. Routine Description
  185. Called by the ip router manager to add an interface when it finds our
  186. information block within the interface's configuration. We verify the
  187. information and create an entry for the interface in our interface
  188. table. Then we see all the configured addresses for the interface and
  189. create a binding structure for each address The interface comes up as
  190. UNBOUND-DISABLED (INACTIVE).
  191. Arguments
  192. InterfaceName The name of the interface, used for logging.
  193. InterfaceIndex The positive integer used to refer to this interface.
  194. AccessType Access type of the interface
  195. InterfaceInfo Our config for this interface
  196. Return Value
  197. NO_ERROR Success
  198. Error Code o/w
  199. --*/
  200. {
  201. DWORD dwErr = NO_ERROR;
  202. TRACE4(ENTER, "Entering AddInterface: %S %u %u 0x%08x",
  203. InterfaceName, InterfaceIndex, AccessType, InterfaceInfo);
  204. // interface properties unused for now
  205. UNREFERENCED_PARAMETER(InterfaceType);
  206. UNREFERENCED_PARAMETER(MediaType);
  207. UNREFERENCED_PARAMETER(ConnectionType);
  208. if (AccessType != IF_ACCESS_POINTTOPOINT)
  209. AccessType = IF_ACCESS_BROADCAST;
  210. do // breakout loop
  211. {
  212. // validate parameters
  213. if ((wcslen(InterfaceName) is 0) or
  214. !((AccessType is IF_ACCESS_BROADCAST) or
  215. (AccessType is IF_ACCESS_POINTTOPOINT)) or
  216. !InterfaceInfo)
  217. {
  218. dwErr = ERROR_INVALID_PARAMETER;
  219. break;
  220. }
  221. dwErr = NM_AddInterface(InterfaceName,
  222. InterfaceIndex,
  223. AccessType,
  224. InterfaceInfo);
  225. } while(FALSE);
  226. TRACE1(LEAVE, "Leaving AddInterface: %u", dwErr);
  227. return dwErr;
  228. }
  229. DWORD
  230. WINAPI
  231. DeleteInterface (
  232. IN ULONG InterfaceIndex
  233. )
  234. /*++
  235. Routine Description
  236. Called by the ip router manager to delete an interface and free its
  237. resources. If the interface is ACTIVE we shut it down.
  238. Arguments
  239. InterfaceIndex The index of the interface to be deleted
  240. Return Value
  241. NO_ERROR Success
  242. Error Code o/w
  243. --*/
  244. {
  245. DWORD dwErr = NO_ERROR;
  246. TRACE1(ENTER, "Entering DeleteInterface: %u", InterfaceIndex);
  247. dwErr = NM_DeleteInterface(InterfaceIndex);
  248. TRACE1(LEAVE, "Leaving DeleteInterface: %u", dwErr);
  249. return dwErr;
  250. }
  251. DWORD
  252. WINAPI
  253. InterfaceStatus (
  254. IN ULONG InterfaceIndex,
  255. IN BOOL InterfaceActive,
  256. IN DWORD StatusType,
  257. IN PVOID StatusInfo
  258. )
  259. /*++
  260. Routine Description
  261. Called by ip router manager to bind/unbind/activate/deactivate interfaces.
  262. BIND (
  263. (StatusType is RIS_INTERFACE_ADDRESS_CHANGE) and
  264. (((PIP_ADAPTER_BINDING_INFO) StatusInfo)->AddressCount > 0)
  265. )
  266. Called by the ip router manager once it learns the address(es) on an
  267. interface. This may happen as soon as the router starts (after the
  268. interface is added, of course) when the interface has a static address
  269. or may happen when an interface acquires a DHCP address or may happen
  270. when IPCP acquires the address for a dial up link. The binding may
  271. consist of one or more addresses.
  272. UNBIND (
  273. (StatusType is RIS_INTERFACE_ADDRESS_CHANGE) and
  274. (((PIP_ADAPTER_BINDING_INFO) StatusInfo)->AddressCount is 0)
  275. )
  276. Called when the interface loses its ip Address(es). This may happen
  277. when the interface is shutting down. It may be because an admin
  278. disabled IP on the interface (as opposed to just disabling the protocol
  279. on the interface). It can happen when the admin releases a DHCP
  280. acquired interface or when a dial up link disconnects.
  281. ENABLED (RIS_INTERFACE_ENABLED)
  282. Called to enable the interface after it has been added or when the
  283. interface is being reenabled after being disabled by the admin. The
  284. bindings on an interface are kept across Enable-Disable.
  285. DISABLED (RIS_INTERFACE_DISABLED)
  286. Called to disable an interface. This is usually in response to an
  287. admin setting the AdminStatus in IP to DOWN. This is different from an
  288. admin trying to disable an interface by setting a flag in our interface
  289. config because that is opaque to IP. That is a routing protocol
  290. specific disable and is conveyed to us via SetInterfaceConfig() calls.
  291. THIS IS AN IMPORTANT DISTINCTION. A ROUTING PROTOCOL NEEDS TO MANTAIN
  292. TWO STATES - AN NT STATE AND A PROTOCOL SPECIFIC STATE.
  293. INTERFACE ACTIVE
  294. This flag is used to activate the protocol over the interface
  295. independent of whether the interface has been bound or enabled.
  296. An unnumbered interface will not have a binding even when activated.
  297. Arguments
  298. InterfaceIndex The index of the interface in question
  299. InterfaceActive Whether the interface can send and receive data
  300. StatusType RIS_INTERFACE_[ADDRESS_CHANGED|ENABLED|DISABLED]
  301. SattusInfo Pointer to IP_ADAPTER_BINDING_INFO containing info
  302. about the addresses on the interface
  303. Return Value
  304. NO_ERROR Success
  305. Error Code o/w
  306. --*/
  307. {
  308. DWORD dwErr = NO_ERROR;
  309. TRACE4(ENTER, "Entering InterfaceStatus: %u %u %u 0x%08x",
  310. InterfaceIndex, InterfaceActive, StatusType, StatusInfo);
  311. do // breakout loop
  312. {
  313. dwErr = NM_InterfaceStatus(InterfaceIndex,
  314. InterfaceActive,
  315. StatusType,
  316. StatusInfo);
  317. } while(FALSE);
  318. TRACE1(LEAVE, "Leaving InterfaceStatus: %u", dwErr);
  319. return dwErr;
  320. }
  321. DWORD
  322. WINAPI
  323. GetInterfaceConfigInfo (
  324. IN ULONG InterfaceIndex,
  325. IN PVOID InterfaceInfo,
  326. IN OUT PULONG BufferSize,
  327. OUT PULONG StructureVersion,
  328. OUT PULONG StructureSize,
  329. OUT PULONG StructureCount
  330. )
  331. /*++
  332. Routine Description
  333. Called by the IP Router Manager to retrieve an interface's
  334. configuration. Usually this is because an admin utility is displaying
  335. this information. The Router Manager calls us with a NULL config and
  336. ZERO size. We return the required size to it. It then allocates the
  337. needed memory and calls us a second time with a valid buffer. We
  338. validate parameters each time and copy out our config if we can.
  339. Arguments
  340. InterfaceIndex Index of the interface being queried
  341. InterfaceInfo Pointer to buffer to store the config
  342. BufferSize Size of the buffer
  343. Return Value
  344. NO_ERROR Success
  345. Error Code o/w
  346. --*/
  347. {
  348. DWORD dwErr = NO_ERROR;
  349. TRACE3(ENTER, "Entering GetInterfaceConfigInfo: %u 0x%08x 0x%08x",
  350. InterfaceIndex, InterfaceInfo, BufferSize);
  351. do // breakout loop
  352. {
  353. // validate parameters
  354. if(BufferSize is NULL)
  355. {
  356. dwErr = ERROR_INVALID_PARAMETER;
  357. break;
  358. }
  359. dwErr = NM_GetInterfaceInfo(InterfaceIndex,
  360. InterfaceInfo,
  361. BufferSize,
  362. StructureVersion,
  363. StructureSize,
  364. StructureCount);
  365. } while(FALSE);
  366. TRACE1(LEAVE, "Leaving GetInterfaceConfigInfo: %u",
  367. dwErr);
  368. return dwErr;
  369. }
  370. DWORD
  371. WINAPI
  372. SetInterfaceConfigInfo (
  373. IN ULONG InterfaceIndex,
  374. IN PVOID InterfaceInfo,
  375. IN ULONG StructureVersion,
  376. IN ULONG StructureSize,
  377. IN ULONG StructureCount
  378. )
  379. /*++
  380. Routine Description
  381. Called by the IP Router Manager to set an interface's configuration.
  382. Usually this is because an admin utility modified this information.
  383. After validating parameters we update our config if we can.
  384. Arguments
  385. InterfaceIndex Index of the interface being updated
  386. InterfaceInfo Buffer with our updated configuration
  387. Return Value
  388. NO_ERROR Success
  389. Error Code o/w
  390. --*/
  391. {
  392. DWORD dwErr = NO_ERROR;
  393. TRACE2(ENTER, "Entering SetInterfaceConfigInfo: %u 0x%08x",
  394. InterfaceIndex, InterfaceInfo);
  395. do // breakout loop
  396. {
  397. // validate parameters
  398. if(InterfaceInfo is NULL)
  399. {
  400. dwErr = ERROR_INVALID_PARAMETER;
  401. break;
  402. }
  403. dwErr = NM_SetInterfaceInfo(InterfaceIndex, InterfaceInfo);
  404. } while(FALSE);
  405. TRACE1(LEAVE, "Leaving SetInterfaceConfigInfo: %u", dwErr);
  406. return dwErr;
  407. }
  408. DWORD
  409. WINAPI
  410. GetEventMessage (
  411. OUT ROUTING_PROTOCOL_EVENTS *Event,
  412. OUT MESSAGE *Result
  413. )
  414. /*++
  415. Routine Description
  416. This is called by the IP Router Manager if we indicate that we have a
  417. message in our queue to be delivered to it (by setting the
  418. g_ce.hMgrNotificationEvent)
  419. Arguments
  420. Event Routing Protocol Event Type
  421. Result Message associated with the event
  422. Return Value
  423. NO_ERROR Success
  424. Error Code o/w
  425. --*/
  426. {
  427. DWORD dwErr = NO_ERROR;
  428. TRACE2(ENTER, "Entering GetEventMessage: 0x%08x 0x%08x",
  429. Event, Result);
  430. do // breakout loop
  431. {
  432. // validate parameters
  433. if (!Event or !Result)
  434. {
  435. dwErr = ERROR_INVALID_PARAMETER;
  436. break;
  437. }
  438. dwErr = CM_GetEventMessage(Event, Result);
  439. } while(FALSE);
  440. TRACE1(LEAVE, "Leaving GetEventMessage: %u", dwErr);
  441. return dwErr;
  442. }
  443. DWORD
  444. WINAPI
  445. DoUpdateRoutes (
  446. IN ULONG InterfaceIndex
  447. )
  448. /*++
  449. Routine Description
  450. This function is called by the IP Router Manger to ask us to update
  451. routes over a Demand Dial link. The link has already been brought up
  452. so should be in ENABLED-BOUND state. After we are done we need to set
  453. the g_ce.hMgrNotificationEvent to inform the Router Manager that we
  454. have a message in our queue to be delivered to it. The Router Manager
  455. will call our GetEventMessage() function in which we will inform it
  456. that we are done with update routes (and the routes have been stored in
  457. RTMv2). The Router Manager will "freeze" these routes by converting
  458. them to AUTOSTATIC.
  459. Arguments
  460. InterfaceIndex Interface index on which to do the update
  461. Return Value
  462. NO_ERROR Success
  463. Error Code o/w
  464. --*/
  465. {
  466. DWORD dwErr = NO_ERROR;
  467. TRACE1(ENTER, "Entering DoUpdateRoutes: %u", InterfaceIndex);
  468. dwErr = NM_DoUpdateRoutes(InterfaceIndex);
  469. TRACE1(LEAVE, "Leaving DoUpdateRoutes: %u", dwErr);
  470. return dwErr;
  471. }
  472. DWORD
  473. WINAPI
  474. MibCreate (
  475. IN ULONG InputDataSize,
  476. IN PVOID InputData
  477. )
  478. /*++
  479. Routine Description
  480. This function does nothing, since IPSAMPLE does not support creation of
  481. interface objects via SNMP. However, this could be implemented as a
  482. sequence of calls to NM_AddInterface(), IE_BindInterface() and
  483. IE_EnableInterface. The input data would then have to contain the
  484. interface's index, configuration, and binding.
  485. Arguments
  486. InputData Relevant input, some struct defined in ipsamplerm.h
  487. InputDataSize Size of the input
  488. Return Value
  489. ERROR_CAN_NOT_COMPLETE for now
  490. --*/
  491. {
  492. DWORD dwErr = ERROR_CAN_NOT_COMPLETE;
  493. TRACE2(ENTER, "Entering MibCreate: %u 0x%08x",
  494. InputDataSize, InputData);
  495. TRACE1(LEAVE, "Leaving MibCreate: %u", dwErr);
  496. return dwErr;
  497. }
  498. DWORD
  499. WINAPI
  500. MibDelete (
  501. IN ULONG InputDataSize,
  502. IN PVOID InputData
  503. )
  504. /*++
  505. Routine Description
  506. This function does nothing, since IPSAMPLE does not support deletion of
  507. interface objects via SNMP. However, this could be implemented as a
  508. call to NM_DeleteInterface(). The input data would then have to
  509. contain the interface's index.
  510. Arguments
  511. InputData Relevant input, some struct defined in ipsamplerm.h
  512. InputDataSize Size of the input
  513. Return Value
  514. ERROR_CAN_NOT_COMPLETE for now
  515. --*/
  516. {
  517. DWORD dwErr = ERROR_CAN_NOT_COMPLETE;
  518. TRACE2(ENTER, "Entering MibDelete: %u 0x%08x",
  519. InputDataSize, InputData);
  520. TRACE1(LEAVE, "Leaving MibDelete: %u", dwErr);
  521. return dwErr;
  522. }
  523. DWORD
  524. WINAPI
  525. MibSet (
  526. IN ULONG InputDataSize,
  527. IN PVOID InputData
  528. )
  529. /*++
  530. Routine Description
  531. This function sets IPSAMPLE's global or interface configuration.
  532. Arguments
  533. InputData Relevant input, struct IPSAMPLE_MIB_SET_INPUT_DATA
  534. InputDataSize Size of the input
  535. Return Value
  536. NO_ERROR success
  537. Error Code o/w
  538. --*/
  539. {
  540. DWORD dwErr = NO_ERROR;
  541. TRACE2(ENTER, "Entering MibSet: %u 0x%08x",
  542. InputDataSize, InputData);
  543. do // breakout loop
  544. {
  545. // validate parameters
  546. if ((!InputData) or
  547. (InputDataSize < sizeof(IPSAMPLE_MIB_SET_INPUT_DATA)))
  548. {
  549. dwErr = ERROR_INVALID_PARAMETER;
  550. break;
  551. }
  552. dwErr = MM_MibSet((PIPSAMPLE_MIB_SET_INPUT_DATA) InputData);
  553. } while(FALSE);
  554. TRACE1(LEAVE, "Leaving MibSet: %u", dwErr);
  555. return dwErr;
  556. }
  557. DWORD
  558. WINAPI
  559. MibGet (
  560. IN ULONG InputDataSize,
  561. IN PVOID InputData,
  562. IN OUT PULONG OutputDataSize,
  563. OUT PVOID OutputData
  564. )
  565. /*++
  566. Routine Description
  567. This function retrieves one of...
  568. . global configuration
  569. . interface configuration
  570. . global stats
  571. . interface stats
  572. . interface binding
  573. Called by an admin (SNMP) utility. It actually passes through the IP
  574. Router Manager, but all that does is demux the call to the desired
  575. routing protocol.
  576. Arguments
  577. InputData Relevant input, struct IPSAMPLE_MIB_GET_INPUT_DATA
  578. InputDataSize Size of the input
  579. OutputData Buffer for struct IPSAMPLE_MIB_GET_OUTPUT_DATA
  580. OutputDataSize IN size of output buffer received
  581. OUT size of output buffer required
  582. Return Value
  583. NO_ERROR success
  584. Error Code o/w
  585. --*/
  586. {
  587. DWORD dwErr = NO_ERROR;
  588. TRACE4(ENTER, "Entering MibGet: %u 0x%08x 0x%08x 0x%08x",
  589. InputDataSize, InputData, OutputDataSize, OutputData);
  590. do // breakout loop
  591. {
  592. // validate parameters
  593. if ((!InputData) or
  594. (InputDataSize < sizeof(IPSAMPLE_MIB_GET_INPUT_DATA)) or
  595. (!OutputDataSize))
  596. {
  597. dwErr = ERROR_INVALID_PARAMETER;
  598. break;
  599. }
  600. dwErr = MM_MibGet((PIPSAMPLE_MIB_GET_INPUT_DATA) InputData,
  601. (PIPSAMPLE_MIB_GET_OUTPUT_DATA) OutputData,
  602. OutputDataSize,
  603. GET_EXACT);
  604. } while(FALSE);
  605. TRACE1(LEAVE, "Leaving MibGet: %u", dwErr);
  606. return dwErr;
  607. }
  608. DWORD
  609. WINAPI
  610. MibGetFirst (
  611. IN ULONG InputDataSize,
  612. IN PVOID InputData,
  613. IN OUT PULONG OutputDataSize,
  614. OUT PVOID OutputData
  615. )
  616. /*++
  617. Routine Description
  618. This function retrieves one of...
  619. . global configuration
  620. . interface configuration
  621. . global stats
  622. . interface stats
  623. . interface binding
  624. It differs from MibGet() in that it always returns the FIRST entry in
  625. whichever table is being queried. There is only one entry in the
  626. global configuration and global stats tables, but the interface
  627. configuration, interface stats, and interface binding tables are sorted
  628. by IP address; this function returns the first entry from these.
  629. Arguments
  630. InputData Relevant input, struct IPSAMPLE_MIB_GET_INPUT_DATA
  631. InputDataSize Size of the input
  632. OutputData Buffer for struct IPSAMPLE_MIB_GET_OUTPUT_DATA
  633. OutputDataSize IN size of output buffer received
  634. OUT size of output buffer required
  635. Return Value
  636. NO_ERROR success
  637. Error Code o/w
  638. --*/
  639. {
  640. DWORD dwErr = NO_ERROR;
  641. TRACE4(ENTER, "Entering MibGetFirst: %u 0x%08x 0x%08x 0x%08x",
  642. InputDataSize, InputData, OutputDataSize, OutputData);
  643. do // breakout loop
  644. {
  645. // validate parameters
  646. if ((!InputData) or
  647. (InputDataSize < sizeof(IPSAMPLE_MIB_GET_INPUT_DATA)) or
  648. (!OutputDataSize))
  649. {
  650. dwErr = ERROR_INVALID_PARAMETER;
  651. break;
  652. }
  653. dwErr = MM_MibGet((PIPSAMPLE_MIB_GET_INPUT_DATA) InputData,
  654. (PIPSAMPLE_MIB_GET_OUTPUT_DATA) OutputData,
  655. OutputDataSize,
  656. GET_FIRST);
  657. } while(FALSE);
  658. TRACE1(LEAVE, "Leaving MibGetFirst: %u", dwErr);
  659. return dwErr;
  660. }
  661. DWORD
  662. WINAPI
  663. MibGetNext (
  664. IN ULONG InputDataSize,
  665. IN PVOID InputData,
  666. IN OUT PULONG OutputDataSize,
  667. OUT PVOID OutputData
  668. )
  669. /*++
  670. Routine Description
  671. This function retrieves one of...
  672. . global configuration
  673. . interface configuration
  674. . global stats
  675. . interface stats
  676. . interface binding
  677. It differs from both MibGet() and MibGetFirst() in that it returns the
  678. entry AFTER the one specified in the indicated table. Thus, in the
  679. interface configuration, interface stats, and interface binding tables,
  680. this function supplies the entry after the one with the input address.
  681. If there are no more entries in the table being queried we return
  682. ERROR_NO_MORE_ITEMS. Unlike SNMP we don't walk to the next table.
  683. This does not take away any functionality since the NT SNMP agent
  684. will try the next variable (having ID one greater than the ID passed
  685. in) automatically on getting this error.
  686. Arguments
  687. InputData Relevant input, struct IPSAMPLE_MIB_GET_INPUT_DATA
  688. InputDataSize Size of the input
  689. OutputData Buffer for struct IPSAMPLE_MIB_GET_OUTPUT_DATA
  690. OutputDataSize IN size of output buffer received
  691. OUT size of output buffer required
  692. Return Value
  693. NO_ERROR success
  694. Error Code o/w
  695. --*/
  696. {
  697. DWORD dwErr = NO_ERROR;
  698. TRACE4(ENTER, "Entering MibGetFirst: %u 0x%08x 0x%08x 0x%08x",
  699. InputDataSize, InputData, OutputDataSize, OutputData);
  700. do // breakout loop
  701. {
  702. // validate parameters
  703. if ((!InputData) or
  704. (InputDataSize < sizeof(IPSAMPLE_MIB_GET_INPUT_DATA)) or
  705. (!OutputDataSize))
  706. {
  707. dwErr = ERROR_INVALID_PARAMETER;
  708. break;
  709. }
  710. dwErr = MM_MibGet((PIPSAMPLE_MIB_GET_INPUT_DATA) InputData,
  711. (PIPSAMPLE_MIB_GET_OUTPUT_DATA) OutputData,
  712. OutputDataSize,
  713. GET_NEXT);
  714. } while(FALSE);
  715. TRACE1(LEAVE, "Leaving MibGetNext: %u", dwErr);
  716. return dwErr;
  717. }
  718. DWORD
  719. WINAPI
  720. MibSetTrapInfo (
  721. IN HANDLE Event,
  722. IN ULONG InputDataSize,
  723. IN PVOID InputData,
  724. OUT PULONG OutputDataSize,
  725. OUT PVOID OutputData
  726. )
  727. /*++
  728. Routine Description
  729. This function does nothing at the moment...
  730. Return Value
  731. ERROR_CAN_NOT_COMPLETE for now
  732. --*/
  733. {
  734. DWORD dwErr = ERROR_CAN_NOT_COMPLETE;
  735. TRACE0(ENTER, "Entering MibSetTrapInfo");
  736. TRACE1(LEAVE, "Leaving MibSetTrapInfo: %u", dwErr);
  737. return dwErr;
  738. }
  739. DWORD
  740. WINAPI
  741. MibGetTrapInfo (
  742. IN ULONG InputDataSize,
  743. IN PVOID InputData,
  744. OUT PULONG OutputDataSize,
  745. OUT PVOID OutputData
  746. )
  747. /*++
  748. Routine Description
  749. This function does nothing at the moment...
  750. Return Value
  751. ERROR_CAN_NOT_COMPLETE for now
  752. --*/
  753. {
  754. DWORD dwErr = ERROR_CAN_NOT_COMPLETE;
  755. TRACE0(ENTER, "Entering MibGetTrapInfo");
  756. TRACE1(LEAVE, "Leaving MibGetTrapInfo: %u", dwErr);
  757. return dwErr;
  758. }
  759. //----------------------------------------------------------------------------
  760. // Function: RegisterProtocol
  761. //
  762. // Returns protocol ID and functionality for IPRIP
  763. //----------------------------------------------------------------------------
  764. DWORD
  765. APIENTRY
  766. RegisterProtocol(
  767. IN OUT PMPR_ROUTING_CHARACTERISTICS pRoutingChar,
  768. IN OUT PMPR_SERVICE_CHARACTERISTICS pServiceChar
  769. )
  770. /*++
  771. Routine Description
  772. This is the first function called by the IP Router Manager. The Router
  773. Manager tells the routing protocol its version and capabilities. It
  774. also tells our DLL, the ID of the protocol it expects us to register.
  775. This allows one DLL to support multiple routing protocols. We return
  776. the functionality we support and a pointer to our functions.
  777. Arguments
  778. pRoutingChar The routing characteristics
  779. pServiceChar The service characteristics (IPX 'thingy')
  780. Return Value
  781. NO_ERROR success
  782. ERROR_NOT_SUPPORTED o/w
  783. --*/
  784. {
  785. DWORD dwErr = NO_ERROR;
  786. TRACE0(ENTER, "Entering RegisterProtocol");
  787. do // breakout loop
  788. {
  789. if(pRoutingChar->dwProtocolId != MS_IP_SAMPLE)
  790. {
  791. dwErr = ERROR_NOT_SUPPORTED;
  792. break;
  793. }
  794. if ((pRoutingChar->fSupportedFunctionality
  795. & (RF_ROUTING|RF_DEMAND_UPDATE_ROUTES)) !=
  796. (RF_ROUTING|RF_DEMAND_UPDATE_ROUTES))
  797. {
  798. dwErr = ERROR_NOT_SUPPORTED;
  799. break;
  800. }
  801. pRoutingChar->fSupportedFunctionality =
  802. (RF_ROUTING | RF_DEMAND_UPDATE_ROUTES);
  803. // Since we are not a service advertiser (and IPX thing)
  804. pServiceChar->fSupportedFunctionality = 0;
  805. pRoutingChar->pfnStartProtocol = StartProtocol;
  806. pRoutingChar->pfnStartComplete = StartComplete;
  807. pRoutingChar->pfnStopProtocol = StopProtocol;
  808. pRoutingChar->pfnGetGlobalInfo = GetGlobalInfo;
  809. pRoutingChar->pfnSetGlobalInfo = SetGlobalInfo;
  810. pRoutingChar->pfnQueryPower = NULL;
  811. pRoutingChar->pfnSetPower = NULL;
  812. pRoutingChar->pfnAddInterface = AddInterface;
  813. pRoutingChar->pfnDeleteInterface = DeleteInterface;
  814. pRoutingChar->pfnInterfaceStatus = InterfaceStatus;
  815. pRoutingChar->pfnGetInterfaceInfo = GetInterfaceConfigInfo;
  816. pRoutingChar->pfnSetInterfaceInfo = SetInterfaceConfigInfo;
  817. pRoutingChar->pfnGetEventMessage = GetEventMessage;
  818. pRoutingChar->pfnUpdateRoutes = DoUpdateRoutes;
  819. pRoutingChar->pfnConnectClient = NULL;
  820. pRoutingChar->pfnDisconnectClient = NULL;
  821. pRoutingChar->pfnGetNeighbors = NULL;
  822. pRoutingChar->pfnGetMfeStatus = NULL;
  823. pRoutingChar->pfnMibCreateEntry = MibCreate;
  824. pRoutingChar->pfnMibDeleteEntry = MibDelete;
  825. pRoutingChar->pfnMibGetEntry = MibGet;
  826. pRoutingChar->pfnMibSetEntry = MibSet;
  827. pRoutingChar->pfnMibGetFirstEntry = MibGetFirst;
  828. pRoutingChar->pfnMibGetNextEntry = MibGetNext;
  829. pRoutingChar->pfnMibSetTrapInfo = MibSetTrapInfo;
  830. pRoutingChar->pfnMibGetTrapInfo = MibGetTrapInfo;
  831. } while (FALSE);
  832. TRACE1(LEAVE, "Leaving RegisterProtocol: %u", dwErr);
  833. return dwErr;
  834. }