489 lines
13 KiB
C
489 lines
13 KiB
C
/*++ 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 SMTP Service DLL
|
||
|
||
Functions Exported:
|
||
|
||
UINT ResolveVarBinding();
|
||
UINT MibStatisticsWorker();
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
# include "mib.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)
|
||
{
|
||
|
||
return;
|
||
} // PrintAsnObjectIdentifier()
|
||
|
||
|
||
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.
|
||
//
|
||
|
||
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 ( 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.
|
||
//
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
|
||
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.
|
||
//
|
||
|
||
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()
|
||
|