一、编译安装

1、下载net-snmp-5.7.3.tar.gz压缩包并上传至linux

2、tar -xzvf net-snmp-5.7.3.tar.gz 解压

3、进入net-snmp-5.7.3目录,运行./configure进行配置安装环境

--prefix=/usr/local/snmp 设置安装位置为/usr/local/snmp/

--with-mib-modules=myModule 载入自定义的mib库

4、make 命令(make需要安装perl库环境)

5、make install 命令

#检测安装是否成功
[root@zbx-agent01 net-snmp-5.7.3]# cd /usr/local/snmp/sbin
[root@zbx-agent01 sbin]# ls
snmpd  snmptrapd
[root@zbx-agent01 sbin]# ./snmpd -v

NET-SNMP version:  5.7.3
Web:               http://www.net-snmp.org/
Email:             net-snmp-coders@lists.sourceforge.net

6、将net-snmp目录下的EXAMPLE.conf复制到/usr/local/snmp/share/snmp/下,并改名为snmpd.conf

#修snmpd.conf文件
#          sec.name       source      community
  com2sec notConfigUser  default       public
  
#       groupName       securityModel    securityName
group   notConfigGroup      v1           notConfigUser  
group   notConfigGroup      v2c          notConfigUser

#       name     incl/excl     subtree         mask(optional)
  view  all      included        .1
  
#          group        context sec.model sec.level prefix read   write  notif
 access  notConfigGroup ""      any       noauth    exact  all  none none

7、启动snmpd服务

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

8、测试

cd /usr/local/snmp/bin
./snmpget -v 1 -c public localhost sysUpTime.0 
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (188447) 0:31:24.47

二、YUM安装

1、安装

yum install -y net-snmp net-snmp-utils net-snmp-perl

2、配置,具体参考编译方式的配置文件

3、启动并验证snmp

systemctl start snmpd
systemctl enable snmpd

三、加载自定义MIB库

1、使用MIB builder生成MIB文件TEST-MIB.my

--
-- TEST-MIB2.txt
-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0  Build 88
-- Tuesday, April 14, 2020 at 16:21:12
--

        TEST-MIB2 DEFINITIONS ::= BEGIN
 
                IMPORTS
                        OBJECT-GROUP
                                FROM SNMPv2-CONF
                        enterprises, Integer32, OBJECT-TYPE, MODULE-IDENTITY
                                FROM SNMPv2-SMI;


                -- 1.3.6.1.4.1.1
                monitorSystem 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
                cabinet1 OBJECT IDENTIFIER ::= { monitorSystem 1 }


                -- 1.3.6.1.4.1.1.1.1
                mainVoltage OBJECT-TYPE
                        SYNTAX Integer32
                        MAX-ACCESS read-write
                        STATUS current
                        DESCRIPTION
                                "mainVoltage"
                        ::= { cabinet1 1 }

                subVoltage OBJECT-TYPE
                        SYNTAX Integer32
                        MAX-ACCESS read-write
                        STATUS current
                        DESCRIPTION
                                "subVoltage"
                        ::= { cabinet1 2 }

        END

--
-- TEST-MIB2.txt
--

2、将生成的文件放到/usr/local/snmp/share/snmp/mibs/目录下,使用/usr/local/snmp/bin/snmptranslate -Tp -IR TEST-MIB2::monitorSystem 查看MIB文件是否正常,并显示节点树

3、执行命令

env MIBS="+/usr/local/snmp/share/snmp/mibs/TES-MIB.my" /usr/local/snmp/bin/mib2c -c mib2c.scalar.conf TEST-MIB2::monitorSystem

在/usr/local/snmp/bin/mib2c下生成monitorSystem.c和monitorSystem.h

4、将monitorSystem.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 "monitorSystem.h"

/** Initializes the monitorSystem module */
void
init_monitorSystem(void)
{
    const oid mainVoltage_oid[] = { 1,3,6,1,4,1,1,1,1 };
    const oid subVoltage_oid[] = { 1,3,6,1,4,1,1,1,2 };

    DEBUGMSGTL(("monitorSystem", "Initializing\n"));

    netsnmp_register_scalar(
        netsnmp_create_handler_registration("mainVoltage", handle_mainVoltage,
                               mainVoltage_oid, OID_LENGTH(mainVoltage_oid),
                               HANDLER_CAN_RWRITE
        ));
    netsnmp_register_scalar(
        netsnmp_create_handler_registration("subVoltage", handle_subVoltage,
                               subVoltage_oid, OID_LENGTH(subVoltage_oid),
                               HANDLER_CAN_RWRITE
        ));
}

int
handle_mainVoltage(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. */
    static int mainVoltageValue;

    switch(reqinfo->mode) {

        case MODE_GET:
            snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
                                     &mainVoltageValue/* 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/* 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 (0/* XXX: error? */) {
                netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_BADVALUE/* some error */);
            }
            break;

        case MODE_SET_COMMIT:
            /* XXX: delete temporary storage */
            mainVoltageValue = *requests->requestvb->val.integer;

            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_mainVoltage\n", reqinfo->mode );
            return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}
int
handle_subVoltage(netsnmp_mib_handler *handler,
                          netsnmp_handler_registration *reginfo,
                          netsnmp_agent_request_info   *reqinfo,
                          netsnmp_request_info         *requests)
{
    int ret;

    static int subVoltageValue;
    /* 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,
                                     &subVoltageValue/* 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/* 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 (0/* XXX: error? */) {
                netsnmp_set_request_error(reqinfo, requests,SNMP_ERR_BADVALUE /* some error */);
            }
            break;

        case MODE_SET_COMMIT:
            /* XXX: delete temporary storage */
            subVoltageValue =*requests->requestvb->val.integer;

            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_subVoltage\n", reqinfo->mode );
            return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}

5、将monitorSystem.c和monitorSystem.h文件放至/root/net-snmp-5.7.3/agent/mibgroup/目录下

6、将net-snmp-5.7.3重新编译

./configure --prefix=/usr/local/snmp --with-mib-modules=monitorSystem
make
make intall

7、重新编译前需将snmpd服务停止

8、使用snmpget获取值、使用snmpset设置值

#获取值
/usr/local/snmp/bin/snmpget -c public -v2c localhost 1.3.6.1.4.1.1.1.1.0
#设置为200
/usr/local/snmp/bin/snmpset -c private -v2c localhost 1.3.6.1.4.1.1.1.2.0 i 200
最后修改:2022 年 09 月 19 日
如果觉得我的文章对你有用,请随意赞赏