snmputil的源码是对snmp操作的很好例子。
// General notes:
// Microsoft's SNMP Management API for Windows NT is implemented as a DLL
// that is linked with the developer's code. These APIs (examples follow in
// this file) allow the developer's code to generate SNMP queries and receive
// SNMP traps. A simple MIB compiler and related APIs are also available to
// allow conversions between OBJECT IDENTIFIERS and OBJECT DESCRIPTORS.
// Necessary includes.
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <snmp.h>
#include <mgmtapi.h>
// Constants used in this example.
#define GET 1
#define GETNEXT 2
#define WALK 3
#define TRAP 4
#define TIMEOUT 6000 /* milliseconds */
#define RETRIES 3
#pragma comment(lib, "Mgmtapi.lib")
#pragma comment(lib,"Snmpapi.lib");
// Main program.
INT main(IN int argumentCount,IN char *argumentVector[])
{
INT operation;
LPSTR agent;
LPSTR community;
RFC1157VarBindList variableBindings;
LPSNMP_MGR_SESSION session;
INT timeout = TIMEOUT;
INT retries = RETRIES;
BYTE requestType;
AsnInteger errorStatus;
AsnInteger errorIndex;
char *chkPtr = NULL;
// Parse command line arguments to determine requested operation.
// Verify number of arguments...
if (argumentCount < 5 && argumentCount != 2)
{
printf("Error: Incorrect number of arguments specified.\n");
printf("\nusage: snmputil [get|getnext|walk] agent community oid [oid ...]\n");
printf(" snmputil trap\n");
return 1;
}
// Get/verify operation...
argumentVector++;
argumentCount--;
if (!strcmp(*argumentVector, "get"))
operation = GET;
else if (!strcmp(*argumentVector, "getnext"))
operation = GETNEXT;
else if (!strcmp(*argumentVector, "walk"))
operation = WALK;
else if (!strcmp(*argumentVector, "trap"))
operation = TRAP;
else
{
printf("Error: Invalid operation, '%s', specified.\n",*argumentVector);
return 1;
}
if (operation != TRAP)
{
if (argumentCount < 4)
{
printf("Error: Incorrect number of arguments specified.\n");
printf("\nusage: snmputil [get|getnext|walk] agent community oid [oid ...]\n");
printf(" snmputil trap\n");
return 1;
}
// Get agent address...
argumentVector++;
argumentCount--;
agent = (LPSTR)SNMP_malloc(strlen(*argumentVector) + 1);
strcpy(agent, *argumentVector);
// Get agent community...
argumentVector++;
argumentCount--;
community = (LPSTR)SNMP_malloc(strlen(*argumentVector) + 1);
strcpy(community, *argumentVector);
// Get oid's...
variableBindings.list = NULL;
variableBindings.len = 0;
while(--argumentCount)
{
AsnObjectIdentifier reqObject;
argumentVector++;
// Convert the string representation to an internal representation.
if (!SnmpMgrStrToOid(*argumentVector, &reqObject))
{
printf("Error: Invalid oid, %s, specified.\n", *argumentVector);
return 1;
}
else
{
// Since sucessfull, add to the variable bindings list.
variableBindings.len++;
if ((variableBindings.list = (RFC1157VarBind *)SNMP_realloc(
variableBindings.list, sizeof(RFC1157VarBind) *
variableBindings.len)) == NULL)
{
printf("Error: Error allocating oid, %s.\n",*argumentVector);
return 1;
}
variableBindings.list[variableBindings.len - 1].name =
reqObject; // NOTE! structure copy
variableBindings.list[variableBindings.len - 1].value.asnType =
ASN_NULL;
}
} // end while()
// Make sure only one variable binding was specified if operation
// is WALK.
if (operation == WALK && variableBindings.len != 1)
{
printf("Error: Multiple oids specified for WALK.\n");
return 1;
}
// Establish a SNMP session to communicate with the remote agent. The
// community, communications timeout, and communications retry count
// for the session are also required.
if ((session = SnmpMgrOpen(agent, community, timeout, retries)) == NULL)
{
printf("error on SnmpMgrOpen %d\n", GetLastError());
return 1;
}
} // end if(TRAP)
// Determine and perform the requested operation.
if (operation == GET || operation == GETNEXT)
{
// Get and GetNext are relatively simple operations to perform.
// Simply initiate the request and process the result and/or
// possible error conditions.
if (operation == GET)
requestType = ASN_RFC1157_GETREQUEST;
else
requestType = ASN_RFC1157_GETNEXTREQUEST;
// Request that the API carry out the desired operation.
if (!SnmpMgrRequest(session, requestType, &variableBindings,
&errorStatus, &errorIndex))
{
// The API is indicating an error.
printf("error on SnmpMgrRequest %d\n", GetLastError());
}
else
{
// The API succeeded, errors may be indicated from the remote agent.
if (errorStatus > 0)
{
printf("Error: errorStatus=%d, errorIndex=%d\n",
errorStatus, errorIndex);
}
else
{
// Display the resulting variable bindings.
UINT i;
char *string = NULL;
for(i=0; i < variableBindings.len; i++)
{
SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
printf("Variable = %s\n", string);
if (string) SNMP_free(string);
printf("Value = ");
SnmpUtilPrintAsnAny(&variableBindings.list[i].value);
printf("\n");
} // end for()
}
}
// Free the variable bindings that have been allocated.
SnmpUtilVarBindListFree(&variableBindings);
}
else if (operation == WALK)
{
// Walk is a common term used to indicate that all MIB variables
// under a given OID are to be traversed and displayed. This is
// a more complex operation requiring tests and looping in addition
// to the steps for get/getnext above.
AsnObjectIdentifier root;
AsnObjectIdentifier tempOid;
SnmpUtilOidCpy(&root, &variableBindings.list[0].name);
requestType = ASN_RFC1157_GETNEXTREQUEST;
while(1)
{
if (!SnmpMgrRequest(session, requestType, &variableBindings,
&errorStatus, &errorIndex))
{
// The API is indicating an error.
printf("error on SnmpMgrRequest %d\n", GetLastError());
break;
}
else
{
// The API succeeded, errors may be indicated from the remote
// agent.
// Test for end of subtree or end of MIB.
if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
SnmpUtilOidNCmp(&variableBindings.list[0].name,
&root, root.idLength))
{
printf("End of MIB subtree.\n\n");
break;
}
// Test for general error conditions or sucesss.
if (errorStatus > 0)
{
printf("Error: errorStatus=%d, errorIndex=%d \n",errorStatus, errorIndex);
break;
}
else
{
// Display resulting variable binding for this iteration.
char *string = NULL;
SnmpMgrOidToStr(&variableBindings.list[0].name, &string);
printf("Variable = %s\n", string);
if (string) SNMP_free(string);
printf("Value = ");
SnmpUtilPrintAsnAny(&variableBindings.list[0].value);
printf("\n");
}
} // end if()
// Prepare for the next iteration. Make sure returned oid is
// preserved and the returned value is freed.
SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name);
SnmpUtilVarBindFree(&variableBindings.list[0]);
SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid);
variableBindings.list[0].value.asnType = ASN_NULL;
SnmpUtilOidFree(&tempOid);
} // end while()
// Free the variable bindings that have been allocated.
SnmpUtilVarBindListFree(&variableBindings);
SnmpUtilOidFree(&root);
}
else if (operation == TRAP)
{
// Trap handling can be done two different ways: event driven or
// polled. The following code illustrates the steps to use event
// driven trap reception in a management application.
HANDLE hNewTraps = NULL;
if (!SnmpMgrTrapListen(&hNewTraps))
{
printf("error on SnmpMgrTrapListen %d\n", GetLastError());
}
else
{
printf("snmputil: listening for traps...\n");
}
while(1)
{
DWORD dwResult;
if ((dwResult = WaitForSingleObject(hNewTraps, 0xffffffff))
== 0xffffffff)
{
printf("error on WaitForSingleObject %d\n",
GetLastError());
}
else if (!ResetEvent(hNewTraps))
{
printf("error on ResetEvent %d\n", GetLastError());
}
else
{
AsnObjectIdentifier enterprise;
AsnNetworkAddress IPAddress;
AsnInteger genericTrap;
AsnInteger specificTrap;
AsnTimeticks timeStamp;
RFC1157VarBindList variableBindings;
UINT i;
char *string = NULL;
while(SnmpMgrGetTrap(&enterprise, &IPAddress, &genericTrap,
&specificTrap, &timeStamp, &variableBindings))
{
printf("snmputil: trap generic=%d specific=%d\n",
genericTrap, specificTrap);
if (IPAddress.length == 4) {
printf(" from -> %d.%d.%d.%d\n",
(int)IPAddress.stream[0], (int)IPAddress.stream[1],
(int)IPAddress.stream[2], (int)IPAddress.stream[3]);
}
if (IPAddress.dynamic) {
SNMP_free(IPAddress.stream);
}
for(i=0; i < variableBindings.len; i++)
{
SnmpMgrOidToStr(&variableBindings.list[i].name, &string);
printf("Variable = %s\n", string);
if (string) SNMP_free(string);
printf("Value = ");
SnmpUtilPrintAsnAny(&variableBindings.list[i].value);
} // end for()
printf("\n");
SnmpUtilOidFree(&enterprise);
SnmpUtilVarBindListFree(&variableBindings);
}
}
} // end while()
} // end if(operation)
if (operation != TRAP)
{
// Close SNMP session with the remote agent.
if (!SnmpMgrClose(session))
{
printf("error on SnmpMgrClose %d\n", GetLastError());
return 1;
}
}
// Let the command interpreter know things went ok.
return 0;
} // end main()