Simple Manager
This
document explains how to create SNMP management application using NuDesign
Multiprotocol C++ Framework.
Here
is the listing of the simple manager.
int main(int argc, char* argv[])
{
Initiate
use of Ws2_32.dll (windows socket) by a process.
BSocketManager sockMgr;
Create
non-volatile storage handler and load parameters. In this case we use file
(ascii flat file) as non-volatile storage, handler is implemented in BFileNV
class that is a part of NuDesign
Multiprotocol C++ Framework.
BFileNV nv;
tInt32 err = nv.ReadFile("SimpleMgr.xnv");
if (err != NDERR_NO_ERROR)
{
cout << "Failed. Err#
" << hex << err << endl;
exit(-1);
}
Create
UDP transport handler and initialize it. Note that manager requires two
transport-endpoints, one for receiving notifications (tarps/informs) and one
for sending requests and notifications.
tUint8 tepType[2];
port[0] = 0; // first available
tepType[0] = TETYPE_SEND;
port[1] = 162;
tepType[1] = TETYPE_NOTIFRECV;
BUdpTransport transport;
err = transport.Initialize(port, tepType, 2);
if (err != NDERR_NO_ERROR)
{
cout << "transport init
failed" << endl;
exit(-1);
}
SNMP
manager requires two callback objects: one to call while handling outgoing
requests (error, timeout, report, response) and one to call while handling
incoming notifications (trap, inform). The 1st one must be object of
the class that implements ICallbackSnmpOriginator interface, while the 2nd
one has to implement ICallbackSnmpNotifRcvr interface).
CmdGenCB cmdGenCallback(g_ctx);
NotifRcvrCB notifRcvrCallback;
Create
SNMP manager. The last parameter is ptr to implementation of ISnmpCrypto
interface. This is required only for SNMPv3 operation. If SNMPmanager is to be
used for SNMPv1 and/or SNMPv2c then this parameter may be omitted.
BSslCrypto crypto;
BSnmpManager snmpMgr( eSNMPv3,
transport,
&cmdGenCallback,
¬ifRcvrCallback,
&nv,
&crypto);
cmdGenCallback.m_pSnmpMgr = &snmpMgr;
Start
SNMP manager. SNMP manager creates required modules (engine, message processor,
security subsystem, command generator, notification receiver, notification
originator), initializes from non-volatile storage, creates receiver and
worker(s) threads and returns.
err = snmpMgr.Start();
if (err != NDERR_NO_ERROR)
{
cout << "Failed.
err=" << hex << err << endl;
exit(-1);
}
SNMP
manager is operating on its own threads so here we want to stop program.
Otherwise it’ll exit and destroy the manager (before doing anything useful).
This is an example of simple menu system that accepts single character as input
and determines what to execute.
char ch = 'a';
while (true)
{
if (ch == 'q')
{
break;
}
// . . .
}
Stop
SNMP manager. This will shutdown all the threads, and save the manager’s
configuration to non-volatile storage.
snmpMgr.Stop();
{
return 0;
}
To
send get request we have to prepare target object and varbind list.
Following
code shows how to create varbind list with single varbind for get (or getnext)
request.
Note that we need to pass only object identifier of the MIB object to be
retrieved. Value part of varbind is automatically set to NULL.
BVarBindList vbl;
BObjectIdentifier oi("1.3.6.1.2.1.1.1.0"); // sysDescr
vbl.Append(oi);
Target
object is instance of BSnmpV3Target class. Here is the example how to
initialize it.
BSnmpV3Target target;
BAddrINet addr("127.0.0.1:161");
target.address.Set(addr);
target.timeout = 3;
target.numRetries = 1;
Depending
of the version of request, security part of the target must be initialized. For
SNMPv1 or SNMPv2c, community is required
target.community = "public";
while
for the SNMPv3 security model, and security name must be initialized:
target.securityModel = SNMP_SECURITY_MODEL_USM; // 3
target.userName = "md5";
Finally,
to send request, call appropriate version of Get method if command generator.
Assuming the snmpMgr is instance of BSnmpManager, for v1/v2c get request call
snmpMgr.cmdGen.Get(eSNMPv2c, target, vbl, rqId);
and
for v3 request call
snmpMgr.cmdGen.Get(eSNMPv3, target, vbl, rqId,
g_ctx, eSecurityLevel_authNoPriv);
We’ve
seen target and vbl, but what is rqId? This is 32-bit integer and it will be
set to request id field from the generated get-pdu (it is passed by reference).
This should be saved so response could be correlated with request (in the
simple manager this value is ignored!).
In
SNMPv3 version of Get, there is one more parameter: context. Context is
instance of the BContext class and represents (context engine id, context name)
from the SNMPv3 scoped PDU. Usually context engine id is equal to authoritative
engine id (engine id of the target agent) and context engine id is zero-length
string. The implementation of the Simple manager assumes this fact and
initializes context engine id and name in the OnReport method of the CmdGenCB
class (CmdGenCB implements ICallbackSnmpOriginator interface) when
unknownEngineId report is received.
Advanced
SNMP managers should allow changing of the context engine id/name to provide
correct values for agents with non-default context name(s) or when SNMPv3 proxy
forwarding is being used.
Set
Set
request is different from Get just in preparing varbind list. For set we have
to provide the (new) value for the MIB object.
BVarBindList vbl;
BObjectIdentifier
oi("1.3.6.1.2.1.1.4.0"); // sysContact
BObjectSyntax val;
val.SetOctets (“Mr. SNMP”);
vbl.Append(oi,
val);