简单网络管理协议SNMP在嵌入式设备中的子代理实现

6 篇文章 0 订阅

简单网络管理协议SNMP在嵌入式设备中的子代理实现

摘要:简单网络管理协议(SNMP:Simple Network Management Protocol)IETF定义的一套网络管理协议。利用SNMP,一个管理工作站可以远程管理所有支持这种协议的网络设备,包括监视网络状态、修改网络设备配置、接收网络事件警告等。当前物联网设备增长迅速,物联网设备总数已达到百亿数量级,由此网络设备的管理尤为重要。除了常规意义上的路由器、交换机和服务器等网络设备,还包括各行各业的嵌入式设备,这些设备也可以实现SNMP协议的支持,方便统一管理,本文主要以所在行业的嵌入式设备(后面简称设备)进行概述,以项目为背景,介绍了SNMP在设备中的子代理实现。

关键词:简单网络管理协议;管理工作站;嵌入式设备;子代理

 

案例背景

目前大多厂商设备没有统一的协议,各家都是自己的私有协议,涉及到多家厂商的设备和后端平台对接都需要进行协议对接,如果改变控制协议,开发难度大,且时间周期长,因此提出了一种迂回的解决方案,各家控制协议不变,只要提供SNMP协议支持即可。由于SNMP协议比较简单,已有多种开源版本实现,对于底层实现并不需要关注,只需要增加自己的业务逻辑即可。

负责的一个海外项目需要设备提供SNMP协议支持,实现设备受中心大平台的控制和管理,因此对于设备来说,只需要开发一个代理程序,作为中间人,实现后端平台与前端设备的交互。

系统框图

如图1所示,整个系统包括两大模块,管理站和代理,通过SNMP协议进行交互,SNMP协议属于应用层协议,传输层采用UDP协议。管理站可以对代理进行Get/Set请求,即读写操作,代理进行Get/Set应答;代理还可以进行Trap告警,即主动推送。按C/S模型划分,管理站属于客户端,代理属于服务器。

        图1  SNMP的典型应用场景框图

SNMP介绍

SNMP中被管理的对象组成了一个树形结构,每个对象都是一个节点,定义在MIB数据库中,典型的MIB树形结构如图2 所示。

图2  典型MIB树形结构

SNMP访问一个被管对象都是通过对象命名树上的节点去访问,也就是说,如果你要定义一个被管对象,那么你就必须要在对象命名树上为它创建一个节点。一般对于企业开发而言,大都会在.1.3.6.1.4.1{iso(1) org(3) dod(6) internet(1) private(4) enterprises(1)}这个节点下重新创建新的节点给被管对象使用。

设备中SNMP子代理实现

SNMP目前的实现版本较多,主流的有C语言版本的Net-SNMP,C++版本的SNMP++,Java版本的jSNMP和Python版本的PySNMP。项目中采用了更为普遍的Net-SNMP,将源码下载进行编译安装到设备系统中,默认的SNMP代理(SNMP主代理snmpd)即可使用,接下来就是考虑如何将设备的业务逻辑实现SNMP支持,即扩展代理,常用三种扩展代理方式:

  1. 将自定义的.c和.h文件放入到SNMP的源代码安装包的扩展目录内,编译net-snmp时将扩展模块一同集成到net-snmp的libnetsnmpmib.a中。

     2. 将源文件和头文件编译成动态库,让net-snmp动态加载。

     3. 将新的MIB编译成子代理的模式,它将依附主代理运行,达到附加新MIB的目的。

项目中选择了实现方式3,下面详细介绍操作流程:

1)将协议文档转换为MIB文件;

一般来讲,自定义的MIB文件中变量模式主要有两种,一种是简单变量(就是单独的一个变量,可直接进行赋值),另一种是基于表的形式,其实就是需要实现一个链表,以设备某命令节点(简单变量)为例,

-- 1.3.6.1.4.1.1618.3.2.2.1

XXXCommandFlashObjs OBJECT IDENTIFIER

      ::= { XXXCommandObjs 1 }

-- 1.3.6.1.4.1.1618.3.2.2.1.1

XXXCommandFlash OBJECT-TYPE

      SYNTAX CommandFlash

      ACCESS read-write

      STATUS current

      DESCRIPTION "The flash command."

       ::= { XXXCommandFlashObjs 1 }

2)利用snmp的工具mib2c将mib文件的变量转换为源文件.c和.h将自己的业务代码在合适的位置加入即可;指令为:mib2c mib2c.scalar.conf [MIB模块名::节点变量名],以命令XXXCommandFlash为例,源文件中会自动生成两个函数,如下:

/** 初始化节点及注册回调处理函数*/

void init_XXXCommandFlash(void)

{

const oid XXXCommandFlash_oid[] = { 1,3,6,1,4,1,1618,3,2,2,1,1 };

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

netsnmp_register_scalar(netsnmp_create_handler_registration( "XXXCommandFlash",

               handle_XXXCommandFlash,

              XXXCommandFlash_oid,

              OID_LENGTH(XXXCommandFlash_oid),

              HANDLER_CAN_RWRITE ));

}

/** 节点处理函数,包括Get/Set处理*/

int handle_XXXCommandFlash(netsnmp_mib_handler *handler,

                          netsnmp_handler_registration *reginfo,

                          netsnmp_agent_request_info   *reqinfo,

                          netsnmp_request_info         *requests)

{

     switch(reqinfo->mode) {

        case MODE_GET:

                 //业务代码,调用设备SDK处理(Get前处理), Get

                 break;

        case MODE_SET_RESERVE1: /*Check*/ break;

        case MODE_SET_RESERVE2: break;

        case MODE_SET_FREE: break;

        case MODE_SET_ACTION: /*Set*/ break;

        case MODE_SET_COMMIT:

                //业务代码,调用设备SDK处理(Set后处理)

              break;

        case MODE_SET_UNDO: break;

}

3)同(2),将设备所有配置相关的节点进行初始化和注册节点处理回调函数这里为了减少代码编写工作,可以使用C++模板,将普通变量抽象为一类模板,将表变量抽象为一类模板,最终完成初始化函数的编写:

void init_yyysnmp(YYY &yyy);  //函数名必须为init_XXX,才能被snmp代理识别,yyy为设备句柄

上面描述的都是Get/Set节点的处理,对于Trap节点直接调用Net-SNMP提供的API即可。

4)子代理main函数编写示例如下:

static int keep_running = 1;

int main (int argc, char **argv)

{

SdkInit("127.0.0.1", PLATFORM); //设备 SDK初始化

std::string ip = "127.0.0.1";

YYY yyy(ip);

yyy.Login("password");          //登录设备

snmp_enable_filelog("/syslog/snmpd.log", 1);  //初始化snmp日志文件

netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,NETSNMP_DS_AGENT_ROLE, 1);           //配置NET-SNMP为子代理模式

  //SOCK_STARTUP;            //初始化TCPIP,Windows需要

  init_agent("yyysnmp");       //初始化代理库

  init_yyysnmp(yyy);             //新增mib初始化函数,步骤(3)所述

  init_snmp("yyysnmp");       //读yyysnmp.conf配置文件

  while(keep_running) {

      agent_check_and_process(1); //blocking check and handle request

  }

  snmp_shutdown("yyysnmp");      //子代理关机

  shutdown_agent();

  yyy.Logout();                  //注销设备

  return 0;

}

5)编译子代理源码,生成子代理应用程序YYYsnmp;

6)snmpd.conf配置文件修改;

#################################################################

# Subagent control

# The agent can support subagents using a number of extension mechanisms.

# From the 4.2.1 release, AgentX support is being compiled in by default.

#

master agentx        //开启子代理

rocommunity public   //只读类型变量的访问社区为public

rwcommunity private  //读写类型变量的访问社区为private

#################################################################

7)启动程序;包括设备主控mainControl,snmp主代理snmpd程序,snmp子代理YYYsnmp。

综上,设备中便实现了支持SNMP协议的子代理应用程序,后端大平台便可以使用SNMP对前端设备进行监控和控制,整个系统的框图为:

图3  基于SNMP协议的系统实现

如图3所示,后端管理平台作为网络管理工作站,通过SNMP协议对前端设备进行管理。后端平台通过SNMP协议与主代理进行通信,包括Get/Set消息,由主代理通过AgentX扩展协议将消息转发给子代理进行处理,子代理通过SDK与设备应用进行通信,对于trap告警消息直接由子代理上传给后端平台。关于SNMP,snmpd和AgentX的底层实现我们并不需要关注,直接将snmpd移植过来即可,我们关注的是根据子代理开发流程(上文介绍)将我们的业务代码编译为子代理即可。

之所以选用子代理方式进行开发,是因为AgentX协议是实现SNMP分布式扩展的通信协议,根据业务的扩展,会涉及到不断添加新的MIB,这样对于新增的MIB我们可以单独编译成一个新的子代理,形成一主多从(一个主代理master,多个子代理sub-agent)的架构,即分布式监控架构,这样就实现了动态扩展代理的需求,分布式架构如图4所示。

                                                        图4  基于SNMP子代理的分布式管理系统

总结

本案例主要给出了嵌入式设备的SNMP子代理实现方式,其它嵌入式设备完全可以复用实现流程,这样就可以实现不同厂商、支持不同协议的嵌入式设备可被后端平台统一进行管理,这也是分布式系统的一种简单实现方式。

参考文献

[1] 深入理解Net-SNMP[M], 张春强, 机械工业出版社.

[2] http://www.net-snmp.org/ Net-SNMP官方网站

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值