net-snmp开发代理入门

编程技术到不存在问题,可是要快熟编写net-snmp代理到还是遇到了不少小问题,网上资料也比较少,通过官网和《深入理解Net-SNMP》一书,基本搞定了net-snmp开发代理的过程,其他的都是编程的工作了。

本文的目的也是希望可以快速通过net-snmp实现代理的开发,本文基本概念就省了,直接开始如何开始开发一个自定义代理。

开发一个代理:

(1)需要编写自己的MIB库

建议使用Mib Editor(中国人写的,强),MG-SOFT的MIB工具在我的Windows10上出现崩溃和不能打开保存的文件。Mib Editor需要安装JDK1.6,请到Oracle官网找历史版本。

Mib Editor估计是采用Eclipse的框架写的,先建立一个项目,然后新建一个Mib文件(新建时“类别”选择MIB,不要选择子节点,就在“文件类型”中看到“空MIB文件”)

(2)编译net-snmp源码

在开发阶段,建议使用动态库的方式开发,如果后期觉得效率有问题,或者在嵌入式系系统中运行时,才考虑使用静态编译的方式(静态编译很耗时间,动态库一样可以用GDB调试)。

编译net-snmp源码的方式的简单方式如下:

./configure

make

make install

当然,./configure有一堆的参数,入门时先不需要关心,缺省就可以用了。

编译后,还需要生产一个配置文件,这个在《深入理解Net-SNMP》一书中有详细的步骤。本文后面会贴上我生成的配置文件,保配置文件保存到/usr/local/share/snmp/snmpd.conf。

(3)使用mib2c工具生成测试代码

这里,我们对于标量(普通的量)采用mib2c.scalar.conf, 对于表格采用mib2c.iterator_access.conf。

对于标量生成的C代码很简单,对于只读标量,只需要实现GET方法即可。

比如:mib2c -c mib2c.scalar.conf WILLSERVICE-ROADLAMP-GATEWAY-MIB::lampController

int
handle_controllerCount(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. */
    lampctrl_t* plampctrl = lampctrl_get_object();
    switch(reqinfo->mode) {

        case MODE_GET:
            snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER,
                                    &plampctrl->count, sizeof(plampctrl->count));
            break;


        default:
            /* we should never get here, so this is a really bad error */
            snmp_log(LOG_ERR, "unknown mode (%d) in handle_controllerCount\n", reqinfo->mode );
            return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}
主要在于snmp_set_var_typed_value函数的实现,后面两个参数就是返回变量的指针和变量数据的长度。该示例为返回控制器数量。MIB配置如下:

controllerCount OBJECT-TYPE
    SYNTAX      Counter32
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
            "Communication node count."
    ::= { lampController 1 }

(4)编译mib2c生成的代码

该过程说起来简单,尤其是静态编译而言,可是对动态编译而言,就需要自己去摸索了。

静态编译的方法:

重新使用configure,并指定需要编译的代理模块:

编译静态模块官网的例子是:

./configure --with-mib-modules="nstAgentModuleObject"

编译动态模块的官网例子是:

$ cc `net-snmp-config --cflags` -fPIC -shared -g -O0 -o nstAgentPluginObject.so nstAgentPluginObject.c `net-snmp-config --libs`
对于简单的标量开发而言,以上方法没有问题,对于表格的情况,mib2c生成了多个文件,需要写自己的Makefile来编译。


简单的Makefile如下:

#!/bin/sh

LIB=$(patsubst %.c,%.o,$(wildcard *.c))
DLL=lampController.so

CFLAGS+= -fno-strict-aliasing -g -O2 -Ulinux -Dlinux=linux -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/lib64/perl5/CORE -I. -I/usr/local/include
DLLLDFLAGS=`net-snmp-config --libs`

all:$(DLL)

$(DLL):%.so:$(LIB)
        gcc $(DLLLDFLAGS) -shared -rdynamic -g  $^ -o $@

$(LIB):%.o:%.c
        gcc -c $(CFLAGS) -g -dH -fPIC -Wall $^ -o $@

clean:
        rm -rf *.o

注意:net-snmp-config–cflags生产编译标志,最好不直接使用,而是把生成后的内容写到Makefile文件中,其中有一个-pipe选项导致文件没有编译通过,也会生产目标文件,这样就会出现有错误,也可能把程序编译了,从而出现问题。

以上Makefile可以把目录下的文件都编译生成一个动态库,需要修改DLL的宏定义。

假如我们通过mib2c生成代码后

注意:net-snmp框架是通过模块名来加载动态库的函数的,比如:

dlmod lampController /home/oracle/yhb/soloarlamp/bin/liblampcontroller.so

net-snmp会在该动态库中查找init_lampController函数,来注册OID。

dlmod 需要添加到snmp的配置文件中,缺省位置:/usr/local/share/snmp/snmpd.conf

(5)运行和测试

启动snmp进程,通过-D可以打开调试:

snmpd -f -Lo -Ddlmod,lampController

此时既可以通过snmpwalk取得对应的数据了:

比如:

snmpget -v2c -c public localhost WILLSERVICE-ROADLAMP-GATEWAY-MIB::controllerCount.0

就可以返回:

WILLSERVICE-ROADLAMP-GATEWAY-MIB::controllerCount.0 = Counter32: 2

注意后面的0,最好使用snmpwalk命令来获取数据:

[oracle@jkj mibs]$ snmpwalk -v2c -c public localhost WILLSERVICE-ROADLAMP-GATEWAY-MIB::lampController
WILLSERVICE-ROADLAMP-GATEWAY-MIB::controllerCount.0 = Counter32: 2
WILLSERVICE-ROADLAMP-GATEWAY-MIB::controllerId."A00001" = STRING: "A00001"
WILLSERVICE-ROADLAMP-GATEWAY-MIB::controllerId."A00002" = STRING: "A00002"
WILLSERVICE-ROADLAMP-GATEWAY-MIB::controllerUpTime."A00001" = Timeticks: (1450859937) 167 days, 22:09:59.37
WILLSERVICE-ROADLAMP-GATEWAY-MIB::controllerUpTime."A00002" = Timeticks: (1450859943) 167 days, 22:09:59.43

(对于net-snmp的使用,请参见我的另外一篇文章)

(本来打算弄一个教学视频的,等有时间的时候弄一个,有问题的,请回帖,我会回答问题的)


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值