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.

488 lines
13 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects.
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name :
  4. mib.c
  5. Abstract:
  6. This defines Auxiliary functions for defining an SNMP Extension Agent
  7. for collecting and querying Statistical information.
  8. Author:
  9. Murali R. Krishnan ( MuraliK ) 23-Feb-1995
  10. Environment:
  11. User Mode -- Win32
  12. Project:
  13. SNMP Extension DLL for SMTP Service DLL
  14. Functions Exported:
  15. UINT ResolveVarBinding();
  16. UINT MibStatisticsWorker();
  17. Revision History:
  18. --*/
  19. # include "mib.h"
  20. static UINT
  21. MibLeafFunction(
  22. IN OUT RFC1157VarBind * pRfcVarBinding,
  23. IN UINT pduAction,
  24. IN struct _MIB_ENTRY * pMibeCurrent,
  25. IN struct _MIB_ENTRIES * pMibEntries,
  26. IN LPVOID pStatistics
  27. );
  28. static UINT
  29. MibGetNextVar(
  30. IN OUT RFC1157VarBind * pRfcVarBinding,
  31. IN MIB_ENTRY * pMibeCurrent,
  32. IN MIB_ENTRIES * pMibEntries,
  33. IN LPVOID pStatistics
  34. );
  35. static VOID
  36. PrintAsnObjectIdentifier( IN char * pszOidDescription,
  37. IN AsnObjectIdentifier * pAsno)
  38. {
  39. return;
  40. } // PrintAsnObjectIdentifier()
  41. UINT
  42. ResolveVarBinding(
  43. IN OUT RFC1157VarBind * pRfcVarBinding,
  44. IN BYTE pduAction,
  45. IN LPVOID pStatistics,
  46. IN LPMIB_ENTRIES pMibEntries
  47. )
  48. /*++
  49. Description:
  50. This function resolves a single variable binding. Modifies the variable
  51. on a GET or a GET-NEXT.
  52. Arguments:
  53. pRfcVarBinding pointer to RFC Variable Bindings
  54. pduAction Protocol Data Unit Action specified.
  55. pStatistics pointer to statisitcs data structure containing
  56. values of counter data.
  57. pMibEntries pointer to MIB_ENTRIES context information
  58. which contains prefix, array of MIB_ENTRIES and
  59. count of the entries.
  60. Returns:
  61. Standard PDU error codes.
  62. Note:
  63. --*/
  64. {
  65. AsnObjectIdentifier AsnTempOid;
  66. LPMIB_ENTRY pMibScan;
  67. UINT pduResult = SNMP_ERRORSTATUS_NOERROR;
  68. LPMIB_ENTRY pMibUpperBound =
  69. pMibEntries->prgMibEntry + pMibEntries->cMibEntries;
  70. //
  71. // Search for the variable binding name in the mib.
  72. //
  73. for( pMibScan = pMibEntries->prgMibEntry;
  74. pMibScan < pMibUpperBound;
  75. pMibScan++) {
  76. int iCmpResult;
  77. //
  78. // Create a fully qualified OID for the current item in the MIB.
  79. // and use it for comparing against variable to be resolved.
  80. //
  81. SNMP_oidcpy( &AsnTempOid, pMibEntries->pOidPrefix);
  82. SNMP_oidappend( &AsnTempOid, &pMibScan->asnOid);
  83. iCmpResult = SNMP_oidcmp( &pRfcVarBinding->name, &AsnTempOid);
  84. SNMP_oidfree( &AsnTempOid);
  85. if ( iCmpResult == 0) {
  86. //
  87. // Found a match. Stop the search and process.
  88. //
  89. break;
  90. } else
  91. if ( iCmpResult < 0) {
  92. //
  93. // This could be the OID of a leaf ( withoug a trailing 0) or
  94. // it could contain an invalid OID ( between valid OIDs).
  95. //
  96. if ( pduAction == MIB_GETNEXT) {
  97. //
  98. // Advance the variable binding to next entry
  99. //
  100. SNMP_oidfree( &pRfcVarBinding->name);
  101. SNMP_oidcpy( &pRfcVarBinding->name,
  102. pMibEntries->pOidPrefix);
  103. SNMP_oidappend( &pRfcVarBinding->name, &pMibScan->asnOid);
  104. if ( ( pMibScan->bType != ASN_RFC1155_OPAQUE) &&
  105. ( pMibScan->bType != ASN_SEQUENCE)) {
  106. pduAction = MIB_GET;
  107. }
  108. } else {
  109. pduResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  110. }
  111. //
  112. // Stop and process the appropriate entry.
  113. //
  114. break;
  115. } // ( iCmpResult < 0)
  116. } // for
  117. if ( pMibScan >= pMibUpperBound) {
  118. pduResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  119. }
  120. if ( pduResult == SNMP_ERRORSTATUS_NOERROR) {
  121. //
  122. // A match is found or further processing is required.
  123. //
  124. if ( pMibScan->pMibFunc == NULL) {
  125. //
  126. // This happens only if the match is for Group OID
  127. //
  128. pduResult = ( ( pduAction != MIB_GETNEXT) ?
  129. SNMP_ERRORSTATUS_NOSUCHNAME:
  130. MibGetNextVar( pRfcVarBinding,
  131. pMibScan,
  132. pMibEntries,
  133. pStatistics));
  134. } else {
  135. pduResult = ( pMibScan->pMibFunc) ( pRfcVarBinding,
  136. pduAction,
  137. pMibScan,
  138. pMibEntries,
  139. pStatistics);
  140. }
  141. }
  142. return ( pduResult);
  143. } // ResolveVarBinding()
  144. UINT
  145. MibStatisticsWorker(
  146. IN OUT RFC1157VarBind * pRfcVarBinding,
  147. IN UINT pduAction,
  148. IN struct _MIB_ENTRY * pMibeCurrent,
  149. IN struct _MIB_ENTRIES * pMibEntries,
  150. IN LPVOID pStatistics
  151. )
  152. /*++
  153. This function resolves the variables assuming that there is statistical
  154. information ( sequence of counters) in the data passed in pStatistics.
  155. Arguments:
  156. pRfcVarBind pointer to RFC variable binding to be resolved.
  157. pduAction protocol data unit action to be taken.
  158. pMibeCurrent pointer to MIB_ENTRY which is o be used for resolution.
  159. pMibEntries pointer to MIB_ENTRIES structure to be used
  160. as context for resolving and performing the action.
  161. pStatistics pointer to sequence of counters used for data resolution.
  162. Returns:
  163. Standard PDU error codes.
  164. --*/
  165. {
  166. UINT pduResult = SNMP_ERRORSTATUS_NOERROR;
  167. // default indicating action to be done at end of switch
  168. switch( pduAction) {
  169. case MIB_SET:
  170. case MIB_GETNEXT:
  171. // action is performed at the end of switch statement.
  172. break;
  173. case MIB_GETFIRST:
  174. case MIB_GET:
  175. //
  176. // If no statistics do no action.
  177. // If this is the header field ( non-leaf) do no action
  178. // Otherwise, perform action as if this is the leaf node.
  179. //
  180. if ( pStatistics == NULL || pMibeCurrent->lFieldOffset == -1) {
  181. pduResult = SNMP_ERRORSTATUS_GENERR;
  182. }
  183. // Action on this node is performed at the end of the switch statement.
  184. break;
  185. default:
  186. pduResult = SNMP_ERRORSTATUS_GENERR;
  187. break;
  188. } // switch()
  189. if ( pduResult == SNMP_ERRORSTATUS_NOERROR) {
  190. //
  191. // Use the generic leaf function to perform the action specified.
  192. //
  193. pduResult = MibLeafFunction( pRfcVarBinding, pduAction, pMibeCurrent,
  194. pMibEntries, pStatistics);
  195. }
  196. return ( pduResult);
  197. } // MibStatisticsWorker()
  198. static UINT
  199. MibLeafFunction(
  200. IN OUT RFC1157VarBind * pRfcVarBinding,
  201. IN UINT pduAction,
  202. IN struct _MIB_ENTRY * pMibeCurrent,
  203. IN struct _MIB_ENTRIES * pMibEntries,
  204. IN LPVOID pStatistics
  205. )
  206. /*++
  207. This function resolves the variables assuming that there is statistical
  208. information ( sequence of counters) in the data passed in pStatistics
  209. and that this is a leaf node of the MIB tree.
  210. This is a generic function for leaf nodes.
  211. Arguments:
  212. pRfcVarBind pointer to RFC variable binding to be resolved.
  213. pduAction protocol data unit action to be taken.
  214. pMibeCurrent pointer to MIB_ENTRY which is o be used for resolution.
  215. pMibEntries pointer to MIB_ENTRIES structure to be used
  216. as context for resolving and performing the action.
  217. pStatistics pointer to sequence of counters used for data resolution.
  218. Returns:
  219. Standard PDU error codes.
  220. --*/
  221. {
  222. UINT pduResult = SNMP_ERRORSTATUS_NOSUCHNAME; // default is error value.
  223. switch( pduAction ) {
  224. case MIB_GETNEXT:
  225. //
  226. // Determine if we're within the range and not at the end.
  227. // If not within the range the above default pduResult == NOSUCHNAME
  228. // is the required error message.
  229. //
  230. if ( ( pMibeCurrent >= pMibEntries->prgMibEntry) &&
  231. ( pMibeCurrent <
  232. ( pMibEntries->prgMibEntry + pMibEntries->cMibEntries))) {
  233. pduResult = MibGetNextVar( pRfcVarBinding,
  234. pMibeCurrent,
  235. pMibEntries,
  236. pStatistics);
  237. }
  238. break;
  239. case MIB_GETFIRST:
  240. case MIB_GET:
  241. //
  242. // Make sure that this variable's ACCESS is GET'able.
  243. // If the access prohibits from GETting it, report error as
  244. // NOSUCHNAME ( default value of pduResult in initialization above)
  245. //
  246. if(( pMibeCurrent->uiAccess == MIB_ACCESS_READ ) ||
  247. ( pMibeCurrent->uiAccess == MIB_ACCESS_READWRITE ) ) {
  248. DWORD dwValue;
  249. //
  250. // Setup pRfcVarBinding's return value.
  251. //
  252. pRfcVarBinding->value.asnType = pMibeCurrent->bType;
  253. dwValue = *( (LPDWORD )((LPBYTE )pStatistics +
  254. pMibeCurrent->lFieldOffset));
  255. pduResult = SNMP_ERRORSTATUS_NOERROR; // we found a value.
  256. switch( pMibeCurrent->bType) {
  257. case ASN_RFC1155_GAUGE:
  258. pRfcVarBinding->value.asnValue.gauge = (AsnGauge ) dwValue;
  259. break;
  260. case ASN_RFC1155_COUNTER:
  261. pRfcVarBinding->value.asnValue.counter = (AsnCounter ) dwValue;
  262. break;
  263. case ASN_INTEGER:
  264. pRfcVarBinding->value.asnValue.number = (AsnInteger ) dwValue;
  265. break;
  266. case ASN_RFC1155_IPADDRESS:
  267. case ASN_OCTETSTRING:
  268. //
  269. // Not supported for this MIB (yet).
  270. // Fall through to indicate generic error.
  271. //
  272. default:
  273. //
  274. // Sorry! Type in Mibe does not suit our purpose.
  275. // Indicate generic error.
  276. //
  277. pduResult = SNMP_ERRORSTATUS_GENERR;
  278. break;
  279. } // innner switch
  280. } // if ( valid read access)
  281. break;
  282. case MIB_SET:
  283. //
  284. // We don't support settable variables (yet).
  285. // Fall through for error.
  286. //
  287. default:
  288. pduResult = SNMP_ERRORSTATUS_GENERR;
  289. break;
  290. } // switch ( pduAction)
  291. return ( pduResult);
  292. } // MibLeafFunction()
  293. static UINT
  294. MibGetNextVar(
  295. IN OUT RFC1157VarBind * pRfcVarBinding,
  296. IN MIB_ENTRY * pMibeCurrent,
  297. IN MIB_ENTRIES * pMibEntries,
  298. IN LPVOID pStatistics)
  299. /*++
  300. Description:
  301. This function sets the binding variable to iterate to the next variable.
  302. Arguments:
  303. pRfcVarBind pointer to RFC variable binding to be resolved.
  304. pMibeCurrent pointer to MIB_ENTRY which is o be used for resolution.
  305. pMibEntries pointer to MIB_ENTRIES structure to be used
  306. as context for resolving and performing the action.
  307. pStatistics pointer to sequence of counters used for data resolution.
  308. Returns:
  309. PDU Error Codes.
  310. --*/
  311. {
  312. UINT pduResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  313. LPMIB_ENTRY pMibUpperBound =
  314. pMibEntries->prgMibEntry + pMibEntries->cMibEntries;
  315. //
  316. // If within the range of MIB ENTRIES process.
  317. //
  318. if ( pMibeCurrent >= pMibEntries->prgMibEntry) {
  319. //
  320. // Scan through the remaining MIB Entries
  321. //
  322. LPMIB_ENTRY pMibeScan;
  323. for( pMibeScan = pMibeCurrent+1;
  324. pMibeScan < pMibUpperBound;
  325. pMibeScan++ ) {
  326. //
  327. // Setup variable bindings for the next MIB variable
  328. //
  329. SNMP_oidfree( &pRfcVarBinding->name);
  330. SNMP_oidcpy( &pRfcVarBinding->name, pMibEntries->pOidPrefix);
  331. SNMP_oidappend( &pRfcVarBinding->name, &pMibeScan->asnOid);
  332. //
  333. // If the function pointer is not NULL and the type of the MIB
  334. // variable is anything but OPAQUE, then call the function to
  335. // process the MIB variable.
  336. //
  337. if(( pMibeScan->pMibFunc != NULL ) &&
  338. ( pMibeScan->bType != ASN_RFC1155_OPAQUE ) ) {
  339. pduResult = ( pMibeScan->pMibFunc)( pRfcVarBinding,
  340. MIB_GETFIRST,
  341. pMibeScan,
  342. pMibEntries,
  343. pStatistics);
  344. break;
  345. }
  346. //
  347. // On failure in the scan, pduResult will have default value
  348. // as initialized above in declaration.
  349. //
  350. } // for
  351. }
  352. return ( pduResult);
  353. } // MibGetNextVar()