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

一、编写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.4
testSet 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 
#include 
#include 
#include "testSet.h"

//这里是添加的,buf用于保存控制端设置的值,也用于返回。
#define BUFSIZE 1024
static char buf[BUFSIZE] = "test Write";    //给一个默认值
/** Initializes the testSet module */
void
init_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));
}

int
handle_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模块)

[[email protected]]# ./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();


编译并安装

[[email protected]]# make

[[email protected]]# 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操作成功!

你可能感兴趣的:(net-snmp学习总结,net-snmp总结)