【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.h和myModule.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; }
需要对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
参考地址