net-snmp添加自訂MIB,net-snmp自訂mib
我所知道的添加自訂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 Testwriting 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: 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 codebase (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.hwriting 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.hrunning 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 */voidinit_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));} inthandle_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 */voidinit_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));} inthandle_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=gccFLAGS=-I. `net-snmp-config --cflags` -gDLFLAGS=-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 : cleanclean : 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完成