2020-11-19

ubuntu net-snmp5.7.3安装与使用

安装

  1. 官网下载net-snmp 5.7.3
  2. 解压
    tar -zxvf net-snmp-5.7.3

     

  3. 进入到解压后的文件夹,会看到configure文件,运行configure,并对安装目录进行设置
    ./configure --prefix=/usr/local/net-snmp

    然后一路回车即可。当出现下边显示的时候,表示配置文件执行完毕。出现的信息可能不一样,这个主要取决于配置信息,只要出现的信息在格式一致即可。在配置文件执行期间

                Net-SNMP configuration summary:
    ---------------------------------------------------------
     
      SNMP Versions Supported:    1 2c 3
      Building for:               linux
      Net-SNMP Version:           5.7.3
      Network transport support:  Callback Unix Alias TCP UDP IPv4Base SocketBase TCPBase UDPIPv4Base UDPBase
      SNMPv3 Security Modules:     usm
      Agent MIB code:            default_modules =>  snmpv3mibs mibII ucd_snmp notification notification-log-mib target agent_mibs agentx disman/event disman/schedule utilities host
      MYSQL Trap Logging:         unavailable
      Embedded Perl support:      disabled
      SNMP Perl modules:          building -- not embeddable
      SNMP Python modules:        disabled
      Crypto support from:        crypto
      Authentication support:     MD5 SHA1
      Encryption support:         DES AES
      Local DNSSEC validation:    disabled
     
    ---------------------------------------------------------
    

     

  4. 编译

    sudo make

    在编译期间可能会出现cannot find -lperl的问题,这是因为电脑没有安装perl库,安装一个perl库即可

    sudo apt-get install libperl-dev

     

  5. 安装

    sudo make install

    编译成功后就可以安装了,前面设置了安装路径是/usr/local/net-snmp,因为这个路径是的所有者(own)和所在组(group)都是root,所有需要sudo来执行。安装完成后进入目录/usr/local/net-snmp/sbin即可看到可执行文件snmpd,执行输出一下版本信息。因为我们这里还没有把它的路径添加到环境变量,所有还不能在任意位置直接输入snmpd来运行。

配置文件snmpd.conf

安装过程中遇到的问题 

  1. 在arm开发板上的ubuntu系统上安装,在执行配置文件是,单单只执行sudo ./configure --prefix=/usr/local/net-snmp出现--host=arm-xxx的问题
    UNAME_MACHINE = aarch64
    UNAME_RELEASE = 4.19.36-vhulk1905.1.0.h276.eulerosv2r8.aarch64
    UNAME_SYSTEM  = Linux
    UNAME_VERSION = #1 SMP Mon Apr 1 00:00:00 UTC 2019
    configure: error: cannot guess build type; you must specify one
    

    这个问题是由于config.sub和config.guess版本比较低,我们需要更新最新版本的config.sub和config.guess.执行下边命令进行下载

    wget -O /tmp/config.sub "git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD"
    wget -O /tmp/config.guess "git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD"
    

    现在之后将下载好的config.sub和config.guess文件放到SNMP源码目录(net-snmp-5.7.3),覆盖原有的文件,然后再重新执行配置文件。

  2. 安装-lperl库之后还是提醒缺少perl库,这个问题出现在执行配置文件时缺少参数,执行下述命令运行配置文件

    ./configure --prefix=/usr/local/net-snmp --disable-shared --disable-scripts --with-endianness=little -enable-mini-agent --disable-ipv6 --disable-manuals  --disable-ucd-snmp-compatibility --enable-as-needed --disable-embedded-perl
    

    然后在进行make编译。编译成功会出现下边两行

    chmod a+x net-snmp-config
    touch net-snmp-config-x

     

net-snmp的MIBs扩展_添加get

  1. 编写MIB文件,

    这里我们建立一个mib文件,命名为TEST-GET-MIB.txt,放在/usr/local/net-snmp/share/snmp/mibs/目录下因为这个目录是snmpd的默认目录,只要把MIB库放入该目录就可以自动加载MIB库,否则需要修改snmpd.conf文件,自定义的MIB文件如下:

    --开始
    TEST-GET-MIB DEFINITIONS ::= BEGIN
     
    --引入部分
    IMPORTS
        enterprises
            FROM RFC1155-SMI            
        Integer32,OBJECT-TYPE
            FROM SNMPv2-SMI            
        DisplayString
            FROM SNMPv2-TC
        TEXTUAL-CONVENTION
            FROM SNMPv2-TC; --引用结束,用分号
     
     
    --定义节点
    --enterprises的OID是1.3.6.1.4
    testGet    OBJECT IDENTIFIER ::= { enterprises 77695 }
     
    GetTime     OBJECT IDENTIFIER ::= { testGet   1}
     
    GetTime OBJECT-TYPE       --对象名称
    SYNTAX DisplayString      --类型
    MAX-ACCESS read-only      --访问方式
    STATUS current            --状态
    DESCRIPTION               --描述
    "get current time"   
    ::= { testGet  1 }       --父节点
     
    --结束定义
    END

    写完后我们测一个MIB库有没有问题,在linux机器上用snmptranslate-Tp -IR TEST-GET-MIB::testGet显示结果如下:(这个测试不需要启动snmpd进程

    ./snmptranslate -Tp -IR TEST-GET-MIB::testGet
    
    +--testGet(77695)
       |
       +-- -R-- String    GetTime(1)
                Textual Convention: DisplayString
                Size: 0..255

     

  2. 生成源代码,

    我们可以先来获取一下前面定义的 testGet 节点的值试试。 因为 enterprises 的OID是 1.3.6.1.4 ,而 testGet是 enterprises 的叶子(77695),而 GetTime 又是 testGet 的叶子节点(1)。所以其OID为 1.3.6.1.4.77695.1 。 
    下面使用snmpget来测试一下(测试之前要先启动snmpd进程)

    [root@localhostbin]# ./snmpget -c public -v 2c localhost 1.3.6.1.4.1.77695.1.0

    SNMPv2-SMI::enterprises.77695.1= No Such Object available on this agent at this OID  

    结果是No Such Object available on this agent at this OID,我们需要用mib2c程序生成所需要的.c和.h文件。

    执行env  MIBS="+/usr/local/net-snmp/share/snmp/mibs/TEST-GET-MIB.txt" ./mib2c  testGet,会引导你逐渐生成testGet.h和testGet.c,先选2再选1,过程如下:

    
    shuo@ubuntu:/usr/local/net-snmp/bin$ sudo env MIBS="+/usr/local/net-snmp/share/snmp/mibs/TEST-GET-MIB.txt" ./mib2c  testGet
    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:                              testGet
      numeric translation:              .1.3.6.1.4.1.77695
      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 testGet")
      2) If you want to magically "tie" integer variables to integer
         scalars
         (by hand use: "mib2c -c mib2c.int_watch.conf testGet")
      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 testGet.h
    writing to testGet.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 testGet.c
    running indent on testGet.h

     

  3. 修改生成的代码,只需修改.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 "testGet.h"
     
    /** Initializes the testGet module */
    void
    init_testGet(void)
    {
        const oid       GetTime_oid[] = { 1, 3, 6, 1, 4, 1, 77695, 1 };
     
        DEBUGMSGTL(("testGet", "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;
    }

     

  4. 编译配置

    把testGet.c和testGet.h复制到/net-snmp-5.7.3/agent/mibgroup/路径下

    设置编译参数(红色部分即为加上我们自己的mib模块)

    [root@localhostnet-snmp-5.7.3]# ./configure  --prefix=/usr/local/net-snmp   --with-mib-modules="testGet"

    编译并安装

    shuo@ubuntu:/usr/local/net-snmp/bin$ sudo make

    shuo@ubuntu:/usr/local/net-snmp/bin$ sudo make install

  5. 测试

    启动snmpd服务

    shuo@ubuntu:/usr/local/net-snmp/bin$ sudo ./snmpd -f -Le

    Turning on AgentXmaster support.

    NET-SNMP version5.7.3

    No Shmem line in/proc/meminfo

     

    我们再调用snmpget来测试结果:

    shuo@ubuntu:/usr/local/net-snmp/bin$ ./snmpget  -v2c -c public localhost  1.3.6.1.4.1.77695.1.0

     

    如果显示出了当前的时间,说明我们添加自定义MIB get操作成功!

 

net-snmp的MIBs扩展_添加set

  1. 这里我们建立一个mib文件,命名为TEST-SET-MIB.txt,放在/usr/local/net-snmp/share/snmp/mibs/目录下因为这个目录是snmpd的默认目录,只要把MIB库放入该目录就可以自动加载MIB库,否则需要修改snmpd.conf文件,自定义的MIB文件如下:
    
    --开始
    TEST-SET-MIB DEFINITIONS ::= BEGIN
     
    --引入部分
    IMPORTS
        enterprises
            FROM RFC1155-SMI
        Integer32,OBJECT-TYPE
            FROM SNMPv2-SMI
        DisplayString
            FROM SNMPv2-TC
        TEXTUAL-CONVENTION
            FROM SNMPv2-TC; --引用结束,用分号
     
     
    --定义节点
    --enterprises的OID是1.3.6.1.4
    testSet OBJECT IDENTIFIER ::= {enterprises 77587}
     
    writeObject OBJECT IDENTIFIER ::= {testSet 1}
     
    writeObject OBJECT-TYPE   --对象名称
    SYNTAX      DisplayString --类型
    MAX-ACCESS  read-write    --访问方式
    STATUS      current       --状态
    DESCRIPTION "test write"  --描述
    ::= {testSet 1}           --父节点
     
    --结束定义
    END

    写完后我们测一个MIB库有没有问题,在linux机器上用snmptranslate-Tp -IR TEST-SET-MIB::testSet显示结果如下:(这个测试不需要启动snmpd进程)

     shuo@ubuntu:/usr/local/net-snmp/bin$./snmptranslate -Tp -IR TEST-SET-MIB::testSet
    +--testSet(77587)
       |
       +-- -RW- String    writeObject(1)
                Textual Convention: DisplayString
                Size: 0..255

     

  2. 生成源代码
    执行envMIBS="+/usr/local/net-snmp/share/snmp/mibs/TEST-SET-MIB.txt" ./mib2c testSet,会引导你逐渐生成testSet.h和testSet.c,先选2再选1。

  3. 修改.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 "testSet.h"
     
    //这里是添加的,buf用于保存控制端设置的值,也用于返回。
    #define BUFSIZE 1024
    static char buf[BUFSIZE] = "test Write";    //给一个默认值
    /** Initializes the testSet module */
    void
    init_testSet(void)
    {
        const oid       writeObject_oid[] = { 1, 3, 6, 1, 4, 1, 77587, 1 };
     
        DEBUGMSGTL(("testSet", "Initializing\n"));
     
        netsnmp_register_scalar(netsnmp_create_handler_registration
                                ("writeObject", handle_writeObject,
                                 writeObject_oid, OID_LENGTH(writeObject_oid),
                                 HANDLER_CAN_RWRITE));
    }
     
    int
    handle_writeObject(netsnmp_mib_handler *handler,
                       netsnmp_handler_registration *reginfo,
                       netsnmp_agent_request_info *reqinfo,
                       netsnmp_request_info *requests)
    {
        int             ret;
     
     
        switch (reqinfo->mode) {
      //是获取操作
        case MODE_GET:
            snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
                 /*这里填buf,用于返回数据给控制端*/      buf  /* XXX: a pointer to the scalar's data */,
                 /*这里是buf数据字节数,注意writeObject类型*/ strlen(buf)  /* 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
             */
        //下面是设置操作的,也就是snmpset
     
            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/* 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 
                /* 获取控制端使用snmpset传来的数据 */
                memcpy(buf,requests->requestvb->buf,requests->requestvb->val_len);
            if ( 0/* XXX: error? */ ) {//这个先不管了
                netsnmp_set_request_error(reqinfo, requests, 0/* some error */);
            }
            break;
     
        case MODE_SET_COMMIT:
            /*
             * XXX: delete temporary storage 
             */
            if ( 0/* 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 ( 0/* 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_writeObject\n",reqinfo->mode);
            return SNMP_ERR_GENERR;
        }
     
        return SNMP_ERR_NOERROR;
    }

     

  4. 配置编译
     

    把testSet.c和testSet.h复制到/net-snmp-5.7.3/agent/mibgroups/路径下

    设置编译参数(红色部分即为加上我们自己的mib模块)

     shuo@ubuntu:~/Downloads/net-snmp-5.7.3$ sudo ./configure  --prefix=/usr/local/net-snmp   --with-mib-modules="testSet"

    编译并安装
     

     shuo@ubuntu:~/Downloads/net-snmp-5.7.3$ sudo make
     shuo@ubuntu:~/Downloads/net-snmp-5.7.3$ sudo make install

     

  5. 测试
     

    启动snmpd服务

    再调用snmpget来测试结果:
     

     shuo@ubuntu:/usr/local/net-snmp/bin$./snmpget -c public -v 2c localhost 1.3.6.1.4.1.77587.1.0

    输出:SNMPv2-SMI::enterprises.77587.1.0= STRING: "test Write"


    执行

    ./snmpset -c public -v 2c localhost 1.3.6.1.4.1.77587.1.0 s"hello world"

    如果出现如下所示的错误,是snmpd.conf的错误,需要添加一行rwcommunity setExample(注意,如果之前已经有rocommunity public这句话,将rocommunity改为rwcommunity是不行的,必须在其下边在写一行rwcommunity setExample才行,反正我是这样的情况,具体原因还没搞明白)

    Error in packet.
    
    Reason: noAccess
    
    Failed object:SNMPv2-SMI::enterprises.77587.1.0

    再通过./snmpset -c setExample -v 2c localhost 1.3.6.1.4.1.77587.1.0 s "hello world"设置以后,有如下提示,说明设置成功了。

    SNMPv2-SMI::enterprises.77587.1.0= STRING: "hello world"

    大大

C++代码示例

  1. main
    #include <net-snmp/net-snmp-config.h>
    
    #if HAVE_STDLIB_H
    #include <stdlib.h>
    #endif
    #if HAVE_UNISTD_H
    #include <unistd.h>
    #endif
    #if HAVE_STRING_H
    #include <string.h>
    #else
    #include <strings.h>
    #endif
    #include <sys/types.h>
    #if HAVE_NETINET_IN_H
    #include <netinet/in.h>
    #endif
    #include <stdio.h>
    #include <ctype.h>
    #if TIME_WITH_SYS_TIME
    # ifdef WIN32
    #  include <sys/timeb.h>
    # else
    #  include <sys/time.h>
    # endif
    # include <time.h>
    #else
    # if HAVE_SYS_TIME_H
    #  include <sys/time.h>
    # else
    #  include <time.h>
    # endif
    #endif
    #if HAVE_SYS_SELECT_H
    #include <sys/select.h>
    #endif
    #if HAVE_WINSOCK_H
    #include <winsock.h>
    #endif
    #if HAVE_NETDB_H
    #include <netdb.h>
    #endif
    #if HAVE_ARPA_INET_H
    #include <arpa/inet.h>
    #endif
    
    #include <net-snmp/utilities.h>
    
    #include <net-snmp/net-snmp-includes.h>
    #include <vector>
    #include <map>
    #include <iostream>
    
    //得到指定oid的被管理对象的值
    void Get(const char *ip_v2,char *community_v2,const char *oidstr_v2)
    {
        netsnmp_session session, *ss;
        netsnmp_pdu *pdu;
        netsnmp_pdu *response;
    
        oid anOID[MAX_OID_LEN];
        size_t anOID_len;
    
        netsnmp_variable_list *vars;
        int status;
        int count=1;
    
        init_snmp("snmpget");
        snmp_sess_init( &session );
        session.version = SNMP_VERSION_2c;
        session.peername = strdup(ip_v2);
        session.community = (unsigned char*)community_v2;
        session.community_len = strlen(community_v2);
        session.retries = 3;
        session.timeout = 100;
        session.remote_port = 161;
        SOCK_STARTUP;
    
        ss = snmp_open(&session);
        if (!ss)
        {
            snmp_sess_perror("ack", &session);
            SOCK_CLEANUP;
            exit(1);
        }
    
    
        pdu = snmp_pdu_create(SNMP_MSG_GET);
        anOID_len = MAX_OID_LEN;
        if (!snmp_parse_oid(oidstr_v2, anOID, &anOID_len))
        {
            snmp_perror(oidstr_v2);
            SOCK_CLEANUP;
            exit(1);
        }
    
        snmp_add_null_var(pdu, anOID, anOID_len);
    
        /*
         * Send the Request out.
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)
        {
            //for(vars = response->variables; vars; vars = vars->next_variable)
            //print_variable(vars->name, vars->name_length, vars);
            for(vars = response->variables; vars; vars = vars->next_variable)
            {
                if (vars->type == ASN_OCTET_STR)
                {
                    char *sp = (char *)malloc(1 + vars->val_len);
                    memcpy(sp, vars->val.string, vars->val_len);
                    sp[vars->val_len] = '\0';
                    printf("value #%d is a string: %s\n", count++, sp);
                    free(sp);
                }else
                    printf("value #%d is NOT a string! Ack!\n", count++);
            }
        } else {
            /*
             * FAILURE: print what went wrong!
             */
            if (status == STAT_SUCCESS)
                fprintf(stderr, "Error in packet\nReason: %s\n",snmp_errstring(response->errstat));
            else if (status == STAT_TIMEOUT)
                fprintf(stderr, "Timeout: No response from %s.\n",session.peername);
            else
                snmp_sess_perror("snmpget", ss);
        }
    
        if (response)
            snmp_free_pdu(response);
        snmp_close(ss);
        SOCK_CLEANUP;
    
    }
    //得到指定oid的下一个被管理对象的值
    void GetNext(const char *ip_v2,char *community_v2,const char *oidstr_v2)
    {
        netsnmp_session session, *ss;
        netsnmp_pdu *pdu;
        netsnmp_pdu *response;
    
        oid anOID[MAX_OID_LEN];
        size_t anOID_len;
    
        netsnmp_variable_list *vars;
        int status;
        int count=1;
        char value[100];
    
        init_snmp("snmpgetnext");
        snmp_sess_init( &session );
        session.version = SNMP_VERSION_2c;
        session.peername = strdup(ip_v2);
        session.community = (unsigned char*)community_v2;
        session.community_len = strlen(community_v2);
        session.retries = 3;
        session.timeout = 100;
        session.remote_port = 161;
        SOCK_STARTUP;
    
    
        ss = snmp_open(&session);
        if (ss == NULL)
        {
            snmp_sess_perror("snmpgetnext", &session);
            SOCK_CLEANUP;
            exit(1);
        }
    
    
        pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
        anOID_len = MAX_OID_LEN;
        if (!snmp_parse_oid(oidstr_v2, anOID, &anOID_len))
        {
            snmp_perror(oidstr_v2);
            SOCK_CLEANUP;
            exit(1);
        }
    
        snmp_add_null_var(pdu, anOID, anOID_len);
    
        /*
         * Send the Request out.
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)
        {
            for(vars = response->variables; vars; vars = vars->next_variable)
            {
                unsigned char  *buf = NULL;
                size_t buf_len = 256, out_len = 0;
                FILE * f = stdout;
                if ((buf = (unsigned char *)calloc(buf_len,1)) == NULL)
                {
                    fprintf(f, "[TRUNCATED]\n");
                    return;
                }
                else
                {
                    if (sprint_realloc_variable(&buf, &buf_len, &out_len, 1,vars->name, vars->name_length, vars))
                    {
                        //fprintf(f, "%s\n", buf);
                        printf("caixiaofei: %s\n",buf);
                    }
                    else
                    {
                        fprintf(f, "%s [TRUNCATED]\n", buf);
                    }
                }
                SNMP_FREE(buf);
            }
        } else {
            if (status == STAT_SUCCESS)
                fprintf(stderr, "Error in packet\nReason: %s\n",snmp_errstring(response->errstat));
            else if (status == STAT_TIMEOUT)
                fprintf(stderr, "Timeout: No response from %s.\n",session.peername);
            else
                snmp_sess_perror("snmpget", ss);
        }
    
        if (response)
            snmp_free_pdu(response);
        snmp_close(ss);
        SOCK_CLEANUP;
    }
    //给指定oid的被管理对象设定值
    void Set(const char *ip_v2,char *community_v2,const char *oidstr_v2,char types,char *values)
    {
        netsnmp_session session, *ss;
        netsnmp_pdu *pdu;
        netsnmp_pdu *response;
    
        oid anOID[MAX_OID_LEN];
        size_t anOID_len;
    
        netsnmp_variable_list *vars;
        int status;
        int count=1;
        char value[100];
    
        init_snmp("snmpgetnext");
        snmp_sess_init( &session );
        session.version = SNMP_VERSION_2c;
        session.peername = strdup(ip_v2);
        session.community = (unsigned char*)community_v2;
        session.community_len = strlen(community_v2);
        session.retries = 3;
        session.timeout = 100;
        session.remote_port = 161;
        SOCK_STARTUP;
    
    
        ss = snmp_open(&session);
        if (ss == NULL)
        {
            snmp_sess_perror("snmpgetnext", &session);
            SOCK_CLEANUP;
            exit(1);
        }
    
    
        pdu = snmp_pdu_create(SNMP_MSG_SET);
        anOID_len = MAX_OID_LEN;
        if (!snmp_parse_oid(oidstr_v2, anOID, &anOID_len))
        {
            snmp_perror(oidstr_v2);
            SOCK_CLEANUP;
            exit(1);
        }
    
        snmp_add_var(pdu, anOID, anOID_len,types, values);
    
        /*
         * Send the Request out.
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)
        {
            for(vars = response->variables; vars; vars = vars->next_variable)
            {
                unsigned char  *buf = NULL;
                size_t buf_len = 256, out_len = 0;
                FILE * f = stdout;
                if ((buf = (unsigned char *)calloc(buf_len,1)) == NULL)
                {
                    fprintf(f, "[TRUNCATED]\n");
                    return;
                }
                else
                {
                    if (sprint_realloc_variable(&buf, &buf_len, &out_len, 1,vars->name, vars->name_length, vars))
                    {
                        //fprintf(f, "%s\n", buf);
                        printf("caixiaofei: %s\n",buf);
                    }
                    else
                    {
                        fprintf(f, "%s [TRUNCATED]\n", buf);
                    }
                }
                SNMP_FREE(buf);
            }
        } else {
            if (status == STAT_SUCCESS)
                fprintf(stderr, "Error in packet\nReason: %s\n",snmp_errstring(response->errstat));
            else if (status == STAT_TIMEOUT)
                fprintf(stderr, "Timeout: No response from %s.\n",session.peername);
            else
                snmp_sess_perror("snmpget", ss);
        }
    
        if (response)
            snmp_free_pdu(response);
        snmp_close(ss);
    
        SOCK_CLEANUP;
    }
    int main(int argc, char ** argv)
    {
        Get("127.0.0.1","public","1.3.6.1.4.1.77587.1.0");
        Set("127.0.0.1","whoareyou","1.3.6.1.4.1.77587.1.0",'s',"cxf");
        return (0);
    }

     

net-snmp设置开机启动

        1.#vi /usr/local/snmp/share/snmp/snmpd.conf //编辑snmpd.conf

把里面的mynetwork/24 改成需要查看snmp信息的主机ip地址或是网段,把community 改成public

        2.# vi /etc/rc.local \\设置netsnmp自启动,即在末尾加上

/usr/local/snmp/sbin/snmpd -c /etc/snmp/snmpd.conf &

        3.#vi /etc/profile \\设置环境变量即在umask 022命令前加上

export  PATH=/usr/local/bin:/usr/local/sbin:$PATH

        4.将/usr/local/snmp/bin/目录下的文件拷贝到/usr/bin

        cp /usr/local/snmp/bin/*  /usr/bin

        5.修改脚本文件

        sudo gedit /etc/rc.local

        在里边添加命令

        sudo /usr/local/net-snmp/sbin/snmpd -f -Lo -C -c /usr/local/net-snmp/share/snmp/snmpd.conf

        6.给rc.local执行的权限

        sudo chmod +x /etc/rc.local

参考文章

  1. https://blog.csdn.net/JIANGXIN04211/article/details/78475155
  2. https://blog.csdn.net/JIANGXIN04211/article/details/78477890
  3. https://www.cnblogs.com/oloroso/p/4595123.html
  4. https://www.cnblogs.com/oloroso/p/4814467.html
  5. https://blog.csdn.net/lyyybz/article/details/82284270
  6. http://www.52rd.com/Blog/Detail_RD.Blog_cxf17_16839.html

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值