snmp++操作之set

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 协议中常用的几种,用于实现设备间的监控、通知和配置等功能。通过这些操作,网络管理员可以监控网络设备的状态、配置参数、响应事件等,帮助及时发现和解决网络问题

set 操作

1.代理程序开启监听
2.管理程序去对某个oid发起get操作
3.代理程序处理get请求,将oid对应的value发给管理程序。
4.管理程序获取value并打印
5.管理程序将这个oid和新的vlaue绑定起来,放进pdu对象。然后发起set请求
6.代理程序处理set请求。然后将oid的value值修改为新的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();
}

#管理程序

#ifdef WIN32
#define strcasecmp _stricmp
#endif

#ifdef SNMP_PP_NAMESPACE
using namespace Snmp_pp;
#endif

// determine the smi type and get a value from the user
bool determine_vb(SmiUINT32 val, Vb &vb)
{
    char buffer[255];

    if (val == sNMP_SYNTAX_NOSUCHINSTANCE)
    {
        std::cout << "Instance does not exists but can be created.\n";
        std::cout << "Please enter one of the following types:\n\n";
        std::cout << "Integer:  " << sNMP_SYNTAX_INT << "\n";
        std::cout << "Bits:     " << sNMP_SYNTAX_BITS << "\n";
        std::cout << "STRING:   " << sNMP_SYNTAX_OCTETS << "\n";
        std::cout << "Oid:      " << sNMP_SYNTAX_OID << "\n";
        std::cout << "IpAddress:" << sNMP_SYNTAX_IPADDR << "\n\n";
        std::cout << "Please choose value type: ";
        std::cin >> val;
        vb.set_syntax(val);
    }
    std::cout << "Value Type is ";

    switch (val)
    {

    // octet string
    case sNMP_SYNTAX_OCTETS:
    {
        std::cout << "Octet String\n";
        std::cout << "Please enter new value: ";
        std::cin >> buffer;
        OctetStr octetstr(buffer);
        if (octetstr.valid())
        {
            vb.set_value(octetstr);
            return true;
        }
        else
        {
            std::cout << "Invalid OctetStr\n";
            return false;
        }
    }

        // IP Address
    case sNMP_SYNTAX_IPADDR:
    {
        std::cout << "IP Address\n";
        std::cout << "Please enter new value: ";
        std::cin >> buffer;
        IpAddress ipaddress(buffer);
        if (ipaddress.valid()) {
            vb.set_value(ipaddress);
            return true;
        }
        else {
            std::cout << "Invalid IP Address\n";
            return false;
        }
    }

        // Oid
    case sNMP_SYNTAX_OID:
    {
        std::cout << "Oid\n";
        std::cout << "Please enter new value: ";
        std::cin >> buffer;
        Oid oid(buffer);
        if (oid.valid()) {
            vb.set_value(oid);
            return true;
        }
        else {
            std::cout << "Invalid Oid\n";
            return false;
        }
    }

        // TimeTicks
    case sNMP_SYNTAX_TIMETICKS:
    {
        std::cout << "TimeTicks\n";
        std::cout << "Please enter new value: ";
        std::cin >> buffer;
        unsigned long i;
        i = atol(buffer);
        TimeTicks timeticks(i);
        if (timeticks.valid()) {
            vb.set_value(timeticks);
            return true;
        }
        else {
            std::cout << "Invalid TimeTicks\n";
            return false;
        }
    }

        // Gauge32
    case sNMP_SYNTAX_GAUGE32:
    {
        std::cout << "Gauge32\n";
        std::cout << "Please enter new value: ";
        std::cin >> buffer;
        unsigned long i;
        i = atol(buffer);
        Gauge32 gauge32(i);
        if (gauge32.valid()) {
            vb.set_value(gauge32);
            return true;
        }
        else {
            std::cout << "Invalid Gauge32\n";
            return false;
        }
    }

    case sNMP_SYNTAX_CNTR32:
    {
        std::cout << "Counter32\n";
        std::cout << "Please enter new value: ";
        std::cin >> buffer;
        unsigned long i;
        i = atol(buffer);
        Counter32 counter32(i);
        if (counter32.valid()) {
            vb.set_value(counter32);
            return true;
        }
        else {
            std::cout << "Invalid Counter32\n";
            return false;
        }
    }

    case sNMP_SYNTAX_CNTR64:
    {
        std::cout << "Counter64\n";
        std::cout << "Please enter value (low 32 bit): ";
        std::cin >> buffer;
        unsigned long i;
        i = atol(buffer);
        Counter64 counter64;
        counter64.set_low(i);

        std::cout << "Please enter value (high 32 bit): ";
        std::cin >> buffer;
        i = atol(buffer);
        counter64.set_high(i);

        if (counter64.valid()) {
            vb.set_value(counter64);
            return true;
        }
        else {
            std::cout << "Invalid Counter64\n";
            return false;
        }
    }

    case sNMP_SYNTAX_INT:
    {
        std::cout << "Integer\n";
        std::cout << "Please enter new value: ";
        std::cin >> buffer;
        unsigned long i;
        i = atol(buffer);
        long l ;
        l = (long) i;
        vb.set_value(l);
        return true;
    }

    case sNMP_SYNTAX_NOSUCHOBJECT:
    {
        std::cout << "NO SUCH OBJECT\n";
        std::cout << "Object cannot be created.\n";
        return false;
    }
    default:
        std::cout << "Unknown Data Type " << val << "\n";
        return false;
    }
}


int main(int argc, char **argv)
{


    DefaultLog::log()->set_filter(ERROR_LOG, 7);
    DefaultLog::log()->set_filter(WARNING_LOG, 7);
    DefaultLog::log()->set_filter(EVENT_LOG, 7);
    DefaultLog::log()->set_filter(INFO_LOG, 7);


    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
        std::cout << "Invalid Address or DNS Name, " << argv[1] << "\n";
    }
    Oid oid("1.3.6.1.2.1.1.1.101");      // default is sysName
    //---------[ 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
    OctetStr get_community;

        get_community = community;

    //----------[ 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)
    {
        std::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(get_community); // set the read community name
    ctarget.set_writecommunity(community);// set the write community name


    //-------[ issue the request, blocked mode ]-----------------------------
    std::cout << "SNMP++ Set to " << " Retries=" << retries<< " Timeout=" << timeout * 10 <<"ms";

    std::cout << " SET-community=" << community.get_printable()<< " GET-community=" << get_community.get_printable() << std::endl << std::flush;

    SnmpTarget *target;
    target = &ctarget;

    // first get the variabel to determine its type
    if ((status = snmp.get(pdu,*target))== SNMP_CLASS_SUCCESS)
    {
        pdu.get_vb(vb,0);
        std::cout << "Oid = " << vb.get_printable_oid() <<" "<< "Current Value = " << vb.get_printable_value() << std::endl;

        if (determine_vb(vb.get_syntax(), vb))
        {
            // do the Set
            Pdu setpdu;

            vb.set_oid(oid);           // use the same oid as the inquire
            setpdu += vb;
            status = snmp.set(setpdu, *target);
            std::cout << "Set Status = " << snmp.error_msg(status) << "\n";
        }
    }
    else
    {
        std::cout << "SNMP++ Set Error, " << snmp.error_msg(status) << "\n";
    }

    Snmp::socket_cleanup();  // Shut down socket subsystem
}

管理程序的运行截图:
在这里插入图片描述
此时以及获取到oid 对应的value ;我们将新的value 输入 然后发起set请求。
代理程序截图
管理程序截图

注意事项

1.读写权限

我们来看代理的代码部分:

       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")));

后面的加入的这四个对象,前面三个都是READONLY,最后一个是READWRITE类型的。所以我们再演示的时候也是用的最后一个oid,因为只要这个oid是可以读写的,前面都是只能读的。所以再进行这个操作时前提是这个oid对象是可以读写的。

2.value类型

这个new 的MibLeaf的值是字符串类型的也就是OctetStr,当然也可以是其它类型例如数字类型,sNMP_SYNTAX_INT32。所以我们再get的时候 需要判断value的类型是什么,来决定你的新输入的value是什么类型的。

总结

set操作用来改变某个oid所对应的value值。改变的方式就是发起get请求,看看这个oid的值是多少,然后将oid和新的value组成一个新的vb对象,将这个vb对象放进pdu对象里面,通过set操作发送过去。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SNMP++是一个C++库,用于实现SNMP(简单网络管理协议)的管理和监控。它提供了一组类和方法,可以用于构建SNMP管理应用程序。这些类和方法提供了SNMP的基本功能,例如,获取SNMP对象、设置SNMP对象、监视SNMP对象的值变化等等。下面是实现SNMP操作模块的一些步骤: 1. 下载SNMP++库并安装它。 2. 创建一个SNMP++的管理器对象,并设置SNMP协议版本、管理主机IP地址、管理主机SNMP团体名等参数。 3. 使用SNMP++提供的类和方法,实现SNMP的基本操作,例如,获取SNMP对象、设置SNMP对象、监视SNMP对象的值变化等等。 4. 将实现的SNMP操作模块集成到你的应用程序中,并根据需要进行调试和测试。 下面是一个简单的示例代码,用于获取并显示SNMP对象的值: ```c++ #include <iostream> #include "snmp_pp/snmp_pp.h" using namespace std; using namespace Snmp_pp; int main(int argc, char **argv) { int status; UdpAddress address("127.0.0.1/161"); Snmp snmp(status); if (status != SNMP_CLASS_SUCCESS) { cout << "SNMP++ Session Create Fail, Exit Program." << endl; return 1; } snmp_version version = version1; OctetStr community("public"); Pdu pdu; Vb vb; vb.set_oid("1.3.6.1.2.1.1.1.0"); pdu += vb; SnmpTarget target(address); target.set_version(version); target.set_retry(3); target.set_timeout(1000); target.set_readcommunity(community); SnmpErrorReport error; SnmpTarget *pTarget = &target; status = snmp.get(pdu, *pTarget, error); if (status == SNMP_CLASS_SUCCESS) { pdu.get_vb(vb, 0); cout << "SNMP Object Value: " << vb.get_printable_value() << endl; } else { cout << "SNMP Get Error: " << error.get_report() << endl; } return 0; } ``` 在上面的示例代码中,我们创建了一个SNMP++的管理器对象,并设置了SNMP协议版本、管理主机IP地址、管理主机SNMP团体名等参数。然后,我们使用SNMP++提供的类和方法,实现了SNMP的基本操作,即获取SNMP对象的值。最后,我们将这个示例代码集成到我们的应用程序中,并测试它的运行情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值