uxsnmp.cpp

来自「JdonFramework need above jdk 1.4.0 This」· C++ 代码 · 共 2,128 行 · 第 1/5 页

CPP
2,128
字号
          ((UTarget*)utarget)->set_engine_id(engine_id);        } // else: engineID="" --> automatic engineID discovery      }      // set context_engine_id of pdu, if it is not set      if (pdu.get_context_engine_id().len() == 0)      {        debugprintf(8, "Setting contextEngineID of Pdu to (%s)",                    engine_id.get_printable());        pdu.set_context_engine_id(engine_id);        backupPdu.set_context_engine_id(engine_id);      }      debugprintf(4,"Snmp::snmp_engine: engineID (%s), securityName (%s)"                  "securityModel (%i) security_level (%i)",                  engine_id.get_printable(), security_name.get_printable(),                  security_model, pdu.get_security_level());      debugprintf(4," Addr/Port (%s)",udp_address.get_printable());      status = snmpmsg.loadv3( pdu, engine_id, security_name,                               security_model, (snmp_version)version);    }    else#endif      status = snmpmsg.load( pdu, community_string,(snmp_version) version);    if ( status != SNMP_CLASS_SUCCESS)    {      debugprintf(0, "snmp message load error!");      return status;    }    //------[ send the request ]    lock();    status = send_snmp_request(iv_session_used,			       snmpmsg.data(), (size_t) snmpmsg.len(),			       udp_address);    unlock();    if ( status != 0)      return SNMP_CLASS_TL_FAILED;    if ((pdu_action == sNMP_PDU_RESPONSE) ||        (pdu_action == sNMP_PDU_REPORT))      return SNMP_CLASS_SUCCESS; // don't wait for an answer#ifdef _SNMPv3    if ((version == version3) && ((action == sNMP_PDU_GET_ASYNC) ||                                  (action == sNMP_PDU_SET_ASYNC) ||                                  (action == sNMP_PDU_GETNEXT_ASYNC) ||                                  (action == sNMP_PDU_GETBULK_ASYNC) ||                                  (action == sNMP_PDU_INFORM_ASYNC))) {      // add callback for v3      struct V3CallBackData *v3CallBackData;      v3CallBackData = new struct V3CallBackData;      v3CallBackData->pdu = new Pdu(pdu);      v3CallBackData->pdu->set_type(backupPdu.get_type());      v3CallBackData->non_reps = non_reps;      v3CallBackData->max_reps = max_reps;      v3CallBackData->target = new UTarget(*utarget);      v3CallBackData->oldCallback = cb;      v3CallBackData->cbd = cbd;      v3CallBackData->reports_received = reports_received;      // Add the message to the message queue      eventListHolder->snmpEventList()->AddEntry(req_id, this, iv_session_used,						 target, pdu,						 snmpmsg.data(),						 (size_t) snmpmsg.len(),						 udp_address,						 v3CallBack,						 (void *)v3CallBackData);    }    else#endif    {      eventListHolder->snmpEventList()->AddEntry( req_id, this,						  iv_session_used,						  target, pdu,						  snmpmsg.data(),						  (size_t) snmpmsg.len(),						  udp_address,						  cb, (void *)cbd);    }    //----[ if an async mode request then return success ]-----    if (( action == sNMP_PDU_GET_ASYNC) ||        ( action == sNMP_PDU_SET_ASYNC) ||        ( action == sNMP_PDU_GETNEXT_ASYNC) ||        ( action == sNMP_PDU_GETBULK_ASYNC) ||        ( action == sNMP_PDU_INFORM_ASYNC))      return SNMP_CLASS_SUCCESS;    // Now wait for the response (or timeout) for our message.    // This handles any necessary retries.    status = eventListHolder->SNMPBlockForResponse(req_id, pdu);    if (pdu.get_type() != REPORT_MSG) {#ifdef _SNMPv3      if (status == SNMPv3_MP_OK)        return SNMP_CLASS_SUCCESS;      else#endif        return status;    }#ifdef _SNMPv3    else      if (status == SNMPv3_USM_DECRYPTION_ERROR)        return status;    // We received a REPORT-MSG, check if we should try another time    Vb first_vb;    Oid first_oid;    pdu.get_vb(first_vb,0);    first_vb.get_oid(first_oid);    debugprintf(1,"received oid: %s with value: %s",                first_vb.get_printable_oid(), first_vb.get_printable_value());    debugprintf(1, "%s", error_msg(first_oid));    switch (maxloops)    {      case 0:      {	// This was our first try, so we may receive a unknown engine id 	// report or a not in time window report        if (first_oid == oidUsmStatsUnknownEngineIDs)        {	  pdu = backupPdu; // restore pdu and try again	  break;        }        else if (first_oid == oidUsmStatsNotInTimeWindows)        {          ++maxloops; // increase it, as the next request must succeed	  pdu = backupPdu; // restore pdu and try again	  break;        }        return (status == SNMPv3_MP_OK) ? SNMP_CLASS_SUCCESS : status;      }      case 1:      {	// This was the second try, engine id discovery should be ok	// so test only for not in time report        if (first_oid == oidUsmStatsNotInTimeWindows)        {	  pdu = backupPdu; // restore pdu and try again	  break;        }        return (status == SNMPv3_MP_OK) ? SNMP_CLASS_SUCCESS : status;      }      case 2:      {	// We tried three times: one for engine id discovery, one for	// time sync and we still get a report --> somethings wrong!        return (status == SNMPv3_MP_OK) ? SNMP_CLASS_SUCCESS : status;      }    }  }#endif  return status;}#ifdef _SNMPv3int Snmp::engine_id_discovery(OctetStr &engine_id,			      const int timeout_sec,			      const UdpAddress &addr){  unsigned char *message;  int message_length;  SnmpSocket sock;  SnmpMessage snmpmsg;  unsigned char snmpv3_message[60] = {    0x30, 0x3a,          0x02, 0x01, 0x03,                   // Version: 3          0x30, 0x0f,                         // global header length 15                0x02, 0x03, 0x01, 0x00, 0x00, // message id                0x02, 0x02, 0x10, 0x00,       // message max size                0x04, 0x01, 0x04,             // flags (reportable set)                0x02, 0x01, 0x03,             // security model USM          0x04, 0x10,                         // security params                0x30, 0x0e,                      0x04, 0x00,             // no engine id                      0x02, 0x01, 0x00,       // boots 0                      0x02, 0x01, 0x00,       // time 0                      0x04, 0x00,             // no user name                      0x04, 0x00,             // no auth par                      0x04, 0x00,             // no priv par          0x30, 0x12,                0x04, 0x00,                   // no context engine id                0x04, 0x00,                   // no context name          0xa0, 0x0c,                         // GET PDU                0x02, 0x02, 0x34, 0x26,       // request id                0x02, 0x01, 0x00,             // error status no error                0x02, 0x01, 0x00,             // error index 0                0x30, 0x00                    // no data  };  message = (unsigned char *)snmpv3_message;  message_length = 60;  engine_id.clear();  UdpAddress uaddr(addr);  if (uaddr.get_ip_version() == Address::version_ipv4)  {    if (iv_snmp_session != INVALID_SOCKET)      sock = iv_snmp_session;    else    {      uaddr.map_to_ipv6();      sock = iv_snmp_session_ipv6;    }  }  else    sock = iv_snmp_session_ipv6;  lock();  if (send_snmp_request(sock, message, message_length, uaddr) < 0)  {    debugprintf(0, "Error sending message.");    unlock();    return SNMP_CLASS_TL_FAILED;  }  // now wait for the responses  Pdu dummy_pdu;  fd_set readfds;  int nfound = 0;  struct timeval fd_timeout;  msec end_time;  end_time += timeout_sec * 1000;  do  {    FD_ZERO(&readfds);    FD_SET(sock, &readfds);    end_time.GetDeltaFromNow(fd_timeout);    nfound = select((int)(sock + 1), &readfds, NULL, NULL, &fd_timeout);    if ((nfound > 0) && (FD_ISSET(sock, &readfds)))    {      // receive message      UdpAddress from;      int res = receive_snmp_response(sock, *this, dummy_pdu,				      from, engine_id, true /* process_msg */);      if ((res == SNMP_CLASS_SUCCESS) ||	  (res == SNMPv3_MP_UNKNOWN_PDU_HANDLERS))      {	  //dummy_pdu.get_context_engine_id(engine_id);	debugprintf(3, "Response received from (%s) id %s.",		    from.get_printable(), engine_id.get_printable());	return SNMP_CLASS_SUCCESS;      }      else      {	debugprintf(0, "Error receiving discovery response.");      }    }  } while ((nfound > 0) ||	   (fd_timeout.tv_sec > 0) || (fd_timeout.tv_usec > 0));  unlock();  return SNMP_CLASS_TIMEOUT;}#endif// Send a SNMP Broadcast message.int Snmp::broadcast_discovery(UdpAddressCollection &addresses,			      const int timeout_sec,			      const UdpAddress &addr,			      const snmp_version version,			      const OctetStr *community){  unsigned char *message;  int message_length;  SnmpSocket sock;  SnmpMessage snmpmsg;#ifdef _SNMPv3  unsigned char snmpv3_broadcast_message[60] = {    0x30, 0x3a,          0x02, 0x01, 0x03,                   // Version: 3          0x30, 0x0f,                         // global header length 15                0x02, 0x03, 0x01, 0x00, 0x00, // message id                0x02, 0x02, 0x10, 0x00,       // message max size                0x04, 0x01, 0x04,             // flags (reportable set)                0x02, 0x01, 0x03,             // security model USM          0x04, 0x10,                         // security params                0x30, 0x0e,                      0x04, 0x00,             // no engine id                      0x02, 0x01, 0x00,       // boots 0                      0x02, 0x01, 0x00,       // time 0                      0x04, 0x00,             // no user name                      0x04, 0x00,             // no auth par                      0x04, 0x00,             // no priv par          0x30, 0x12,                0x04, 0x00,                   // no context engine id                0x04, 0x00,                   // no context name          0xa0, 0x0c,                         // GET PDU                0x02, 0x02, 0x34, 0x26,       // request id                0x02, 0x01, 0x00,             // error status no error                0x02, 0x01, 0x00,             // error index 0                0x30, 0x00                    // no data  };  if (version == version3)  {    message = (unsigned char *)snmpv3_broadcast_message;    message_length = 60;  }  else#endif  {    Pdu pdu;    Vb vb;    OctetStr get_community;    vb.set_oid("1.3.6.1.2.1.1.1.0");    pdu +=vb;    pdu.set_error_index(0);            // set error index to none    pdu.set_request_id(MyMakeReqId()); // determine request id to use    pdu.set_type(sNMP_PDU_GET);        // set pdu type    if (community)      get_community = *community;    else      get_community = "public";    int status = snmpmsg.load(pdu, get_community, version);    if (status != SNMP_CLASS_SUCCESS)    {      debugprintf(0, "Error encoding broadcast pdu (%i).", status);      return status;    }    message        = snmpmsg.data();    message_length = snmpmsg.len();  }  UdpAddress uaddr(addr);  if (uaddr.get_ip_version() == Address::version_ipv4)  {    if (iv_snmp_session != INVALID_SOCKET)      sock = iv_snmp_session;    else    {      uaddr.map_to_ipv6();      sock = iv_snmp_session_ipv6;    }  }  else    sock = iv_snmp_session_ipv6;  lock();  if (send_snmp_request(sock, message, message_length, uaddr) < 0)  {    debugprintf(0, "Error sending broadast.");    unlock();    return SNMP_CLASS_TL_FAILED;  }  // now wait for the responses  Pdu dummy_pdu;  OctetStr engine_id;  fd_set readfds;  int nfound = 0;  struct timeval fd_timeout;  msec end_time;  end_time += timeout_sec * 1000;  do  {    FD_ZERO(&readfds);    FD_SET(sock, &readfds);    end_time.GetDeltaFromNow(fd_timeout);    nfound = select((int)(sock + 1), &readfds, NULL, NULL, &fd_timeout);    if ((nfound > 0) && (FD_ISSET(sock, &readfds)))    {      // receive message      UdpAddress from;      if (receive_snmp_response(sock, *this, dummy_pdu,				from, engine_id, false /* process_msg */)	  == SNMP_CLASS_SUCCESS)      {	addresses += from;      }      else      {	debugprintf(0, "Error receiving broadcast response.");      }    }  } while ((nfound > 0) ||	   (fd_timeout.tv_sec > 0) || (fd_timeout.tv_usec > 0));  unlock();#ifdef __DEBUG  for (int i=0; i < addresses.size(); ++i)  {    debugprintf(3, "Broadcast response received from (%s).",		addresses[i].get_printable());  }#endif  return 0;}//     Starts the working thread for the recovery of the pending eventsbool Snmp::start_poll_thread(const int select_timeout){#ifdef _THREADS	    // store the timeout value for later    m_iPollTimeOut = select_timeout;    // if 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?