文章目录
snmp六种操作简述
Get(获取操作):
Get 操作用于从管理设备向代理设备获取指定 OID(对象标识符)的值。
管理设备发送 Get 报文包含要获取的 OID 列表,代理设备则根据这些 OID 返回对应的值。
Get Next(获取下一个操作):
Get Next 操作用于从代理设备获取比指定 OID 更大的第一个 OID 的值。
管理设备发送 Get Next 报文包含一个或多个 OID,代理设备则返回比这些 OID 大的第一个 OID 的值。
Get Bulk(批量获取操作):
Get Bulk 操作允许一次获取多个 OID 的值,减少交互次数,提高效率。
管理设备发送 Get Bulk 报文指定起始 OID、请求的个数等参数,代理设备返回相应的值。
Set(设置操作):
Set 操作用于向代理设备设定指定 OID 的值,用于配置设备的参数。
管理设备发送 Set 报文包含要设置的 OID 和对应的值,代理设备根据指定的 OID 进行配置。
Inform(通知操作):
Inform 操作用于向管理设备发送一个通知,通知管理设备某些事件的发生。
代理设备主动发送 Inform 报文给指定的管理设备,通知特定的事件或状态。
Trap(陷阱操作):
Trap 操作用于代理设备向管理设备发送一个告警或事件通知,通知管理设备发生了某些重要的事件。
代理设备可以主动发送 Trap 报文给一个或多个管理设备,告知管理设备设备的状态或发生的事件。
这些操作是 SNMP 协议中常用的几种,用于实现设备间的监控、通知和配置等功能。通过这些操作,网络管理员可以监控网络设备的状态、配置参数、响应事件等,帮助及时发现和解决网络问题
getNext 操作
1.代理程序开启监听
2.管理程序去对某些oid发起getNext操作
3.代理程序处理getNext请求,将oid对应的下一个oid的value发送给管理程序
4.管理程序获取value并打印
代理程序
#include <QCoreApplication>
#include "agent_dev.h"
#include "agent_dev_global.h"
#include<snmp_pp/snmp_pp.h>
#include<agent_pp/agent++.h>
#include<agent_pp/mib.h>
#include<agent_pp/mib_entry.h>
#include<agent_pp/request.h>
#include<QDebug>
#include<agent_pp/snmp_group.h>
#include<agent_pp/system_group.h>
#include <agent_pp/snmp_target_mib.h>
#include <agent_pp/snmp_notification_mib.h>
#include"qagent.h"
using namespace std;
using namespace Snmp_pp;
using namespace Agentpp;
#define SYSDESCR "1.3.6.1.2.1.1.1.0" //ObjectID for system descriptor
#define SYSOBJECTID "1.3.6.1.2.1.1.2.0" //ObjectID for system object ID
#define SYSCONTACT "1.3.6.1.2.1.1.4.0" //ObjectID for system contact
#define coldStart "1.3.6.1.6.3.1.1.5.1"
#define ZYX1 "1.3.6.1.2.1.1.1.0"
#define ZYX2 "1.3.6.1.2.1.1.1.1"
#define ZYX3 "1.3.6.1.2.1.1.1.101"
bool run = true;
static void sig(int signo)
{
if ((signo == SIGTERM) || (signo == SIGINT) ||(signo == SIGSEGV))
{
printf ("\n");
switch (signo)
{
case SIGSEGV:
{
qDebug()<<"Segmentation fault, aborting.";
exit(1);
}
case SIGTERM:
case SIGINT:
{
if (run)
{
qDebug()<<"User abort";
run = false;
}
}
}
}
}
void init_signals()
{
signal (SIGTERM, sig);
signal (SIGINT, sig);
signal (SIGSEGV, sig);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Snmp::socket_startup();//初始化socket,这一步是一定要有的,不然snmp构造会失败。
int status;
unsigned short port = 161; //161为监听端口 162为Trap端口
UdpAddress address("127.0.0.1");
address.set_port(port);
Snmpx snmp(status,address);
if( SNMP_CLASS_SUCCESS == status)
{
Mib mib;
//将MibLeaf对象添加进mib里面,MibLeaf对象,包含了oid和oid对应的value。这个value可以是字符串也可以是数字等。
mib.add(new snmpGroup());
mib.add(new snmp_target_mib());
mib.add(new snmp_notification_mib());
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.0", READONLY, new OctetStr("SYSDESCR")));
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.1", READONLY, new OctetStr("zyx1")));
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.2", READONLY, new OctetStr("zyx2")));
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.101", READWRITE, new OctetStr("zyx3")));
//创建RequestList
RequestList* reqList = new RequestList(&mib);
mib.set_request_list(reqList);
init_signals();
reqList->set_snmp(&snmp);
mib.init(); //mib 初始化
//监听循环 此处循环何时退出可根据实际情况来做修改
Request* req;
while (run)
{
req = reqList->receive(2);//接收请求,已经timeout时间为5秒,在这里阻塞2秒来等待请求,如果请求到来往下执行,如果没有到来,2秒过后继续往下执行
if (req)
{
mib.process_request(req);//处理请求,这个处理时内部封装了的,你的get,getnext,bulk,walk,set等,都是这个函数去处理,至于内部是怎么处理的,就不知道了。
}
else
{
mib.cleanup();//执行周期性的清理和维护任务。
}
}
delete reqList;
Snmp::socket_cleanup();
}
else
{
qDebug()<<"snmp port init failed!";
}
return a.exec();
}
管理程序
#include <QCoreApplication>
#include<snmp_dev.h>
#include<snmp_pp/snmp_pp.h>
#include<snmp_pp/oid.h>
#include <winsock2.h>
using namespace std;
#ifdef SNMP_PP_NAMESPACE
using namespace Snmp_pp;
#endif
int main(int argc, char **argv)
{
Snmp::socket_startup(); // Initialize socket subsystem
//---------[ make a GenAddress and Oid object to retrieve ]---------------
UdpAddress address("127.0.0.1"); // make a SNMP++ Generic address
if ( !address.valid()) // check validity of address
{
cout << "Invalid Address or DNS Name, " <<endl;
}
Oid oid("1.3.6.1.2.1.1.1.0"); // default is sysDescr
cout << "GETNEXT for OID " << oid.get_printable() << "\n";
//---------[ determine options to use ]-----------------------------------
snmp_version version=version1; // default is v1
int retries=1; // default retries is 1
int timeout=100; // default is 1 second
u_short port=161; // default snmp port is 161
OctetStr community("public"); // community name
//----------[ create a SNMP++ session ]-----------------------------------
int status;
// bind to any port and use IPv6 if needed
Snmp snmp(status, 0, (address.get_ip_version() == Address::version_ipv6));
if ( status != SNMP_CLASS_SUCCESS)
{
cout << "SNMP++ Session Create Fail, " << snmp.error_msg(status) << "\n";
return 1;
}
//--------[ build up SNMP++ object needed ]-------------------------------
Pdu pdu; // construct a Pdu object
Vb vb; // construct a Vb object
vb.set_oid( oid); // set the Oid portion of the Vb
pdu += vb; // add the vb to the Pdu
address.set_port(port);
CTarget ctarget( address); // make a target using the address
ctarget.set_version( version); // set the SNMP version SNMPV1 or V2
ctarget.set_retry( retries); // set the number of auto retries
ctarget.set_timeout( timeout); // set timeout
ctarget.set_readcommunity( community); // set the read community name
//-------[ issue the request, blocked mode ]-----------------------------
cout << "SNMP++ GetNext to " << " Retries=" << retries<< " Timeout=" << timeout * 10 <<"ms";
cout << " Community=" << community.get_printable() << endl << flush;
SnmpTarget *target;
target = &ctarget;
status = snmp.get_next( pdu, *target);
if (status == SNMP_CLASS_SUCCESS)
{
pdu.get_vb( vb,0);
cout << "Oid = " << vb.get_printable_oid() << " "<< "Value = " << vb.get_printable_value() << endl;
}
else
{
cout << "SNMP++ GetNext Error, " << snmp.error_msg( status)
<< " (" << status <<")" << endl;
}
Snmp::socket_cleanup(); // Shut down socket subsystem
}
我们的对(1.3.6.1.2.1.1.1.0)这个oid发起了getNext的请求,代理程序就会返回这个oid的下一个oid。
代理程序在mib中添加了如下对象
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.0", READONLY, new OctetStr("SYSDESCR")));
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.1", READONLY, new OctetStr("zyx1")));
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.2", READONLY, new OctetStr("zyx2")));
mib.add(new MibLeaf("1.3.6.1.2.1.1.1.101", READWRITE, new OctetStr("zyx3")));
从oid来看(1.3.6.1.2.1.1.1.0)的下一个oid就是(1.3.6.1.2.1.1.1.1)所以将或者oid的以及value返回。
这个oid的顺序并不是按照添加顺序来的,它的getNext和添加顺序无关。你可以把它想象成一颗二叉树,它会沿着某一个节点一直往下走,走到底再返回上一个节点继续走。它的getNext操作就类似这样。