windows下使用net-snmp实现agent扩展(一)

来源:互联网 发布:淘宝耐克正品店铺 贴吧 编辑:程序博客网 时间:2024/05/21 09:42
项目上需要用snmp来做告警监控管理,达到对系统的运行状态的监测。这几天研究了一下,发现网上资料比较少,大多数抄来抄去,能够正确运行的更少。所以,总结了一下,把相关的代码放上来,希望能够帮助同样遇到困惑的朋友。 havenzhao http://vcsky.net

项目名称为DCS系统,采用VS2010开发,DCS作为被监测的对象,因此需要实现snmp的Agent扩展。最开始的方法,采用了WinSnmp,发现步骤很繁琐,需要编写dll,需要手动修改注册表,需要安装snmp协议服务,可行性和意义都不大。又研究了开源软件net-snmp,snmp++,agent++。网上说net-snmp主要适用于Linux平台,在这几天的开发中,它完全能够胜任Windows平台,只是网上的资料偏少而已。

DCS就是使用net-snmp(版本是5.7.1),实现了Windows平台下的Agent端,实现了get、set、trap命令。

接下来的工作,我们这样展开:

1、首先要得到四个lib库以及一个dll文件:netsnmp.lib netsnmpagent.lib netsnmpmibs.lib netsnmptrapd.lib,netsnmp.dll。在下载了net-snmp的源码后,编译,需要阅读源码下的“README.win32”文件,工程默认的是VC6.0的,但由于要装SDK之类的,我直接转化为VS2010的了,实际上,还可以转为VS2003、VS2005、VS2008,看你手头上用的哪个版本的编译器了。只编译win32dll.dsw工程就可以得到想要的东西了。

2、下载net-snmp的5.4版msi文件安装,默认路径C:\usr安装,安装过程中选择开发支持。没有找到5.7的,随便下个5.4的,安装上就行,但要主要选用默认的安装路径(更改安装路径,不知道可不可行,没有尝试),一路默认即可。安装的目的在于我们要配置后缀名为conf的文件,没有这个配置选项,将不能使用net-snmp的服务,我怀疑这个文件在源码中有个对应关系,不然怎么知道配置文件在路径C:\usr\etc\snmp下呢?如果只实现trap命令,这步可以省略。

3、建立C++的控制台工程,一个空的工程就可以。设置工程的包含头文件和lib文件。这里需要注意的一点是:include头文件,我把net-snmp5.7.1下的头文件都包含过来了,lib库文件,就是上面4个lib库,别忘了设置连接器:在项目属性的--连接器--输入--"附加依赖项":添加netsnmp.lib netsnmpagent.lib netsnmpmibs.lib netsnmptrapd.lib wsock32.lib; 如果环境变量没有起作用,netsnmp.dll与exe文件放在同一文件夹下就可以了。注意:wsock32.lib是其它lib库里用到的,缺少它会报错。

4、工程建立完了,配置好了,那就写代码吧!新建3个文件,一个入口函数文件,一个mib库的实现文件,一个头文件。我们先拿网上的例子试一下,参照这篇文章;http://hi.baidu.com/haven2002/item/d2d0bac02eed32bd0d0a7b9d

example-demon.c

[cpp] view plain copy
print?
  1. #include <net-snmp/net-snmp-config.h>   
  2. #include <net-snmp/net-snmp-includes.h>   
  3. #include <net-snmp/agent/net-snmp-agent-includes.h>   
  4. #include <signal.h>  
  5. #include "nstAgentSubagentObject.h"  
  6. static int keep_running;  
  7. RETSIGTYPE   
  8. stop_server(int a) {   
  9.           keep_running = 0;   
  10. }  
  11. int main (int argc, char **argv) {   
  12.         //int agentx_subagent=1; /* change this if you want to be a SNMP master agent */   
  13.         int agentx_subagent=0;   
  14.         int background = 0; /* change this if you want to run in the background */   
  15.         int syslog = 0; /* change this if you want to use syslog */  
  16.         /* print log errors to syslog or stderr */   
  17.         if (syslog)   
  18.          ;   
  19.           //snmp_enable_calllog();   
  20.         else   
  21.           snmp_enable_stderrlog();  
  22.         /* we're an agentx subagent? */   
  23.         if (agentx_subagent) {   
  24.           /* make us a agentx client. */   
  25.           netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);   
  26.         }  
  27.         /* run in background, if requested */   
  28.         if (background && netsnmp_daemonize(1, !syslog))   
  29.             exit(1);  
  30.         /* initialize tcpip, if necessary */   
  31.         SOCK_STARTUP;  
  32.         /* initialize the agent library */   
  33.         init_agent("example-demon");  
  34.         /* initialize mib code here */  
  35.         /* mib code: init_nstAgentSubagentObject from nstAgentSubagentObject.C */   
  36.         init_nstAgentSubagentObject();   
  37.         /* initialize vacm/usm access control        */   
  38.         if (!agentx_subagent) {   
  39.             init_vacm_vars();   
  40.             init_usmUser();   
  41.         }  
  42.         /* example-demon will be used to read example-demon.conf files. */   
  43.         /*在这里读取一个example-demon.conf的配置文件,这是关键*/   
  44.         init_snmp("example-demon");  
  45.         /* If we're going to be a snmp master agent, initial the ports */   
  46.         if (!agentx_subagent)   
  47.           init_master_agent();        /* open the port to listen on (defaults to udp:161) */  
  48.         /* In case we recevie a request to stop (kill -TERM or kill -INT) */   
  49.         keep_running = 1;   
  50.         signal(SIGTERM, stop_server);   
  51.         signal(SIGINT, stop_server);  
  52.         snmp_log(LOG_INFO,"example-demon is up and running.\n");  
  53.         /* your main loop here... */   
  54.         while(keep_running) {   
  55.           /* if you use select(), see snmp_select_info() in snmp_api(3) */   
  56.           /*           --- OR ---        */   
  57.           agent_check_and_process(1); /* 0 == don't block */   
  58.         }  
  59.         /* at shutdown time */   
  60.         snmp_shutdown("example-demon");   
  61.         SOCK_CLEANUP;  
  62.         return 0;   
  63. }  

nstAgentSubagentObject.h

[cpp] view plain copy
print?
  1. /*  
  2. * Note: this file originally auto-generated by mib2c using  
  3. *              : mib2c.int_watch.conf,v 5.0 2002/04/20 07:30:13 hardaker Exp $  
  4. */   
  5. #ifndef NSTAGENTSUBAGENTOBJECT_H   
  6. #define NSTAGENTSUBAGENTOBJECT_H  
  7. /*  
  8. * function declarations  
  9. */   
  10. void                  init_nstAgentSubagentObject(void);  
  11. #endif                                /* NSTAGENTSUBAGENTOBJECT_H */  

nstAgentSubagentObject.c

[cpp] view plain copy
print?
  1. /*  
  2. * Note: this file originally auto-generated by mib2c using  
  3. *              : mib2c.int_watch.conf,v 5.0 2002/04/20 07:30:13 hardaker Exp $  
  4. */  
  5. #include <net-snmp/net-snmp-config.h>   
  6. #include <net-snmp/net-snmp-includes.h>   
  7. #include <net-snmp/agent/net-snmp-agent-includes.h>   
  8. #include "nstAgentSubagentObject.h"  
  9. /*  
  10. * the variable we want to tie an OID to.        The agent will handle all  
  11. * * GET and SET requests to this variable changing it's value as needed.  
  12. */  
  13. static int  nstAgentSubagentObject = 6;  
  14. /*  
  15. * our initialization routine, automatically called by the agent  
  16. * (to get called, the function name must match init_FILENAME())  
  17. */   
  18. void   
  19. init_nstAgentSubagentObject(void)   
  20. {   
  21.           static oid            nstAgentSubagentObject_oid[] =   
  22.               { 1, 3, 6, 1, 4, 1, 8072, 2, 4, 1, 1, 2, 0 };  
  23.           /*  
  24.            * a debugging statement.        Run the agent with -DnstAgentSubagentObject to see  
  25.            * the output of this debugging statement.  
  26.            */   
  27.           DEBUGMSGTL(("nstAgentSubagentObject",   
  28.                       "Initializing the nstAgentSubagentObject module\n"));  
  29.           /*  
  30.            * the line below registers our variables defined above as  
  31.            * accessible and makes it writable.        A read only version of any  
  32.            * of these registration would merely call  
  33.            * register_read_only_int_instance() instead.        The functions  
  34.            * called below should be consistent with your MIB, however.  
  35.            *  
  36.            * If we wanted a callback when the value was retrieved or set  
  37.            * (even though the details of doing this are handled for you),  
  38.            * you could change the NULL pointer below to a valid handler  
  39.            * function.  
  40.            */   
  41.           DEBUGMSGTL(("nstAgentSubagentObject",   
  42.                       "Initalizing nstAgentSubagentObject scalar integer.        Default value = %d\n",   
  43.                       nstAgentSubagentObject));  
  44.           netsnmp_register_int_instance("nstAgentSubagentObject",   
  45.                                         nstAgentSubagentObject_oid,   
  46.                                         OID_LENGTH(nstAgentSubagentObject_oid),   
  47.                                         &nstAgentSubagentObject, NULL);  
  48.           DEBUGMSGTL(("nstAgentSubagentObject",   
  49.                       "Done initalizing nstAgentSubagentObject module\n"));   
  50. }   


编译链接通过!恭喜你!

5、 在C:\usr\etc'\snmp下建立example-demon.conf。内容如下:

#community 的读写根据需要设, 
rwcommunity        public 
agentaddress        161

6、如果开启snmpd服务,先关闭。启动上面项目的可执行文件。

7、启动cmd,执行:

snmpget -v1 -c public localhost 1.3.6.1.4.1.8072.2.4.1.1.2.0

结果:NET-SNMP-MIB::netSnmp.2.4.1.1.2.0 = INTEGER: 6

snmpset -v1 -c public localhost 1.3.6.1.4.1.8072.2.4.1.1.2.0 i 5

结果:NET-SNMP-MIB::netSnmp.2.4.1.1.2.0 = INTEGER: 5

snmpget -v1 -c public localhost 1.3.6.1.4.1.8072.2.4.1.1.2.0

结果:NET-SNMP-MIB::netSnmp.2.4.1.1.2.0 = INTEGER: 5

OK!大功告成!

至此,havenzhao http://vcsky.net 我们实现了windows下利用net-snmp扩展。这只是一个最简单的例子,能够使用agent接收一个int变量的get/set命令。接下来,我们发现这只是万里长征的第一步……

原创粉丝点击