SNMP_PP_CHS Charpter 18

1.         Snmp Class

SNMP++Snmp Class的对象模型(Object Modeling Technique)视图

Snmp classSNMP++中最为重要的类。Snmp class封装了SNMP的会话。通过处理与指定代理端的会话,SNMP++(实现了)对网络管理应用的逻辑绑定。会话所控制的是PDU的构建、分发、接受。其他大多数API需要程序员直接操作会话,(也即)需要提供可靠的传输机制来控制超时、重发、查重。Snmp class管理了大部分的会话,得到解放的程序员只需要关注于代理端的管理,方便了代码的开发和测试。如果不这样(没有SNMP++),你就只有去设计、实现、测试你自己的SNMP引擎。(那么)Snmp class是如何管理通信的呢:1、在UDPIPX连接基础上管理传输层;2、负责打包和解包PDU中的绑定变量(译注:前面讲到过的VB);3、分发和接收PDU4、管理所有SNMP所需的资源。

Snmp class使用简单。它为网络管理应用提供了6种基本操作:Snmp::get, Snmp::set, Snmp::get_next, Snmp::get_bulk, Snmp::inform() Snmp::trap(),每种操作都可分为阻塞和非阻塞(异步)两种方式。当有多个异步的操作同时申请通信时,需要采用多重通信。发送Notification的处理是通过Snmp::trap() Snmp::inform(),即陷阱通知的发送;接收标志信息的处理是通过Snmp::notify_register() Snmp::notify_unregister(),即陷阱通知的接收。

Snmp class使用安全。构造函数和析构函数完成了对所有资源的加载和卸载,(从而)减小了内存的崩溃和泄漏的可能性。所有SNMP的内部机制都隐藏起来了,也就避免了不小心而修改到这些内部机制。

Snmp class可移植。对操作系统和网络系统而言,Snmp class的接口是可移植的。绝大多数SNMP++的类都可以在任何ANSI / ISO C++编译器上编译和使用。(只需要)修改少量代码,就可以实现对SNMP++的平台切换。

1.1.        Snmp Class成员函数列表

Snmp Class Member Functions

Description

Constructor

 

     Snmp::Snmp( int &status);

构造一个Snmp对象,status定义的是成功状态

Destructor

 

     Snmp::~Snmp( );

销毁,释放所有资源,关闭会话

Member Functions

 

     char * error_msg( const int status);

返回所给错误状态的文本字符串

     int get( Pdu &pdu,  SnmpTarget &target);

调用阻塞方式的SNMP get。从target获取Pdu

     int set( Pdu &pdu, SnmpTarget &target);

调用阻塞方式的SNMP set。对target设置Pdu

     int get_next( Pdu &pdu, SnmpTarget &target);

调用阻塞方式的SNMP get next。针对target上的Pdu

     int get_bulk( Pdu &pdu, SnmpTarget &target,

                          const int non_repeaters,

                           const int max_reps);

调用阻塞方式的SNMP get bulk(但是V2 targets只使用get-next

     int inform( Pdu &pdu, SnmpTarget &target);

调用阻塞方式的inform

     int get( Pdu &pdu,  SnmpTarget &target,

                 snmp_callback callback,        

                 void * callback_data=0);       

调用SNMP异步get。从target获取Pdu,需要用到(用户)定义的回调和回调的参数

     int set( Pdu &pdu,  SnmpTarget &target,

                 snmp_callback callback,        

                 void * callback_data=0);

调用SNMP异步set。对target设置Pdu,需要用到(用户)定义的回调和回调的参数

     int get_next( Pdu &pdu,  SnmpTarget &target,

                snmp_callback callback,        

                void * callback_data=0);

调用SNMP异步get next。从target获取下一个Pdu,需要用到(用户)定义的回调和回调的参数

     int get_bulk( Pdu &pdu,  SnmpTarget &target,

                          const int non_repeaters,

                          const int max_reps

                         snmp_callback callback,        

                         void * callback_data=0);

调用SNMP异步get bulk。从target获取批量Pdu,需要用到(用户)定义的回调和回调的参数

     int inform( Pdu &pdu, SnmpTarget &target,

                       snmp_callback callback,  

                       void * callback_data=0);  

调用异步inform。需要用到notify的回调。

     int trap( Pdu &pdu,  SnmpTarget &target);

向指定的target发送一个trap

     int notify_register( TargetCollection &targets,

                     OidCollection &trapids,

                     snmp_callback callback,

                     void * callback_data=0);

对接收trapinform(的操作)注册

     int notify_register( TargetCollection &targets,

                     OidCollection &trapids,

               AddressCollection &listen_addresses,

                     snmp_callback callback,

                     void * callback_data=0);

对接收trapinform(的操作)注册,并用AddressCollection指出监听的接口。

   int notify_unregister();

Un-register to receive traps and/or informs.

撤消对接收trapinform(的操作)注册

   int cancel( const unsigned long rid);

Cancels a pending asynchronous request for a given request id.

取消(针对所给)请求id的异步请求的等待

1.2.        双效的API

所有的Snmp class成员函数都是双效的。(这就是说)对于SNMP version 1version 2c ,他们可以使用统一的参数表。这解放了程序员,(因为程序员)不用为了与SNMP version 2的代理端通讯(而去)修改代码。

1.3.        Snmp Class的公共成员函数

(通过)Snmp Class提供的许多成员函数可以创建、管理、终结一个会话。多个Snmp对象可以在同一时间建立。

1.3.1.       Snmp Class的构造和析构函数

Snmp Class的构造和析构函数允许开启和关闭会话。通过构建一个Snmp对象来开启一个Snmp会话。(由此可对)UDPIPX套接口(实现)构建和管理,直到对象被销毁。Snmp对象可(选择)被动态或静态的实例化。

1.3.2.       Snmp Class构造函数

该构造函数以参数方式返回状态(status)。因为C++的构造函数没有返回值,调用者必须提供一个状态值(status)以供实例化对象后(针对状态的)检查。调用者需要检查返回值(是否)是“SNMP_CLASS_SUCCESS”。如果构造函数的状态不表示成功,该会话(也就)不可用。

// constructor, blocked SNMP object

Snmp::Snmp(  int &status);                  // construction status

1.3.3.       Snmp Class析构函数

Snmp Class的析构函数关闭相应的会话,并释放所有资源和内存

// destructor             

Snmp::~Snmp();

1.3.4.       Snmp Class发送请求的成员函数

为了访问或修改代理端的MIB,请求必须通过Snmp::get(), Snmp::set(),  Snmp::get_next(), Snmp::get_bulk(), Smnp::inform()以及Snmp::trap()(来发送)。所有这些成员函数接受同样的参数表。

1.3.5.       Snmp Class的阻塞方式成员函数: Get

(阻塞方式的)成员函数get允许从指定target的代理端获取对象。调用者必须指定目标target以及要请求的Pdu

//--------[ get ]-------------------------------------------   

int  Snmp::get(  Pdu &pdu,                 // Pdu to get

                SnmpTarget &target);          // specified target

1.3.6.       Snmp Class的阻塞方式成员函数: Get Next

(阻塞方式的)成员函数get next可以用来遍历代理端的MIB

//---------[ get next ]--------------------------------------

 int Snmp::get_next( Pdu &pdu,              // Pdu to get next

                   SnmpTarget &target);       // specified target

1.3.7.       Snmp Class的阻塞方式成员函数: Set

(阻塞方式的)成员函数set允许设置代理端的对象

//---------[ set ]--------------------------------------------

 int   Snmp::set( Pdu &pdu,                    // Pdu to set

                SnmpTarget &target);         // specified target

1.3.8.       Snmp Class的阻塞方式成员函数: Get Bulk

SNMP++SNMP version 1version 2Target提供了一个获取批量(数据)的接口。在SNMP version 1中的(相应)操作对应到成员函数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

1.3.9.       Snmp Class的阻塞方式成员函数:Inform

SNMP++提供了一个Inform接口,(由此可直接)在V2的代理端和网管端(内部之间)发送消息。

//-----------[ inform ]----------------------------------------------------------

int Snmp::inform( Pdu &pdu,                                    // pdu to send

                             SnmpTarget &target);                 // destination target

为一个Inform指定其Id

Inform ID的指定方法与trap ID一样。(可通过)用成员函数Pdu::set_notify_id()来为一个informPDU指定其IDInform标识符(ID)代表了其使用的Oid。为了建立Inform ID,可以用需要的Inform ID值来直接建立一个Oid对象,然后用成员函数Pdu::set_notify_id()把一个Pdu加载(在其上)。反过来,一个informID可以用成员函数Pdu::get_notify_id()来获取。

Inform上指定TimeStamp(译注:时间信息)

要给一个inform PDU指定时间信息,可用成员函数Pdu::set_notify_timestamp()。如果一个Pdu没有用该成员函数就发出去了,那么会使用一个来自SNMP++引擎(默认的)timestamp

1.4.        Snmp Class的异步方式成员函数

一个Snmp实例可以支持阻塞与异步两种方式的请求。异步请求(将会)立即返回所控制的线程,并不需要等待呼叫者的应答。为了达到该目的,使用了所谓的回调程序机制。当发出异步请求时,调用者必须指定回调函数,(还可)选择性的指定一个回调函数的参数。

1.4.1.       SNMP++异步回调函数的类型定义

typedef void (*snmp_callback)( int,                   // reason

                           Snmp*,                // session handle

                           Pdu &,                 // Pdu passed in

                           SnmpTarget &,  // source target

                           void * );               // callback data

1.4.1.1.       回调的参数说明

Reason(s) , int

该整形的原因参数描述了调用回调的原因。回调被调用的原因包括以下几种:

SNMP_CLASS_ASYNC_RESPONSE:收到了一个SNMP应答。这可以是一个(来自)get, set, get-next, get-bulkinform的应答。用Pdu参数保存实际应答的PDU,用SnmpTarget参数保存发送应答的target

SNMP_CLASS_TIMEOUT:一个SNMP++请求超时,该请求由target实例提供的超时与重发信息的机制(来处理)。为了重用,用 Pdu参数保存Pdu请求的原值,用SnmpTarget参数保存target的原值。

SNMP_CLASS_SESSION_DESTROYED:会话被销毁,(此时)所有正在等待的异步请求都不会完成。

SNMP_CLASS_NOTIFICATION:收到一个notification, trapinform请求。Pdu对象会保存实际的notify,通过Pdu成员函数Pdu::get_notify_id(), Pdu::get_notify_timestamp()Pdu::get_notifty_enterprise()来获得notification id, timestampenterprise

Snmp++ Session, Snmp*

该参数保存发送请求的会话的值。由此可以在time-outget-next情况下(实现)会话的重用。

Response PDU, Pdu&

该参数为esponse, notifietrap保存了应答 Pdu”。当原因(译注:前面提到的reason参数)为失败时,Pdu参数保存了请求 Pdu”的原值。一旦Pdu对象越界,其值就不可得了。

Target , SnmpTarget&

该参数为response, notifietrap保存了Pdu的来源。如果原因(译注:前面提到的reason参数)为失败,当有请求发出时,target的原值(就会)被用到。

Callback data ,void *

当有请求发出时,回调的参数可以作为一个可选的参数提供。如果指定了该参数,将会返回(相关)信息。如果没有指定,该值取空(null)。

1.4.2.       取消一个异步请求

SNMP++允许在完成之前取消(相应的)异步请求。这很有用,(尤其)当你需要在代码中提前退出或指定的回调已经失效的时候。当Snmp对象发出的请求被销毁时,异步请求会自动取消,这时指定的回调会收到一个“SNMP_CLASS_SESSION_DESTROYED”的原因。另一方面,可以用成员函数Snmp::cancel()来取消单个的异步请求。该成员函数通过参数request_id无影响的取消对应的异步请求。

//-------------[ cancel a request ]-----------------------------------

int Snmp::cancel( const unsigned long rid);

1.4.3.       Snmp Class的异步成员函数:Get

异步get允许从指定的代理端获取SNMP对象。当请求PDU”发出后,异步get调用就会返回,它不会等待应答PDU”。当收到应答PDU”时,会调用程序员定义的回调。在回调中,可以用任何喜欢的方式实现有效的应答。

//------------------------[ 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

1.4.4.       Snmp Class的异步成员函数:Set

异步成员函数set的工作方式与get雷同。

//------------------------[ 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

1.4.5.       Snmp Class的异步成员函数:Get Next

异步成员函数get-next的工作方式与异步getset雷同。

//------------------------[ 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

1.4.6.       Snmp Class的异步成员函数:Get Bulk

异步成员函数get- bulk的工作方式与异步getset雷同。

//------------------------[ 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

1.4.7.       Snmp Class的异步成员函数:Inform

//--------------------[ 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

1.5.        SNMP++通知的方法

SNMP++ API支持收发trap的成员函数

1.5.1.       发送Trap

发送trap(的函数)是一个有用的管理程序(managerAPI。可用函数与其他管理端进行通讯。

//-----------------------[ send a trap ]----------------------------------

int  Snmp::trap( Pdu &pdu,                                 // Pdu to send

               SnmpTarget &target);                // destination target

1.5.1.1.       发送Trap的成员函数的参数说明

Pdu &pdu 

要发送的Pdu,它是trap所包含的有效负载。

SnmpTarget &target

发送Trap的目的地

指定一个TrapId

Trap Id的指定方式与Inform Id(译注:后面会讲到)一样。可用成员函数Pdu::set_notify_id()来指定trap PDUIDTrap标识符(ID)在SMI SNMPv2中是以Oid表示的。SNMP++预定义了以下6种通用的trap Oid。(只需)用想要的trap id值来赋给一个Oid对象就可以生成一个trap id。相反的,可用成员函数Pdu::get_notify_id()来获取trap id

SNMP++为通用Trap ID定义的Oid对象

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” )

如果要发送(某个)企业指定的trap,调用者可能需要指定一个除上面以外的Oid

指定Trap的时间信息

可用成员函数Pdu::set_notify_timestamp()来指定trap PDU的时间信息。如果一个Pdu没调用这个成员函数就发送了,那么会使用一个来自SNMP++引擎的时间信息。

1.5.1.2.       指定Trap Enterprise

不用被企业指定的trap困扰,任何trap的企业都代表了产生trap的代理端的MIB。对trap的发送者(来说)它是系统标识符(System Object Identifier),但是从理论上讲它可以表示任何Oid的值。为了设置该参数,SNMP++允许使用成员函数Pdu::set_notify_enterprise()来设置enterprise,而且这个(参数)是可选的。如果使用了所提供的enterprise,(该enterprise)会加载在对应的Pdu对象上。

1.5.1.3.       SNMPv1 Trap指定特殊的Trap

为了给SNMPv1 Trap指定特殊的Trap值,trapidOid应该构造如下:trapid 的最末子idsubid)代表指定的要使用的值;倒数第二个子id应该是零。即,为了指定特殊的Trap值,需要添加两个额外的子id,一个是零、一个是值(“0.X”)。这个约定与规定SNMPv1SNMPv2trap映射的RFC 1452(的描述)一致。

1.5.2.       接收Notification

接收SNMP++ trapinform(的时候),允许应用程序使用指定的过滤器来接收trapinform。不像其他的SNMP操作,trapinform是在任何可能出现的时候主动发出的。因此informstraps属于异步的动作。通过SNMP++提供的成员函数,调用者(可以)指定informstraps的过滤器。可用informstraps的类型、来源和目标来过滤informstraps

//-----------------------[ 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();

1.5.2.1.       注册TrapInform

每个Snmp class实例可以为它们自己的traps / informs注册。也就是说,一个Snmp对象可以有它自己的一套过滤器和回调,当收到的trapinform满足过滤条件时就会调用。当每个新的呼叫清理了先前的过滤器设置时,成员函数Snmp::notify_register()可能会多次被调用。当调用成员函数Snmp:notify_unregister()Snmp实例撤消时,相应的接收Trap / inform的会话将会终止。

1.5.2.2.       Snmp::notify_register()的基本形式

notification的注册基本形式中包括:notification类型、notification来源、过滤参数、OidCollectionTargetCollection。使用该形式的notify_register()会在所有本地端口上触发notification的监听。所以如果本地机器有多重初始地址(即它会有多重网络接口),所有的接口将会被开启,并使用已知的port / socket来接收notify。例如:如果我的机器是双网卡的,两个卡都支持IPInternet Protocol)协议,其中一个还支持IPXInternet Exchange Protocol)协议;(如果)调用基本形式的notify_register(),则会在两个IP接口上使用已知的SNMP trap端口,在IPX接口上使用已知的trap IPX套接字(socket number)。

1.5.2.3.       Snmp::notify_register()的备用形式

作为备用,重载形式的notify_register()可接受一个附加参数,进而允许指定本地接口来监听informAddressCollectionAddressCollection参数包含了一组需要监听的Address对象列表,包括:IpAddresses, IpxAddresses, UdpAddresses IpxSockAddresses。下表描述了AddressCollection以及notify_register()的运作方式:

AddressCollection Element Behavior Definition

Address Class

Value

Description

IpAddress

Any value except 0.0.0 .0

用已知的IP端口监听指定的IP接口

IpAddress

0.0.0 .0

用已知的IP端口监听所有IP接口

UdpAddress

Any value except 0.0.0 .0

用已知的UDP端口监听指定的UDP接口

UdpAddress

0.0.0 .0

用已知的UDP端口监听所有UDP接口

IpxAddress

Any value except 00000000:000000000000

用已知的IPX端口监听指定的IPX接口

IpxAddress

00000000:000000000000

用已知的IPX端口监听所有IPX接口

IpxSockAddress

Any value except 00000000:000000000000

用已知的IPX套接字监听指定的IPX接口

IpxSockAddress

00000000:000000000000

用已知的IPX套接字监听所有IPX接口

1.5.2.4.       notify_regsiter()的过滤功能

当(需要)过滤时,过滤器的行为(如下):如果收到的informtrapOidCollection中的id单元(item)一致,并且收到的informtrapTargetCollection中的单元一致,则相应的inform / trap会被送到调用者指定的回调中。注意,如果OidCollection为空,则所有的inform都将通过id检查,(同样的)如果TargetCollection为空,则所有的inform都将通过Target检查。

1.5.3.       使用OidCollection, TargetCollectionAddressCollections过滤

SNMP++提供了3种有序集合的collection classe,共同来收集Oids, TargetsAddresses。所有collection classe操作形式都一样,因为它们是从同样的C++模板类SnmpCollection派生来的。统一的集合操作如下:

Target and Oid Collection Class Member Functions

Description

Constructors

 

     SnmpCollection::SnmpCollection(void);

构造一个空的集合

     SnmpCollection::SnmpCollection(const T &t );

用单一元素构造一个集合

Destructors

 

     SnmpCollection::SnmpCollection();

销毁集合,释放所有资源

Member Functions

 

     int size();

返回集合的大小

     SnmpCollection & operator += ( T &t);

增加一个元素到集合

     SnmpCollection & operator = (SnmpCollection &collection);

将一个集合赋给另一个

     T& operator[]( int p);

访问集合中的一个元素

     int set_element( const T& i, const int p);

在集合种设置一个已有的元素

     int get_element( T& i, const int p);

从集合获取一个元素

1.5.3.1.       生成并使用集合作为过滤器

生成并使用SnmpCollections作为接收一个trap / inform的过滤器是简单而直接的。Notify的注册(函数)有3个参数:TargetCollection, OidCollectionAddressCollection。要构造这些过滤器,首先得实例化一个集合,然后用重载的操作符“+=”把元素加入其中。

// 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” ;

1.6.        SNMP++ Class返回的错误号

使用SNMP++时,可返回多种(错误)编号。这些错误号可穿越平台,进而帮助应用的开发者发现并检查错误条件。

1.6.1.       Snmp Class的错误消息成员函数

如果在使用Snmp成员函数过程中出现了一个错误,成员函数Snmp::error_msg( )可以用来检索出一个友好的错误字符串。

//------------------------[ error message]-----------------------------

char * Snmp::error_msg( const int status);       // returns string for provided status


你可能感兴趣的:(云的SNMP++)