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

/*++ 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()