Object Modeling Technique
(OMT) view of the SNMP++ Snmp Class
|
The most important class in SNMP++ is the Snmp class. The Snmp class is an
encapsulation of a SNMP session. SNMP++ provides a logical binding of a
management application with a SNMP++ session to and from specified agents.
Handled by the session is the construction, delivery
and reception of PDUs. Most APIs require the
programmer to directly manage the session. This includes providing a reliable
transport mechanism handling time-outs, retries and packet duplication. The
SNMP class manages a large part of the session and frees the implementor to concentrate on the agent management. By
going through the Snmp class for session management,
the implementor is driving through well developed and
tested code. The alternative is to design, implement and test your own SNMP
engine. The Snmp class manages a session by 1)
managing the transport layer over a UDP or IPX connection. 2) handles packaging and un-packaging of variable bindings into
PDUs 3) provides for the delivery and reception of PDUs and 4) manages all necessary SNMP resources.
The Snmp class is easy to
use. Six basic methods, Snmp::get, Snmp::set, Snmp::get_next, Snmp::get_bulk, Snmp::inform() and Snmp::trap() provide the
basic functions for a network management application. Blocking or non-blocking
(asynchronous) methods may be used.
Multiple sessions may be used each asynchronously firing
simultaneous requests. Notification Sending and receiving are supported through
the Snmp::trap() and Snmp::inform(), trap and
inform sending, and Snmp::notify_register() and Snmp::notify_unregister() for trap and inform reception.
The Snmp class is safe to
use. The constructor and destructors allocate and de-allocate all resources
needed. This minimizes the likelihood of corrupt or leaked memory. All of the
internal SNMP mechanisms are hidden and thus cannot be inadvertently modified.
The Snmp class is portable.
The Snmp class interface is portable across OS’s and NOS’s. The majority of
the SNMP++ classes can be compiled and used on any ANSI / ISO C++ compiler. The
amount of coding needed to port SNMP++ to another platform is minimal.
Snmp Class Member Functions |
Description |
Constructor |
|
Snmp::Snmp(
int &status); |
Construct a Snmp object,
status defines success. |
Destructor |
|
Snmp::~Snmp(
); |
Destructor, frees all resources, closes session. |
Member
Functions |
|
char * error_msg( const int status); |
Returns text string for a given error status. |
int
get( Pdu &pdu, SnmpTarget
&target); |
Invokes blocked SNMP get. Gets Pdu
from target. |
int
set( Pdu &pdu, SnmpTarget &target); |
Invokes blocked SNMP set. Sets Pdu
from target. |
int
get_next( Pdu &pdu, SnmpTarget &target); |
Invokes blocked SNMP get next, using Pdu from target. |
int
get_bulk( Pdu &pdu, SnmpTarget &target,
const int non_repeaters,
const int max_reps); |
Invokes blocked SNMP get bulk ( V2 targets only
otherwise uses get-next ) |
int
inform( Pdu &pdu, SnmpTarget &target); |
Invoke a blocked mode inform. |
int
get( Pdu &pdu, SnmpTarget
&target,
snmp_callback callback,
void * callback_data=0); |
Invokes SNMP asynchronous get. Gets Pdu from target, uses defined callback and callback data. |
int
set( Pdu &pdu, SnmpTarget
&target,
snmp_callback callback,
void * callback_data=0); |
Invokes SNMP asynchronous set. Sets Pdu from target, uses defined callback and callback data. |
int
get_next( Pdu &pdu, SnmpTarget &target,
snmp_callback callback,
void * callback_data=0); |
Invokes SNMP asynchronous get next. Get next Pdu from target, uses defined callback and callback data. |
int
get_bulk( Pdu &pdu, SnmpTarget &target,
const int non_repeaters,
const int max_reps
snmp_callback callback,
void * callback_data=0); |
Invokes SNMP asynchronous get bulk. Get bulk Pdu from target, uses defined callback and callback data.
( V2 targets only otherwise uses get-next ) |
int
inform( Pdu &pdu, SnmpTarget &target,
snmp_callback callback,
void * callback_data=0); |
Invokes asynchronous inform. Uses notify callback. |
int
trap( Pdu &pdu, SnmpTarget
&target); |
Sends a trap to the specified target. |
int
notify_register( TargetCollection
&targets,
OidCollection &trapids,
snmp_callback callback,
void * callback_data=0); |
Register to receive traps and/or informs. |
int
notify_register( TargetCollection
&targets, OidCollection &trapids,
AddressCollection
&listen_addresses,
snmp_callback callback,
void * callback_data=0); |
Register to receive traps and/or informs and
specify listen interfaces using the AddressCollection. |
int notify_unregister(); |
Un-register to receive traps and/or informs. |
int cancel( const unsigned long rid); |
Cancels a pending asynchronous request for a given
request id. |
All
Snmp class member functions are bilingual. That is
they may be used with identical parameter lists for SNMP version 1 or version
2c Targets. This frees the programmer from having to modify code to talk to a
SNMP version 2 agent.
The Snmp class
provides a variety of member functions for creating, managing and terminating a
session. Multiple Snmp objects may be instantiated at
the same time.
The constructors and destructors for the Snmp class allow sessions to be opened and closed. By
constructing a Snmp object, a Snmp
session is open. UDP or IPX sockets
are created and managed until the objects are destroyed. Snmp
objects may be instantiated dynamically or statically.
A required construction parameter is the
return status. Since constructors do not return values in C++, the caller must
provide a status which should be checked after instantiating the object. The
caller should check the return status for ‘SNMP_CLASS_SUCCESS’. If the
construction status does not indicate success, the session should not be used.
// constructor, blocked SNMP object Snmp::Snmp( int
&status); // construction status |
The SNMP class destructor closes the session and
releases all resources and memory.
// destructor
Snmp::~Snmp(); |
In order to access or modify an agent’s
MIB, requests must be made via the Snmp::get(), Snmp::set(), Snmp::get_next(),
Snmp::get_bulk(), Smnp::inform()
andSnmp::trap(). All of these member functions accept
the similar parameter lists.
The get member function allows getting objects from
the agent at the specified target. The caller must specify the destination
target and requested Pdu.
//--------[ get ]------------------------------------------- int Snmp::get( Pdu &pdu,
//
Pdu to get
SnmpTarget &target); //
specified target |
The get next member function may be used to traverse an agents MIB.
//---------[ get next
]-------------------------------------- int Snmp::get_next(
Pdu &pdu,
//
Pdu to get next
SnmpTarget &target); //
specified target |
The set member function allows setting agent’s
objects.
//---------[ set
]-------------------------------------------- int Snmp::set(
Pdu &pdu,
//
Pdu to set
SnmpTarget &target); // specified target |
SNMP++
provides a get bulk interface for both SNMP version 1 and version 2 Targets.
For SNMP version 1operation, this member function will map over get next.
//--------[ get bulk
]------------------------------------------- int
Snmp::get_bulk( Pdu &pdu,
//
pdu to get_bulk
Target &target,
//
destination target
const int non_repeaters, //
non repeaters
const int max_reps);
//
maximum reps |
SNMP++
provides a inform interface for sending informs to V2 agents and managers.
//-----------[ inform
]---------------------------------------------------------- int
Snmp::inform( Pdu &pdu,
// pdu to
send
SnmpTarget &target);
//
destination target
|
Specifying the Id of an Inform
Inform
IDs are specified in the same manner as trap IDs. Using the Pdu::set_notify_id() member function, the ID
of an inform PDU may be specified. Inform
identifiers are represented using Oids. To create a Inform ID, simply create an Oid
object with the desired inform ID value. And then attach it to a Pdu using the Pdu::set_notify_id() member function.
Conversely, the ID of a inform can be obtained using the Pdu::get_notify_id() member function.
Specifying the TimeStamp
on a Inform
To
specify the timestamp on ainform PDU, the Pdu::set_notify_timestamp() member function can be used. If a Pdu
is sent without calling this member function, a timestamp from the SNMP++
engine will be utilized.
An Snmp instance
can support both blocked mode and asynchronous mode requests. Asynchronous
requests return thread of control immediately and do not require that the
caller wait for the response. In order to make this happen, a callback routine
mechanism is utilized. When making asynchronous requests, the caller must
specify a callback function and an optional callback data parameter.
typedef
void (*snmp_callback)( int,
// reason
Snmp*,
// session handle
Pdu &,
// Pdu passed
in
SnmpTarget &, //
source target
void * );
// callback data |
Reason(s) , int
The
reason parameter is an integer which describes why the callback was called. The
callback may have been called for a variety of reasons including the following.
SNMP_CLASS_ASYNC_RESPONSE: An SNMP response has been received. This
is a response to a get, set, get-next, get-bulk or
inform. The Pdu parameter holds the actual response
PDU and the SnmpTarget parameter holds the target
which issued the response.
SNMP_CLASS_TIMEOUT: A SNMP++ request has timed out based on
the time-out and retry information provided in the target instance. The Pdu parameter holds the original request Pdu for reuse. The SnmpTarget
parameter holds the original target.
SNMP_CLASS_SESSION_DESTROYED. The session has been destroyed. All
pending asynchronous requests were not completed.
SNMP_CLASS_NOTIFICATION:
A notification, trap or inform request, has arrived. The Pdu object holds the actual notify. The notification id,
timestamp and enterprise are available through Pdu
member functions Pdu::get_notify_id(), Pdu::get_notify_timestamp()
and Pdu::get_notifty_enterprise().
Snmp++
Session, Snmp*
This
parameter holds the value of the session which made the request. This allows
the session to be reused in time-out or get-next conditions.
Response PDU, Pdu&
This
parameter holds the response Pdu for responses, notifies and traps. In the event the reason was a
failure, the Pdu parameter holds the original request
Pdu. Once the Pdu object
goes out of scope, its values are no longer attainable.
Target ,
SnmpTarget&
This
parameter holds the source of the Pdu for responses, notifies and traps. If the reason was a failure,
the value is the original target used when the request was made.
Callback data ,void
*
When
the request was placed, an optional argument may be provided allowing callback
data. This information is returned in this parameter if it was specified. If it
was not specified, this value is null.
//-------------[
cancel a request ]----------------------------------- int
Snmp::cancel( const unsigned long rid); |
SNMP++ allows asynchronous requests to be
canceled before they have completed. This is useful for situations where your code
may need to exit prematurely or when the specified callback is no longer
available. Asynchronous requests are canceled automatically when the Snmp object used to issue the requests is destroyed. When
this happens, the specified callback will receive a ‘SNMP_CLASS_SESSION_DESTROYED’ reason. Alternatively, an individual asynchronous request may be canceled
using the Snmp::cancel() member function. This member function silently cancels
the asynchronous request specified with the request_id
parameter.
The asynchronous get allows getting SNMP objects from
the specified agent. The asynchronous get call will return as soon as the
request PDU has been sent. It does not wait for the response PDU. The
programmer’s defined callback will be called when the response PDU has arrived.
The implementation of the callback may utilize the response payload in any
desired manner.
//------------------------[
get async ]----------------------------------
int Snmp::get ( Pdu &pdu,
//
Pdu to get async
SnmpTarget &target,
//
destination target
snmp_callback
callback,
//
async callback
void * callback_data=0); //
callback data |
The
asynchronous set member function works in the same manner as the get counter
part.
//------------------------[
set async ]----------------------------------
int Snmp::set( Pdu &pdu,
//
Pdu to set async
SnmpTarget &target,
//
destination target
snmp_callback
callback,
//
async callback
void
* callback_data=0); //
callback data |
The
asynchronous get-next member function works in the same manner as does async get and async set.
//------------------------[
get next async ]----------------------------- int
Snmp::get_next( Pdu &pdu,
// Pdu to get_next
SnmpTarget &target,
//
destination
snmp_callback
callback,
//
async callback
void * callback_data=0); //
callback data |
The
asynchronous get-bulk member function works in the same manner as does async get and async set.
//------------------------[
get bulk async ]----------------------------- int
Snmp::get_bulk(Pdu &pdu,
// Pdu to get_bulk
async
Target &target,
//
destination target
const int non_repeaters, //
non repeaters
const int max_reps,
//
max repetitions
snmp_callback
callback, //
async callback
void * callback_data=0); //
callback data
|
//--------------------[ inform async
]---------------------------------------- int Snmp::inform(
Pdu &pdu,
// pdu to send
SnmpTarget &target,
// destination target
snmp_callback
callback,
// callback function
void * callback_data=0);
// callback data |
The
SNMP++ API supports member functions for both sending and receiving traps.
//-----------------------[
send a trap ]---------------------------------- int Snmp::trap(
Pdu &pdu,
//
Pdu to send
SnmpTarget &target);
//
destination target |
Sending
traps are a useful part of a manager API which allow for event communication to
other management stations.
Pdu
&pdu
The Pdu to send. This is where the payload of the trap is
contained.
SnmpTarget
&target
Where to send the trap.
Specifying the Id of a Trap
Trap
Ids are specified in the same manner as Inform Ids. Using the Pdu::set_notify_id() member function, the ID of a trap PDU may be specified. Trap identifiers are represented using
the SMI SNMP version 2 traps, which are represented using Oids.
SNMP++ predefines the following six generic trap Oids.
To create a trapid, simply create an Oid object with the desired trap id value. And the attach
it to a Pdu using the Pdu::set_notify_id() member function.
Conversely, the id of a trap can be obtained using the Pdu::get_notify_id() member function.
SNMP++ Defined Oid
Objects for Generic Trap IDs
coldStart ("1.3.6.1.6.3.1.1.5.1”)
warmStart ("1.3.6.1.6.3.1.1.5.2”)
linkDown ("1.3.6.1.6.3.1.1.5.3”)
linkUp ("1.3.6.1.6.3.1.1.5.4”)
authenticationFailure ("1.3.6.1.6.3.1.1.5.5”)
egpNeighborLoss ("1.3.6.1.6.3.1.1.5.6”)
To
send an enterprise specific trap, the caller may specify an Oid
which is not in the above generic set.
Specifying the TimeStamp
on a Trap
To
specify the timestamp on a trap PDU, the Pdu::set_notify_timestamp() member function
can be used. If a Pdu is sent without calling this
member function, a timestamp from the SNMP++ engine will be utilized.
Not to be confused with enterprise
specific traps, the enterprise of any trap represents where the trap originated
from in an agents MIB. Typically this is the System Object Identifier of the
trap sender, but in theory it may take on any Oid
value. In order to accommodate this parameter, SNMP++ allows setting enterprise
using the Pdu::set_notify_enterprise() member function. This is an optional call. If used the enterprise provided will be attached to the Pdu object.
For specification of a SNMP version 1 specific
value, the trapid Oid
should be constructed as follows. The last subid of
the trapid represents the specific value to use. The
second to the last subid should be zero. So, to
specify a trap specific value, two extra subids need
to be appended, a zero and a value or “0.X”. This convention is consistent with
RFC 1452 which specifies SNMP version 1 to SNMP version 2 trap mappings.
SNMP++ trap and inform reception allows
applications to receive traps and informs based on caller specified filtering. Unlike other SNMP operations, informs
and traps are unsolicited events which may occur at any time. Informs and traps
are therefor asynchronous events. SNMP++ provides
member functions which allow for caller specified filtering of informs and
traps. Informs and traps can be filtered based on their type, source and
destination.
//-----------------------[
register to receive traps and
informs]------------------------------------------- //
default form listens on all local
interfaces using well known port/ socket #’s int
Snmp::notify_register(OidCollection &ids,
//
types to listen for
TargetCollection &targets,
// targets to
listen for
snmp_callback callback,
//
callback to use
void *callback_data=0);
//
optional callback data //------------------------[
register to receive traps and informs ]---------------------------------------- // alternate form, AddressCollection
allows local listen interface specification int
Snmp::notify_register(OidCollection &ids,
//
types to listen for
TargetCollection &targets,
// targets to
listen for
AddressCollection &local_interfaces, //
interfaces to listen on
snmp_callback callback,
//
callback to use
void *callback_data=0);
//
optional callback data //-----------------------[
un-register to get traps and informs]------------------------------------------ int
Snmp::notify_unregister(); |
Each Snmp class
instance may be registered for its own unique set of traps / informs. That is , a Snmp object can have its
own set of filters and callback to invoke when a trap or inform arrives meeting
the filter criteria. The Snmp::notify_register() member function may be invoked multiple times where each
new call clears the previous filter settings. Trap / inform reception for a
particular session ceases when either the Snmp:notify_unregister() member function is invoked or
when the Snmp instance is destroyed.
The basic or typical form for notification
registration includes notification type, and notification source filtering
parameters or an OidCollection and a TargetCollection. Using this form of notify_register() will cause
notification listening to occur on all local interfaces. Thus, if the local
machine is multi-homed ( it has multiple network
interfaces) all interfaces will be opened up for notify reception using the
well known port / socket numbers. For example, say my machine has two network
cards, both running the Internet Protocol (IP) and only one using the Internet
Exchange Protocol (IPX). Calling the basic form of notify_register()
will listen on both IP interfaces using the well known SNMP trap port and on
the IPX interface using the well known trap IPX socket number.
The alternate or name overloaded form of notify_register()
accepts one additional parameter which allows specification of the local
interface to listen for informs, or the AddressCollection.
The AddressCollection parameter contains a list of
Address objects to listen on including IpAddresses, IpxAddresses, UdpAddresses and IpxSockAddresses.
The following is a list of interpretations of Addresses in the
Collection and how notify_register() will behave.
AddressCollection Element Behavior Definition
Address
Class |
Value |
Description |
IpAddress |
Any value except 0.0.0.0 |
Listen on IP interface specified
using well known IP port. |
IpAddress |
0.0.0.0 |
Listen on all IP interfaces
using well known IP port. |
UdpAddress |
Any value except 0.0.0.0 |
Listen on IP interface specified
using IP port specified. |
UdpAddress |
0.0.0.0 |
Listen on al IP interfaces using
IP port specified. |
IpxAddress |
Any value except
00000000:000000000000 |
Listen on IPX interface specified
using well known IPX socket number. |
IpxAddress |
00000000:000000000000 |
Listen on all IPX interfaces
using well known IPX socket number. |
IpxSockAddress |
Any
value except 00000000:000000000000 |
Listen
on IPX interface specified using socket number specified. |
IpxSockAddress |
00000000:000000000000 |
Listen
on all IPX interfaces using socket number specified. |
When filtering, filters behave as follows.
If an incoming inform or trap matches any item in the OidCollection
of ids AND the incoming inform or
trap matches any item in the TargetCollection THEN the inform
/ trap will be forwarded to the callers specified callback. Note, if the OidCollection is empty then all informs will pass the id
check, if the TargetCollection is empty, then all
informs will pass the Target check.
SNMP++ provides three ordered collection
classes for putting together collections of Oids,
Targets and Addresses. All collection classes operate in the identical manner
since they are derived from the same C++ template, SnmpCollection.
The Generic operations for the collections are as follows.
Target
and Oid Collection Class Member Functions |
Description |
Constructors |
|
SnmpCollection::SnmpCollection(void); |
Construct an empty Collection . |
SnmpCollection::SnmpCollection(const
T &t ); |
Construct a Collection using a
single element. |
Destructors |
|
SnmpCollection::SnmpCollection(); |
Destroy the Collection, free up
all resources. |
Member
Functions |
|
int
size(); |
Return the size of the
collection. |
SnmpCollection
& operator += ( T &t); |
Append a
element to a Collection. |
SnmpCollection
& operator = (SnmpCollection &collection); |
Assign a Collection to another
Collection. |
T& operator[]( int p); |
Access an element in a
Collection. |
int
set_element( const T& i,
const int p); |
Set an existing element in a
Collection. |
int
get_element( T& i,
const int p); |
Get a
element from a Collection. |
Making
and using a SnmpCollections as a trap / inform
reception filters are easy and straightforward. Three of the arguments for
notify registrations are collections, TargetCollection,
OidCollection and AddressCollection.
To build up these filters, first instantiate a collection and
then add elements to it using the overloaded ‘+=’ operator.
// example of making trap reception
filters // target collection TargetCollection my_targets; my_targets += cisco_router; my_targets += fore_switch; // Oid
collection OidCollection my_trapids; my_trapids += coldStart; my_trapids += warmStart; // Address collection AddressCollection my_addresses; my_addresses += (IpAddress)
“10.4.8.5”; my_addresses += (GenAddress)
“01020304:010203040506”; |
There are a variety of return codes when
using SNMP++. The error codes are common across platforms and may aid the
application programmer in finding and detecting error conditions.
If an error occurs during usage of the Snmp member function, the Snmp::error_msg( ) member function may
be used to retrieve an friendly error string.
//------------------------[
error message]----------------------------- char * Snmp::error_msg(
const int status); // returns string for provided status |