Net-snmp总结(三)-net-snmp的MIBs扩展_添加get

来源:互联网 发布:折弯机模具规格算法 编辑:程序博客网 时间:2024/05/20 20:18

一、编写MIB文件

MIB文件是用 ASN.1 语法来描述的,所以为了精确定义MIB中各管理对象,用户不得不参考一些ASN.1语法的有关文档如RFC1155、RFC1212等等来定义设备自己的MIB。ASN.1是抽象句法表示法一 (Abstract SyntaxNotation One) 的简称,对于每个管理对象它都用文本来描述,一般文件的后缀名都用“.mib”,在net-snmp中后缀名是“.mib.txt”。

关于MIB文件示例,可以见编译安装后的net-snmp目录,一般是 /usr/local/net-snmp/share/snmp/mibs/。  

ls/usr/local/net-snmp/share/snmp/mibs/

AGENTX-MIB.txt                       IPV6-TCP-MIB.txt                     SNMP-NOTIFICATION-MIB.txt

...

IPV6-MIB.txt                         SNMP-MPD-MIB.txt                     UDP-MIB.txt

这里我们建立一个mib文件,命名为TEST-GET-MIB.txt,放在/usr/local/net-snmp/share/snmp/mibs/目录下因为这个目录是snmpd的默认目录,只要把MIB库放入该目录就可以自动加载MIB库,否则需要修改snmpd.conf文件,自定义的MIB文件如下:

--开始TEST-GET-MIB DEFINITIONS ::= BEGIN--引入部分IMPORTS    enterprises        FROM RFC1155-SMI                Integer32,OBJECT-TYPE        FROM SNMPv2-SMI                DisplayString        FROM SNMPv2-TC    TEXTUAL-CONVENTION        FROM SNMPv2-TC; --引用结束,用分号--定义节点--enterprises的OID是1.3.6.1.4testGet    OBJECT IDENTIFIER ::= { enterprises 77695 }GetTime     OBJECT IDENTIFIER ::= { testGet   1}GetTime OBJECT-TYPE       --对象名称SYNTAX DisplayString      --类型MAX-ACCESS read-only      --访问方式STATUS current            --状态DESCRIPTION               --描述"get current time"   ::= { testGet  1 }       --父节点--结束定义END 

写完后我们测一个MIB库有没有问题,在linux机器上用snmptranslate-Tp -IR TEST-GET-MIB::testGet显示结果如下:(这个测试不需要启动snmpd进程

[root@localhostbin]# ./snmptranslate -Tp -IR TEST-GET-MIB::testGet

+--testGet(77695)   |   +-- -R-- String    GetTime(1)            Textual Convention: DisplayString            Size: 0..255

OK,snmp自动发现了这个MIB库, 有了自定义的OID,接下来开始添加处理程序。

二、生成源代码

我们可以先来获取一下前面定义的 testGet 节点的值试试。 因为 enterprises 的OID是 1.3.6.1.4 ,而 testGet是 enterprises 的叶子(77695),而 GetTime 又是 testGet 的叶子节点(1)。所以其OID为 1.3.6.1.4.77695.1 。 
下面使用snmpget来测试一下(测试之前要先启动snmpd进程

[root@localhostbin]# ./snmpget -c public -v 2c localhost 1.3.6.1.4.1.77695.1.0

SNMPv2-SMI::enterprises.77695.1= No Such Object available on this agent at this OID  

结果是No Such Object available on this agent at this OID,我们需要用mib2c程序生成所需要的.c和.h文件。


执行envMIBS="+/usr/local/net-snmp/share/snmp/mibs/TEST-GET-MIB.txt" ./mib2ctestGet,会引导你逐渐生成testGet.h和testGet.c,先选2再选1,过程如下:

[root@localhost bin]# env MIBS="+/usr/local/net-snmp/share/snmp/mibs/TEST-GET-MIB.txt" ./mib2c  testGetwriting to -mib2c has multiple configuration files depending on the type ofcode you need to write.  You must pick one depending on your need.You requested mib2c to be run on the following part of the MIB tree:  OID:                              testGet  numeric translation:              .1.3.6.1.4.1.77695  number of scalars within:         1  number of tables within:          0  number of notifications within:   0First, do you want to generate code that is compatible with theucd-snmp 4.X line of code, or code for the newer Net-SNMP 5.X codebase (which provides a much greater choice of APIs to pick from):  1) ucd-snmp style code  2) Net-SNMP style codeSelect your choice : 2**********************************************************************                 GENERATING CODE FOR SCALAR OBJECTS:**********************************************************************  It looks like you have some scalars in the mib you requested, so I  will now generate code for them if you wish.  You have two choices  for scalar API styles currently.  Pick between them, or choose not  to generate any code for the scalars:  1) If you're writing code for some generic scalars     (by hand use: "mib2c -c mib2c.scalar.conf testGet")  2) If you want to magically "tie" integer variables to integer     scalars     (by hand use: "mib2c -c mib2c.int_watch.conf testGet")  3) Don't generate any code for the scalarsSelect your choice: 1    using the mib2c.scalar.conf configuration file to generate your code.writing to testGet.hwriting to testGet.c*********************************************************************** NOTE WELL: The code generated by mib2c is only a template.  *YOU*  ** must fill in the code before it'll work most of the time.  In many ** cases, spots that MUST be edited within the files are marked with  ** /* XXX */ or /* TODO */ comments.                                  ***********************************************************************running indent on testGet.crunning indent on testGet.h

mib2c已经统计出我们的mib库包含1个scalar变量,0个table变量,0个通知变量,Scalar就是包含我们常用的整型,字符串,时间等等数据类型。table就是scalar的一种集合,有一个和多个列组成,类似于数据库中的表。它必须具有索引项,用来按一定顺序检索表项,当然我们只写了一个标量的OID,不是表结构也不是通知结构

生成的testGet.h如下

/* * Note: this file originally auto-generated by mib2c using *        $ */#ifndef TESTGET_H#define TESTGET_H/* * function declarations */void            init_testGet(void);Netsnmp_Node_Handler handle_GetTime;#endif                          /* TESTGET_H */

生成的testGet.c文件如下:

/* * Note: this file originally auto-generated by mib2c using *        $ */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "testGet.h"/** Initializes the testGet module */voidinit_testGet(void){/* * Note: this file originally auto-generated by mib2c using *        $ */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "testGet.h"/** Initializes the testGet module */voidinit_testGet(void){    const oid       GetTime_oid[] = { 1, 3, 6, 1, 4, 1, 77695, 1 };    DEBUGMSGTL(("testGet", "Initializing\n"));    netsnmp_register_scalar(netsnmp_create_handler_registration                            ("GetTime", handle_GetTime, GetTime_oid,                             OID_LENGTH(GetTime_oid), HANDLER_CAN_RONLY));}inthandle_GetTime(netsnmp_mib_handler *handler,               netsnmp_handler_registration *reginfo,               netsnmp_agent_request_info *reqinfo,               netsnmp_request_info *requests){    /*     * We are never called for a GETNEXT if it's registered as a     * "instance", as it's "magically" handled for us.     */    /*     * a instance handler also only hands us one request at a time, so     * we don't need to loop over a list of requests; we'll only get one.     */    switch (reqinfo->mode) {    case MODE_GET:        snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,                                 /*                                  * XXX: a pointer to the scalar's data                                  */ ,                                 /*                                  * XXX: the length of the data in bytes                                  */ );        break;    default:        /*         * we should never get here, so this is a really bad error         */        snmp_log(LOG_ERR, "unknown mode (%d) in handle_GetTime\n",                 reqinfo->mode);        return SNMP_ERR_GENERR;    }    return SNMP_ERR_NOERROR;}     

以上的代码都是自动生成的,我们没有写一行代码,到了这一步,我们需要把testGet.c里面的XXX改成自己的值,也就两行,修改后testGet.c文件代码如下:

/* * Note: this file originally auto-generated by mib2c using *        $ */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "testGet.h"/** Initializes the testGet module */voidinit_testGet(void){    const oid       GetTime_oid[] = { 1, 3, 6, 1, 4, 1, 77695, 1 };    DEBUGMSGTL(("testGet", "Initializing\n"));    netsnmp_register_scalar(netsnmp_create_handler_registration                            ("GetTime", handle_GetTime, GetTime_oid,                             OID_LENGTH(GetTime_oid), HANDLER_CAN_RONLY));}inthandle_GetTime(netsnmp_mib_handler *handler,               netsnmp_handler_registration *reginfo,               netsnmp_agent_request_info *reqinfo,               netsnmp_request_info *requests){    /*     * We are never called for a GETNEXT if it's registered as a     * "instance", as it's "magically" handled for us.     */    /*     * a instance handler also only hands us one request at a time, so     * we don't need to loop over a list of requests; we'll only get one.     */         time_t t;    switch (reqinfo->mode) {    case MODE_GET:                time(&t);            char szTime[100];        snprintf(szTime,100,"%s",ctime(&t));                snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,                                         /*                                          * XXX: a pointer to the scalar's data                                          */ szTime,                                         /*                                          * XXX: the length of the data in bytes                                          */ strlen(szTime));        break;    default:        /*         * we should never get here, so this is a really bad error         */        snmp_log(LOG_ERR, "unknown mode (%d) in handle_GetTime\n",                 reqinfo->mode);        return SNMP_ERR_GENERR;    }    return SNMP_ERR_NOERROR;}

三、配置编译

把testGet.c和testGet.h复制到/net-snmp-5.7.3/agent/mibgroups/路径下

设置编译参数(红色部分即为加上我们自己的mib模块)

[root@localhostnet-snmp-5.7.3]# ./configure  --prefix=/usr/local/net-snmp   --with-mib-modules="testGet"


查看文件net-snmp-5.7.3/agent/mibgroup/mib_module_inits.h,发现已经添加到初始化中。

/*This file is automatically generated by configure.  Do not modify by hand. */

  if (should_init("testGet"))init_testGet();


编译并安装

[root@localhostnet-snmp-5.7.3]# make

[root@localhostnet-snmp-5.7.3]# make install

四、测试新加的MIB

启动snmpd服务

[root@localhostsbin]# ./snmpd -f -Le

Turning on AgentXmaster support.

NET-SNMP version5.7.3

No Shmem line in/proc/meminfo

 

我们再调用snmpget来测试结果:

[root@localhostbin]# ./snmpget  -v2c -c publiclocalhost  1.3.6.1.4.1.77695.1.0

SNMPv2-SMI::enterprises.77695.1.0= STRING: "Fri Nov  3 14:02:13 2017

"

显示出了当前的时间,说明我们添加自定义MIB get操作成功!

原创粉丝点击