欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > snmp/mib采用子代理模式,编码,部署

snmp/mib采用子代理模式,编码,部署

2025/3/25 14:29:47 来源:https://blog.csdn.net/m0_37570820/article/details/146421277  浏览:    关键词:snmp/mib采用子代理模式,编码,部署

0.环境
0.1 编译net-snmp
     cd net-snmp-5.7.2
     ./configure --prefix=/usr/local/snmp

        BEGIN failed--compilation aborted at Makefile.PL line 1.

        make: *** [perlmakefiles] Error 2      
        
    yum install cpan -y
    make && make install
    /usr/local/snmp/sbin/snmpd  启动
    
0.2 直接安装(本文采用直接安装的方式)
    yum install -y net-snmp, net-snmp-devel,net-snmp-perl,net-snmp-utils

    vim /etc/snmp/snmpd.conf    
        master agentx  
        rocommunity public  
        rwcommunity public
    service snmpd restart
    
    service snmpd restart

    
1.验证
1.1 snmpd服务
    vim /etc/snmp/snmpd.conf    
        master agentx  
        rocommunity public  
        rwcommunity public
    service snmpd restart   
    
1.2 启动编写的子代理程序:
  ./snmp_agent_mib &
  提示NET-SNMP version 5.9.3 AgentX subagent connected
  
1.3 mib查询  
  1.3.1  验证方式1:
  
      验证mib文件是否有错(LINUO-ATCA-BOARD-STATUS-MIB.txt):
       snmptranslate -Tp -IR LINUO-ATCA-BOARD-STATUS-MIB::atcaModule  //解析出来说明mib文件没有语法错误之类的
        
        snmpget -v2c -c public localhost 1.3.6.1.4.1.12001.5.1.0
                  SNMPv2-SMI::enterprises.12001.5.1.0 = Gauge32: 2
        
        snmpget -v2c -c public localhost 1.3.6.1.4.1.12001.5.5.1.0
                  SNMPv2-SMI::enterprises.12001.5.5.1.0 = Gauge32: 3
 
  1.3.2 验证方式2:
       安装mib-browse 加载LINUO-ATCA-BOARD-STATUS-MIB.txt后进行查询
2.mib文件

-- LINUO-ATCA-BOARD-STATUS-MIB.my
LINUO-ATCA-BOARD-STATUS-MIB DEFINITIONS ::= BEGIN

    IMPORTS
        OBJECT-GROUP, MODULE-COMPLIANCE, NOTIFICATION-GROUP
            FROM SNMPv2-CONF
        enterprises, OBJECT-TYPE, MODULE-IDENTITY, Unsigned32
            FROM SNMPv2-SMI
        DisplayString
            FROM SNMPv2-TC;

-- Module Identity
-- OID: 1.3.6.1.4.1.12001
    atcaModule MODULE-IDENTITY
        LAST-UPDATED "202310010000Z"  -- Update with actual timestamp
        ORGANIZATION
            "LINUO Corporation"
        CONTACT-INFO
            "Postal: LINUO Corp\nEmail: support@linuo.com"
        DESCRIPTION
            "MIB for ATCA Board Status Monitoring."
        ::= { enterprises 12001 }  -- 1.3.6.1.4.1.12001

-- Top-level OID structure
    linuoAtca OBJECT IDENTIFIER ::= { atcaModule 5 }  -- 1.3.6.1.4.1.12001.5

-- Node 1: atcaCollectionStatus (Unsigned32)
-- OID: 1.3.6.1.4.1.12001.5.1
    atcaCollectionStatus OBJECT-TYPE
        SYNTAX      Unsigned32
        MAX-ACCESS  read-only
        STATUS      current
        DESCRIPTION
            "Status of ATCA board collection."
        ::= { linuoAtca 1 }

-- Subtree for chassis info
    atcaChassis OBJECT IDENTIFIER ::= { linuoAtca 5 }  -- 1.3.6.1.4.1.12001.5.5

-- Node 2: atcaBoardInfoIndex (Unsigned32)
-- OID: 1.3.6.1.4.1.12001.5.5.1
    atcaBoardInfoIndex OBJECT-TYPE
        SYNTAX      Unsigned32
        MAX-ACCESS  read-only
        STATUS      current
        DESCRIPTION
            "Index identifier for ATCA board chassis information."
        ::= { atcaChassis 1 }

END

3.代码(为了方便贴上来集中在一个文件中)

/* add by zhuwei 2025/3/18
 *
 * 安装依赖库(如 Net-SNMP):yum install net-snmp net-snmp-utils
 *                            yum install net-snmp-devel  //相关头文件
 * 编译:gcc -o snmp_agent snmp_agent.c -lnetsnmpagent -lnetsnmphelpers -lnetsnmpmibs -lnetsnmp   //相关库在/usr/lib64
 * 配置文件(/etc/snmp/snmpd.conf):

 * 启动 Agent:./snmp_agent_mib
 * 客户端测试:snmpget -v2c -c public localhost 1.3.6.1.4.1.12001.5.1.0
 * 查看调试日志:net-snmp-config --log-file   
 *               tail -f /var/log/snmpd.log
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <net-snmp/net-snmp-config.h>  // 必须首先包含
#include <net-snmp/types.h>            // 定义 oid、netsnmp_container 等
#include <net-snmp/library/tools.h>    // 提供基础工具函数
#include <net-snmp/library/container.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/net-snmp-includes.h>

extern int netsnmp_running;

const char *app_name = "snmp_agent_mib";
static int reconfig = 0;


// 定义 atcaCollectionStatus 的 OID
 const oid atcaCollectionStatus_oid[] = { 1, 3, 6, 1, 4, 1, 12001, 5, 1 };

// 定义 atcaBoardInfoIndex 的 OID
const oid atcaBoardInfoIndex_oid[] = { 1, 3, 6, 1, 4, 1, 12001, 5, 5, 1 };

#ifdef __GNUC__
    #define UNUSED __attribute__((unused))
#else
    #define UNUSED
#endif


RETSIGTYPE stop_server(UNUSED int a) 
{
    puts("捕捉到信号 SIGTERM/SIGINT");
    netsnmp_running = 0;
}

#ifdef SIGHUP
RETSIGTYPE hup_handler(int sig)
{
    puts("捕捉到信号 SIGHUP");
    reconfig = 1;
    signal(SIGHUP, hup_handler);
}
#endif


void reg_sig()
{
#ifdef SIGTERM
    signal(SIGTERM, stop_server);
#endif
#ifdef SIGINT
    signal(SIGINT, stop_server);
#endif
#ifdef SIGHUP
    signal(SIGHUP, hup_handler);
#endif
}

int handle_atcaCollectionStatus(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
);
int handle_atcaBoardInfoIndex(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
);


void register_oids() 
{
    netsnmp_handler_registration *reg;

    // 注册 atcaCollectionStatus
    reg = netsnmp_create_handler_registration(
        "atcaCollectionStatus",
        handle_atcaCollectionStatus, // 回调函数
        atcaCollectionStatus_oid,
        OID_LENGTH(atcaCollectionStatus_oid),
        HANDLER_CAN_RONLY
    );
    
    if(MIB_REGISTERED_OK != netsnmp_register_scalar(reg))
    {
        printf("atcaCollectionStatus register fail \n");
    }

    // 注册 atcaBoardInfoIndex(类似逻辑)
    reg = netsnmp_create_handler_registration(
        "atcaBoardInfoIndex",
        handle_atcaBoardInfoIndex, // 回调函数
        atcaBoardInfoIndex_oid,
        OID_LENGTH(atcaBoardInfoIndex_oid),
        HANDLER_CAN_RONLY
    );

    if(MIB_REGISTERED_OK != netsnmp_register_scalar(reg))
    {
        printf("atcaBoardInfoIndex register fail \n");
    }
}


unsigned int read_hardware_status() {
    // 通过 ioctl 或内存映射读取硬件寄存器
   // int fd = open("/dev/atca_device", O_RDONLY);
    unsigned int status = 2;
    //ioctl(fd, ATCA_GET_STATUS, &status);
   // close(fd);
    return status;
}

int handle_atcaCollectionStatus(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
) {
    unsigned int status = 0;
    switch (reqinfo->mode) {
        case MODE_GET:
            // 从设备读取数据(示例值)
            status = read_hardware_status(); // 自定义数据采集函数
            snmp_set_var_typed_value(
                requests->requestvb,
                ASN_UNSIGNED, // 数据类型与 MIB 一致
                &status,
                sizeof(status)
            );
            break;
        default:
            // 不支持的操作(如 SET)
            return SNMP_ERR_GENERR;
    }
    return SNMP_ERR_NOERROR;
}


unsigned int read_hardware_index() {
    // 通过 ioctl 或内存映射读取硬件寄存器
    //int fd = open("/dev/atca_device", O_RDONLY);
    unsigned int status = 3;
    //ioctl(fd, ATCA_GET_STATUS, &status);
    //close(fd);
    return status;
}


int handle_atcaBoardInfoIndex(
    netsnmp_mib_handler *handler,
    netsnmp_handler_registration *reginfo,
    netsnmp_agent_request_info *reqinfo,
    netsnmp_request_info *requests
) {
    unsigned int status = 0;
    switch (reqinfo->mode) {
        case MODE_GET:
            // 从设备读取数据(示例值)
            status = read_hardware_index(); // 自定义数据采集函数
            snmp_set_var_typed_value(
                requests->requestvb,
                ASN_UNSIGNED, // 数据类型与 MIB 一致
                &status,
                sizeof(status)
            );
            break;
        default:
            // 不支持的操作(如 SET)
            return SNMP_ERR_GENERR;
    }
    return SNMP_ERR_NOERROR;
}

static void usage(const char *prog)
{
    fprintf(stderr,
            "USAGE: %s [OPTIONS]\n"
            "\n"
            "OPTIONS:\n", prog);

    fprintf(stderr,
            "  -d\t\t\tdump all traffic\n"
            "  -D TOKEN[,...]\tturn on debugging output for the specified "
            "TOKENs\n"
            "\t\t\t   (ALL gives extremely verbose debugging output)\n"
            "  -f\t\t\tDo not fork() from the calling shell.\n"
            "  -h\t\t\tdisplay this help message\n"
            "  -H\t\t\tdisplay a list of configuration file directives\n"
            "  -L LOGOPTS\t\tToggle various defaults controlling logging:\n");
    snmp_log_options_usage("\t\t\t  ", stderr);
#ifndef DISABLE_MIB_LOADING
    fprintf(stderr,
            "  -m MIB[:...]\t\tload given list of MIBs (ALL loads "
            "everything)\n"
            "  -M DIR[:...]\t\tlook in given list of directories for MIBs\n");
#endif /* DISABLE_MIB_LOADING */
#ifndef DISABLE_MIB_LOADING
    fprintf(stderr,
            "  -P MIBOPTS\t\tToggle various defaults controlling mib "
            "parsing:\n");
    snmp_mib_toggle_options_usage("\t\t\t  ", stderr);
#endif /* DISABLE_MIB_LOADING */
    fprintf(stderr,
            "  -v\t\t\tdisplay package version number\n"
            "  -x TRANSPORT\tconnect to master agent using TRANSPORT\n");
    exit(1);
}

static void version(void)
{
    fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
    exit(0);
}


int main (int argc, char **argv)
{
    int arg;
    char* cp = NULL;
    int dont_fork = 0, do_help = 0;

    while ((arg = getopt(argc, argv, "dD:fhHL:"
    #ifndef DISABLE_MIB_LOADING
                       "m:M:"
    #endif /* DISABLE_MIB_LOADING */
                       "n:"
    #ifndef DISABLE_MIB_LOADING
                       "P:"
    #endif /* DISABLE_MIB_LOADING */
                       "vx:")) != EOF) 
    {
        switch (arg) {
        case 'd':
          
          //netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_LOG_FILE, "/var/log/snmpd.log");
          //netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_DEBUG_LEVEL, 3);
          netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,NETSNMP_DS_LIB_DUMP_PACKET, 1);
          
          break;

        case 'D':
          debug_register_tokens(optarg);
          snmp_set_do_debugging(1);
          break;

        case 'f':
          dont_fork = 1;
          break;

        case 'h':
          usage(argv[0]);
          break;

        case 'H':
          do_help = 1;
          break;

        case 'L':
          if (snmp_log_options(optarg, argc, argv) < 0) {
            exit(1);
          }
          break;

    #ifndef DISABLE_MIB_LOADING
        case 'm':
          if (optarg != NULL) {
            setenv("MIBS", optarg, 1);
          } else {
            usage(argv[0]);
          }
          break;

        case 'M':
          if (optarg != NULL) {
            setenv("MIBDIRS", optarg, 1);
          } else {
            usage(argv[0]);
          }
          break;
    #endif /* DISABLE_MIB_LOADING */

        case 'n':
          if (optarg != NULL) {
            app_name = optarg;
            netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                                  NETSNMP_DS_LIB_APPTYPE, app_name);
          } else {
            usage(argv[0]);
          }
          break;

    #ifndef DISABLE_MIB_LOADING
        case 'P':
          cp = snmp_mib_toggle_options(optarg);
          if (cp != NULL) {
            fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
            usage(argv[0]);
          }
          break;
    #endif /* DISABLE_MIB_LOADING */

        case 'v':
          version();
          break;

        case 'x':
          if (optarg != NULL) {
            netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                                  NETSNMP_DS_AGENT_X_SOCKET, optarg);
          } else {
            usage(argv[0]);
          }
          break;

        default:
          fprintf(stderr, "invalid option: -%c\n", arg);
          usage(argv[0]);
          break;
        }
    }
    if (do_help) 
    {
      netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
                           NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1);
    }
    else
    {    
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,NETSNMP_DS_AGENT_ROLE, 1);

#if 0
        if (!dont_fork) 
        {
            if (netsnmp_daemonize(1, snmp_stderrlog_status()) != 0)
                exit(1);
        }            
#endif         
        SOCK_STARTUP;
    }
    
    init_agent(app_name);
    
    register_oids();
    
    //load app_name.conf
    init_snmp(app_name);
    
    
    if (do_help) 
    {
        fprintf(stderr, "Configuration directives understood:\n");
        read_config_print_usage("  ");
        exit(0);
    }    
    
    netsnmp_running = 1;
    reg_sig();    
    
    while(netsnmp_running) 
    {
        if (reconfig) 
        {
            free_config();
            read_configs();
            reconfig = 0;
        }
        agent_check_and_process(1);
    }    

    snmp_shutdown(app_name);
    
    shutdown_agent();
    
    SOCK_CLEANUP;
    
    exit(0);
    
}


4.Makefile

# Makefile for SNMP Agent (snmp_agent_mib)

# Compiler and flags
CC = gcc
CFLAGS = -g -Wall -I/usr/include/net-snmp
LDFLAGS += -L/usr/local/lib -Wl,-rpath=/usr/local/lib
LDFLAGS += -lnetsnmpagent -lnetsnmphelpers -lnetsnmpmibs -lnetsnmp

# Targets
TARGET = snmp_agent_mib
SRC = snmp_agent_mib.c

all: $(TARGET)

$(TARGET): $(SRC)
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

clean:
    rm -f $(TARGET)

.PHONY: all clean

5.代码直接拷贝编译运行即能使用

   需要set的tx可以自行添加.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词