|
|
/*++ BUILD Version: 0001 // Increment this if a change has global effects.
Copyright (c) 1995 Microsoft Corporation
Module Name : mib.c
Abstract:
This defines Auxiliary functions for defining an SNMP Extension Agent for collecting and querying Statistical information.
Author:
Murali R. Krishnan ( MuraliK ) 23-Feb-1995
Environment: User Mode -- Win32 Project:
SNMP Extension DLL for Gopher Service DLL
Functions Exported:
UINT ResolveVarBinding(); UINT MibStatisticsWorker(); Revision History:
--*/
/************************************************************
* Include Headers ************************************************************/
# include "mib.h"
# include "dbgutil.h"
static UINT MibLeafFunction( IN OUT RFC1157VarBind * pRfcVarBinding, IN UINT pduAction, IN struct _MIB_ENTRY * pMibeCurrent, IN struct _MIB_ENTRIES * pMibEntries, IN LPVOID pStatistics );
static UINT MibGetNextVar( IN OUT RFC1157VarBind * pRfcVarBinding, IN MIB_ENTRY * pMibeCurrent, IN MIB_ENTRIES * pMibEntries, IN LPVOID pStatistics );
static VOID PrintAsnObjectIdentifier( IN char * pszOidDescription, IN AsnObjectIdentifier * pAsno) {
# if DBG
UINT len = pAsno->idLength; UINT i;
DBG_ASSERT( pAsno != NULL);
DBGPRINTF( ( DBG_CONTEXT, "Printing Oid %s = %08x. Length = %u.\n", pszOidDescription, pAsno, len));
for(i = 0; i < len; i++) {
DBGPRINTF( ( DBG_CONTEXT, "AsnOid[ %u] = %u\n", i, pAsno->ids[i])); }
# endif // DBG
return; } // PrintAsnObjectIdentifier()
/************************************************************
* Functions ************************************************************/
UINT ResolveVarBinding( IN OUT RFC1157VarBind * pRfcVarBinding, IN BYTE pduAction, IN LPVOID pStatistics, IN LPMIB_ENTRIES pMibEntries ) /*++
Description: This function resolves a single variable binding. Modifies the variable on a GET or a GET-NEXT.
Arguments: pRfcVarBinding pointer to RFC Variable Bindings pduAction Protocol Data Unit Action specified. pStatistics pointer to statisitcs data structure containing values of counter data. pMibEntries pointer to MIB_ENTRIES context information which contains prefix, array of MIB_ENTRIES and count of the entries. Returns: Standard PDU error codes.
Note: --*/ { AsnObjectIdentifier AsnTempOid; LPMIB_ENTRY pMibScan; UINT pduResult = SNMP_ERRORSTATUS_NOERROR; LPMIB_ENTRY pMibUpperBound = pMibEntries->prgMibEntry + pMibEntries->cMibEntries;
//
// Search for the variable binding name in the mib.
//
IF_DEBUG( SNMP_RESOLVE) {
DBGPRINTF( ( DBG_CONTEXT, " ResolveVarBinding( Var=%08x, Action=%x) called.\n", pRfcVarBinding, pduAction)); PrintAsnObjectIdentifier( " Variable to Resolve", &pRfcVarBinding->name); }
for( pMibScan = pMibEntries->prgMibEntry; pMibScan < pMibUpperBound; pMibScan++) {
int iCmpResult;
//
// Create a fully qualified OID for the current item in the MIB.
// and use it for comparing against variable to be resolved.
//
SNMP_oidcpy( &AsnTempOid, pMibEntries->pOidPrefix); SNMP_oidappend( &AsnTempOid, &pMibScan->asnOid); iCmpResult = SNMP_oidcmp( &pRfcVarBinding->name, &AsnTempOid); SNMP_oidfree( &AsnTempOid);
IF_DEBUG( SNMP_RESOLVE) {
DBGPRINTF( ( DBG_CONTEXT, " Comparing with suffix Oid %08x yields %d\n", &pMibScan->asnOid, iCmpResult)); PrintAsnObjectIdentifier( " StatisticsSuffix", &pMibScan->asnOid); }
if ( iCmpResult == 0) { //
// Found a match. Stop the search and process.
//
break; } else if ( iCmpResult < 0) {
//
// This could be the OID of a leaf ( withoug a trailing 0) or
// it could contain an invalid OID ( between valid OIDs).
//
if ( pduAction == MIB_GETNEXT) { //
// Advance the variable binding to next entry
//
SNMP_oidfree( &pRfcVarBinding->name); SNMP_oidcpy( &pRfcVarBinding->name, pMibEntries->pOidPrefix); SNMP_oidappend( &pRfcVarBinding->name, &pMibScan->asnOid); if ( ( pMibScan->bType != ASN_RFC1155_OPAQUE) && ( pMibScan->bType != ASN_SEQUENCE)) {
pduAction = MIB_GET; }
} else {
pduResult = SNMP_ERRORSTATUS_NOSUCHNAME; } //
// Stop and process the appropriate entry.
//
break; } // ( iCmpResult < 0)
} // for
if ( pMibScan >= pMibUpperBound) {
pduResult = SNMP_ERRORSTATUS_NOSUCHNAME; } if ( pduResult == SNMP_ERRORSTATUS_NOERROR) {
//
// A match is found or further processing is required.
//
DBG_ASSERT( pMibScan < pMibUpperBound); if ( pMibScan->pMibFunc == NULL) { //
// This happens only if the match is for Group OID
//
pduResult = ( ( pduAction != MIB_GETNEXT) ? SNMP_ERRORSTATUS_NOSUCHNAME: MibGetNextVar( pRfcVarBinding, pMibScan, pMibEntries, pStatistics)); } else { pduResult = ( pMibScan->pMibFunc) ( pRfcVarBinding, pduAction, pMibScan, pMibEntries, pStatistics); } }
IF_DEBUG( SNMP_RESOLVE) {
DBGPRINTF( ( DBG_CONTEXT, " ResolveVarBinding returns %u.\n", pduResult)); } return ( pduResult);
} // ResolveVarBinding()
UINT MibStatisticsWorker( IN OUT RFC1157VarBind * pRfcVarBinding, IN UINT pduAction, IN struct _MIB_ENTRY * pMibeCurrent, IN struct _MIB_ENTRIES * pMibEntries, IN LPVOID pStatistics ) /*++
This function resolves the variables assuming that there is statistical information ( sequence of counters) in the data passed in pStatistics.
Arguments: pRfcVarBind pointer to RFC variable binding to be resolved. pduAction protocol data unit action to be taken. pMibeCurrent pointer to MIB_ENTRY which is o be used for resolution. pMibEntries pointer to MIB_ENTRIES structure to be used as context for resolving and performing the action. pStatistics pointer to sequence of counters used for data resolution.
Returns: Standard PDU error codes.
--*/ { UINT pduResult = SNMP_ERRORSTATUS_NOERROR; // default indicating action to be done at end of switch
switch( pduAction) {
case MIB_SET: case MIB_GETNEXT: // action is performed at the end of switch statement.
break;
case MIB_GETFIRST: case MIB_GET:
//
// If no statistics do no action.
// If this is the header field ( non-leaf) do no action
// Otherwise, perform action as if this is the leaf node.
//
if ( pStatistics == NULL || pMibeCurrent->lFieldOffset == -1) {
pduResult = SNMP_ERRORSTATUS_GENERR; }
// Action on this node is performed at the end of the switch statement.
break;
default: pduResult = SNMP_ERRORSTATUS_GENERR; break; } // switch()
if ( pduResult == SNMP_ERRORSTATUS_NOERROR) {
//
// Use the generic leaf function to perform the action specified.
//
pduResult = MibLeafFunction( pRfcVarBinding, pduAction, pMibeCurrent, pMibEntries, pStatistics); } return ( pduResult); } // MibStatisticsWorker()
static UINT MibLeafFunction( IN OUT RFC1157VarBind * pRfcVarBinding, IN UINT pduAction, IN struct _MIB_ENTRY * pMibeCurrent, IN struct _MIB_ENTRIES * pMibEntries, IN LPVOID pStatistics ) /*++
This function resolves the variables assuming that there is statistical information ( sequence of counters) in the data passed in pStatistics and that this is a leaf node of the MIB tree. This is a generic function for leaf nodes.
Arguments: pRfcVarBind pointer to RFC variable binding to be resolved. pduAction protocol data unit action to be taken. pMibeCurrent pointer to MIB_ENTRY which is o be used for resolution. pMibEntries pointer to MIB_ENTRIES structure to be used as context for resolving and performing the action. pStatistics pointer to sequence of counters used for data resolution.
Returns: Standard PDU error codes.
--*/ { UINT pduResult = SNMP_ERRORSTATUS_NOSUCHNAME; // default is error value.
switch( pduAction ) {
case MIB_GETNEXT: //
// Determine if we're within the range and not at the end.
// If not within the range the above default pduResult == NOSUCHNAME
// is the required error message.
//
if ( ( pMibeCurrent >= pMibEntries->prgMibEntry) && ( pMibeCurrent < ( pMibEntries->prgMibEntry + pMibEntries->cMibEntries))) {
pduResult = MibGetNextVar( pRfcVarBinding, pMibeCurrent, pMibEntries, pStatistics); }
break; case MIB_GETFIRST: case MIB_GET: //
// Make sure that this variable's ACCESS is GET'able.
// If the access prohibits from GETting it, report error as
// NOSUCHNAME ( default value of pduResult in initialization above)
//
if(( pMibeCurrent->uiAccess == MIB_ACCESS_READ ) || ( pMibeCurrent->uiAccess == MIB_ACCESS_READWRITE ) ) { DWORD dwValue; //
// Setup pRfcVarBinding's return value.
//
DBG_ASSERT( pStatistics != NULL);
pRfcVarBinding->value.asnType = pMibeCurrent->bType; dwValue = *( (LPDWORD )((LPBYTE )pStatistics + pMibeCurrent->lFieldOffset));
pduResult = SNMP_ERRORSTATUS_NOERROR; // we found a value.
switch( pMibeCurrent->bType) { case ASN_RFC1155_GAUGE: pRfcVarBinding->value.asnValue.gauge = (AsnGauge ) dwValue; break; case ASN_RFC1155_COUNTER: pRfcVarBinding->value.asnValue.counter = (AsnCounter ) dwValue; break; case ASN_INTEGER: pRfcVarBinding->value.asnValue.number = (AsnInteger ) dwValue; break; case ASN_RFC1155_IPADDRESS: case ASN_OCTETSTRING: //
// Not supported for this MIB (yet).
// Fall through to indicate generic error.
//
default: //
// Sorry! Type in Mibe does not suit our purpose.
// Indicate generic error.
//
pduResult = SNMP_ERRORSTATUS_GENERR; break; } // innner switch
} // if ( valid read access)
break; case MIB_SET: //
// We don't support settable variables (yet).
// Fall through for error.
//
default: pduResult = SNMP_ERRORSTATUS_GENERR; break; } // switch ( pduAction)
return ( pduResult);
} // MibLeafFunction()
static UINT MibGetNextVar( IN OUT RFC1157VarBind * pRfcVarBinding, IN MIB_ENTRY * pMibeCurrent, IN MIB_ENTRIES * pMibEntries, IN LPVOID pStatistics) /*++
Description: This function sets the binding variable to iterate to the next variable.
Arguments: pRfcVarBind pointer to RFC variable binding to be resolved. pMibeCurrent pointer to MIB_ENTRY which is o be used for resolution. pMibEntries pointer to MIB_ENTRIES structure to be used as context for resolving and performing the action. pStatistics pointer to sequence of counters used for data resolution.
Returns: PDU Error Codes. --*/ { UINT pduResult = SNMP_ERRORSTATUS_NOSUCHNAME; LPMIB_ENTRY pMibUpperBound = pMibEntries->prgMibEntry + pMibEntries->cMibEntries;
//
// If within the range of MIB ENTRIES process.
//
if ( pMibeCurrent >= pMibEntries->prgMibEntry) {
//
// Scan through the remaining MIB Entries
//
LPMIB_ENTRY pMibeScan;
for( pMibeScan = pMibeCurrent+1; pMibeScan < pMibUpperBound; pMibeScan++ ) {
//
// Setup variable bindings for the next MIB variable
//
SNMP_oidfree( &pRfcVarBinding->name); SNMP_oidcpy( &pRfcVarBinding->name, pMibEntries->pOidPrefix); SNMP_oidappend( &pRfcVarBinding->name, &pMibeScan->asnOid);
//
// If the function pointer is not NULL and the type of the MIB
// variable is anything but OPAQUE, then call the function to
// process the MIB variable.
//
if(( pMibeScan->pMibFunc != NULL ) && ( pMibeScan->bType != ASN_RFC1155_OPAQUE ) ) { pduResult = ( pMibeScan->pMibFunc)( pRfcVarBinding, MIB_GETFIRST, pMibeScan, pMibEntries, pStatistics); break; }
//
// On failure in the scan, pduResult will have default value
// as initialized above in declaration.
//
} // for
}
return ( pduResult);
} // MibGetNextVar()
/************************ End of File ***********************/
|