首页 > 解决方案 > SNMP:响应 PDU 太大

问题描述

我需要测试一个基于snmp++库的驱动代码。当我启动这个驱动代码时,我打印出如下错误日志

我用的是SNMP++v3.2.25,在网络上找到了一个SNMP模拟器,发给SNMP驱动,还是打印出错误日志

我使用的 SNMP 模拟器是 SnmpTrapGen V1.1。我在 CMD 命令中发送了

int ScsSnmp::init_snmp()
{
    Snmp::socket_startup();
    int status;
//  UdpAddress address(m_local_addr);
    m_snmp = new Snmp(status/*,address*/);
    if (( m_snmp == NULL) || ( status != SNMP_CLASS_SUCCESS))
    {
        printlog(LOGE_SNMP + m_link,"constructing Snmp Object failed ");
    }
    else
    {
        TargetCollection targets;
        OidCollection trapids;
        Oid trapoid = OidAlarmReportNotificationType;
        Oid heartoid = OidHeartbeatNotificationType;
        trapids += trapoid;
        trapids += heartoid;
        m_snmp->notify_set_listen_port(TRAP_LISTEN_PORT);
        ScsSnmp* myself = this;
        if ( status = m_snmp->notify_register( trapids, targets,my_trap_callback,myself) != SNMP_CLASS_SUCCESS)
        {
            printlog(LOGE_SNMP + m_link,"Snmp Trap Register Error : %s ",m_snmp->error_msg(status));
            return -1;
        }
        m_snmp->start_poll_thread(1000);    //1000ms
    }
    return 0;
}

void ScsSnmp::my_trap_callback (int reason, Snmp *session,Pdu &pdu, SnmpTarget &target, void *data)
{
    ScsSnmp* scssnmp = (ScsSnmp*)data;
    printlog(LOGE_SNMP + scssnmp->m_link,"start my_trap_callback");
    if ( reason == SNMP_CLASS_NOTIFICATION) 
    {
        Vb nextVb;
        GenAddress addr;
        target.get_address(addr);
        IpAddress from(addr);   
        Oid notify_id,ent;
        pdu.get_notify_id(notify_id);
        pdu.get_notify_enterprise(ent);
        if (notify_id == OidAlarmReportNotificationType)
        {
            memset(scssnmp->m_alarm_msg,0,128);
            memset(scssnmp->m_alarm_info.station,0,64);
            memset(scssnmp->m_alarm_info.subsystem,0,64);
            memset(scssnmp->m_alarm_info.devicetype,0,64);
            memset(scssnmp->m_alarm_info.device,0,64);
            memset(scssnmp->m_alarm_info.alarm_msg,0,128);
            for (int i = 0;i<pdu.get_vb_count();i++)
            {
                pdu.get_vb(nextVb, i);
                scssnmp->process_alarm_vb(nextVb);
            }
            memset(scssnmp->m_alarm_buf,0,512);
            memcpy(scssnmp->m_alarm_buf,&scssnmp->m_alarm_head,sizeof(alarm_head));
            memcpy(scssnmp->m_alarm_buf+sizeof(alarm_head),&scssnmp->m_alarm_info,sizeof(alarm_event_info));
            bool ret = scssnmp->m_ctrl_inf->addAlarm(scssnmp->m_alarm_buf,512);
            if (ret)
            {
                printlog(LOGE_SNMP + scssnmp->m_link,"add an event alarm success !");
            }
            else
            {
                printlog(LOGE_SNMP + scssnmp->m_link,"add an event alarm failed !");
            }

        }
        else if (notify_id == OidHeartbeatNotificationType)
        {
            printlog(LOGE_SNMP + scssnmp->m_link,"get a heartbeat !");
        }
        else
        {
            printlog(LOGE_SNMP + scssnmp->m_link,"Trap notify id is wrong,id=%s",notify_id.get_printable());
        }

    }
    else
    {
        printlog(LOGE_SNMP + scssnmp->m_link,"Trap Receive Error = ",session->error_msg(reason));
    }
    printlog(LOGE_SNMP + scssnmp->m_link,"end my_trap_callback");
}

我想通过模拟器发送SNMP陷阱。然后SNMP驱动接收数据并打印出来。简单地说,你想测试数据接口是否工作。但实际接收接口不断打印错误日志

标签: snmp

解决方案


我们之前遇到过这种情况,但它在 snmp get 响应中。这总是表示响应 pdu 大于 65535 字节。在端口 162 上进行数据包捕获将提供更清晰的验证。当我们在 snmp get 请求中遇到这个问题时,我们减少了每个请求中发送的 OID 的数量来解决这个问题。


推荐阅读