我所知道的添加自定義MIB的方法有三種 1.靜態載入,將生成的.c和.h文件加入到相應的位置,重新編譯snmp庫,優點是不需要修改配置文件,缺點是每次添加都得重新編譯; 2.動態載入,將生成的.c和.h文件再編譯成.so庫,修改snmpd.conf配置文件。優點是每次添加不需要重新編譯,缺點是必須支 ...
我所知道的添加自定義MIB的方法有三種 1.靜態載入,將生成的.c和.h文件加入到相應的位置,重新編譯snmp庫,優點是不需要修改配置文件,缺點是每次添加都得重新編譯; 2.動態載入,將生成的.c和.h文件再編譯成.so庫,修改snmpd.conf配置文件。優點是每次添加不需要重新編譯,缺點是必須支持dlmod命令; 3.子代理擴展,將生成的.c和.h文件編譯成可執行程式,運行該程式和snmpd即可,優點是操作簡單,缺點是需要運行兩個程式才行。 三種方法的前幾步是一樣的,都是編寫MIB,生成.c和.h文件,補全.c文件。 1.編寫MIB MIB的語法見http://blog.csdn.net/shanzhizi/article/details/15340305,寫得很清楚,很詳細。 下麵給出我自己的MIB文件。 -- Test-SLK-MIB.txt Test-SLK-MIB DEFINITIONS ::= BEGIN IMPORTS OBJECT-GROUP, MODULE-COMPLIANCE, NOTIFICATION-GROUP FROM SNMPv2-CONF enterprises, Integer32, Unsigned32, OBJECT-TYPE, MODULE-IDENTITY, NOTIFICATION-TYPE FROM SNMPv2-SMI DisplayString FROM SNMPv2-TC; Test MODULE-IDENTITY LAST-UPDATED "201601221450Z" --必須以Z結尾 ORGANIZATION "" CONTACT-INFO "" DESCRIPTION "Video's Server MIB." ::= { enterprises 745352 } Time OBJECT IDENTIFIER ::= { Test 1 } GetTime OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "Example : 2016/1/22" ::= { Time 1 } END -- Test-SLK-MIB.txt 這個MIB文件很簡單,只有一個OID 1.3.6.1.4.1.745352.1.1,把這個MIB放入MIBS文件夾,我的位於/usr/local/snmp/share/snmp/mibs。 2.生成.c和.h文件 運行命令mib2c Test-SLK-MIB::Test 出現的選項依次選2和1. [root@localhost mibs]# env MIBS="+/etc/snmp/mibs/Test-MIB.my" mib2c Test writing to - mib2c has multiple configuration files depending on the type of code 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: Test numeric translation: .1.3.6.1.4.1.16535 number of scalars within: 1 number of tables within: 0 number of notifications within: 0 First, do you want to generate code that is compatible with the ucd-snmp 4.X line of code, or code for the newer Net-SNMP 5.X code base (which provides a much greater choice of APIs to pick from): 1) ucd-snmp style code 2) Net-SNMP style code Select 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 Test") 2) If you want to magically "tie" integer variables to integer scalars (by hand use: "mib2c -c mib2c.int_watch.conf Test") 3) Don't generate any code for the scalars Select your choice: 1 using the mib2c.scalar.conf configuration file to generate your code. writing to Test.h writing to Test.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 Test.h running indent on Test.c 生成的Test.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 "Test.h" /** Initializes the Test module */ void init_Test(void) { const oid GetTime_oid[] = { 1, 3, 6, 1, 4, 1, 745352, 1, 1 }; DEBUGMSGTL(("Test", "Initializing\n")); netsnmp_register_scalar(netsnmp_create_handler_registration ("GetTime", handle_GetTime, GetTime_oid, OID_LENGTH(GetTime_oid), HANDLER_CAN_RONLY)); } int handle_GetTime(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { /* * 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; default: /* * we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, "unknown mode (%d) in handle_GetTime\n", reqinfo->mode); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; } 3.補全Test.c 在代碼中XXX處添加相應的值,代碼中都有說明,XXX: a pointer to the scalar's data,這個要我們填一個指針,XXX: the length of the data in bytes 這個要我們填數據的大小,當然要先定義,然後去獲取啊。 補全後 /* * 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 "Test.h" #include <time.h> /** Initializes the Test module */ void init_Test(void) { const oid GetTime_oid[] = { 1, 3, 6, 1, 4, 1, 745352, 1, 1 }; DEBUGMSGTL(("Test", "Initializing\n")); netsnmp_register_scalar(netsnmp_create_handler_registration ("GetTime", handle_GetTime, GetTime_oid, OID_LENGTH(GetTime_oid), HANDLER_CAN_RONLY)); } int handle_GetTime(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { /* * 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. */ time_t t; switch (reqinfo->mode) { case MODE_GET: time(&t); char szTime[100]; snprintf(szTime,100,"%s",ctime(&t)); snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, /* * XXX: a pointer to the scalar's data */ szTime, /* * XXX: the length of the data in bytes */ strlen(szTime)); break; default: /* * we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, "unknown mode (%d) in handle_GetTime\n", reqinfo->mode); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; } 接下來根據方法不同,步驟也不同。 一、靜態鏈接 把Test.c和Test.h複製到/net-snmp-5.7.3/agent/mibgroups,這裡是說net-snmp源碼里。 編譯./configure --prefix=/usr/local/snmp --with-mib-modules=Test,make && make install。 靜態載入成功 二、動態載入 編寫makefile文件 CC=gcc FLAGS=-I. `net-snmp-config --cflags` -g DLFLAGS=-shared -fPIC -g Test.so: Test.c $(CC) $(CFLAGS) $(DLFLAGS) -c -o Test.o Test.c $(CC) $(CFLAGS) $(DLFLAGS) -o Test.so Test.o .PHONY : clean clean : rm -f *.so *.o 編譯生成.so庫。 修改snmpd.conf配置文件,在文件末尾加入dlmod Test ${Test.so所在絕對路徑}/Test.so 啟動snmpd, /usr/local/snmpd -f -L -DTest,dlmod -c /usr/local/snmp/etc/snmpd.conf 動態載入完成 三、子代理擴展 生成Test程式: net-snmp-config --compile-subagent Test Test.c 啟動snmpd,Test /usr/local/snmpd -c /usr/local/snmp/etc/snmpd.conf ./Test 完成