zoukankan      html  css  js  c++  java
  • 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 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 "));
        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 ",
                     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 "));
        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 ",
                     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
    完成
  • 相关阅读:
    Windows 编程入门,了解什么是UWP应用。
    java getway springcloud 记录请求数据
    nginx服务器配置传递给下一层的信息的一些参数-设置哪些跨域的域名可访问
    e.printStackTrace() 原理的分析
    关于性能测试组出现的问题查询和优化
    springboot connecting to :mongodb://127.0..0.1:27017/test authentication failed
    redis 集群 slots are covered by nodes.
    @PostConstruct +getapplicationcontext.getbean springboot获取getBean
    idea 错误: 找不到或无法加载主类 xx.xxx.Application
    elastic-job和spring cloud版本冲突2
  • 原文地址:https://www.cnblogs.com/yechanglv/p/6931096.html
Copyright © 2011-2022 走看看