现在的位置: 首页 > 综合 > 正文

net-snmp agent开发

2013年10月22日 ⁄ 综合 ⁄ 共 7128字 ⁄ 字号 评论关闭

1、
系统环境:
opensuse 11.3

2、
需要安装的net-snmp包:
net-snmp
net-snmp-devel
perl-SNMP
snmp-mibs
libsnmp20
可以使用 zypper 安装来解决包依赖问题(zypper install net-snmp 和 net-snmp-devel)。

3、
写一个MIB库:(参照ASN.1抽象标记语言生成SMI、MIB)
 MyMIB DEFINITIONS::=BEGIN

      
 IMPORTS     

             
     enterprises,OBJECT-TYPE,Integer32,TimeTicks

                    
      FROM SNMPv2-SMI
.....

4、编译
MIB库存放路径:/usr/share/snmp/mibs/mymib.mib
配置文件路径: /etc/snmp/mymib.conf
指令:
env MIBS="+/usr/share/snmp/mibs/mymib.mib" mib2c mymib
利用向导生成.c文件
  步骤如下: (选2)Net-SNMP style code --> (选1) destroyed independently of the SNMP agent -->
      (选2)mib2c -c mib2c.iterate_access.conf mymib -->看到提示:
**********************************************************************
NOTE:  The only files you MUST modify should be the following:
  mymib_access.c
  mymib_access.h
  mymib_checkfns_local.h
  mymib_checkfns_local.c
**********************************************************************
则生成成功。

5、修改部分代码:
修改mymib.c mymibIfTable_handler函数

修改点1:
138         case MODE_GET:
       // 不采用链表方式,可以注释掉这里。
139            /* data_context =  netsnmp_extract_iterator_context(request);
140             if (data_context == NULL) {
141                 netsnmp_set_request_error(reqinfo, request,
142                                           SNMP_NOSUCHINSTANCE);
143                 continue;
144             }*/
145             break;

修改点2:
switch(reqinfo->mode) {
161             case MODE_GET:
162                 switch(table_info->colnum) {
163                     case COLUMN_IFINDEX:
164                             {
       // 这里就是查询返回值的地方:get_ifIndex就是节点对应的函数。
       // 可以根据自己的需要修改get_ifIndex函数即可。
165                                 long *retval;
166                                 size_t retval_len = 0;
167                                 retval = get_ifIndex(data_context, &retval_len);
168                                 if (retval)
169                                     snmp_set_var_typed_value(var, ASN_INTEGER,
170                                                              retval,
171                                                              retval_len);
172        FREEPTR(retval);
173                             }
174                         break;

修改mymib_access.c

修改点3:
mymibIfTable_get_first_data_point中
 37     netsnmp_variable_list *vptr;
 38
 39     //*my_loop_context = /** XXX */;
 40     //*my_data_context = /** XXX */;
 41
 42     vptr = put_index_data;
 43
 44     //snmp_set_var_value(vptr, /** XXX: ifIndex data */, /** XXX: length of ifIndex data */);
 snmp_set_var_value(vptr, NULL, 0);
 45     vptr = vptr->next_variable;

修改点4:
 57 netsnmp_variable_list *
 58 tosIfTable_get_next_data_point(void **my_loop_context, void **my_data_context,
 59                          netsnmp_variable_list *put_index_data,
 60                          netsnmp_iterator_info *mydata)
 61 {
 62
 63     netsnmp_variable_list *vptr;
 64
 65     *my_loop_context = /** XXX */;
 66     *my_data_context = /** XXX */;
 67
 68     vptr = put_index_data;
 69
 70     snmp_set_var_value(vptr, /** XXX: ifIndex data */, /** XXX: length of ifIndex data */);
 71     vptr = vptr->next_variable;
 72
 73     return put_index_data;
 74 }

===》
 57 netsnmp_variable_list *
 58 tosIfTable_get_next_data_point(void **my_loop_context, void **my_data_context,
 59                          netsnmp_variable_list *put_index_data,
 60                          netsnmp_iterator_info *mydata)
 61 {
 62     mydata = NULL;
 63     put_index_data = NULL;
 64     return put_index_data;
 65 }

 

修改点5:
122 /** XXX: return a data pointer to the data for the ifIndex column and set
123          ret_len to its proper size in bytes. */
124       long *get_ifIndex(void *data_context, size_t *ret_len) {
125       return NULL; /** XXX: replace this with a pointer to a real value */
126       }

===》

219       long *get_ifIndex(void *data_context, size_t *ret_len)
220       {
221           long *pagent = (long *)calloc( 4, 2);
222             pagent[0] = 100;
223             data_context = pagent;
224             *ret_len = 4;
225             return data_context; /** XXX: replace this with a pointer to a real value */
226       }

6、编译链接

gcc -g -o mymib mymib_new.c mymib.c mymib_access.c -I/usr/include -L/usr/lib/ -lnetsnmp -lnetsnmpagent -lnetsnmpmibs -lnetsnmphelpers

7、配置
 修改/etc/snmp/snmpd.conf

 添加以下参数:

 // 允许启动监听705
 15 agentxsocket tcp:localhost:705
 16 master agentx
 // 允许访问的客户端IP,以及密码
 18 # These really aren't meant for production use.  They include all MIBS
 19 # and can use considerable resources.  See snmpd.conf(5) for information
 20 # on setting up groups and limiting MIBS.
 21 rocommunity public 127.0.0.1
 22 rocommunity public 192.168.71.237
 23 rocommunity public 192.168.71.238
 24 rocommunity public 127.0.0.1

8、启动服务
  
主代理服务:
   service snmpd start
子代理服务
   ./mymib
   看到提示:NET-SNMP version 5.5 AgentX subagent connected,表示子代理已经连接上主代理.
  

9、客户端
snmpget -v 2c -c public 192.168.71.237 .1.3.6.1.4.1.14331.5.5.1.5.1.2.0
就可以看到代理信息。

附件 (主程序框架):
 1 /*主函数:mymib_new.c */
  2 #include <net-snmp/net-snmp-config.h>
  3 #include <net-snmp/net-snmp-includes.h>
  4 #include <net-snmp/agent/net-snmp-agent-includes.h>
  5 #include <signal.h>
  6
  7
  8 #include "mymib.h"
  9 static int keep_running;
 10
 11 RETSIGTYPE stop_server(int a)
 12 {
 13     keep_running = 0;
 14 }
 15
 16
 17
 18 int main (int argc, char **argv)
 19 {
 20
 21     int agentx_subagent=1; /* change this if you want to be a SNMP master agent */
 22     int background = 0; /* change this if you want to run in the background */
 23     int syslog = 0; /* change this if you want to use syslog */
 24
 25     /* print log errors to syslog or stderr */
 26     if (syslog)
 27         snmp_enable_calllog();
 28     else
 29         snmp_enable_stderrlog();
 30
 31     /* we're an agentx subagent? */
 32     if (agentx_subagent)
 33     {
 34         /* make us a agentx client. */
 35         netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
 36
 37
 38         netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET,
 39                 "tcp:localhost:705");
 40     }
 41
 42
 43     /* run in background, if requested */
 44     if (background && netsnmp_daemonize(1, !syslog))
 45         exit(1);
 46
 47     /* Initialize tcpip, if necessary */
 48     SOCK_STARTUP;
 49
 50     /* Initialize the agent library */
 51     int nret = init_agent("mymib-daemon");
 52
 53     /* Initialize our mib code here */
 54     init_mymib();
 55
 56     /* initialize vacm/usm access control  */
 57     if (!agentx_subagent)
 58     {
 59         void  init_vacm_vars();
 60         void  init_usmUser();
 61     }
 62
 63     //init_mib_internals();
 64
 65     /* Example-demon will be used to read example-demon.conf files. */
 66     init_snmp("mymib-daemon");
 67
 68     /* If we're going to be a snmp master agent, initial the ports */
 69     if (!agentx_subagent)
 70         init_master_agent();  /* open the port to listen on (defaults to udp:161) */
 71
 72     /* In case we recevie a request to stop (kill -TERM or kill -INT) */
 73     keep_running = 1;
 74     signal(SIGTERM, stop_server);
 75     signal(SIGINT, stop_server);
 76     snmp_log(LOG_INFO,"mymib-daemon is up and running./n");
 77
 78     /* your main loop here... */
 79     while(keep_running)
 80     {
 81         /* if you use select(), see snmp_select_info() in snmp_api(3) */
 82         /*     --- OR ---  */
 83         agent_check_and_process(1); /* 0 == don't block */
 84     }
 85
 86
 87     /* at shutdown time */
 88     snmp_shutdown("mymibsec-daemon");
 89     SOCK_CLEANUP;
 90
 91     return 0;
 92 }
 93

 

参考:
网管SNMP Agent的快速开发
http://www.wangchao.net.cn/bbsdetail_53491.html

用NET-SNMP软件包开发简单客户端代理
http://bibu.blogchina.com/inc/net_snmp_doc.htm

How can I run AgentX with a different socket address?
http://net-snmp.sourceforge.net/wiki/index.php/FAQ:Agent_12

Re: working with tables... - SNMP
http://fixunix.com/snmp/382842-re-working-tables.html

 

 

抱歉!评论已关闭.