Net-snmp总结(四)-net-snmp的MIBs扩展_添加set

来源:互联网 发布:淘宝不能结算怎么回事 编辑:程序博客网 时间:2024/06/05 09:35

一、编写MIB文件

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

--开始TEST-SET-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.4testSet OBJECT IDENTIFIER ::= {enterprises 77587}writeObject OBJECT IDENTIFIER ::= {testSet 1}writeObject OBJECT-TYPE   --对象名称SYNTAX      DisplayString --类型MAX-ACCESS  read-write    --访问方式STATUS      current       --状态DESCRIPTION "test write"  --描述::= {testSet 1}           --父节点--结束定义END

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

[root@localhostbin]# ./snmptranslate -Tp -IR TEST-SET-MIB::testSet

+--testSet(77587)   |   +-- -RW- String    writeObject(1)            Textual Convention: DisplayString            Size: 0..255

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

二、生成源代码

执行envMIBS="+/usr/local/net-snmp/share/snmp/mibs/TEST-SET-MIB.txt" ./mib2c testSet,会引导你逐渐生成testSet.h和testSet.c,先选2再选1。

具体生成过程参考上一篇文档

生成的testSet.h如下

 * Note: this file originally auto-generated by mib2c using *        $ */#ifndef TESTSET_H#define TESTSET_H/* * function declarations */void            init_testSet(void);Netsnmp_Node_Handler handle_writeObject;#endif                          /* TESTSET_H */
经过修改的testSet.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 "testSet.h"//这里是添加的,buf用于保存控制端设置的值,也用于返回。#define BUFSIZE 1024static char buf[BUFSIZE] = "test Write";    //给一个默认值/** Initializes the testSet module */voidinit_testSet(void){    const oid       writeObject_oid[] = { 1, 3, 6, 1, 4, 1, 77587, 1 };    DEBUGMSGTL(("testSet", "Initializing\n"));    netsnmp_register_scalar(netsnmp_create_handler_registration                            ("writeObject", handle_writeObject,                             writeObject_oid, OID_LENGTH(writeObject_oid),                             HANDLER_CAN_RWRITE));}inthandle_writeObject(netsnmp_mib_handler *handler,                   netsnmp_handler_registration *reginfo,                   netsnmp_agent_request_info *reqinfo,                   netsnmp_request_info *requests){    int             ret;    switch (reqinfo->mode) {  //是获取操作    case MODE_GET:        snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,             /*这里填buf,用于返回数据给控制端*/      buf  /* XXX: a pointer to the scalar's data */,             /*这里是buf数据字节数,注意writeObject类型*/ strlen(buf)  /* XXX: the length of the data in bytes */);        break;        /*         * SET REQUEST         *         * multiple states in the transaction.  See:         * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg         */    //下面是设置操作的,也就是snmpset        case MODE_SET_RESERVE1: //这个不管它                /* or you could use netsnmp_check_vb_type_and_size instead */            ret = netsnmp_check_vb_type(requests->requestvb, ASN_OCTET_STR);            if ( ret != SNMP_ERR_NOERROR ) {                netsnmp_set_request_error(reqinfo, requests, ret );            }            break;    case MODE_SET_RESERVE2:            /* XXX malloc "undo" storage buffer */            //我们不需要动态申请内存,直接略过        if ( 0/* XXX if malloc, or whatever, failed: */ ) {            netsnmp_set_request_error(reqinfo, requests,SNMP_ERR_RESOURCEUNAVAILABLE);        }        break;    case MODE_SET_FREE:        /*         * XXX: free resources allocated in RESERVE1 and/or         * RESERVE2.  Something failed somewhere, and the states         * below won't be called.          */        break; //  这里是我们的重点,控制端传过来的数据就在这里获取    case MODE_SET_ACTION:        /*         * XXX: perform the value change here             /* 获取控制端使用snmpset传来的数据 */            memcpy(buf,requests->requestvb->buf,requests->requestvb->val_len);        if ( 0/* XXX: error? */ ) {//这个先不管了            netsnmp_set_request_error(reqinfo, requests, 0/* some error */);        }        break;    case MODE_SET_COMMIT:        /*         * XXX: delete temporary storage          */        if ( 0/* XXX: error? */ ) {            /*             * try _really_really_ hard to never get to this point              */            netsnmp_set_request_error(reqinfo, requests,SNMP_ERR_COMMITFAILED);        }        break;    case MODE_SET_UNDO:        /*         * XXX: UNDO and return to previous value for the object          */        if ( 0/* XXX: error? */ ) {            /*             * try _really_really_ hard to never get to this point              */            netsnmp_set_request_error(reqinfo, requests,SNMP_ERR_UNDOFAILED);        }        break;    default:        /*         * we should never get here, so this is a really bad error          */        snmp_log(LOG_ERR, "unknown mode (%d) in handle_writeObject\n",reqinfo->mode);        return SNMP_ERR_GENERR;    }    return SNMP_ERR_NOERROR;}

三、配置编译

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

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

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


查看文件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("testSet"))init_testSet();


编译并安装

[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 -c public -v 2c localhost 1.3.6.1.4.1.77587.1.0

SNMPv2-SMI::enterprises.77587.1.0= STRING: "test Write"

 

设置时提示报错,这和snmpd的配置文件的权限有关。

[root@localhostbin]# ./snmpset -c public -v 2c localhost 1.3.6.1.4.1.77587.1.0 s"hello world"

Error in packet.

Reason: noAccess

Failed object:SNMPv2-SMI::enterprises.77587.1.0

 

打开snmpd.conf文件,添加如下一行,然后重启snmpd

rwcommunitypublic

 

再通过./snmpset-c public -v 2c localhost 1.3.6.1.4.1.77587.1.0 s "hello world"设置以后,有如下提示,说明设置成功了。

SNMPv2-SMI::enterprises.77587.1.0= STRING: "hello world"

 

然后再次调用snmpget

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

SNMPv2-SMI::enterprises.77587.1.0= STRING: "hello world"

至此我们添加自定义MIB Set操作成功!