博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux net-snmp(之mib2c工具生成标量节点代码)
阅读量:2384 次
发布时间:2019-05-10

本文共 11429 字,大约阅读时间需要 38 分钟。

-----------------------------------------禁止转载-----------------------------------------

在linux下编译net-snmp后,在/usr/local/snmp/bin目录下看到mib2c程序,此程序是根据MIB文件自动生成子代理模块代码的工具。

MIB文件可以自己写,也可以使用MIB Builder软件生成,链接:https://pan.baidu.com/s/1N36NQrTIvZ0SxB7u4tP9xA,提取码:6cqd

下面使用MIB builder生成一个简单MIB文件,test节点是我们要操作的节点,group节点的类型是OBJECT-GROUP,这个节点没啥用,但是在这个软件上必须要建立一个group节点并把test节点添加进来才不会报错,不知道为什么

下面是生成的TEST-MIB.my文件内容(语法其实很简单,可以照葫芦画瓢):

---- TEST-MIB.my-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0  Build 88-- Tuesday, April 14, 2020 at 16:21:12--	TEST-MIB DEFINITIONS ::= BEGIN 		IMPORTS			OBJECT-GROUP							FROM SNMPv2-CONF						enterprises, Integer32, OBJECT-TYPE, MODULE-IDENTITY							FROM SNMPv2-SMI;				-- 1.3.6.1.4.1.1		a MODULE-IDENTITY 			LAST-UPDATED "202004141615Z"		-- April 14, 2020 at 16:15 GMT			ORGANIZATION 				"Organization."			CONTACT-INFO 				"Contact-info."			DESCRIPTION 				"Description."			::= {
enterprises 1 } ---- Node definitions-- -- 1.3.6.1.4.1.1.1 b OBJECT IDENTIFIER ::= {
a 1 } -- 1.3.6.1.4.1.1.1.1 test OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS read-write STATUS current DESCRIPTION "Description." ::= {
b 1 } -- 1.3.6.1.4.1.1.2 group OBJECT-GROUP OBJECTS {
test } STATUS current DESCRIPTION "Description." ::= {
a 2 } END---- TEST-MIB.my--

将生成的TEST-MIB.my文件放到linux的/usr/local/snmp/share/snmp/mibs/目录下,然后使用“sudo /usr/local/snmp/bin/snmptranslate -Tp -IR XXX-MIB::节点”命令可以查看此MIB文件格式是否正常,正常如下,会显示节点树,group节点没啥用,忽略:

MIB文件没问题,就可以执行命令“env MIBS="+/usr/local/snmp/share/snmp/mibs/XXX-MIB.my" /usr/local/snmp/bin/mib2c 节点”,生成代码,生成期间会有选择选项如下:

chens@chens-Lenovo-G400:~$ env MIBS="+/usr/local/snmp/share/snmp/mibs/TEST-MIB.my" /usr/local/snmp/bin/mib2c awriting 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:                       	    a  numeric translation:       	    .1.3.6.1.4.1.1  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 a")  2) If you want to magically "tie" integer variables to integer     scalars     (by hand use: "mib2c -c mib2c.int_watch.conf a")  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 a.hwriting to a.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 a.crunning indent on a.hchens@chens-Lenovo-G400:~$

成功生成a.c a.h(文件名称取决于mib2c生成代码命令中的节点名称),但是生成的文件是不完整的,要根据自己的业务补充代码,下面为生成后未修改的代码:

/* * Note: this file originally auto-generated by mib2c using *        $ */#include 
#include
#include
#include "a.h"/** Initializes the a module */voidinit_a(void){
const oid test_oid[] = {
1,3,6,1,4,1,1,1,1 }; DEBUGMSGTL(("a", "Initializing\n")); netsnmp_register_scalar( netsnmp_create_handler_registration("test", handle_test, test_oid, OID_LENGTH(test_oid), HANDLER_CAN_RWRITE ));}inthandle_test(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_INTEGER, /* 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_INTEGER); 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_test\n", reqinfo->mode ); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR;}

下面为修改后的代码,中文注释是要修改的地方:

/* * Note: this file originally auto-generated by mib2c using *        $ */#include 
#include
#include
#include "a.h"/** Initializes the a module */voidinit_a(void){
const oid test_oid[] = {
1,3,6,1,4,1,1,1,1 }; DEBUGMSGTL(("a", "Initializing\n")); netsnmp_register_scalar( netsnmp_create_handler_registration("test", handle_test, test_oid, OID_LENGTH(test_oid), HANDLER_CAN_RWRITE ));}inthandle_test(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. */ int value = 10; int setValue; switch(reqinfo->mode) {
case MODE_GET: //这里是读取节点内容 snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, &value /*添加读取的内容*/ /* XXX: a pointer to the scalar's data */, 4 /*内容长度*/ /* 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_INTEGER); if ( ret != SNMP_ERR_NOERROR ) {
netsnmp_set_request_error(reqinfo, requests, ret ); } break; case MODE_SET_RESERVE2: /* XXX malloc "undo" storage buffer */ if (0 /*这里填出错的条件*/) {
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: //这里是设置test节点,我们这里只是打印一下要设置的值,实际根据业务情况进行处理 //获取设置的值,其他类型的数据可以到net-snmp官网看requests结构体的成员 setValue = *requests->requestvb->val.integer; printf("setvalue:%d\n", setValue); if (0/*这里填错误条件*/) {
netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_BADVALUE/*报错的宏,snmp官网可查*/); } break; case MODE_SET_COMMIT: /* XXX: delete temporary storage */ 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_test\n", reqinfo->mode ); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR;}

将a.c和a.h放到net-snmp源码目录的agent/mibgroup/目录下,进行编译:

1)./configure --prefix=/usr/local/snmp --with-mib-modules=“a”
ps:–with-mib-modules="a"是将a模块加载到snmpd中,这样编译出来的snmpd程序就支持a中的节点操作,假如要将a、b、c三个模块加载进去,则跟参数–with-mib-modules=“a b c”
2)make
3)sudo make install

测试:

1)执行sudo /usr/local/snmp/sbin/snmpd -f -Le -c /usr/local/etc/snmpd.conf
ps:-f -Le参数是终端显示snmpd的打印信息
2)执行sudo /usr/local/snmp/bin/snmpget -c public -v2c localhost 1.3.6.1.4.1.1.1.1.0,获取test节点的值
3)执行sudo /usr/local/snmp/bin/snmpset -c public -v2c localhost 1.3.6.1.4.1.1.1.1.0 i 12,设置test节点的值为12
运行截图:
在这里插入图片描述

你可能感兴趣的文章
Add Two Numbers
查看>>
Longest Substring Without Repeating Characters
查看>>
Median of Two Sorted Arrays
查看>>
Search for a Range
查看>>
罗马数字与阿拉伯数字的相互转化
查看>>
3Sum
查看>>
Next Permutation
查看>>
sys文件系统
查看>>
Mysql常用命令大全
查看>>
辞职后五险一金怎么处理?
查看>>
几种开源的TCP/IP协议栈对比
查看>>
C语言之断言
查看>>
程序员技术练级攻略
查看>>
#define
查看>>
C语言之if...else PK switch...case
查看>>
关于SVN方面的问题
查看>>
深入理解C语言
查看>>
编程成就:开发人员如何升级
查看>>
如何防止代码腐烂
查看>>
va_start va_end 的使用和原理
查看>>