【snmp】net-snmp添加自定义MIB(标量)

 

安装net-snmp见:【snmp】centos6.5安装和配置snmp5.7.1

net-snmp添加自定义MIB(表格) 见:【snmp】net-snmp添加自定义MIB(表格)

一、编写MIB文件

 My-MIB.txt文件内容如下,新增的叶子节点myNode的oid为1.3.6.1.4.1.310.1.1

My-MIB DEFINITIONS::= BEGIN
	IMPORTS
		enterprises, OBJECT-TYPE, Integer32
    FROM SNMPv2-SMI
		TEXTUAL-CONVENTION, DisplayString
    FROM SNMPv2-TC;

	myModule MODULE-IDENTITY 
		LAST-UPDATED "202007231640Z"		
		ORGANIZATION 
			"Organization."
		CONTACT-INFO 
			"Contact-info."
		DESCRIPTION 
			"Description."
		::= { enterprises 310 }

	myObj OBJECT IDENTIFIER::={myModule 1}
 
	myNode OBJECT-TYPE
		SYNTAX      DisplayString
		ACCESS      read-write
		STATUS      current
		DESCRIPTION "my node"
		::={myObj 1}
END

 

 

二、使用mib2c命令生成.c和.h文件

上传My-MIB.txt到linux机器的/usr/local/snmp/share/snmp/mibs目录下

 

1、使用如下命令查看文件格式是否正确

/usr/local/snmp/bin/snmptranslate -Tp -IR My-MIB::myModule

 

2、执行如下命令生成标量文件

env MIBS="+/usr/local/snmp/share/snmp/mibs/My-MIB.txt" /usr/local/snmp/bin/mib2c -c mib2c.scalar.conf My-MIB::myModule

以上命令执行完后会生成myModule.hmyModule.c文件

生成的原代码(myModule.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 "myModule.h"

/** Initializes the myModule module */
void
init_myModule(void)
{
    const oid       myNode_oid[] = { 1, 3, 6, 1, 4, 1, 310, 1, 1 };

    DEBUGMSGTL(("myModule", "Initializing\n"));

    netsnmp_register_scalar(netsnmp_create_handler_registration
                            ("myNode", handle_myNode, myNode_oid,
                             OID_LENGTH(myNode_oid), HANDLER_CAN_RWRITE));
}

int
handle_myNode(netsnmp_mib_handler *handler,
              netsnmp_handler_registration *reginfo,
              netsnmp_agent_request_info *reqinfo,
              netsnmp_request_info *requests)
{
    int             ret;
    /*
     * 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;

        /*
         * SET REQUEST
         *
         * multiple states in the transaction.  See:
         * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
         */
    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 ( /* 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 
         */
        if ( /* XXX: error? */ ) {
            netsnmp_set_request_error(reqinfo, requests, /* some error */
                                      );
        }
        break;

    case MODE_SET_COMMIT:
        /*
         * XXX: delete temporary storage 
         */
        if ( /* 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 ( /* 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_myNode\n",
                 reqinfo->mode);
        return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}
View Code

 

需要对myModule.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 "myModule.h"

/** Initializes the myModule module */
void
init_myModule(void)
{
    const oid       myNode_oid[] = { 1, 3, 6, 1, 4, 1, 310, 1, 1 };

    DEBUGMSGTL(("myModule", "Initializing\n"));

    netsnmp_register_scalar(netsnmp_create_handler_registration
                            ("myNode", handle_myNode, myNode_oid,
                             OID_LENGTH(myNode_oid), HANDLER_CAN_RWRITE));
}



/**定义一个变量*/
static char buff[256]="";

int
handle_myNode(netsnmp_mib_handler *handler,
              netsnmp_handler_registration *reginfo,
              netsnmp_agent_request_info *reqinfo,
              netsnmp_request_info *requests)
{
    int             ret;
    /*
     * 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,
                                  buff, //定义的变量名称buff
                                  strlen(buff) //buff的长度
                                  );
        break;

        /*
         * SET REQUEST
         *
         * multiple states in the transaction.  See:
         * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
         */
    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 /* 出错条件 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 
         */
        if ( 0/* 出错条件 */ ) {
            netsnmp_set_request_error(reqinfo, requests, 0/* 错误 error */
                                      );
        }
        break;

    case MODE_SET_COMMIT:
        /*
         * XXX: delete temporary storage 
         */
        memcpy(buff,requests->requestvb->buf,requests->requestvb->val_len); // 将set的值赋值给变量buff
        buff[requests->requestvb->val_len] ='\0';   //设置字符串结束符
        if ( 0/* 出错条件 */ ) {
            /*
             * 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/* 出错条件 */ ) {
            /*
             * 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_myNode\n",
                 reqinfo->mode);
        return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}

 

三、载入自定义的MIB库

 

1、将myModule.h 和修改后的myModule.c文件复制到linux机器的net-snmp-5.7.1/agent/mibgroup/目录下

 

2、如果snmp服务在运行,停止snmp服务

 

3、/root/net-snmp-5.7.1目录下依次执行下面3个命令编译安装

 ./configure --prefix=/usr/local/snmp --with-mib-modules="myModule"

 make

 make install

 

 

四、测试

 

1、执行/usr/local/snmp/sbin/snmpd -c /usr/local/snmp/etc/snmpd.conf 命令启动snmp服务

 

2、设置myNode的值为"harara"

/usr/local/snmp/bin/snmpset -v 2c -c public localhost 1.3.6.1.4.1.310.1.1.0 s harara

 

 

3、查看myNode的值

/usr/local/snmp/bin/snmpget -v 2c -c public localhost 1.3.6.1.4.1.310.1.1.0

 

 

 

 

 

 

参考地址

Net-SNMP中MIB库的扩展

linux下snmpset

net-snmp添加自定义MIB

 

 

posted @ 2020-07-23 17:49  harara  阅读(3688)  评论(2编辑  收藏  举报