SNMP++作为一个历史悠久的开源包,网上有许多老旧的编译教程,较难使用。
VS2013环境下编译好的SNMP++.lib和头文件下载链接https://download.youkuaiyun.com/download/void_1912/12048976
注意:本教程编译生成的SNMP++不含snmpV3版本
按照本教程,可顺利的编译。如有问题可联系我:zhujy1997@foxmail.com
0X00 下载开发包
开发包可从官网https://agentpp.com/download.html#SNMP_PP 中下载得到
网速慢的同学https://download.youkuaiyun.com/download/void_1912/12048963(本教程中所写步骤,皆从该版本中实现)
将三个压缩包依次解压,将解压后的文件放于一个文件夹下,修改SNMP++-3.3.11文件夹名字
进入VS2013文件夹中,打开README.win32,
看到提示可以知道,为了避免config_snmp_pp.h头文件冲突,删除掉VS2013/snmp++/include中的config_snmp_pp.h
打开VS2013中的SNMP++ 文件夹,点击SNMP++.sln启动工程
对SNMP++工程进行配置,设置包含目录
将两个include包含进来,(其实只要移动一下头文件只包含一个也是可以的)
手动移除config_snmp_pp.h,在添加 \snmp++\include\snmp_pp目录下的config_snmp_pp.h,不移除再添加会发现打不开该头文件,并有一堆错误信息。
由于不需要使用SNMPv3版本,进入config_snmp_pp.h,关掉SNMPv3
修改两处地方,第二处为是否选择使用openssl,如果不关掉,并且没有导入openssl.lib的话会有如下报错:
直接生成解决方案,编译器报错,双击错误信息进入对应源码文件,
直接注释掉该行,重新生成解决方案,生成成功。
0x01 测试SNMP++是否成功
新建一个Win32控制台工程。建立空项目。
将 \vs2013\SNMP++\include下的这两个头文件丢到 \snmp++\include目录下
将\snmp++\include拷贝到自己的工程目录下,并将生成的SNMP++.lib一并丢入
设置工程中的属性
将include目录包含进来,可根据需求,自行设计成动态目录。
设置链接器中的附加目录
添加lib引用
只需添加上SNMP++.lib和ws2_32.lib两个lib即可,ws2_32.lib用于启动winsocket
添加main.cpp,贴上snmp++/consoleExamples中的test_cpp代码,运行即可,
/*_############################################################################
_##
_## test_app.cpp
_##
_## SNMP++ v3.3
_## -----------------------------------------------
_## Copyright (c) 2001-2013 Jochen Katz, Frank Fock
_##
_## This software is based on SNMP++2.6 from Hewlett Packard:
_##
_## Copyright (c) 1996
_## Hewlett-Packard Company
_##
_## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
_## Permission to use, copy, modify, distribute and/or sell this software
_## and/or its documentation is hereby granted without fee. User agrees
_## to display the above copyright notice and this license notice in all
_## copies of the software and any documentation of the software. User
_## agrees to assume all liability for the use of the software;
_## Hewlett-Packard and Jochen Katz make no representations about the
_## suitability of this software for any purpose. It is provided
_## "AS-IS" without warranty of any kind, either express or implied. User
_## hereby grants a royalty-free license to any and all derivatives based
_## upon this software code base.
_##
_##########################################################################*/
char test_app_cpp_version[] = "@(#) SNMP++ $Id$";
#include <libsnmp.h>
#include "snmp_pp/snmp_pp.h"
#ifdef WIN32
#define strcasecmp _stricmp
#endif
#ifdef SNMP_PP_NAMESPACE
using namespace Snmp_pp;
#endif
// default request oids
#define NUM_SYS_VBS 6
#define sysDescr "1.3.6.1.2.1.1.1.0"
#define sysObjectID "1.3.6.1.2.1.1.2.0"
#define sysUpTime "1.3.6.1.2.1.1.3.0"
#define sysContact "1.3.6.1.2.1.1.4.0"
#define sysName "1.3.6.1.2.1.1.5.0"
#define sysLocation "1.3.6.1.2.1.1.6.0"
//#define sysServices "1.3.6.1.2.1.1.7.0" // not all agents support this...
// default notification oid
#define coldStart "1.3.6.1.6.3.1.1.4.3.0.1"
int main(int argc, char **argv)
{
int status;
char *req_str = (char*) "get";
// char *dflt_req_oid = (char*) sysDescr;
char *dflt_trp_oid = (char*)coldStart;
char *genAddrStr = (char*) "127.0.0.1"; // localhost
char *oid_str = (char*)NULL;
if (argc > 1) genAddrStr = argv[1];
if (argc > 2) req_str = argv[2];
if (argc > 3) oid_str = argv[3];
Snmp::socket_startup(); // Initialize socket subsystem
IpAddress ipAddr(genAddrStr);
if (!ipAddr.valid()) {
std::cout << "Invalid destination: " << genAddrStr << std::endl;
return(1);
}
// bind to any port and use IPv6 if needed
Snmp snmp(status, 0, (ipAddr.get_ip_version() == Address::version_ipv6));
if (status){
std::cout << "Failed to create SNMP Session: " << status << std::endl;
return(1);
}
std::cout << "Created session successfully" << std::endl;
CTarget target(ipAddr);
if (!target.valid()) {
std::cout << "Invalid target" << std::endl;
return(1);
}
Pdu pdu;
Vb vb;
if (strcmp(req_str, "get") == 0) {
Vb vbl[NUM_SYS_VBS];
vbl[0].set_oid(sysDescr);
vbl[1].set_oid(sysObjectID);
vbl[2].set_oid(sysUpTime);
vbl[3].set_oid(sysContact);
vbl[4].set_oid(sysName);
vbl[5].set_oid(sysLocation);
// vbl[6].set_oid(sysServices);
std::cout << "Send a GET-REQUEST to: " << ipAddr.get_printable() << std::endl;
if (!oid_str) {
if (strcmp(genAddrStr, "localhost") == 0 ||
strcmp(genAddrStr, "127.0.0.1") == 0){
pdu.set_vblist(vbl, NUM_SYS_VBS);
}
else {
for (int i = 0; i<NUM_SYS_VBS; i++)
pdu += vbl[i];
}
}
else {
Oid req_oid(oid_str);
if (!req_oid.valid()) {
std::cout << "Request oid constructor failed for:" << oid_str << std::endl;
return(1);
}
vb.set_oid(req_oid);
pdu += vb;
}
status = snmp.get(pdu, target);
if (status){
std::cout << "Failed to issue SNMP Get: (" << status << ") "
<< snmp.error_msg(status) << std::endl;
return(1);
}
else{
std::cout << "Issued get successfully" << std::endl;
int vbcount = pdu.get_vb_count();
if (vbcount == NUM_SYS_VBS) {
pdu.get_vblist(vbl, vbcount);
for (int i = 0; i<vbcount; i++) {
std::cout << vbl[i].get_printable_oid() << " : " <<
vbl[i].get_printable_value() << std::endl;
}
}
else {
for (int i = 0; i<vbcount; i++) {
pdu.get_vb(vb, i);
std::cout << vb.get_printable_oid() << " : " <<
vb.get_printable_value() << std::endl;
}
}
}
}
else if (strcmp(req_str, "trap") == 0) {
std::cout << "Send a TRAP to: " << ipAddr.get_printable() << std::endl;
if (!oid_str)
oid_str = dflt_trp_oid;
Oid notify_oid(oid_str);
if (!notify_oid.valid()) {
std::cout << "Notify oid constructor failed for:" << oid_str << std::endl;
return(1);
}
pdu.set_notify_id(notify_oid);
// Use a simple payload
vb.set_oid(sysLocation);
vb.set_value("This is a test");
pdu += vb;
status = snmp.trap(pdu, target);
if (status){
std::cout << "Failed to issue SNMP Trap: (" << status << ") "
<< snmp.error_msg(status) << std::endl;
return(1);
}
else {
std::cout << "Success" << std::endl;
}
}
else {
std::cout << "Invalid SNMP operation: " << req_str << std::endl;
std::cout << "Usage: " << argv[0] << " hostname [get | trap]" << std::endl;
return(1);
}
Snmp::socket_cleanup(); // Shut down socket subsystem
return(0);
}