Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The MIB source files perform the actual resolving of MIB variables. It contains the following header files: Windows.h, Snmp.h, and Testmib.h.
/*********************************************************************/
#include <windows.h>
#include <snmp.h>
#include "testmib.h" // Contains definitions for the table structure
// describing the MIB.
// If an addition or deletion to the MIB is necessary, there are
// several places in the code that must be checked and possibly
// changed. The last field in each MIB entry is used to point to the
// NEXT leaf variable. If an addition or deletion is made, these
// pointers might need to be updated to reflect the modification.
UINT OID_Prefix[] = {1, 3, 6, 1, 4, 1, 12};
// The prefix to all of these MIB variables is
// 1.3.6.1.4.1.12
AsnObjectIdentifier MIB_OidPrefix =
{OID_SIZEOF(OID_Prefix), OID_Prefix};
UINT MIB_toaster[] = {2};
// Definition of leaf variables under the toaster group. All leaf
// variables have a zero appended to their OID to indicate that it is
// the only instance of this variable and that it exists.
UINT MIB_toasterManufacturer[] = {2, 1, 0};
UINT MIB_toasterModelNumber[] = {2, 2, 0};
UINT MIB_toasterControl[] = {2, 3, 0};
UINT MIB_toasterDoneness[] = {2, 4, 0};
UINT MIB_toasterToastType[] = {2, 5, 0};
// Storage definitions for MIB
char MIB_toasterManStor[] = "Microsoft Corporation";
char MIB_toasterModelStor[] =
"Example SNMP Extension Agent for Windows CE (TOASTER-MIB).";
AsnInteger MIB_toasterControlStor = 1;
AsnInteger MIB_toasterDonenessStor = 2;
AsnInteger MIB_toasterToastTypeStor = 3;
// MIB definiton
MIB_ENTRY Mib[] = {
{{OID_SIZEOF(MIB_toasterManufacturer), MIB_toasterManufacturer},
&MIB_toasterManStor, ASN_RFC1213_DISPSTRING,
MIB_ACCESS_READ, MIB_leaf_func, &Mib[1]},
{{OID_SIZEOF(MIB_toasterModelNumber), MIB_toasterModelNumber},
&MIB_toasterModelStor, ASN_RFC1213_DISPSTRING,
MIB_ACCESS_READ, MIB_leaf_func, &Mib[2]},
{{OID_SIZEOF(MIB_toasterControl), MIB_toasterControl},
&MIB_toasterControlStor, ASN_INTEGER,
MIB_ACCESS_READWRITE, MIB_control_func, &Mib[3]},
{{OID_SIZEOF(MIB_toasterDoneness), MIB_toasterDoneness},
&MIB_toasterDonenessStor, ASN_INTEGER,
MIB_ACCESS_READWRITE, MIB_doneness_func, &Mib[4]},
{{OID_SIZEOF(MIB_toasterToastType), MIB_toasterToastType},
&MIB_toasterToastTypeStor, ASN_INTEGER,
MIB_ACCESS_READWRITE, MIB_toasttype_func, NULL}};
UINT MIB_num_variables = sizeof Mib / sizeof (MIB_ENTRY);
/**********************************************************************
ResolveVarBind
Resolves a single variable binding. Modifies the variable on a GET
or a GET-NEXT.
**********************************************************************/
UINT ResolveVarBind (
IN OUT RFC1157VarBind *VarBind, // Variable Binding to resolve
IN UINT PduAction) // Action that is specified in PDU
{
MIB_ENTRY *MibPtr;
AsnObjectIdentifier TempOid;
int CompResult;
UINT I;
UINT nResult;
// Search for var bind name in the MIB
I = 0;
MibPtr = NULL;
while (MibPtr == NULL && I < MIB_num_variables)
{
// Construct OID with complete prefix for comparison purposes
SnmpUtilOidCpy (&TempOid, &MIB_OidPrefix);
SnmpUtilOidAppend (&TempOid, &Mib[I].Oid);
// Check for OID in MIB - On a GET-NEXT the OID does not have to
// match exactly a variable in the MIB, it must fall only under
// the MIB root.
CompResult = SnmpUtilOidCmp (&VarBind->name, &TempOid);
if (0 > CompResult)
{
// Because there is not an exact match, the only valid action is
// GET-NEXT
if (MIB_ACTION_GETNEXT != PduAction)
{
nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Because the match was not exact, but varbind name is within MIB,
// you are at the NEXT MIB variable down from the one that was specified.
PduAction = MIB_ACTION_GET;
MibPtr = &Mib[I];
// Replace var bind name with new name
SnmpUtilOidFree (&VarBind->name);
SnmpUtilOidCpy (&VarBind->name, &MIB_OidPrefix);
SnmpUtilOidAppend (&VarBind->name, &MibPtr->Oid);
}
else
{
// An exact match was found.
if (0 == CompResult)
MibPtr = &Mib[I];
}
// Free OID memory before checking another variable
SnmpUtilOidFree (&TempOid);
I++;
} // while
// If OID not within scope of MIB, then no such name
if (MibPtr == NULL)
{
nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Call function to process request. Each MIB entry has a function
// pointer that knows how to process its MIB variable.
nResult = (*MibPtr->MibFunc) (PduAction, MibPtr, VarBind);
// Free temp memory
SnmpUtilOidFree (&TempOid);
Exit:
return nResult;
} // ResolveVarBind
/**********************************************************************
MIB_leaf_func
Performs generic actions on LEAF variables in the MIB.
**********************************************************************/
UINT MIB_leaf_func (
IN UINT Action,
IN MIB_ENTRY *MibPtr,
IN RFC1157VarBind *VarBind)
{
UINT ErrStat;
switch (Action)
{
case MIB_ACTION_GETNEXT:
// If there is no GET-NEXT pointer, this is the end of this MIB
if (MibPtr->MibNext == NULL)
{
ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Set up varbind name of NEXT MIB variable
SnmpUtilOidFree (&VarBind->name);
SnmpUtilOidCpy (&VarBind->name, &MIB_OidPrefix);
SnmpUtilOidAppend (&VarBind->name, &MibPtr->MibNext->Oid);
// Call function to process request. Each MIB entry has a
// function pointer that knows how to process its MIB variable.
ErrStat = (*MibPtr->MibNext->MibFunc) (MIB_ACTION_GET,
MibPtr->MibNext, VarBind);
break;
case MIB_ACTION_GET:
// Make sure that this variable's ACCESS is GET'able
if (MibPtr->Access != MIB_ACCESS_READ &&
MibPtr->Access != MIB_ACCESS_READWRITE)
{
ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Set up varbind's return value
VarBind->value.asnType = MibPtr->Type;
switch (VarBind->value.asnType)
{
case ASN_RFC1155_COUNTER:
case ASN_RFC1155_GAUGE:
case ASN_INTEGER:
VarBind->value.asnValue.number =
* (AsnInteger *) (MibPtr->Storage);
break;
case ASN_OCTETSTRING: // Entails ASN_RFC1213_DISPSTRING also.
VarBind->value.asnValue.string.length =
strlen ((LPSTR)MibPtr->Storage);
if (NULL == (VarBind->value.asnValue.string.stream =
SnmpUtilMemAlloc (VarBind->value.asnValue.string.length*
sizeof (char))))
{
ErrStat = SNMP_ERRORSTATUS_GENERR;
goto Exit;
}
memcpy (VarBind->value.asnValue.string.stream,
(LPSTR)MibPtr->Storage,
VarBind->value.asnValue.string.length);
VarBind->value.asnValue.string.dynamic = TRUE;
break;
default:
ErrStat = SNMP_ERRORSTATUS_GENERR;
goto Exit;
}
break;
case MIB_ACTION_SET:
// Make sure that this variable's ACCESS is SET'able
if (MibPtr->Access != MIB_ACCESS_READWRITE &&
MibPtr->Access != MIB_ACCESS_WRITE)
{
ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Check for proper type before setting
if (MibPtr->Type != VarBind->value.asnType)
{
ErrStat = SNMP_ERRORSTATUS_BADVALUE;
goto Exit;
}
// Save value in MIB
switch (VarBind->value.asnType)
{
case ASN_RFC1155_COUNTER:
case ASN_RFC1155_GAUGE:
case ASN_INTEGER:
* (AsnInteger *) (MibPtr->Storage) =
VarBind->value.asnValue.number;
break;
case ASN_OCTETSTRING: // Entails ASN_RFC1213_DISPSTRING also.
// The storage must be adequate to contain the new string
// including a NULL terminator.
memcpy ((LPSTR)MibPtr->Storage,
VarBind->value.asnValue.string.stream,
VarBind->value.asnValue.string.length);
((LPSTR)MibPtr->Storage)
[VarBind->value.asnValue.string.length] = '\0';
break;
default:
ErrStat = SNMP_ERRORSTATUS_GENERR;
goto Exit;
}
break;
default:
ErrStat = SNMP_ERRORSTATUS_GENERR;
goto Exit;
} // switch
// Signal no error occurred
ErrStat = SNMP_ERRORSTATUS_NOERROR;
Exit:
return ErrStat;
} // MIB_leaf_func
/**********************************************************************
MIB_control_func
Performs specific actions on the toasterControl MIB variable
**********************************************************************/
UINT MIB_control_func (
IN UINT Action,
IN MIB_ENTRY *MibPtr,
IN RFC1157VarBind *VarBind)
{
UINT ErrStat;
switch (Action)
{
case MIB_ACTION_SET:
// Make sure that this variable's ACCESS is SET'able
if (MibPtr->Access != MIB_ACCESS_READWRITE &&
MibPtr->Access != MIB_ACCESS_WRITE)
{
ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Check for proper type before setting
if (MibPtr->Type != VarBind->value.asnType)
{
ErrStat = SNMP_ERRORSTATUS_BADVALUE;
goto Exit;
}
// Make sure the value is valid
if (MIB_TOASTER_UP > VarBind->value.asnValue.number ||
MIB_TOASTER_DOWN < VarBind->value.asnValue.number)
{
ErrStat = SNMP_ERRORSTATUS_BADVALUE;
goto Exit;
}
// Let fall through purposefully for further processing by
// generic leaf function.
case MIB_ACTION_GETNEXT:
case MIB_ACTION_GET:
// Call the more generic function to perform the action
ErrStat = MIB_leaf_func (Action, MibPtr, VarBind);
break;
default:
ErrStat = SNMP_ERRORSTATUS_GENERR;
goto Exit;
} // switch
Exit:
return ErrStat;
} // MIB_control_func
/**********************************************************************
MIB_doneness_func
Performs specific actions on the toasterDoneness MIB variable
**********************************************************************/
UINT MIB_doneness_func (
IN UINT Action,
IN MIB_ENTRY *MibPtr,
IN RFC1157VarBind *VarBind)
{
UINT ErrStat;
switch (Action)
{
case MIB_ACTION_SET:
// Make sure that this variable's ACCESS is SET'able
if (MibPtr->Access != MIB_ACCESS_READWRITE &&
MibPtr->Access != MIB_ACCESS_WRITE)
{
ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Check for proper type before setting
if (MibPtr->Type != VarBind->value.asnType)
{
ErrStat = SNMP_ERRORSTATUS_BADVALUE;
goto Exit;
}
// Make sure the value is valid
if (MIB_TOASTER_LIGHTLYWARM > VarBind->value.asnValue.number ||
MIB_TOASTER_BURNT < VarBind->value.asnValue.number)
{
ErrStat = SNMP_ERRORSTATUS_BADVALUE;
goto Exit;
}
// Let fall through purposefully for further processing by
// generic leaf function.
case MIB_ACTION_GETNEXT:
case MIB_ACTION_GET:
// Call the more generic function to perform the action
ErrStat = MIB_leaf_func (Action, MibPtr, VarBind);
break;
default:
ErrStat = SNMP_ERRORSTATUS_GENERR;
goto Exit;
} // switch
Exit:
return ErrStat;
} // MIB_doneness_func
/**********************************************************************
MIB_toasttype_func
Performs specific actions on the toasterToastType MIB variable
**********************************************************************/
UINT MIB_toasttype_func (
IN UINT Action,
IN MIB_ENTRY *MibPtr,
IN RFC1157VarBind *VarBind)
{
UINT ErrStat;
switch (Action)
{
case MIB_ACTION_SET:
// Make sure that this variable's ACCESS is SET'able
if (MibPtr->Access != MIB_ACCESS_READWRITE &&
MibPtr->Access != MIB_ACCESS_WRITE)
{
ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
goto Exit;
}
// Check for proper type before setting
if (MibPtr->Type != VarBind->value.asnType)
{
ErrStat = SNMP_ERRORSTATUS_BADVALUE;
goto Exit;
}
// Make sure the value is valid
if (MIB_TOASTER_WHITEBREAD > VarBind->value.asnValue.number ||
MIB_TOASTER_OTHERBREAD < VarBind->value.asnValue.number)
{
ErrStat = SNMP_ERRORSTATUS_BADVALUE;
goto Exit;
}
// Let fall through purposefully for further processing by
// generic leaf function.
case MIB_ACTION_GETNEXT:
case MIB_ACTION_GET:
// Call the more generic function to perform the action
ErrStat = MIB_leaf_func (Action, MibPtr, VarBind);
break;
default:
ErrStat = SNMP_ERRORSTATUS_GENERR;
goto Exit;
} // switch
Exit:
return ErrStat;
} // MIB_toasttype_func
See Also
Send Feedback on this topic to the authors