SNMP_PP_CHS —— 中文“snmp_pp.doc”整合版!

SNMP++
C++构建的,处理简单网罗管理协议(SNMP)API
 
这是篇描述 SNMP++ 的文档。面向对象的 SNMP++ 是一套专注于网络管理的开放技术,是 SNMP 协议原理和 C++ 结合的产物。该文档描述了各种各样可移植的 C++ 类( Class ),正是这些 C++ 类构建了 SNMP++ 。同时包含的还有这些类的相关的许多例子。
可以登录 http://rosegarden.external.hp.com/snmp++ ,下载 SNMP++ 的源码,和一些正在实际中使用的例子,以及其他相关文档。
 
译者序:
本着为 CHINESE 人民服务的精神(其实为了自己查起方便),完成了 CHS 的翻译,希望对大家有用。
能力有限,所以文章中会存在许多的不当之处,特别是偶也是一个初学者。只是希望通过这一工作来认识更多的朋友。
俺对书中的内容不作任何担保,呵呵~对使用本书中所述内容进行操作所引起的事故亦不承担任何责任。
 
注意: 为符合 CHS 习惯,在不损害愿意的前提下,在许多中加入了注释:这些地方我用 ... 来标注。
PS 因为原文较老,故而删除了原文中对现在意义不大的两章:
Chapter 1 2.61 版本扩充的内容(截止本文翻译完成,已经是 3.2.20 版了)
Chapter 2 产品正在使用 SNMP++ 的产品( N 年过去,使用 SNMP++ 的产品已经非常多了)
 
陈云昊     Friday, April 07, 2006    21:48:12

 
SNMP++. 1
C++构建的,处理简单网罗管理协议(SNMP)API1
1.     介绍... 6
1.1.      什么是SNMP++. 6
1.2.      SNMP++的本质... 6
1.2.1.        简单易用的SNMP++. 6
1.2.2.        编程安全的SNMP++. 7
1.2.3.        可移植的SNMP++. 8
1.2.4.        可扩充的SNMP++. 8
2.     一个介绍性的例子... 9
2.1.      一个简单的SNMP++例子... 9
2.2.      对介绍性例子的分析... 9
3.     SNMP++特性... 10
3.1.      完整的一套SNMP C++... 10
3.2.      SNMP内存的自动管理... 10
3.3.      简单易用的... 10
3.4.      强大灵活的... 10
3.5.      可移植对象的... 10
3.6.      自动超时和重发机制... 10
3.7.      阻塞模式... 11
3.8.      异步的非阻塞模式... 11
3.9.      NotificationTrap的收发... 11
3.10.     通过双效的API支持SNMPv1SNMPv2. 11
3.11.     支持SNMPGet, Get Next, Get Bulk, Set, InformTrap的操作... 11
3.12.     通过继承实现重定义... 11
4.     Microsoft Windows 系列操作系统上使用SNMP++. 12
4.1.      WinSNMP Version 1.1的使用... 12
4.2.      IPIPX的支持... 12
4.3.      NotificationTrap收发的支持... 12
4.4.      HP OpenView for Windows 兼容... 12
5.     UNIX上使用SNMP++. 13
5.1.      统一的类的接口... 13
5.2.      WindowsUNIX的仿真与移植... 13
5.3.      HP OpenView for UNIX 兼容... 13
6.     SNMP Syntax Classes. 14
7.     Object Id Class. 15
7.1.      对象标识符类... 15
7.2.      Oid Class的成员函数列表... 15
7.3.      一些Oid Class的例子... 16
8.     OctetStr Class. 19
8.1.      八位字节类... 19
8.2.      OctetStr Class的成员函数列表... 19
8.3.      注意... 20
8.4.      一些OctetStr Class的例子... 21
9.     TimeTicks Class. 22
9.1.      时间戳类... 22
9.2.      TimeTicks Class的成员函数列表... 22
9.3.      注意... 22
9.4.      一些TimeTicks Class的例子... 23
10.          Counter32 Class. 24
10.1.     32位计数器类... 24
10.2.     Counter32 Class的成员函数列表... 24
10.3.     一些Counter32 Class的例子... 24
11.          Gauge32 Class. 26
11.1.     容量类... 26
11.2.     Gauge32 Class的成员函数列表... 26
11.3.     一些Gauge32的例子... 26
12.          Counter64 Class. 28
12.1.     64位计数器类... 28
12.2.     Counter64 Class的成员函数列表... 28
12.3.     一些的Counter64 Class例子... 29
13.          Address Class. 30
13.1.     什么是网络地址类?... 30
13.2.     为什么要使用网络地址类?... 30
13.3.     Address class. 30
13.4.     Address Classes及其接口... 30
13.5.     IpAddress Class的特点... 32
13.6.     GenAddress的特点... 32
13.7.     Address Class的有效性... 32
13.8.     UdpAddressesIpxSockAddresses. 33
13.8.1.       UdpAddresses发送请求... 33
13.8.2.       IpxSockAddresses发送请求... 33
13.8.3.       UdpAddressIpxSockAddress接收Notification. 33
13.9.     有效的地址格式... 33
13.10.       Address Class例子... 34
14.          The Variable Binding Class. 36
14.1.     Variable Binding Class成员函数列表... 36
14.2.     Vb Class的公有成员函数... 37
14.2.1.       Vb Class的构造和析构函数... 37
14.2.2.       Vb ClassGet Oid / Set Oid成员函数... 38
14.2.3.       Vb ClassGet Value / Set Value成员函数... 38
14.2.4.       用一个GenAdress对象设置value. 39
14.2.5.       用一个UdpAdress对象设置value. 39
14.2.6.       用一个IpxSockAdress对象设置value. 40
14.2.7.       用一个Octet对象设置value部分... 40
14.2.8.       Vb Class成员函数:Get Value. 40
14.2.9.       Vb 对象的成员函数:Get Syntax. 41
14.2.10.     检查Vb对象的有效性... 42
14.2.11.     Vb对象付给另一个Vb对象... 42
14.2.12.     Vb对象的错误信息... 42
14.3.     Vb Class例子... 42
15.          Pdu Class. 45
15.1.     Pdu Class成员函数列表... 45
15.2.     Pdu Class的构造和析构... 46
15.3.     访问Pdu的成员函数... 46
15.4.     Pdu Class重载操作符... 47
15.5.     Pdu Class处理TrapsInforms的成员函数... 47
15.6.     加载Pdu对象... 48
15.7.     加载Pdu对象... 48
15.8.     卸载Pdu对象... 49
16.          SnmpMessage Class. 50
17.          Target Class. 51
17.1.     抽象的Target51
17.2.     Target地址... 51
17.3.     重发机制... 51
17.4.     Target Class接口... 51
17.5.     CTarget Class (Community为基础的Target)52
17.5.1.       CTarget对象可通过3种不同的方式构建... 53
17.5.2.       修改CTargets. 53
17.5.3.       访问CTargets. 53
17.5.4.       CTargets例子... 54
18.          Snmp Class. 55
18.1.     Snmp Class成员函数列表... 55
18.2.     双效的API56
18.3.     Snmp Class的公共成员函数... 57
18.3.1.       Snmp Class的构造和析构函数... 57
18.3.2.       Snmp Class构造函数... 57
18.3.3.       Snmp Class析构函数... 57
18.3.4.       Snmp Class发送请求的成员函数... 57
18.3.5.       Snmp Class的阻塞方式成员函数: Get57
18.3.6.       Snmp Class的阻塞方式成员函数: Get Next57
18.3.7.       Snmp Class的阻塞方式成员函数: Set58
18.3.8.       Snmp Class的阻塞方式成员函数: Get Bulk. 58
18.3.9.       Snmp Class的阻塞方式成员函数:Inform.. 58
18.4.     Snmp Class的异步方式成员函数... 58
18.4.1.       SNMP++异步回调函数的类型定义... 58
18.4.2.       取消一个异步请求... 59
18.4.3.       Snmp Class的异步成员函数:Get59
18.4.4.       Snmp Class的异步成员函数:Set60
18.4.5.       Snmp Class的异步成员函数Get Next60
18.4.6.       Snmp Class的异步成员函数:Get Bulk. 60
18.4.7.       Snmp Class的异步成员函数:Inform.. 60
18.5.     SNMP++通知的方法... 60
18.5.1.       发送Trap. 61
18.5.2.       接收Notification. 62
18.5.3.       使用OidCollection, TargetCollectionAddressCollections过滤... 63
18.6.     SNMP++ Class返回的错误号... 64
18.6.1.       Snmp Class的错误消息成员函数... 64
19.          运行模式... 65
19.1.     Microsoft Windows事件驱动系统的运作... 65
19.2.     Open Systems Foundation (OSF) X11 Motif的运作... 65
19.3.     不以GUI为基础的应用的运作... 65
20.          状态&错误编号... 67
21.          错误状态值... 68
22.          Snmp Class例子... 69
22.1.     Getting a Single MIB Variable Example. 69
22.2.     Getting Multiple MIB Variables Example. 69
22.3.     Setting a Single MIB Variable Example. 71
22.4.     Setting Multiple MIB Variables Example. 71
22.5.     Walking a MIB using Get-Next Example. 72
22.6.     Sending a Trap Example. 73
22.7.     Receiving Traps Example. 73
23.          参考书目... 75

SNMP++
框架的对象模型( Object Modeling Technique )视图
1.         介绍
目前有许多可以创建网络管理应用的 SNMP API 。大多数 API 都提供了一个很大的函数库,调用这些函数的程序员需要熟悉 SNMP 内部的工作原理和它的资源管理机制。这些 API 大多都是平台相关的,导致了 SNMP 的代码也成了操作系统相关的或者网络系统平台有关的,难以移植。另一方面由于 C++ 有丰富的、可复用的标准类库,用 C++ 开发应用成了目前的主流,然而 C++ 标准类库所缺少的正是一套封装好的处理网络管理的类。如果基于面向对象的方法来进行 SNMP 网络编程,可以提供以下诸多好处:易用、安全、可移植、能扩展。因此 SNMP++ 灵活有效的解决了其他类似 API 执行和管理起来都很痛苦的问题。
1.1.        什么是SNMP++
SNMP++ 是一套 C++ 类的集合,它为网络管理应用的开发者提供了 SNMP 服务。 SNMP++ 并非是现有的 SNMP 引擎的扩充或者封装。事实上为了效率和方便移植,它只用到了现有的 SNMP 库里面极少的一部分。 SNMP++ 也不是要取代其他已有的 SNMP API ,比如 WinSNMP SNMP++ 只是通过 提供强大灵活的功能,降低管理和执行的复杂性 ,把面向对象的优点带到了网络编程中。
1.2.        SNMP++的本质
1.2.1.       简单易用的SNMP++
面向对象的 SNMP 编程应该是简单易用的。毕竟, SNMP 原意就是 简单网络管理协议 SNMP++ 只是将简单还给 SNMP !应用的开发者不需要关心 SNMP 的底层实现机制,因为面向对象的方法已经将 SNMP 内部机制封装、并隐藏好了。 SNMP++ 的简单易用表现在以下方面:
1.2.1.1.       SNMP提供了简单易用的接口
使用 SNMP++ 不需要精通 SNMP ,甚至不需要精通 C++ !因为 SNMP++ 里面几乎没有 C 的指针,所以可以简单的通过 API 直接使用。
1.2.1.2.       可以方便的迁移至SNMPv2
SNMP++ 的主要目标之一就是开发一套 API ,使得迁移至 SNMPv2 的过程中尽可能少地影响现有代码。 SnmpTarget class 使之成为了可能。
1.2.1.3.       保留了对SNMP灵活的底层开发
这是为了方便那些不希望使用面向对象方法,而直接编写 SNMP 的底层机制的用户。虽然 SNMP++ 快速而方便,但是有些时候程序员也许希望直接使用底层的 SNMP API
1.2.1.4.       鼓励程序员用功能强大的C++,不要因学得不够快而去指责它
使用 SNMP++ 的用户不需要精通 C++ 。基本的 SNMP 的知识是必要的,但是实际上也需要对 C++ 初步的理解。
1.2.2.       编程安全的SNMP++
大多数 SNMP API 需要程序员去管理大量的资源。不恰当的装载或卸载这些资源,会导致内存崩溃或泄漏。 SNMP++ 提供的安全机制,可以实现对这些资源的自动管理。 SNMP++ 的用户可以体验到自动管理资源与对话所带来的好处。 SNMP++ 在编程上的安全突出表现在下面的领域:
1.2.2.1.       SNMP资源提供安全的管理
这包括对 SNMP 的结构、会话以及传输层的管理。 SNMP class 被设计成所谓的抽象数据类型( ADT ),隐藏了私有数据,而通过提供公有的成员函数来访问或修改这些隐藏了的实例变量。
1.2.2.2.       提供查错、自动超时重发的机制
SNMP++ 的用户不需要关心如何为不可靠的网络传输机制提供可靠性。可能出现的通信错误包括:数据包丢失、数据包重复以及反复提取数据包。 SNMP++ 消除了所有这些问题出现的可能性,为用户提供了传输层的可靠性。
 
1.2.3.       可移植的SNMP++
SNMP++ 的主要目的之一就是提供一套可移植的 API ,进而穿越各种操作系统( Os )、网络系统( NOS )以及网络管理平台。由于 SNMP++ 隐藏了内部机制,所以从各个平台的角度来看 SNMP++ 的公用接口都是一样的。使用 SNMP++ 的程序员不需要为平台迁移去修改代码。另一个移植方面的问题是在多种协议上运行的能力。目前, SNMP++ 能运行在 IP 协议和 IPX 协议上,或者两者都可以。
1.2.4.       可扩充的SNMP++
扩充不应该只是多一种选择,而是更深层次的。 SNMP++ 不仅是可扩充,而且是很容易扩充。 SNMP++ 的扩充囊括了对下列领域的支持:新的操作系统、网络系统、网络管理平台、网络协议、 SNMPv2 及其新特性。通过派生 C++ 的类, SNMP++ 的用户可以根据自己的喜好继承、重载。
1.2.4.1.       重载SNMP++的基础类
应用的开发者可以通过派生出 SNNP++ 的子类来提供所需的操作和属性,这正是面向对象的核心主题。 SNMP++ 的基础类被打造成通用的、没有包含任何具体的数据结构和操作。通过 C++ 派生类以及重新定义虚函数,可以很容易的添加新属性。

2.         一个介绍性的例子
在开始介绍 SNMP++ 的各种特性之前,这里先举个简单的例子来展现它的强大和简单。该例子是从指定的代理端上获取 SNMP MIB 的系统描述符( System Descriptor object )。包含了创建一个 SNMP++ 会话、获取系统描述符,并打印显示出来的所需的所有代码。其中重发和超时机制已经被 SNMP++ 自动管理了。以下属于 SNMP++ 的代码,采用粗体显示。
2.1.        一个简单的SNMP++例子
#include “snmp_pp.h”
#define SYSDESCR “1.3.6.1.2.1.1.1.0”            // Object ID for System Descriptor
void get_system_descriptor()
{
   int status;                                        // return status      
   CTarget ctarget( (IpAddress) “10.4.8.5”);      // SNMP++ community target
   Vb vb( SYSDESCR);                               // SNMP++ Variable Binding Object
  Pdu pdu;                                            // SNMP++ PDU
 
    //-------[ Construct a SNMP++ SNMP Object ]---------------------------------------
  Snmp snmp( status);                         // Create a SNMP++ session
   if ( status != SNMP_CLASS_SUCCESS) {             // check creation status
      cout << snmp.error_msg( status);                  //  if fail, print error string
      return; }
 
   //-------[ Invoke a SNMP++ Get ]-------------------------------------------------------
  pdu += vb;                                      // add the variable binding to the PDU
  if ( (status = snmp.get( pdu, ctarget)) != SNMP_CLASS_SUCCESS)
      cout << snmp.error_msg( status);
   else {
      pdu.get_vb( vb,0);                             // extract the variable binding from PDU
      cout << “System Descriptor = ”<< vb.get_printable_value(); } // print out the value
 
}; // Thats all!
2.2.        对介绍性例子的分析
真正属于 SNMP++ 的语句就 10 行代码。首先用代理端的 IP 地址建立一个 CTarget 对象;然后用 MIB 对象所定位的系统描述符创建一个变量绑定( Vb );接着就把这个 Vb 纳入一个 Pdu 对象;最后生成一个 Snmp 对象来执行 SNMP get 操作。一旦找到了所需的数据,对应的应答消息就被打印出来。另外,所有的处理错误代码也都包含在内了。

3.         SNMP++特性
3.1.        完整的一套SNMP C++
SNMP++ 是以一套 C++ 类作为基石的。这些类是:对象描述符( Oid )类、变量绑定( Vb )类、协议数据单元( Pdu )类、 Snmp 类。并且,其他各种用抽象语法表示( ASN.1 )来描述的管理信息结构( SMI ),也被抽象成了简单的、面向对象的类型。
3.2.        SNMP内存的自动管理
SNMP++ 的对象被实例化或销毁的时候 , 其相关的类可以自动管理着各种各样的 SNMP 结构和资源。这就使得应用的开发者不用再担心数据结构和资源的卸载,不然就得为防止内存的崩溃或者泄漏提供有效的保护措施。 SNMP++ 的对象的实例化可以是静态的,也可以是动态的。静态的实例化可以在对象脱离它的作用域时卸载掉;动态分配则需要使用 C++ new delete 。在 SNMP++ 内部,有许多被隐藏和保护在公用接口后面的 SMI 结构。所有的 SMI 结构都是在内部管理的,程序员不需要定义或管理 SMI 的结构和它的值。因为在 SNMP++ 内绝大部分地方是不存在 C 的指针的。
3.3.        简单易用的
由于隐藏并管理了所有 SMI 结构和它们的值, SNMP++ 的类使用起来即简单又安全。外部程序员无法破坏到隐藏和保护在作用域后面的东东。
3.4.        强大灵活的
SNMP++ 提供了强大灵活的功能,降低了管理和执行的复杂性。每个 SNMP++ 对象都通过建立一个会话来和一个代理端联系。即由一个 SNMP++ 的对话类的实例,就能处理所有与特定代理端的连接。另外自动重发和超时控制的机制,为每个 SNMP++ 对象都带来了可靠性。一个应用可能会包含许多 SNMP++ 的对象的实例,每个实例都可能与相同或不同的代理端通话。有了这个功能强大的特性,网络管理程序就可以为每个管理单元建立起不同的会话。另一方面,就算单一的 SNMP 会话也可以解决问题。例如:一个应用可以通过一个 SNMP++ 对象来处理图形统计,另一个 SNMP++ 对象监控 trap ,也许还有第三个 SNMP++ 对象用以浏览 SNMP SNMP++ 自动并行处理了同一时刻来自不同 SNMP++ 实例的请求。
3.5.        可移植对象的
SNMP++ 的主体是可以移植的 C++ 代码。其中只有 Snmp Class 的实现与不同的目标操作系统有关。如果你的程序中包含了 SNMP++ 的代码,那么导出这部分代码的时候,就可以不做任何修改。
3.6.        自动超时和重发机制
SNMP++ 提供了自动超时和重发机制,程序员不用去实现超时或重发机制的代码。重发机制是在 SnmpTarget Class 里面定义的,这就使得每一个目标( Target )都具有了它自己的超时 / 重发机制。
3.7.        阻塞模式
SNMP++ 提供了阻塞方式。 MS-Windows 上的阻塞方式可以并发的阻塞从每个 SNMP 类的实例发出的请求。
3.8.        异步的非阻塞模式
SNMP++ 还为应答提供了异步的非阻塞的方式。超时和重发机制同时支持阻塞和异步两种模式。
3.9.        NotificationTrap的收发
SNMP++ 允许在多种传输层上(包括 IP IPX )收发 trap 。而且 SNMP++ 还允许使用非标准的 IP 端口和 IPX 套接口来收发 trap
3.10.     通过双效的API支持SNMPv1SNMPv2
SNMP++ 的设计可同时支持 SNMPv1 SNMPv2 的使用。所有 API 的操作都被设计成了双效的,也即操作是 SNMP 版本无关的。通过使用 SnmpTarget 类,与 SNMP 的版本相关的操作被抽象出来了。
3.11.     支持SNMPGet, Get Next, Get Bulk, Set, InformTrap的操作
SNMP++ 完整的支持 SNMP 6 种操作。这 6 SNMP++ 的成员函数使用相同的参数表,也都支持阻塞和非阻塞(异步)方式。
3.12.     通过继承实现重定义
SNMP++ 是用 C++ 实现的,所以允许程序员重载或重定义那些不适合他们的操作。举个例子:如果一个应用需要特定的 Oid 对象,那就需要建立一个 Oid Class 的子类,用以继承所有 Oid 类的属性和操作,同时在派生类种加入新的属性和操作。

4.         Microsoft Windows 系列操作系统上使用SNMP++
SNMP++ 已经在 MS-Windows 3.1, MS-Windows For Work Groups 3.11, MS-Windows NT 3.51, and MS-Windows ’95 上实现了。
4.1.        WinSNMP Version 1.1的使用
MS-Windows 上可以用 WinSNMP Version 1.1 来运行 SNMP++ 。这就使得其他用 WinSNMP 代码直接写的 SNMP 应用可以与 SNMP++ 的应用兼容。注意,目前 HP MS-Windows 设备使用 WinSNMP ,其他设备不需要使用 WinSNMP 来进行 ANS.1 的编码和解码。但那些没有使用 WinSNMP 的设备也需要与 WinSNMP 的应用兼容,才能和 SNMP++ 的应用兼容。
4.2.        IPIPX的支持
可以通过一个 WinSock compliant stack ,来实现对 IP 的操作。同时为了在 IPX 协议上运行,还需要兼容 Novell 网络的客户程序和驱动 。目前 SNMP++ 已经通过了在广泛多样的协议栈下的运行测试,这些协议栈包括: FTP Netmanage LanWorkPlace MS-WFWG 3.11 ,以及 Windows NT
4.3.        NotificationTrap收发的支持
SNMP++ 包含了对 WinSNMP trap 机制的支持。这同时包括了 trap 的发送和收取。在接收 trap 的时候,还提供了过滤 trap 的功能。
4.4.        HP OpenView for Windows 兼容
已经有大量使用 SNMP++ 创建的应用,实现了 HP OpenView for Windows 的兼容。

5.         UNIX上使用SNMP++
5.1.        统一的类的接口
用在 UNIX 设备上的 SNMP++ 类的接口和 MS-Windows 是一样的。
5.2.        WindowsUNIX的仿真与移植
通过编译、连接对应的 SNMP++ 类, SNMP++ 就可以实现在 UNIX 上运行。 SNMP++/UNIX 的设计决定了它可以同时运行在原始的 UNIX 字符模式、 X-Window 模式,或者 Windows-to-UNIX 的仿真工具上。
5.3.        HP OpenView for UNIX 兼容
已经有大量使用 SNMP++ 创建的应用,实现了与 HP OpenView for UNIX 的兼容。

6.         SNMP Syntax Classes
SNMP++ SNMP Syntax 的对象模型( Object Modeling Technique )视图
SNMP++ SNMP syntax classe 描绘了一个具有 C++ 面向对象风格的视图。即用于描述 SNMP SMI ASN.1 的数据类型视图。它包含了映射到对应的 SMI 类型的一组类的集合。而且为了方便使用,还引入了一些非 SMI 的类。 SNMP++ 为这些 SNMP 数据类型提供了强大、简单易用的接口。下表概要地描述了各种 SNMP++ syntax classes
SNMP++ Syntax Class Name
Class Description
SMI or ASN.1 Counter part
SnmpSyntax
Parent of all syntax classes.
No ASN.1 counter part, used for OO structure.
Oid
Object identifier class.
ASN.1 Object Identifier.
OctectStr
Octet string class.
ASN.1 Octet string.
Uint32
Unsigned 32 bit integer class.
SMI unsigned 32 bit integer.
TimeTicks
TimeTicks class.
SMI time ticks.
Counter32
32 bit counter class.
SMI 32 bit counter.
Gauge32
32 bit gauge class.
SMI 32 bit gauge.
Int32
Signed 32 bit integer.
SMI 32 bit signed integer.
Counter64
64 bit counter class.
SMI 64 bit counter.
Address
Abstract address class.
No ASN.1 counter part used for OO structure.
IpAddress
IP address class.
SMI IP address.
UdpAddress
UdpAddress class
SMI IP address with port specification.
IpxAddress
IPX address class.
No ASN.1 or SMI counter part
IpxSockAddress
IPX Address class with socket number.
No ASN.1 or SMI counter part
MacAddress
MAC address class.
SMI counter part
GenAddress
Generic Address
No ASN.1 or SMI counter part.

7.         Object Id Class
SNMP++ Oid Class 的对象模型( Object Modeling Technique )视图
7.1.        对象标识符类
对象标识符类( Oid )封装了 SMI 的对象标识。信息管理库( MIB )中所定义的 SMI 的对象是一种在 MIB 中找到的数据元素的数据标识。与 SMI Oid 相关的结构和函数,自然都是面向对象的。事实上 Oid class C++ String class 有许多共同之处。如果你熟悉 C++ String class 或者 MFC CString class ,那么你就会感觉 Oid class 用起来很亲切、简单。 Oid class 被设计成了快速有效的类;它可以定义和操作对象标识;不依赖现有的 SNMP API ,完全是可移植的;可以在任何 ANSI C++ 编译器上进行编译。
7.2.        Oid Class的成员函数列表
Oid Class Member Functions
说明
Constructors
 
     Oid::Oid( void);
构造一个空的的 Oid
     Oid::Oid( const char *dotted_string);
用带点的字符串构造新的 Oid
     Oid::Oid( const Oid &oid);
用已有的 Oid 构造新的 Oid
     Oid::Oid( const unsigned long *data, int len);
通过一个指针和长度来构造一个新的 Oid
Destructor
 
     Oid::~Oid( );
销毁一个 Oid ,释放所有的堆
Overloaded Operators
 
     Oid & operator = ( const char *dotted_string);
将一个带点的字符串付给一个 Oid
     Oid & operator = ( const Oid &oid);
将一个 Oid 付给另一个 Oid
     int operator == ( const Oid &lhs, const Oid& rhs);
判断两个 Oid 是否相等
     int operator == ( const Oid& lhs, const char*dotted_string);
判断一个 Oid 是否和一个带点的字符串相等
     int operator != ( const Oid &lhs, const Oid& rhs);
判断两个 Oid 是否不等
     int operator != ( const Oid & lhs, const char *dotted_string);
判断一个 Oid 是否和一个带点的字符串不相等
     int operator < ( const Oid &lhs, const Oid& rhs);
判断一个 Oid 是否比另一个小
     int operator < ( const Oid &lhs, const char *dotted_string);
判断一个 Oid 是否比一个带点的字符串小
     int operator <=( const Oid &lhs,const Oid &rhs);
判断一个 Oid 是否 小于等于 另一个
     int operator <= ( const Oid &lhs, const char *dotted_string);
判断一个 Oid 是否 小于等于 一个带点的字符串
     int operator > ( const Oid &lhs, const Oid &rhs);
判断一个 Oid 是否比另一个大
     int operator > ( const Oid &lhs, const char * dotted_string);
判断一个 Oid 是否比一个带点的字符串大
     int operator >= ( const Oid&lhs, const Oid &rhs);
判断一个 Oid 是否 大于等于 另一个
     int operator >= ( const Oid &lhs, const char* dotted_string);
判断一个 Oid 是否 大于等于 一个带点的字符串
     Oid& operator += ( const char *dotted_string);
将一个带点的字符串加到一个 Oid 后面
     Oid& operator +=( const unsigned long i);
将一个整数加到一个带点的 Oid 字符串后面
     Oid& operator+=( const Oid& oid);
将一个 Oid 加到另一个 Oid 后面
     unsigned long &operator [ ] ( int position);
访问 Oid 的一个独立子单元
Output Member Functions   
 
     char * get_printable( const unsigned int n);
返回一个 Oid n 个带点格式的子单元
     char *get_printable( const unsigned long s, const unsigned long n);
返回从 s 开始,以点号分割的 n 个子单元
     char *get_printable();
返回以点号分割的 Oid 字符串
     operator char *();
同上
Miscellaneous Member Functions
 
     set_data (const unsigned long *data,const unsigned long n);
用指针和长度来设置一个 Oid
     unsigned long len( );
返回 Oid 中子单元的个数(长度)
     trim( const unsigned long n=1);
删除 Oid 最右边的 n 个子单元,默认删除 1
     nCompare( const unsigned long n, const Oid& oid);
从左至右比较 Oid 的前 n 个子单元
     RnCompare( const unsigned long n, const Oid& oid);
从右至左比较 Oid 的后 n 个子单元
     int valid( );
返回 Oid 的有效性
7.3.        一些Oid Class的例子
下面的例子展示了 Oid Class 的不同用法。 Oid Class 不需要依赖其他库和模块。下列代码在 ANSI/ISO C++ 上编译通过
#include “oid.h”
void oid_example()
{
   // construct an Oid with a dotted string and print it out
   Oid o1("1.2.3.4.5.6.7.8.9.1");
   cout << “o1= “ << o1.get_printable ();
   // construct an Oid with another Oid and print it out
   Oid o2(o1);
   cout << “o2= ” << o2.get_printable();
   // trim o2’s last value and print it out
   o2.trim(1);
   cout << “o2= ” << o2.get_printable();
 
   // add a 2 value to the end of o2 and print it out
  o2+=2;
   cout << “o2= ” << o2.get_printable();
 
   // create a new Oid, o3
   Oid o3;
   // assign o3 a value and print it out
   o3="1.2.3.4.5.6.7.8.9.3";
   cout << “o3= ” << o3.get_printable();
 
   // create o4
   Oid o4;

   // assign o4 o1’s value
   o4=o1;
 
   // trim off o4 by 1
   o4.trim(1);
 
   // concat a 4 onto o4 and print it out
  o4+=”.4”;
   cout << “o4= ” << o4.get_printable();
 
   // make o5 from o1 and print it out
   Oid o5(o1);
   cout << “o5= ” << o5.get_printable();
   // compare two not equal oids
   if (o1==o2)   cout << "O1 EQUALS O2";
   else    cout << "o1 not equal to o2";
              
   // print out a piece of o1
   cout << "strval(3) of O1 = “ << o1.get_printable(3);
 
   // print out a piece of o1
   cout << "strval(1,3) of O1 = “ << o1.get_printable(1,3);
 
   // set o1's last subid
  o1[ o1.len()-1] = 49;
   cout << "O1 modified = “ << o1.get_printable();
 
   // set o1's 3rd subid
   o1[2]=49;
   cout << "O1 modified = “ << o1.get_printable();
  
   // get the last subid of 02
   cout << "last of o2 = “ << o2[o2.len()-1];
  
   // get the 3rd subid of 02
   cout << "3rd of o2 = “ << o2[2];
  
   // ncompare
   if (o1.nCompare(3,o2))
      cout << "nCompare o1,o2,3 ==";
   else
     cout << "nCompare o1,o2,3 !=";               
    
   // make an array of oids
   Oid oids[30]; int w;
   for ( w=0;w<30;w++)                          
   {
     oids[w] = "300.301.302.303.304.305.306.307";
     oids[w] += (w+1);
   }  
   for (w=0;w<25;w++)
   {
     sprintf( msg,"Oids[%d] = %s",w, oids[w].get_printable());
     printf(“%s”,msg, strlen(msg));
    } 
}

 
8.         OctetStr Class
SNMP++ OctetStr Class 的对象模型( Object Modeling Technique )视图
8.1.        八位字节类
通过 SNMP++ Octet class ,可以简单且安全地操作 SMI 8 位字节。有了 Octet class ,就不需要通过内部指针和长度来操作 8 位字节了。使用 SNMP++ Octet class 来实例化、操作、销毁一个 8 位字节对象是很简单的,不用担心如何管理内存以及内存是否会泄漏。与 ANSI C++ string class 类似, OctetStr class 可以通过多种方法构造 8 位字节,还可以对它们进行赋值操作,与其他 SNMP++ classes 一起使用。
8.2.        OctetStr Class的成员函数列表
OctetStr Class Member Functions
说明
Constructors
 
     OctetStr::OctetStr( void);
构造一个空的 OctetStr
     OctetStr::OctetStr( const char* string);
用一个没有结束符的字符串构造 OctetStr
     OctetStr::OctetStr( const unsigned char *s, unsigned long int i);
通过一个指针和长度来构造 OctetStr
     OctetStr::OctetStr( const OctetStr &octet);
用已有的 OctetStr 构造新的 OctetStr
Destructor
 
     OctetStr::~OctetStr( );
销毁一个 OctetStr
Overloaded Operators
 
     OctetStr& operator = ( const char *string);   
将一个没有结束符的字符串付给一个 OctetStr
     OctetStr& operator = ( const OctetStr& octet);
将一个 OctetStr 付给另一个 OctetStr
     int operator == ( const OctetStr &lhs, const OctetStr &rhs);
判断两个 OctetStr 对象是否相等
     int operator == ( const OctetStr & lhs, const char *string);
判断 OctetStr 是否和一个 char* 字符串相等
     int operator != ( const OctetStr& lhs, const OctetStr& rhs);
判断两个 OctetStr 对象是否不相等
     int operator != ( const OctetStr& lhs, const char *string);
判断 OctetStr 是否和一个 char* 字符串不相等
     int operator < ( const OctetStr&lhs, const OctetStr& rhs);
判断一个 OctetStr 是否比另一个小
     int operator < ( const OctetStr &lhs, const char * string);
判断一个 OctetStr 是否比另一个 char * 字符串小
     int operator <= ( const OctetStr &lhs, const OctetStr &rhs);
判断一个 OctetStr 是否 小于等于 另一个
     int operator <= ( const OctetStr &lhs, const char * string);
判断一个 OctetStr 是否 小于等于 一个 char * 的字符串
     int operator > ( const OctetStr& lhs, const OctetStr &rhs);
判断一个 OctetStr 是否比另一个大
     int operator > ( const OctetStr& lhs, const char * string);
Test if one OctetStr is greater than a char *.
判断一个 OctetStr 是否比一个 char * 的字符串大
     int operator >= ( const OctetStr& lhs, const OctetStr &rhs);
判断一个 OctetStr 是否 大于等于 另一个
     int operator >= ( const OctetStr& lhs, const char *);
判断一个 OctetStr 是否 大于等于 一个 char* 的字符串
    OctetStr& operator +=( const char * string);
在一个 OctetStr 后面连接一个字符串
    OctetStr& operator +=( const unsigned char c);
在一个 OctetStr 后面连接一个单字符
    OctetStr& operator+=( const OctetStr &octetstr);
将两个 OctetStr 连接在一起
    unsigned char& operator[ ] ( int position i);
用数组的形式来访问一个 OctetStr
Miscellaneous 
 
     void set_data( const unsigned char *s, unsigned long l);
用指针和长度来设置一个 OctetStr
     int nCompare( const unsigned long n, const OctetStr &o);
与另一个 OctetStr 比较前 n 个元素
     unsigned long len();
返回一个 OctetStr 的长度
     int valid();
返回一个 OctetStr 的有效性
     unsigned char * data();
返回一个指向内部数据的指针
     char * get_printable();
格式化输出,如果不是 ASCII 则按 16 进制处理
     char * get_printable_hex();
16 进制格式,进行格式化输出
8.3.        注意
当输出一个 OctetStr 对象时,如果该 8 位字节所包含的字符不是 ASCII 码,对成员函数 char * 或者 get_printable() 的调用,就会自动转换成对成员函数 get_printable_hex() 的调用。这就使得使用者只需要简单地使用成员函数 char * get_printable() 来进行输出。而成员函数 get_printable_hex() 是专门用来把 OctetStr 16 进制格式输出的。
8.4.        一些OctetStr Class的例子
// Octet Class Examples
#include “octet.h”
void octet_example()
{
   OctetStr octet1;    // create an invalid un- initialized octet object
   OctetStr octet2( “Red Hook Extra Bitter Ale”);      // create an octet with a string
   OctetStr octet3( octet2);    // create an octet with another octet
   unsigned char raw_data[50];    // create some raw data
  OctetStr octet4( raw_data, 50);    // create an OctetStr using unsigned char data
  
   octet1 = “Sierra Nevada Pale Ale”;    // assign one octet to another
   cout << octet1.get_printable();    // show octet1 as a null terminated string
   cout << octet4.get_printable_hex();    // show octet4 as a hex string
   cout << (char *) octet1;    // same as get_printable()
   if ( octet1 == octet2)    // compare two octets
      cout << “octet1 is equal to octet2”;
 
   octet2 += “WinterFest Ale”;    // concat a string to an Octet
   if ( octet2 >= octet3)
      cout << “octet2 greater than or equal to octet2”;
 
   octet2[4] = ‘b’;    // modify an element of an OctetStr using [ ]’s
 
   cout << octet.len();    // print out the length of an OctetStr
 
   unsigned char raw_data[100];
  octet1.set_data( raw_data, 100);    // set the data of an to unsigned char data
 
   // get the validity of an OctetStr
   cout << (octet1.valid() )? “Octet1 is valid” : “Octet1 is Invalid”;
 
}; // end octet example

9.         TimeTicks Class
SNMP++ TimeTicks Class 的对象模型( Object Modeling Technique )视图

9.1.        时间戳类
SNMP++ TimeTicks Class 为使用 SMI 中的 timeticks 带来了方便。 SMI 的时间戳被定义成了一种存放无符号长整形的存储单元。为了成为无符号长整形, SMI timeticks 被加工成了一种特殊的类型。因此 SNMP++ TimeTicks 类具有无符号长整形的所有功能和属性,但同时又是一个独立的类。对无符号长整形的任何操作,拿到 TimeTicks 的对象上一样有效。 TimeTicks class 与其他 SNMP++ 的类,比如 Vb class 交互的时候,还可以有些额外的操作:在使用 Vb class 的时候, TimeTicks 的对象可以被置入 Vb 对象(用 Vb::set ),也从 Vb 对象中取出(用 Vb::get )。也即,对于 SMI timeticks ,开发者可以像对无符号长整形一样来操作,并且还提供了一对一的映射关系。
9.2.        TimeTicks Class的成员函数列表
TimeTicks Class Member Functions
说明
Constructors
 
     TimeTicks::TimeTicks( void);
构造一个空的 TimeTicks 对象
     TimeTicks::TimeTicks( const unsigned long i );
用一个无符号长整形来构造一个 TimeTicks 对象
     TimeTicks:;TimeTicks( const TimeTicks &t);
用一个已有的 TimeTicks 对象来构造一个新的
Destructor 
 
     TimeTicks::~TimeTicks( );
销毁一个 TimeTicks 对象
Overloaded Operators
 
      TimeTicks& operator =( const TimeTicks &t);
重载赋值操作符
      char * get_printable();
格式化输出,格式为: DD Days, HH:MM:SS.hh
      operator unsigned long();
TimeTicks 转换为无符号长整形
9.3.        注意
TimeTicks 对象用 TimeTicks::get_printable() 输出时,其值自动被格式化为 “DD days, HH:MM:SS.hh” 。其中 DD 代表天, HH 代表小时( 24 时制的), MM 代表分钟, SS 是秒钟, hh 则是百分之几秒。
9.4.        一些TimeTicks Class的例子
// TimeTicks Examples
#include “timetick.h”
void timeticks_example()
{
    TimeTicks tt;    // create an un-initialized timeticks instance
    TimeTicks tt1( (unsigned long) 57);    // create a timeticks using a number
    TimeTicks tt2( tt1);    // create a timeticks using another instance
 
    tt = 192;    // overloaded assignment to a number
    tt2 = tt;    // overloaded assignment to another timeticks
 
    cout << tt.get_printable();    // print out in DD days, HH:MM:SS.hh
    cout << ( unsigned long) tt;    // print out unsigned long int value
 
}; // end timeticks example

10.     Counter32 Class
SNMP++ Counter32 Class 的对象模型( Object Modeling Technique )视图
10.1.     32位计数器类
当需要用到 SMI 中的 32 位计数器时, SNMP++ Counter32 Class 为之带来了方便。 SMI 的计数器被定义成了一种存放无符号长整形的存储单元。为了成为无符号长整形, SMI counters 被加工成了一种特殊的类型。因此 SNMP++ Counter32 类具有无符号长整形的所有功能和属性,但同时又是一个独立的类。对无符号长整形的任何操作,拿到 Counter32 的对象上一样有效。 Counter32 class 与其他 SNMP++ 的类,比如 Vb class 交互的时候,还可以有些额外的操作:在使用 Vb class 的时候, Counter32 的对象可以被置入 Vb 对象(用 Vb::set ),也从 Vb 对象中取出(用 Vb::get )。也即,对于 SMI counter ,开发者可以像对无符号长整形一样来操作,并且还提供了一对一的映射关系。
10.2.     Counter32 Class的成员函数列表
Counter32 Class Member Functions
说明
Constructors
 
     Counter32::Counter32( void);
构造一个空的 Counter32 对象
     Counter32::Counter32( const unsigned long i );
用一个无符号长整形来构造一个 Counter32 对象
     Counter32::Counter32( const Counter32 &c);
用一个已有的 Counter32 对象来构造一个新的
Destructor
 
     Counter32::~Counter32( );
销毁一个 TimeTicks 对象
Overloaded Operators
 
     Counter32& operator = ( const Counter32& c);
重载赋值操作符
     char * get_printable();
格式化输出 Counter32 对象
     operator unsigned long( );
Counter32 转换为无符号长整形
10.3.     一些Counter32 Class的例子
// Counter Examples
#include “counter.h”
void counter_example()
{
 
    Counter32 ctr;    // create an un-initialized counter instance
    Counter32 ctr1( (unsigned long) 57);            // create a counter using a number
    Counter32 ctr2(ctr1);    // create a counter using another instance
 
    ctr = 192;    // overloaded assignment to a number
    ctr1 = ctr;    // overloaded assignment to another counter
cout << (unsigned long) ctr;     // behave like an unsigned long int
 
}; // end counter example

11.     Gauge32 Class
SNMP++ Gauge32 Class 的对象模型( Object Modeling Technique )视图

11.1.     容量类
SNMP++ Gauge32 Class 为使用 SMI 中的 timeticks 带来了方便。 SMI 的容量被定义成了一种存放无符号长整形的存储单元。为了成为无符号长整形, SMI gauges 被加工成了一种特殊的类型。因此 SNMP++ Gauge32 类具有无符号长整形的所有功能和属性,但同时又是一个独立的类。对无符号长整形的任何操作,拿到 Gauge32 的对象上一样有效。 Gauge32 class 与其他 SNMP++ 的类,比如 Vb class 交互的时候,还可以有些额外的操作:在使用 Vb class 的时候, TimeTicks 的对象可以被置入 Vb 对象(用 Vb::set ),也从 Vb 对象中取出(用 Vb::get )。也即,对于 SMI gauge ,开发者可以像对无符号长整形一样来操作,并且还提供了一对一的映射关系。
11.2.     Gauge32 Class的成员函数列表
Gauge32 Class Member Functions
说明
Constructors
 
     Gauge32::Gauge32( void);
构造一个空的 Gauge32 对象
     Gauge32::Gauge32( const unsigned long i );
用一个无符号长整形来构造一个 Gauge32 对象
     Gauge32::Gauge32( const Gauge32 &g);
用一个已有的 Gauge32 对象来构造一个新的
Destructor
 
    Gauge32::Gauge32( );
销毁一个 Gauge32 对象
Overloaded Operators
 
    Gauge32& operator = ( const Gauge32 &g);
重载赋值操作符
    char * get_printable();
格式化输出 Gauge32 对象
    operator unsigned long( );
Gauge32 转换为无符号长整形
11.3.     一些Gauge32的例子
// Gauge Examples
#include “gauge.h”
void gauge_example()
{
    Gauge32 gge ;    // create an un-initialized Gauge instance
    Gauge32gge1( (unsigned long) 57);            // create a Gauge using a number
    Gauge32 ctr2(ctr1);     // create a Gauge using another instance
 
    gge = 192;    // overloaded assignment to a number
    gge1 = gge;    // overloaded assignment to another counter
    cout << (unsigned long) gge;    // behave like an unsigned long int
   
}; // end gauge example

12.     Counter64 Class
SNMP++ Counter64 Class 的对象模型( Object Modeling Technique )视图

12.1.     64位计数器类
SNMP++ 64bit counter class 实现了 SMI 64 bit counters 64 位计数器是在 SNMPv2 中定义的一种变量,所以在 SNMPv1 中并不存在这种 MIB 变量。 64 bit counters 由两个无符号长整形(一高位、一低位)组成, Counter64 class 很好的实现了它。因为 Counter64 class 提供了加减乘除操作符的重载,所以它使用起来感觉很自然。
12.2.     Counter64 Class的成员函数列表
Counter64 Class Member Functions
说明
Constructors
 
     Counter64::Counter64( void);
构造一个空的 Counter64 对象
     Counter64::Counter64(const unsigned long hi, const unsigned long low );
用两个无符号长整形来构造一个 Counter64 对象
     Counter64::Counter64( const Counter64 &ctr64);
拷贝构造函数
     Counter64::Counter64( const unsigned long ul);
用一个无符号长整形来构造一个 Counter64 对象
Destructor
 
     Counter64::~Counter64( );
销毁一个 Counter64 对象
Overloaded Operators
 
     Counter64& operator = ( const Counter64 &ctr64);
将一个 Counter64 对象付给另一个
     Counter64& operator = ( const unsigned long i );
用一个无符号长整形设置 Counter64 对象的低位,同时清除了它的高位
     Counter64 operator + ( const Counter64 &ctr64);
两个 Counter64 对象相加
     Counter64 operator - ( const Counter64 &ctr64);
两个 Counter64 对象相减
     Counter64 operator * ( const Counter64 &ctr64);
两个 Counter64 对象相乘
     Counter64 operator / ( const Counter64 &ctr64);
两个 Counter64 对象相除
     int operator == ( Counter64 &lhs, Counter64 &rhs);
判断两个 Counter64 对象是否相等
     int operator != ( Counter64 &lhs, Counter64 &rhs);
判断两个 Counter64 对象是否不相等
     int operator < ( Counter64 &lhs, Counter64 &rhs);
判断一个 Counter64 是否比另一个小
     int operator <= ( Counter64 &lhs, Counter64 &rhs);
判断一个 Counter64 是否 小于等于 另一个
     int operator > ( Counter64 &lhs, Counter64 &rhs);
判断一个 Counter64 是否比另一个大
     int operator >= ( Counter64 &lhs, Counter64 &rhs);
判断一个 Counter64 是否 大于等于 另一个
Member Functions
 
     unsigned long high();
返回 Counter64 对象的高位
     unsigned long low();
返回 Counter64 对象的低位
     void set_high();
设置 Counter64 对象的高位
     void set_low();
设置 Counter64 对象的低位
12.3.     一些的Counter64 Class例子
// Counter64 examples
#include “ctr64.h”
void counter64_example()
{
   Counter64 c64;    // instantiate a 64 bit counter object with no parms
   Counter64 my_c64( 100, 100);    // instantiate a 64 bit counter with a hi and low value
   Counter64 your_c64( my_c64);   // instantiate a 64 counter using another 64bit counter
 
  cout << my_c64.high();               // print out the high portion of the c64
  cout << my_c64.low();                // print out the low portion of the c64
 
   c64 = my_c64 + your_c64;      // overloaded addition
   c64 = my_c64 * your_c64;        // overloaded multiplication
   c64 = my_c64 / your_c64;       // overloaded division
   c64 = my_c64 - your_c64;      // overloaded subtraction
 
    if ( c64 == my_c64)               // overloaded equivalence test
      cout << “c64 equals my_c64/n”;
 
    if ( c64 != my_c64)                   // overloaded not equal test
      cout << “c64 not equal to my_c64/n”;
 
  if ( c64 < my_c64)                   // overloaded less than
      cout << “c64 less than my_c64/n”;
 
}; // end Counter64 example

13.     Address Class
SNMP++ Address Class 的对象模型( Object Modeling Technique )视图
13.1.     什么是网络地址类?
网络地址类 是一组 C++ 类的集合,它提供了简单、安全、可移植、高效地使用网络地址的方法。许多网络管理应用需要通过网络地址来访问和管理设备,包括地址的确认、更改,以及用户接口的分配。 Address class 不但管理了所有指定的网络地址的内部细节,而且还通过封装和隐藏其内部机制,让得到解放的开发应用的程序员可以专注于解决实际问题。开发 Address class 的动机来源于 95 Interop SNMP++ Birds-of-A-Feather (BOF) 上的讨论以及与 Hewlett-Packard OpenView 程序员的交流。
13.2.     为什么要使用网络地址类?
地址类提供了以下好处:自动内存管理、地址确认、移植到任何 C++ 环境、简单易用,及可扩充性。目前的 Address class 4 个子类组成: IpAddress Class, IpxAddress Class, MacAddress class GenAddress class 。将来也许会有其他的子类加入,比如 IP Next Generation (IPng)
13.3.     Address class
所有地址类都派生自同一个抽象基类: Address class 。它是一个抽象类,即这个类不会产生实例对象。 Address class 通过使用虚成员函数,提供了公用接口。也就是说可以使用公用接口调用各个不同地址类的函数。这样的结果是:当需要修改使用了地址类的模块时,需要改动的代码就很少了。
13.4.     Address Classes及其接口
作为基类的 Address Classes 是一个抽象类,它囊括了所有子类的通用操作。也即包含了以下统一的接口:构造、访问、修改地址。

Address Class Member Functions
说明
IpAddress Class Constructors
 
      IpAddress::IpAddress( void);
构造一个空的 IpAddress 对象
      IpAddress::IpAddress( const char *string);
用一个字符串构造一个 IpAddress ,当需要时一般用到 DNS
      IpAddress::IpAddress( const IpAddress &ipa);
拷贝构造函数
IPAddress Member Functions  
 
      char * friendly_name( int & status);
DNS 的名字看起来更友好
UdpAddress Constructors   
 
     UdpAddress::UdpAddress( void);
构造一个无效的 UdpAddress 对象
     UdpAddress::UdpAddress( const char *string);
用一个字符串构造一个 UdpAddress
     UdpAddress::UdpAddress( const UdpAddress &udpa);
用一个已有的 UdpAddress 来构造另一个
UdpAddress Member Functions
 
     void UdpAddress:set_port( const unsigned int p);
设置 UdpAddress 对象的端口号
     unsigned int UdpAddress::get_port();
获取 UdpAddress 对象的端口号
IpxAddress Class Constructors 
 
      IpxAddress::IpxAddress( void);
构造一个空的 IPX 地址
      IpxAddress::IpxAddress( const char *string);
用一个字符串构造一个 IPX 地址
      IpxAddress::IpxAddress( const IpxAddress &ipxa);
拷贝构造函数
IpxSockAddress Constuctors
 
     IpxSockAddress::IpxSockAddress( void);
构造一个空的 IpxSockAddress 对象
     IpxSockAddress::IpxSockAddress( const char *string);
用一个字符串构造一个 IpxSockAddress
     IpxSockAddress::IpxSockAddress( const IpxSockAddress &ipxs);                                                   
用一个已有的 IpxSockAddress 来构造另一个
IpxSockAddress Member Functions
 
     IpxSockAddress::set_socket( const unsigned int s);
从一个 IpxSockAddress 获得套接字
     unsigned int IpxSocketAddress::get_socket();
设置一个 IpxSockAddress 的套接字
MacAddress Constructors
 
      MacAddress::MacAddress( void);
构造一个空的 MacAddress 对象
      MacAddress::MacAddress( const char * string);   
用一个字符串构造一个 MacAddress
      MacAddress::MacAddress( const MacAddress &mac);
拷贝构造函数
GenAddress Constructors
 
     GenAddress::GenAddress( void);
构造一个无效的 GenAddress 对象
     GenAddress::GenAddress( const char * addr);
用一个字符串构造一个 GenAddress
     GenAddress::GenAddress( const GenAddress &addr);
拷贝构造函数
Common Member Functions, applicable to all Address classes
 
      int operator == ( const Address &lhs, const Address rhs);
判断两个地址是否相等
      int operator != ( const Address &lhs, const Address &rhs);
判断两个地址是否不相等
      int operator > ( const Address &lhs, const Address &rhs);
判断一个地址是否大于另一个
      int operator >= (const Address &lhs, const Address &rhs);
判断一个地址是否大于等于另一个
      int operator < ( const Address &lhs, const Address &rhs);
判断一个地址是否小于另一个
      int operator<=( const Address &lhs, const Address &rhs);
判断一个地址是否小于等于另一个
      int operator == ( const Address &lhs, cosnt char *inaddr);
判断一个地址是否等于一个字符串
      int operator > ( const Address &lhs, const char *inaddr);
判断一个地址是否大于一个字符串
      int operator < ( const Address &lhs, const char *inaddr);
判断一个地址是否小于一个字符串
      virtual int valid( );     
判断一个地址的有效性
      unsigned char& operator[]( int position);
允许通过数组的下标操作符来访问一个地址
      char * get_printable ( );
返回格式化输出的地址
13.5.     IpAddress Class的特点
IpAddress Class 可以通过调用成员函数 Address::get_printable() 自动以 DNS 显示出来。如果没有激活 DNS 或者无法识别地址,则返回以点号分割的字符。另一方面,一个 IpAddress 可以用一个友好的名字(字符串,而非以点号分割的数字)来构造,这样构造函数就可以激活 DNS 的显示。如果这个名字没被找到,那么该地址也就是无效的。这个强大的功能允许你在对外表现时,使用友好的名字方式。
13.6.     GenAddress的特点
GenAddress class 允许创建和使用通用的地址,即 GenAddress 拥有其他地址类( IpAddress, IpxAddress MacAddress )的操作和属性,所以你可以使用 GenAddress 来操作任何地址。 GenAddress class 的构造函数允许用任何字符串来建立一个地址。构造函数通过匹配的字符串以及加载在 GenAddress 上的属性与操作,决定其地址的具体类型。这样就解放了程序员,因为面对不一样的地址,程序员不用再专门写代码来处理了。
GenAddress Examples
 
GenAddress address1(“10.4.8.5”);    // make an IP GenAddress
GenAddress address2(“01020304-10111213141516”);    // make an IPX GenAddress
GenAddress address3(“01:02:03:04:05:06”);    // make a MAC GenAddress
 
cout << address3.get_printable();    // print out the GenAddress
 
if ( !address1.valid())    // check validity
    cout << “address1 ! valid”;
13.7.     Address Class的有效性
所有地址类都支持成员函数 ::valid() ,它可以返回指定地址对象的有效性。有效性是在构造或给一个地址对象赋值时决定的。只有在赋值之后,成员函数 ::valid() 才可以被用来判断其有效性。
Address Class Validation Examples
 
MacAddress mac;
mac = “01.010a0d ”;                                      // invalid MAC address
printf(“%s”, (mac.valid() ? “Valid” :”Invalid”));
13.8.     UdpAddressesIpxSockAddresses
大多数时候, SNMP++ 的用户会使用默认的端口号和套接字来进行 SNMP 操作。就 IP 协议而言, 161 端口一般用来作为代理的目标端口, 162 端口一般用作 trap Notification 的接收端口。有些时候需要改变指定的端口号和套接字, UdpAddress class IpxSockAddress class 就允许定义端口和套接字的信息。
13.8.1.    UdpAddresses发送请求
当向一个使用非标准默认端口的代理端发送请求信息时,就需要用到 UdpAddresses class 了。 UdpAddresses class 提供了两个成员函数分别来设置和获取自定义的端口信息。用一个加载了 UdpAddresses 的目标来发送请求,就可以实现 SNMP++ 对自定义端口的使用。
13.8.2.    IpxSockAddresses发送请求
当向一个使用非标准默认 IPX 套接字的代理端发送请求信息时,就需要用到 IpxSockAddresses class 了。 IpxSockAddresses 提供了两个成员函数分别来设置和获取自定义的 IPX 套接字信息。用一个加载了 IpxSockAddress 的目标来发送请求,就可以实现 SNMP++ 对自定义套接字的使用。
13.8.3.    UdpAddressIpxSockAddress接收Notification
UdpAddress IpxSockAddress 还可以通过指定需要修改的端口和套接字来接收 notification 。即允许应用通过非标准的端口和套接字来接收 trap inform
13.9.     有效的地址格式
目前的有效地址格式定义如下:
 
Valid IP format BNF Grammar XXX.XXX.XXX.XXX
ip-address : ip-token DOT ip-token DOT ip-token DOT ip-token
DOT : ‘.’
ip-token : [0-255]
 
Valid IPX format BNF GrammarXXXXXXXX:XXXXXXXXXXXX
ipx-address: net-id SEPARATOR mac-id
SEPARATOR : ‘ ‘ | ‘:’ | ‘-’ | ‘.’
net_id : 1{byte-token}4
mac-id: 1{byte-token}6
byte-token: 1{byte}2
byte: [0-9|a-f|A-F]
 
Valid MAC format BNF Grammar XX:XX:XX:XX:XX:XX
mac-id: byte_token colon byte_token colon byte_token colon byte_token colon byte_token
byte-token: 1{byte}2
byte: [0-9|a-f|A-F]
colon: ‘:’
13.10.Address Class例子
// address class examples
#include “address.h”
void address_examples()
{
   //--------------[ IPAddress construction ]------------------------------------------------------
   IpAddress ip1();    // makes an invalid IpAddress object
   IpAddress ip2(“10.4.8.5”);    // makes a IpAddress verifies dotted format
   IpAddress ip3(ip2);    // makes an IpAddress using another IpAddress
  IpAddress ip4(“trout.rose.hp.com”);       // makes an IpAddress does DNS on string
 
   //-------------[ IPX Address construction ]-----------------------------------------------------
   IpxAddress ipx1();      // makes an invalid IPX address
   IpxAddress ipx2(”);                                // makes and verifies an IPX address
   IpxAddress ipx3( ipx2);    // makes an IPX from another IPX
 
   //--------------[ MAC Address construction ]-----------------------------------------------------
   MacAddress mac1();    // makes an invalid MAC address
   MacAddress mac2(“08:09:12:34:52:12”);    // makes and verifies a MAC address
  MacAddress mac3( mac2);   // makes a MAC from another MAC
 
 //---------------[ Gen Address Construction ]-----------------------------------------------------
 GenAddress addr1(“10.4.8.5”);
 GenAddress addr2(“01020304:050607080900”);
 
   //--------------[ printing addresses ]----------------------------------------------------------------
   cout << (char *) ip2;
   cout << (char *) ipx2;
   cout << (char *) mac2;
 
   //---------------[ assigning Addresses ]------------------------------------------------------------
   ip1 = “15.29.33.10”;
   ipx1 = “00000001-080912345212”;
   mac1 = “08:09:12:34:52:12”;
 
   //--------------[ comparing Addresses ]----------------------------------------------------------
   if ( ip1 == ip2)
       cout << “ip1 == ip2”;
 
   if (ipx1 != ipx2)
      cout << “ipx1 != ipx2”;
 
   if ( mac1 <= mac2)
      cout << “mac1 < mac2”;
 
//---------------[ modifying an address ]-----------------------------------------------------------
   mac1[4] = 15;
   cout << mac2[2];
  
 
}; // end address examples

14.     The Variable Binding Class
SNMP++ Variable Binding ( Vb)Class 的对象模型( Object Modeling Technique )视图
Variable Binding ( Vb) class SNMP“ 绑定变量 的封装。一个 绑定变量 是由 SNMP object ID 及其 SMI value 组合而成的。用面向对象的概念来看,这只是一个简单的关联关系:一个 Vb 对象含有一个 Oid 对象及其 SMI value Vb class 允许应用的开发者实例化 Vb 对象,然后为其分配 Oid 部分(用 Vb::set_value() ),并分配 value 部分(用 Vb::get_value() )。相反的, Oid value 部分可以通过成员函数 Vb::get_oid() Vb::get_value() 提取出来。通过重载了的公有成员函数 Vb::set_value() Vb::get_value() ,可以把不同的 SMI value 针对 绑定变量 进行 设置 取出 绑定变量表 SNMP++ 中表现为 Vb 对象的数组。所有的 SMI 类型都与 Vb Class 兼容。 Vb class 隐藏了所有内部数据。使用者不需要知道 SMI value 的类型, Oid 的内部表示方法,以及其他 SNMP 相关的结构。如果使用的是标准 ANSI C++ 编译器, Vb class 是完全可移植的。
14.1.     Variable Binding Class成员函数列表
Variable Binding Class Member Functions
说明
Constructors
 
   Vb( void);
构造一个空的 Vb 对象
   Vb( const Oid &oid);
Oid 部分构造一个 Vb
   Vb( const Vb &vb);
拷贝构造函数
Destructor
 
    ~Vb();
销毁一个 Vb ,释放所有的资源
Set Oid / Get Oid 
 
    void set_oid( const Oid &oid);
设置一个 Vb Oid 部分
    void get_oid( Oid &oid) const;
获得 Oid 部分
Set Value
 
    void set_value( const SMIValue &val);
设置任一 SmiValue
    void set_value( const int i);
设置一整形 value
    void set_value( const long int i);
设置一长整形 value
    void set_value( const unsigned long int i);
设置一无符号长整形 value
     void set_value( const char WINFAR * ptr);
设置一有结束标志符的字符串 value
Get Value
 
     int get_value( SMIValue &val);
获得任一 SmiValue
     int get_value( int &i);
获得一整形 value
     int get_value( long int &i);
获得一长整形 value
     int get_value( unsigned long int &i);
获得一无符号长整形 value
     int get_value( unsigned char WINFAR * ptr,
unsigned long &len);
获得一无符号字符数组,返回数据及其长度
     int get_value( unsigned char WINFAR * ptr,
unsigned long &len,          
unsigned long maxlen);       
获得一指定长度的无符号字符数组,指定长度不超过最大长度。
     int get_value( char WINFAR *ptr);
获得一有结束标志符的字符串
Miscellaneous
 
     SmiUINT32 get_syntax();
返回 SMI 描述
     char *get_printable_value();
返回格式化 value
     char *get_printable_oid();
返回格式化 Oid 部分
     void set_null();
Vb 对象设置一个空 value
     int valid();
返回一个 Vb 的有效性
Overloaded Operators
 
     Vb& operator=( const Vb &vb);
把一个 Vb 付给另一个
14.2.     Vb Class的公有成员函数
Vb class 提供了许多公有成员函数来访问和修改 Vb 对象。
// A Vb object may be constructed with no arguments. In this case, the Oid and
// value portions must be set with subsequent member function calls.
// constructor with no arguments 
// makes an Vb, un-initialized
Vb::Vb( void);
 
14.2.1.    Vb Class的构造和析构函数
Vb 对象可以用一个 Oid 对象作为构造函数的参数来构造,即把 Vb 对象的 Oid 部分初始化为以参数方式传进来的 Oid Vb 对象生成了一个传进来的 Oid 的拷贝,所以程序员不用担心 Oid 参数的执行期问题。
// constructor to initialize the Oid 
// makes a Vb with Oid portion initialized
Vb::Vb( const Oid oid);
Vb 对象的析构函数释放了所有占用过的内存和资源。对于定义的静态对象,析构函数是在对象作用域结束时自动调用的。动态分配的实例对象需要用 delete 来析构。
// destructor
// if the Vb has a Oid or an octet string then
// the associated memory needs to be freed
Vb::~Vb();
14.2.2.    Vb ClassGet Oid / Set Oid成员函数
成员函数 Get Oid / Set Oid 允许获取 / 设置 Vb 对象的 Oid 部分。当 SNMP 发出 gets 或者 sets 操作的时候,变量的指定是通过 Vb::set_oid( Oid oid). 设置 Vb Oid 值来的。相反, Oid 部分可以通过成员函数 Vb::get_oid( Oid &oid) 来获取。成员函数 get_oid SNMP get next 操作中的非常有用。
Vb 对象的 Oid 部分可以用一个已存在的 Oid 对象来设置
// set value Oid only with another Oid
void Vb::set_oid( const Oid &oid);
Oid 部分可以通过提供一个目标 Oid 对象来检索。这将销毁原先的 Oid 对象的值。
// get Oid portion
void Vb::get_oid( Oid &oid);
14.2.3.    Vb ClassGet Value / Set Value成员函数
成员函数 get_value set_value 允许获取或设置 Vb 对象的 value 部分。这些成员函数通过重载支持对不同类型的获取和设置。隐藏了获取或设置 Vb 的内部机制, 管理了所有内存的分配和释放。这样,程序员就不用担心 SMI-value 的结构以及它们的管理。通常在 SNMP 执行了 get 后,用成员函数 get value 来获取 Vb 对象的 value 。如果希望在 SNMP 执行 set 操作时设置 Vb value 的话,成员函数 set value 就有用了。如果获取的 value Vb 所包含的不匹配,则成员函数 get_value 返回 -1
 
Vb 对象设置一整形 value ,作为 SMI INT 的映射。
// set the value with an int   
void Vb::set_value( const int i);
Vb 对象设置一长整形 value ,作为 SMI INT32 的映射。
// set the value with a long signed int                                                      
void Vb::set_value( const long int i);
Vb 对象设置一无符号长整形 value ,作为 SMI UNIT32 的映射。
// set the value with an unsigned long int
void Vb::set_value( const unsigned long int i);
Vb 对象设置一 Gauge32 对象作为 value ,该 value SMI 32 bit 的映射。
// set the value with a 32 bit gauge
void Vb::set_value( const Gauge32 gauge);
Vb 对象设置一 TimeTicks 对象作为 value ,该 value SMI timeticks 的映射。
// set the value with a TimeTicks
void Vb::set_value( const TimeTicks timeticks);
Vb 对象设置一 Counter32 对象作为 value ,该 value SMI 32 bit counter 的映射。
// set value with a 32 bit counter
void Vb::set_value( const Counter32 counter);
Vb 对象设置一 Counter64 对象作为 value ,该 value 用以构成 SMI 64 bit counter 32bit 的高位部分与低位部分。
// set value to a 64 bit counter  
void Vb::set_value( const Counter64 c64);
用一个 Oid 设置 Vb 对象的 value 部分。
// set value for setting an Oid
// creates own space for an Oid which
// needs to be freed when destroyed
void Vb::set_value( const Oid &varoid);
用一个 char 型的字符串设置一个 Vb 对象的 value 部分。事实上,这在内部是用 8 位字符串作为 SMI value 部分,但是当它是一个 ASCII 字符串(比如系统标识符)时,这种表示却会显得更简单。
// set value on a string
// makes the string an octet
// this must be a null terminates string
void Vb::set_value( const char * ptr);
用一个 IP address 对象设置 Vb value 部分。该成员函数使用了 Address class IP address SMI value 类型的一种。
// set an IPAddress object as a value
void Vb::set_value ( const IpAddress ipaddr);
用一个 IPX address 对象设置 Vb value 部分。该成员函数使用了 Address class IPX address 8 SMI value 类型的一种。
// set an IPXaddress object as a value
void Vb::set_value ( const IpxAddress ipxaddr);
用一个 MAC address 对象设置 Vb value 部分。该成员函数使用了 Address class MAC address 8 SMI value 类型的一种。
// set an MAC address object as a value
void Vb::set_value ( const MacAddress macaddr);
14.2.4.    用一个GenAdress对象设置value
// set an GenAddress object as a value
void Vb::set_value ( const GenAddress genaddr);
14.2.5.    用一个UdpAdress对象设置value
// set an UdpAddress object as a value
void Vb::set_value ( const UdpAddress udpaddr);
14.2.6.    用一个IpxSockAdress对象设置value
// set an IpxSockAddress object as a value
void Vb::set_value ( const IpxSockAddress ipxsockaddr);
14.2.7.    用一个Octet对象设置value部分
// set the value portion to a SNMP++ Octet object
void Vb::set_value( const OctetStr octet);
14.2.8.    Vb Class成员函数:Get Value
所有的成员函数 Vb::get_value 都会修改传进来的参数。如果一个 Vb 对象不包含被请求的参数类型,该参数不会被修改,并且将返回 SNMP_CLASS_INVALID 。否则,如果成功将会返回 SNMP_CLASS_SUCCESS 的状态。
Vb 对象获得一个整形 value
// get value int
// returns 0 on success and value
int Vb::get_value( int &i);
Vb 对象获得一个长整形 value
// get the signed long int 
int Vb::get_value( long int &i);
Vb 对象获得一个无符号长整形 value
// get the unsigned long int
int Vb::get_value( unsigned long int &i );
// get a Gauge32
int Vb::get_value( Gauge32 &gauge);
Vb 对象获得一个 Gauge32
 
 
 
Vb 对象获得一个 TimeTicks
// get a TimeTicks from a Vb
int Vb:get_value( TimeTicks &timeticks);
Vb 对象获得一个 Counter32
// get a counter from a Vb
int Vb::get_value(Counter32 &counter);
Vb 对象获得一个 64 bit counter
// get a 64 bit counter  
int Vb::get_value( Counter64 &counter64);
Vb 对象获得一个 Oid 对象
// get the Oid value  
// free the existing Oid value
// copy in the new Oid value
int Vb::get_value( Oid &varoid);
Vb 对象获得一个无符号 char 型字符串( Octet string
// get a unsigned char string value
// destructive, copies into given ptr of up
// to len length
int Vb::get_value( unsigned char * ptr, unsigned long &len);
Vb 对象获得一个 char 型字符串。该操作获得 octet string 部分,并在其后加一空值。
// get a char * from an octet string
// the user must provide space or
// memory will be stepped on
int Vb::get_value( char *ptr);
Vb 对象获得一个 IP address 对象。 IP address 是一种 Address 对象。
// get an IPAddress                   
int Vb::get_value( IpAddress &ipaddr);
Vb 对象获得一个 IPX Address 对象。 IpxAddress 是一种 Address 对象。
// get an IPXAddress                   
int Vb::get_value( IpxAddress &ipxaddr);
Vb 对象获得一个 MAC Address 对象。 MacAddress 是一种 Address 对象。
// get an MAC address                   
int Vb::get_value( MacAddress &MACaddr);
Vb 对象获得一个 GenAddress 对象。 GenAddress 是一种 Address 对象。
// get an gen address                   
int Vb::get_value( GenAddress &genaddr);
Vb 对象获得一个 UdpAddress 对象。 UdpAddress 是一种 Address 对象
// get an Udp address                   
int Vb::get_value( UdpAddress &Udpaddr);
Vb 对象获得一个 IpxSockAddress 对象。 IpxSockAddress 是一种 Address 对象
// get an IpxSockAddress                    
int Vb::get_value( IpxSockAddress &IpxSockAddr);
Vb 对象获得一个 Octet 对象
// get an Octet object from a Vb
int Vb::get_value( OctetStr, &octet);
14.2.9.    Vb 对象的成员函数:Get Syntax
该函数并未遵循面向对象规则。如果要知道对象代表的事物,可以通过该函数返回对象内部的 id ,但同时也破坏了内部数据的隐藏。如果不考虑数据隐藏的话,有些时候可能还是需要知道 Vb 内部的 value ,以便抽取出那些隐藏的 value 。比如,当实现一个浏览器时需要获取 Vb ,询问 Vb 有什么数据并取出 Vb 包含的数据。该操作所返回的 syntax values 就是 SMI syntax value
// return the current syntax   
// This method violates the OO paradigm but may be useful if
// the caller has a Vb object and does not know what it is.
// This would be useful in the implementation of a browser.
SmiUINT32 get_syntax();
14.2.10.检查Vb对象的有效性
通过调用成员函数 Vb::valid() 可以检查一个 Vb 对象的实例的有效性。有效的 Vb 是那些已经获得了 Oid 的。
// determine if a Vb object is valid
int Vb::valid();
14.2.11.Vb对象付给另一个Vb对象
通过重载赋值操作符 Vb 对象可以相互赋值。这种简单的相互赋值避免以下操作:查询一个 Vb 对象的内容,然后手工将其赋给另一个目标 Vb 对象。
// overloaded Vb assignment
// assignment to another Vb object overloaded
Vb& operator=( const &Vb vb);
14.2.12.Vb对象的错误信息
当用 Vb::get_value() 从一个 Vb 对象获取数据时,由于 Vb 数据类型与你所请求的数据类型的不一致将导致一个错误的出现。例如,假设一个 Vb 对象有一个 OctetStr 对象,你却要求提取 TimeTicks 对象。由于无法返回 TimeTicks Vb::get_value() 会失败。当错误事件发生时,相应的调用模块使用 Vb::get_syntax() 来询问 Vb 的实际值或者错误值。
Vb::get_value() return value
说明
SNMP_CLASS_SUCCESS
成功,返回所请求的值
SNMP_CLASS_INVALID
失败, Vb value 没有包含请求的值
14.3.     Vb Class例子
下面的例子展示了使用 Vb class 的不同方法。除了 Oid class Vb class 不需要依赖于其他库或模块。以下 C++ 代码是 ANSI 兼容的。
#include “oid.h”
#include “vb.h”
vb_test()
{
   // -------[Ways to construct Vb objects ]-------
   // construct a single Vb object
   Vb vb1;
 
   // construct a Vb object with an Oid object
   // this sets the Oid portion of the Vb
   Oid d1(“1.3.6.1.4.12”);
   Vb vb2(d1);
 
   // construct a Vb object with a dotted string
   Vb vb3( (Oid) “1.2.3.4.5.6”);
 
   // construct an array of ten Vbs
   Vb vbs[10];
 
   //------[Ways to set and get the Oid portion of Vb objects ]
 
   // set and get the Oid portion
  Oid d2((Oid)“1.2.3.4.5.6”);
   vb1.set_oid(d2);
   Oid d3;
   vb1.get_oid(d3);
   if (d2==d3) cout << “They better be equal!!/n”;
 
   Vb ten_vbs[10];
   int z;
   for (z=0;z<10;z++)
   ten_vbs[0].set_oid((Oid)“1.2.3.4.5”);
 
   //-------[ ways to set and get values ]
 
   // set & get ints
   int x,y;
   x=5;
  vb1.set_value(x);
   vb1.get_value(y);
   if ( x == y) cout << “x equals y/n”;
   // set and get long ints
   long int a,b;
   a=100;
 
//-------[ ways to set and get values ]
   if ( a == b) cout << “a equals b/n”;
   // set & get unsigned long ints
 unsigned long int c,d;
 c = 1000;
 
  vbs[0].set_value( c);   vbs[0].get_value( d);
   if ( c == d) cout << “c equals d/n”;
 
   // set a 64 bit counter
   Counter64 c64(1000,1001);
  vbs[1].set_value( c64);
 
   // get and set an oid as a value
   Oid o1, o2;
   o1 = “1.2.3.4.5.6”;
   vbs[2].set_value( o1);   vbs[2].get_value( o2);
   if ( o1 == o2) cout << “o1 equals o2/n”;
 
   // set and get an octet string
   unsigned char data[4],outdata[4];
   unsigned long len,outlen;
   len =4; data[0] = 10; data[1] = 12; data[2] = 12; data[3] = 13;
   OctetStr octetstr(data,len);
   vbs[3].set_value( octetstr);
   vbs[3].get_value( octetstr);
 
   // get & set a string
   char beer[80];   char good_beer[80];
   strcpy( beer,”Sierra Nevada Pale Ale”);
  vbs[4].set_value( beer);
   vbs[4].get_value( good_beer);
   printf(“Good Beer = %s/n”,good_beer);
   // get and set an ip an address
  IpAddress ipaddress1, ipaddress2;
   ipaddress1 = “10.4.8.5”;
   vbs[5].set_value( ipaddress1);
   vbs[5].get_value( ipaddress2);
   cout << ipaddress2;
 
} // end vb example
 

15.     Pdu Class
SNMP++ Pdu Class 的对象模型( Object Modeling Technique )视图
SNMP++ Pdu class SMI Protocol Data Unit (PDU) C++ 封装。 PDU 是管理端和代理端进行 SNMP 通讯的基本概念。通过 Pdu class SNMP++ 使得对 PDU 的操作变得简单、安全。 Pdu class 允许简单的构造、析构,以及在 Pdu 对象上加载、卸载 Vb 对象。因为 SNMP++ 是双效的 API ,所以 Pdu class 也是抽象化的,并没有包含 SNMPv1 或者 SNMPv2 的特征性的信息。所有发出请求的 Snmp class 成员函数都可以只使用一个 Pdu 对象。 Pdu class 作为 Snmp class 的接口,处理 SNMP 请求,同时还可作为异步请求和接收 notification 的回调函数的参数。注意,关于对 Vb 的存储, Pdu 对象是从 0 开始的( Pdu 中第一个 vb Vb #0 )。
大多数地方, SNMP++ 中的所有 Pdu 对象都是一样的。即,所有的 Pdu 对象都有同一性( identity )。唯一的例外是当 Pdu 对象被用作发送 otifications , traps informs 的时候。为了支持 notifications ,有 3 个附加的 Pdu Class 成员函数来用作:设置同一性( identity )、时间信息,及 Pdu 对象的 enterprise
15.1.     Pdu Class成员函数列表
Pdu Class Member Functions
说明
Constructors
 
     Pdu::Pdu( void);
构造一个空的 Pdu
     Pdu::Pdu( Vb* pvbs, const int pvb_count);
用一个数组类型的 Vb 及其长度构造一个 Pdu
     Pdu::Pdu( const Pdu &pdu);
用一个 Pdu 构造另一个
Member Functions
 
     int get_vblist( Vb* pvbs, const int pvb_count);
Vb 拷贝到调用的参数列表中( vblist
     int set_vblist( Vb* pvbs, const int pvb_count);
设置 Pdu 调用的参数列表中的 Vb
     int get_vb( Vb &vb, const int index);
获取 Pdu 中一个指定的 Vb
     int set_vb( Vb &vb, const int index);
Pdu 设置一个指定的 Vb
     int get_vb_count();
获取 Pdu Vb 的个数
     int get_error_status();
获取 Pdu 的错误状态
     int get_error_index();
获取 Pdu 的错误索引
     unsigned long get_request_id();
获取 Pdu 的请求标示
     unsigned short get_type();
获取 Pdu 的类型
     int valid();
判断 Pdu 的有效性
     Int delete_vb( const int position);
删除 Pdu 指定位置上的 Vb
     int trim(const int i=1);
删除 Pud 最后位置上的 Vb ,默认删除 1
Member Functions For Inform and Trap Usage
 
     void set_notify_timestamp( const TimeTicks ×tamp);
trap inform Pdu 设置时间信息
     void get_notify_timestamp( TimeTicks & timestamp);
trap inform Pdu 获取时间信息
     void set_notify_id( const Oid id);
设置 trap inform Pdu ID
     void get_notify_id( Oid &id);
获取 trap inform Pdu ID
     void set_notify_enterprise( const Oid &enterprise);
设置 trap inform Pdu enterprise ID
     void get_notify_enterprise( Oid & enterprise);
获取 trap inform Pdu enterprise ID
Overloaded Operators    重载操作符
 
     Pdu& operator=( const Pdu &pdu);
将一个 Pdu 付给另一个
     Pdu& operator+=( Vb &vb);
给一个 Pdu 增加一个 Vb
15.2.     Pdu Class的构造和析构
有多种方法构造 Pdu 对象,可以有也可以没有构造参数
// constructor, no args
Pdu::Pdu( void);
 
// constructor with Vbs and count
Pdu::Pdu( Vb *vbs, const int vb_count);
 
// constructor with another Pdu instance
Pdu::Pdu( const Pdu &pdu);
 
// destructor
Pdu::~Pdu();
15.3.     访问Pdu的成员函数
Pdu class 通过多种成员函数来支持获取和设置 Pdu 成员变量。包括获取和设置 绑定变量 、错误信息、请求信息,和类型信息。
// extract all the Vbs from a Pdu
int Pdu::get_vblist( Vb* vbs, const int vb_count);
 
// deposit Vbs to a Pdu
int Pdu::set_vblist( Vb* vbs, const int vb_count);
 
// get a particular vb
// where index 0 is the 1st vb
int Pdu::get_vb( Vb &vb, const int index);
 
// set a particular Vb
// where index 0 is the 1st Vb
int Pdu::set_vb( Vb &vb, const int index);
 
// return the number of Vbs
int Pdu::get_vb_count();
 
// return the error index
int Pdu::get_error_index();
 
// get the error status
int Pdu::get_error_status();
 
// return the request id
unsigned long Pdu::get_request_id();
 
// get the Pdu type
unsigned short Pdu::get_type();
 
// return the validity of a Pdu
int Pdu::valid();
15.4.     Pdu Class重载操作符
Pdu class 可通过重载操作符,赋值或串连 Vb 对象到 Pdu
// assignment operator for assigning one Pdu to another
Pdu& operator=( const Pdu &pdu);
 
// append a Vb object to the Pdu’s var bind list
Pdy& operator+=( Vb vb);
15.5.     Pdu Class处理TrapsInforms的成员函数
当处理 notifications, traps informs 的时候, SNMP++ 提供了成员函数来获取和设置指定的 notification value 。当使用这些成员函数时,请查阅发送 traps informs 的部分。
// set notify timestamp
void Pdu::set_notify_timestamp( const TimeTicks & timestamp);
 
// get notify timestamp
void Pdu::get_notify_timestamp( TimeTicks & timestamp);
 
// set the notify id
void Pdu::set_notify_id( const Oid id);
 
// get the notify id
void Pdu::get_notify_id( Oid &id);
 
// set the notify enterprise
void Pdu::set_notify_enterprise( const Oid &enterprise);
 
// get the notify enterprise
void Pdu::get_notify_enterprise( Oid & enterprise);
15.6.     加载Pdu对象
为了在管理应用中使用 Pdu 对象,必须在 Pdu 实例中加载 绑定变量表 vblist )。这可以通过从多种方法中选择你需要的来处理。一般在发送 SNMP 请求前加载 Pdu
// set notify timestamp
void Pdu::set_notify_timestamp( const TimeTicks & timestamp);
 
// get notify timestamp
void Pdu::get_notify_timestamp( TimeTicks & timestamp);
 
// set the notify id
void Pdu::set_notify_id( const Oid id);
 
// get the notify id
void Pdu::get_notify_id( Oid &id);
 
// set the notify enterprise
void Pdu::set_notify_enterprise( const Oid &enterprise);
 
// get the notify enterprise
void Pdu::get_notify_enterprise( Oid & enterprise);
15.7.     加载Pdu对象
为了在管理应用中使用 Pdu 对象,必须在 Pdu 实例中加载 绑定变量表 vblist )。这可以通过从多种方法中选择你需要的来处理。一般在发送 SNMP 请求前加载 Pdu
// example of how to load a Pdu object
void load_pdu_examples()
{
  Pdu pdu;                                 // create a Pdu object
   Vb vb;                                          // create a Vb object
  vb.set_oid( SYSDECR);             // set the oid portion of the Vb to System Descriptor
   pdu += vb;                                  // loads the Vb to the Pdu
 
   Pdu my_pdu;                          // create another Pdu object
  Vb vbs[5];                                  // create 5 vbs
  pdu.set_vblist( vbs,5);                // load all 5 to the pdu
}
15.8.     卸载Pdu对象
从阻塞或异步请求中得到请求的 Pdu 后,都需要将 Vb 卸载下来才能把 SMI values 取出。
// example of how to unload a Pdu
void unload_pdu_example( Pdu &pdu)
{
   ins staus;
   Pdu pdu;                                 // create a Pdu object
  Vb vb;                                          // create a Vb object
  vb.set_oid( SYSDECR);             // set the oid portion of the Vb to System Descriptor
  pdu += vb;                                  // loads the Vb to the Pdu
   char message[100];                 // for the system descriptor printable octet
 
   Snmp snmp( status);
   if ( status != SNMP_CLASS_SUCCESS) {
      cout < “SNMP++ error = “ << snmp.error_msg( status) ;
      return;
   }
 
   pdu.get_vb( vb,0);                        // unload the vb
   vb.get_value( message);         // pull the message out of the vb
   cout << message;                         // print it out
 
};

16.     SnmpMessage Class
SnmpMessage Class 允许对 SNMP++ 对象使用抽象编码规则( ASN.1 )和基础编码规则( BER )来编码和解码,进而生成可以在线路上传送的 SNMP 消息。该 class 可以方便的串行化 Pdu 对象,以便于后期的各种使用。大多数 SNMP++ 的用户不需要使用这个类,因为 Snmp class 已经完成了这项任务,包括管理超时和重发。但是如果程序员想对消息编码,这里也为其提供一种选择,例如很多代理系统就在使用它们自己的传输层。 SnmpMessage class 提供的各种成员函数如下表所示:
SnmpMessage Class Member Functions
说明
Constructors
 
     SnmpMessage::SnmpMessage( void);
构造一个空的 SnmpMessage 对象
Member Functions
 
     int load( Pdu pdu, OctetStr community,
snmp_version version);
Pdu 、团体名、版本加载一个 SnmpMessage 对象。版本可以是 SNMPv1 2 。返回错误状态。
     int load( unsigned char * data, unsigned long en);
用原始数据流加载一个 SnmpMessage 对象。当从线路上收取数据报并通过把它加载到一个 SnmpMessage 对象来实现解码时,该函数很有用。
     int unload( Pdu &pdu, OctetStr &community,
                       snmp_version &version);
卸载一个已经加载过的 SnmpMessage 对象。由此可以获得 Pdu 、团体名、版本
     unsigned char * data();
通过原始的 ASN.1/BER 串行化数据缓冲区。该缓冲区的范围可以通过成员函数 ::len() 获得
     unsigned long len()
返回原始数据缓冲区的范围
      int valid();
判断一个 SnmpMessage 对象的有效性

17.     Target Class
Target class 是一个 C++ 类,在 SNMP++ 中用它来定义和使用 target 。一个 target SNMP 通讯中,可以想象成一个代理端的管理层的概念,它由多个网络地址组成。 Targets 包含了重发和超时机制的信息,还有 SNMP 协议类型( SNMPv1 SNMPv2 )等等。目前已有的 Targets 唯一的子类是 Community-based CTarget CTarget class 可用在 SNMPv1 SNMPv2 的通讯上,由此可以重用你已有的代码到 SNMPv2 通讯中,不需要做修改。通过它,还可以使得一个 SNMP++ 会话与某个特定的代理端的属性无关。
17.1.     抽象的Target
SNMP++ 支持抽象 Target 的概念。由该抽象 Target 可以操作所有实际的 Target 派生类。所有使用 Target SNMP++ 成员函数接收的都是抽象 Target ,而不是特指的派生 Target 对象。当需要支持新的 Target 时,这种抽象的接口可以减小代码的改动。
17.2.     Target地址
每个 target 都与一个地址对象( Address object )相关联。该地址是一个 GenAddress ,因此可以处理所有 SNMP++ 地址( IP, IPX 或其他)。为指明被管理的代理端地址并与一个 Target 相关联,只需要简单地通过构造函数的参数或成员函数就可实现。
17.3.     重发机制
每个 Target 都具有重发机制,在该机制中定义了超时和重发。由该重发机制可指定等待一个 SNMP 应答的周期,以及当没有收到一个 SNMP 应答时进行多少次重发。超时的最小单位被定义成百分之一秒,即当取值为 100 代表每个应答等待 1 秒。重发时记录了重发的次数,注意,第一次请求不属于重发,只是发送。所以重发值取 3 ,表示当等待一个应答时最多可以重发 3 次。等待的总时间可以用下列式子计算: Total Wait Time = time-out * (retry+1)
如果一个 SNMP++ 应答没有在上式所计算出来的等待总时间内到来,将会返回一个 SNMP++ 超时的错误号。该操作在阻塞和异步两种调用中都可使用。
17.4.     Target Class接口
Target Class Member Functions
说明
Constructors
 
     CTarget::CTarget( void);
构造一个无效的 CTarget 。重发机制的默认值: community names “public” retry=1 time_out=1
     CTarget::CTarget(const Address &address ,
                    const char *read_community_name,  
                    const char *write_community_name, 
community names Address object 构造一个 CTarget 。重发机制的默认值: retry=1 time-out =100ms
     CTarget( const Address &address
             const OctetStr &read_community_name,
             const OctetStr &write_community_name);
OctetStr Communities Address 构造一个 CTarget
     CTarget::CTarget( Address &address);
Address object 构造一个 CTarget 。重发机制的默认值: community names “public” retry=1 time_out=1
     CTarget::CTarget( const CTarget &target);
拷贝构造函数
Destructor
 
     CTarget::~CTarget();
删除 CTarget 对象,释放所有资源。
Member Functions
 
     char * get_readcommunity();
返回读权限的 community 名称
     void get_readcommunity( OctetStr& read_community_oct);
获取 OctetStr 格式的读权限 community
     void set_readcommunity( const char * get_community);
设置读权限 community
     void set_readcommunity( const OctetStr& read_community);
用一个 OctetStr 设置读权限 community
     char * get_writecommunity();
获取写权限 community
     void get_writecommunity( OctetStr &write_community_oct);
获取 OctetStr 格式的写权限 community
     void set_writecommunity( const char * new_set_community);
设置写权限 community
     void set_writecommunity( const OctetStr& write_community);
 
用一个 OctetStr 设置写权限 community
     int get_address( GenAddress &address);
获取 Address object.
     void set_address( Address &address);
设置 Address 部分
     CTarget& operator=( const CTarget& target);
把一个 CTarget 赋给另一个。
     snmp_version get_version();
返回 SNMP 版本( version1 version2
     void set_version( const snmp_version v);
设置版本( version1 version2
     int operator==( const CTarget &lhs, const CTarget &rhs);
比较两个 CTargets
Abstract Class Member Functions
 
     int valid();
返回一个 Target 的有效性
     void set_retry( const int r);
设置重发值
     int get_retry();
获取重发值
     void set_timeout( const unsigned long t);
设置超时值
     unsigned long get_timeout();
获取超时值
17.5.     CTarget Class (Community为基础的Target)
CTargetclass 允许显示地定义以 Community 为基础的 Target 。一个 CTarget 用以 SNMP Community 为基础的 Target 定义了一个 SNMP 代理端。这包含了 读权限、写权限 community names and an address 。地址是用 SNMP++ Addressclass 来表示的,所以该地址可以是 IP 或者 IPX address Addressclass 是个抽象基类,所以可以实现多态操作)。 CTarget class 使用前提应该是:应用开发者明确地知道代理端所支持的以 SNMP community 为基础的访问方式,即 SNMPv1 SNMPv2
17.5.1.    CTarget对象可通过3种不同的方式构建
// ----------[ instantiating CTarget Objects ]-----------------------------
 
// valid complete instantiation
CTarget    ct((IpAddress)”10.10.10.10”, // Address
                      “public”,        // read community name
                      “public”);       // write community name
 
// valid complete using “public” defaults
CTarget ct( (IpAddress) “1.2.3.4”);
 
// invalid CTarget
CTarget ct;
17.5.2.    修改CTargets
//----[ modifying CTargets ]------------------------------------
ct.set_readcommunity(“private);    // modifying the read community
 
ct.set_writecommunity(“private”);  // modifying the write community
 
ct.set_address( (IpAddress) “15.29.33.210”);
17.5.3.    访问CTargets
//-----[ Accessing CTarget member variables ]-------------------------
 
// get the write community name
cout << “Write community” << ct.get_writecommunity(); 
 
// get the read community name
cout << “Read community ” << ct.get_readcommunity();
 
// get the address
GenAddress address;
ct.get_address( address);
 
// check the validity of a target
if ( ct.valid())
   cout << “Target is valid”;
17.5.4.    CTargets例子
//------------[CTarget class examples ]-----------------------------------------------------------------
 
// create a valid CTarget using a GenAddress
CTarget ct( (GenAddress) “10.20.30.40”);
 
// create a valid CTarget using an IpxAddress
IpxAddress ipxaddress(“01010101-010101010101”);
CTarget my_target( ipxaddress);      // use default “public” for communities
 
// create an invalid CTarget object
CTarget ct;      // no construction params therefor invalid
if ( !ct.valid()) 
   cout << “Invalid CTarget instance!”;
 
// get the read community
cout << “Read Community =” << ct.get_readcommunity();
 
// get the write community
cout << “Write Community = ” << ct.get_writecommunity();
 
// modify the get community
ct.set_readcommunity( “pilsner”);
 
// modify the write community
ct.set_writecommunity(“pale ale”);

18.     Snmp Class
SNMP++ Snmp Class 的对象模型( Object Modeling Technique )视图
Snmp class SNMP++ 中最为重要的类。 Snmp class 封装了 SNMP 的会话。通过处理与指定代理端的会话, SNMP++ 实现了对网络管理应用的逻辑绑定。会话所控制的是 PDU 的构建、分发、接受。其他大多数 API 需要程序员直接操作会话,也即需要提供可靠的传输机制来控制超时、重发、查重。 Snmp class 管理了大部分的会话,得到解放的程序员只需要关注于代理端的管理,方便了代码的开发和测试。如果不这样(没有 SNMP++ ),你就只有去设计、实现、测试你自己的 SNMP 引擎。那么 Snmp class 是如何管理通信的呢: 1 、在 UDP IPX 连接基础上管理传输层; 2 、负责打包和解包 PDU 中的绑定变量; 3 、分发和接收 PDU 4 、管理所有 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++ 的平台切换。
18.1.     Snmp Class成员函数列表
Snmp Class Member Functions
说明
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);
对接收 trap inform 的操作注册
     int notify_register( TargetCollection &targets,
                     OidCollection &trapids,
               AddressCollection &listen_addresses,
                     snmp_callback callback,
                     void * callback_data=0);
对接收 trap inform 的操作注册,并用 AddressCollection 指出监听的接口。
   int notify_unregister();
撤消对接收 trap inform 的操作注册
   int cancel( const unsigned long rid);
取消针对所给请求 id 的异步请求的等待
18.2.     双效的API
所有的 Snmp class 成员函数都是双效的。这就是说对于 SNMP version 1 version 2c ,他们可以使用统一的参数表。这解放了程序员,因为程序员不用为了与 SNMP version 2 的代理端通讯而去修改代码。
18.3.     Snmp Class的公共成员函数
通过 Snmp Class 提供的许多成员函数可以创建、管理、终结一个会话。多个 Snmp 对象可以在同一时间建立。
18.3.1.    Snmp Class的构造和析构函数
Snmp Class 的构造和析构函数允许开启和关闭会话。通过构建一个 Snmp 对象来开启一个 Snmp 会话。由此可对 UDP IPX 套接口实现构建和管理,直到对象被销毁。 Snmp 对象可选择被动态或静态的实例化。
18.3.2.    Snmp Class构造函数
该构造函数以参数方式返回状态( status )。因为 C++ 的构造函数没有返回值,调用者必须提供一个状态值( status )以供实例化对象后针对状态的检查。调用者需要检查返回值是否是 “SNMP_CLASS_SUCCESS” 。如果构造函数的状态不表示成功,该会话也就不可用。
// constructor, blocked SNMP object
Snmp::Snmp( int &status);                  // construction status
18.3.3.    Snmp Class析构函数
Snmp Class 的析构函数关闭相应的会话,并释放所有资源和内存
// destructor             
Snmp::~Snmp();
18.3.4.    Snmp Class发送请求的成员函数
为了访问或修改代理端的 MIB ,请求必须通过 Snmp::get(), Snmp::set(), Snmp::get_next(), Snmp::get_bulk(), Smnp::inform() 以及 Snmp::trap() 来发送。所有这些成员函数接受同样的参数表。
18.3.5.    Snmp Class的阻塞方式成员函数: Get
阻塞方式的成员函数 get 允许从指定 target 的代理端获取对象。调用者必须指定目标 target 以及要请求的 Pdu
//--------[ get ]-------------------------------------------   
int Snmp::get( Pdu &pdu,                 // Pdu to get
                SnmpTarget &target);          // specified target
18.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
18.3.7.    Snmp Class的阻塞方式成员函数: Set
阻塞方式的成员函数 set 允许设置代理端的对象
//---------[ set ]--------------------------------------------
 int   Snmp::set( Pdu &pdu,                     // Pdu to set
                SnmpTarget &target);         // specified target
18.3.8.    Snmp Class的阻塞方式成员函数: Get Bulk
SNMP++ SNMP version 1 version 2 Target 提供了一个获取批量数据的接口。在 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
18.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() 来为一个 inform PDU 指定其 ID Inform 标识符 ID 代表了其使用的 Oid 。为了建立 Inform ID ,可以用需要的 Inform ID 值来直接建立一个 Oid 对象,然后用成员函数 Pdu::set_notify_id() 把一个 Pdu 加载在其上。反过来,一个 inform ID 可以用成员函数 Pdu::get_notify_id() 来获取。
Inform 上指定 TimeStamp 时间信息
要给一个 inform PDU 指定时间信息,可用成员函数 Pdu::set_notify_timestamp() 。如果一个 Pdu 没有用该成员函数就发出去了,那么会使用一个来自 SNMP++ 引擎默认的 timestamp
18.4.     Snmp Class的异步方式成员函数
一个 Snmp 实例可以支持阻塞与异步两种方式的请求。异步请求将会立即返回所控制的线程,并不需要等待呼叫者的应答。为了达到该目的,使用了所谓的回调程序机制。当发出异步请求时,调用者必须指定回调函数,还可选择性的指定一个回调函数的参数。
18.4.1.    SNMP++异步回调函数的类型定义
typedef void (*snmp_callback)( int,                   // reason
                           Snmp*,                // session handle
                           Pdu &,                  // Pdu passed in
                           SnmpTarget &,  // source target
                           void * );               // callback data
18.4.1.1.   回调的参数说明
Reason(s) , int
该整形的原因参数描述了调用回调的原因。回调被调用的原因包括以下几种:
SNMP_CLASS_ASYNC_RESPONSE :收到了一个 SNMP 应答。这可以是一个来自 get, set, get-next, get-bulk inform 的应答。用 Pdu 参数保存实际应答的 PDU ,用 SnmpTarget 参数保存发送应答的 target
SNMP_CLASS_TIMEOUT :一个 SNMP++ 请求超时,该请求由 target 实例提供的超时与重发信息的机制来处理。为了重用,用 Pdu 参数保存 Pdu 请求的原值,用 SnmpTarget 参数保存 target 的原值。
SNMP_CLASS_SESSION_DESTROYED :会话被销毁,此时所有正在等待的异步请求都不会完成。
SNMP_CLASS_NOTIFICATION :收到一个 notification, trap inform 请求。 Pdu 对象会保存实际的 notify ,通过 Pdu 成员函数 Pdu::get_notify_id(), Pdu::get_notify_timestamp() Pdu::get_notifty_enterprise() 来获得 notification id, timestamp enterprise
Snmp++ Session, Snmp*
该参数保存发送请求的会话的值。由此可以在 time-out get-next 情况下实现会话的重用。
Response PDU, Pdu&
该参数为 esponse, notifie trap 保存了 应答 Pdu” 。当 原因 reason 参数)为 失败 时, Pdu 参数保存了 请求 Pdu” 的原值。一旦 Pdu 对象越界,其值就不可得了。
Target , SnmpTarget&
该参数为 response, notifie trap 保存了 Pdu 的来源。如果 原因 reason 参数)为 失败 ,当有请求发出时, target 的原值就会被用到。
Callback data ,void *
当有请求发出时,回调的参数可以作为一个可选的参数提供。如果指定了该参数,将会返回相关信息。如果没有指定,该值取空( null )。
18.4.2.    取消一个异步请求
SNMP++ 允许在完成之前取消相应的异步请求。这很有用,尤其当你需要在代码中提前退出或指定的回调已经失效的时候。当 Snmp 对象发出的请求被销毁时,异步请求会自动取消,这时指定的回调会收到一个 “SNMP_CLASS_SESSION_DESTROYED” 的原因。另一方面,可以用成员函数 Snmp::cancel() 来取消单个的异步请求。该成员函数通过参数 request_id 无影响的取消对应的异步请求。
//-------------[ cancel a request ]-----------------------------------
int Snmp::cancel( const unsigned long rid);
18.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
18.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
18.4.5.    Snmp Class的异步成员函数:Get Next
异步成员函数 get-next 的工作方式与异步 get 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
18.4.6.    Snmp Class的异步成员函数:Get Bulk
异步成员函数 get- bulk 的工作方式与异步 get 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
18.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
18.5.     SNMP++通知的方法
SNMP++ API 支持收发 trap 的成员函数
18.5.1.    发送Trap
发送 trap 的函数是一个有用的管理程序( manager API 。可用函数与其他管理端进行通讯。
//-----------------------[ send a trap ]----------------------------------
int Snmp::trap( Pdu &pdu,                                 // Pdu to send
               SnmpTarget &target);                // destination target
18.5.1.1.   发送Trap的成员函数的参数说明
Pdu &pdu 
要发送的 Pdu ,它是 trap 所包含的有效负载。
SnmpTarget &target
发送 Trap 的目的地
指定一个 Trap Id
Trap Id 的指定方式与 Inform Id 一样。可用成员函数 Pdu::set_notify_id() 来指定 trap PDU ID Trap 标识符 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++ 引擎的时间信息。
18.5.1.2.   指定Trap Enterprise
不用被企业指定的 trap 困扰,任何 trap 的企业都代表了产生 trap 的代理端的 MIB 。对 trap 的发送者来说它是系统标识符( System Object Identifier ),但是从理论上讲它可以表示任何 Oid 的值。为了设置该参数, SNMP++ 允许使用成员函数 Pdu::set_notify_enterprise() 来设置 enterprise ,而且这个参数是可选的。如果使用了所提供的 enterprise ,该 enterprise 会加载在对应的 Pdu 对象上。
18.5.1.3.   SNMPv1 Trap指定特殊的Trap
为了给 SNMPv1 Trap 指定特殊的 Trap 值, trapid Oid 应该构造如下: trapid 的最末子 id subid )代表指定的要使用的值;倒数第二个子 id 应该是零。即,为了指定特殊的 Trap 值,需要添加两个额外的子 id ,一个是零、一个是值( “0.X” )。这个约定与规定 SNMPv1 SNMPv2trap 映射的 RFC 1452 的描述一致。
18.5.2.    接收Notification
接收 SNMP++ trap inform 的时候,允许应用程序使用指定的过滤器来接收 trap inform 。不像其他的 SNMP 操作, trap inform 是在任何可能出现的时候主动发出的。因此 informs traps 属于异步的动作。通过 SNMP++ 提供的成员函数,调用者可以指定<

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