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.

366 lines
12 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. sample\mibmanager.c
  5. Abstract:
  6. The file contains IP Sample's MIB implementation.
  7. Revision History:
  8. MohitT June-15-1999 Created
  9. --*/
  10. #include "pchsample.h"
  11. #pragma hdrstop
  12. DWORD
  13. WINAPI
  14. MM_MibSet (
  15. IN PIPSAMPLE_MIB_SET_INPUT_DATA pimsid)
  16. /*++
  17. Routine Description
  18. Set IPSAMPLE's global or interface configuration.
  19. Locks
  20. Acquires shared (g_ce.pneNetworkEntry)->rwlLock
  21. Releases (g_ce.pneNetworkEntry)->rwlLock
  22. Arguments
  23. pimsid input data, contains global/interface configuration
  24. Return Value
  25. NO_ERROR success
  26. Error Code o/w
  27. --*/
  28. {
  29. DWORD dwErr = NO_ERROR;
  30. ROUTING_PROTOCOL_EVENTS rpeEvent;
  31. MESSAGE mMessage = {0, 0, 0};
  32. PINTERFACE_ENTRY pie;
  33. if (!ENTER_SAMPLE_API()) { return ERROR_CAN_NOT_COMPLETE; }
  34. do // breakout loop
  35. {
  36. // set global configuration
  37. if (pimsid->IMSID_TypeID is IPSAMPLE_GLOBAL_CONFIG_ID)
  38. {
  39. if (pimsid->IMSID_BufferSize < sizeof(IPSAMPLE_GLOBAL_CONFIG))
  40. {
  41. dwErr = ERROR_INVALID_PARAMETER;
  42. break;
  43. }
  44. dwErr = CM_SetGlobalInfo((PVOID) pimsid->IMSID_Buffer);
  45. if (dwErr != NO_ERROR)
  46. break;
  47. rpeEvent = SAVE_GLOBAL_CONFIG_INFO;
  48. }
  49. // set interface configuration
  50. else if (pimsid->IMSID_TypeID is IPSAMPLE_IF_CONFIG_ID)
  51. {
  52. if (pimsid->IMSID_BufferSize < sizeof(IPSAMPLE_IF_CONFIG))
  53. {
  54. dwErr = ERROR_INVALID_PARAMETER;
  55. break;
  56. }
  57. dwErr = NM_SetInterfaceInfo(pimsid->IMSID_IfIndex,
  58. (PVOID) pimsid->IMSID_Buffer);
  59. if (dwErr != NO_ERROR)
  60. break;
  61. rpeEvent = SAVE_INTERFACE_CONFIG_INFO;
  62. mMessage.InterfaceIndex = pimsid->IMSID_IfIndex;
  63. }
  64. // error, unexpected type
  65. else
  66. {
  67. dwErr = ERROR_INVALID_PARAMETER;
  68. break;
  69. }
  70. // notify router manager
  71. if (EnqueueEvent(rpeEvent, mMessage) is NO_ERROR)
  72. SetEvent(g_ce.hMgrNotificationEvent);
  73. } while(FALSE);
  74. LEAVE_SAMPLE_API();
  75. return dwErr;
  76. }
  77. DWORD
  78. WINAPI
  79. MM_MibGet (
  80. IN PIPSAMPLE_MIB_GET_INPUT_DATA pimgid,
  81. OUT PIPSAMPLE_MIB_GET_OUTPUT_DATA pimgod,
  82. IN OUT PULONG pulOutputSize,
  83. IN MODE mMode)
  84. /*++
  85. Routine Description
  86. Handles the structure accesses required to read MIB data. Supports
  87. three modes of querying: EXACT, FIRST, and NEXT, which correspond to
  88. MibGet(), MibGetFirst(), and MibGetNext() respectively.
  89. Locks
  90. Acquires shared (g_ce.pneNetworkEntry)->rwlLock
  91. Releases (g_ce.pneNetworkEntry)->rwlLock
  92. Arguments
  93. pimgid input data
  94. pimgod output buffer
  95. pulOutputSize IN size of output buffer given
  96. OUT size of output buffer needed
  97. mMode query type
  98. Return Value
  99. NO_ERROR success
  100. Error Code o/w
  101. --*/
  102. {
  103. DWORD dwErr = NO_ERROR;
  104. ULONG ulSizeGiven = 0;
  105. ULONG ulSizeNeeded = 0;
  106. PINTERFACE_ENTRY pie;
  107. if (!ENTER_SAMPLE_API()) { return ERROR_CAN_NOT_COMPLETE; }
  108. // compute the size of the buffer available for storing
  109. // returned structures (the size of IMGOD_Buffer)
  110. if (*pulOutputSize < sizeof(IPSAMPLE_MIB_GET_OUTPUT_DATA))
  111. ulSizeGiven = 0;
  112. else
  113. ulSizeGiven = *pulOutputSize - sizeof(IPSAMPLE_MIB_GET_OUTPUT_DATA);
  114. switch (pimgid->IMGID_TypeID)
  115. {
  116. // the global statistics struct is fixed-length.
  117. // there is a single instance.
  118. case IPSAMPLE_GLOBAL_STATS_ID:
  119. {
  120. PIPSAMPLE_GLOBAL_STATS pigsdst, pigssrc;
  121. // only GET_EXACT and GET_FIRST are valid for the
  122. // global stats object since there is only one entry
  123. if (mMode is GET_NEXT)
  124. {
  125. dwErr = ERROR_NO_MORE_ITEMS;
  126. break;
  127. }
  128. // set the output size required for this entry
  129. ulSizeNeeded = sizeof(IPSAMPLE_GLOBAL_STATS);
  130. // check that the output buffer is big enough
  131. if (ulSizeGiven < ulSizeNeeded)
  132. {
  133. dwErr = ERROR_INSUFFICIENT_BUFFER;
  134. break;
  135. }
  136. pimgod->IMGOD_TypeID = IPSAMPLE_GLOBAL_STATS_ID;
  137. // since access to this structure is synchronized through
  138. // locked increments/decrements, we must copy it field by field
  139. pigssrc = &(g_ce.igsStats);
  140. pigsdst = (PIPSAMPLE_GLOBAL_STATS) pimgod->IMGOD_Buffer;
  141. pigsdst->ulNumInterfaces = pigssrc->ulNumInterfaces;
  142. break;
  143. }
  144. // the global configuration structure may be of variable size.
  145. // there is a single instance.
  146. case IPSAMPLE_GLOBAL_CONFIG_ID:
  147. {
  148. // only GET_EXACT and GET_FIRST are valid for the
  149. // global configuration object since there is only one entry
  150. if (mMode is GET_NEXT)
  151. {
  152. dwErr = ERROR_NO_MORE_ITEMS;
  153. break;
  154. }
  155. // CM_GetGlobalInfo() decides whether the buffer size is
  156. // sufficient. if so, it retrieves the global configuration.
  157. // either case it sets the required output buffer size.
  158. dwErr = CM_GetGlobalInfo ((PVOID) pimgod->IMGOD_Buffer,
  159. &ulSizeGiven,
  160. NULL,
  161. NULL,
  162. NULL);
  163. ulSizeNeeded = ulSizeGiven;
  164. // check that the output buffer was big enough
  165. if (dwErr != NO_ERROR)
  166. break;
  167. pimgod->IMGOD_TypeID = IPSAMPLE_GLOBAL_CONFIG_ID;
  168. break;
  169. }
  170. // the interface statistics struct is fixed-length.
  171. // there may be multiple instances.
  172. case IPSAMPLE_IF_STATS_ID:
  173. {
  174. PIPSAMPLE_IF_STATS piisdst, piissrc;
  175. ACQUIRE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
  176. do // breakout loop
  177. {
  178. // retrieve the interface whose stats are to be read
  179. dwErr = IE_GetIndex(pimgid->IMGID_IfIndex,
  180. mMode,
  181. &pie);
  182. if (dwErr != NO_ERROR)
  183. break;
  184. // set the output size required for this entry
  185. ulSizeNeeded = sizeof(IPSAMPLE_IF_STATS);
  186. // check that the output buffer is big enough
  187. if (ulSizeGiven < ulSizeNeeded)
  188. {
  189. dwErr = ERROR_INSUFFICIENT_BUFFER;
  190. break;
  191. }
  192. pimgod->IMGOD_TypeID = IPSAMPLE_IF_STATS_ID;
  193. pimgod->IMGOD_IfIndex = pie->dwIfIndex;
  194. // access to this structure is synchronized through locked
  195. // increments/decrements, so we copy it field by field
  196. piissrc = &(pie->iisStats);
  197. piisdst = (PIPSAMPLE_IF_STATS) pimgod->IMGOD_Buffer;
  198. piisdst->ulNumPackets = piissrc->ulNumPackets;
  199. } while (FALSE);
  200. RELEASE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
  201. break;
  202. }
  203. // the interface configuration structure may be of variable size.
  204. // there may be multiple instances.
  205. case IPSAMPLE_IF_CONFIG_ID:
  206. {
  207. // get the queried interface's index
  208. ACQUIRE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
  209. do // breakout loop
  210. {
  211. dwErr = IE_GetIndex(pimgid->IMGID_IfIndex,
  212. mMode,
  213. &pie);
  214. if (dwErr != NO_ERROR)
  215. break;
  216. // read lock acuired again, which is fine :)
  217. dwErr = NM_GetInterfaceInfo(pie->dwIfIndex,
  218. (PVOID) pimgod->IMGOD_Buffer,
  219. &ulSizeGiven,
  220. NULL,
  221. NULL,
  222. NULL);
  223. ulSizeNeeded = ulSizeGiven;
  224. // check that the output buffer was big enough
  225. if (dwErr != NO_ERROR)
  226. break;
  227. pimgod->IMGOD_TypeID = IPSAMPLE_IF_CONFIG_ID;
  228. pimgod->IMGOD_IfIndex = pie->dwIfIndex;
  229. } while (FALSE);
  230. RELEASE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
  231. break;
  232. }
  233. // the interface binding structure is of variable size.
  234. // there may be multiple instances.
  235. case IPSAMPLE_IF_BINDING_ID:
  236. {
  237. PIPSAMPLE_IF_BINDING piib;
  238. PIPSAMPLE_IP_ADDRESS piia;
  239. ACQUIRE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
  240. do // breakout loop
  241. {
  242. // retrieve the interface whose stats are to be read
  243. dwErr = IE_GetIndex(pimgid->IMGID_IfIndex,
  244. mMode,
  245. &pie);
  246. if (dwErr != NO_ERROR)
  247. break;
  248. // set the output size required for this entry
  249. ulSizeNeeded = sizeof(IPSAMPLE_IF_BINDING) +
  250. pie->ulNumBindings * sizeof(IPSAMPLE_IP_ADDRESS);
  251. // check that the output buffer is big enough
  252. if (ulSizeGiven < ulSizeNeeded)
  253. {
  254. dwErr = ERROR_INSUFFICIENT_BUFFER;
  255. break;
  256. }
  257. pimgod->IMGOD_TypeID = IPSAMPLE_IF_BINDING_ID;
  258. pimgod->IMGOD_IfIndex = pie->dwIfIndex;
  259. piib = (PIPSAMPLE_IF_BINDING) pimgod->IMGOD_Buffer;
  260. piia = IPSAMPLE_IF_ADDRESS_TABLE(piib);
  261. if (INTERFACE_IS_ACTIVE(pie))
  262. piib->dwState |= IPSAMPLE_STATE_ACTIVE;
  263. if (INTERFACE_IS_BOUND(pie))
  264. piib->dwState |= IPSAMPLE_STATE_BOUND;
  265. piib->ulCount = pie->ulNumBindings;
  266. CopyMemory((PVOID) piia, // address,mask pairs
  267. (PVOID) pie->pbeBindingTable, // ditto
  268. pie->ulNumBindings * sizeof(IPSAMPLE_IP_ADDRESS));
  269. } while (FALSE);
  270. RELEASE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
  271. break;
  272. }
  273. default:
  274. {
  275. dwErr = ERROR_INVALID_PARAMETER;
  276. break;
  277. }
  278. }
  279. *pulOutputSize = sizeof(IPSAMPLE_MIB_GET_OUTPUT_DATA) + ulSizeNeeded;
  280. LEAVE_SAMPLE_API();
  281. return dwErr;
  282. }