uxsnmp.cpp

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

CPP
2,128
字号
/*_############################################################################  _##   _##  uxsnmp.cpp    _##  _##  SNMP++v3.2.21a  _##  -----------------------------------------------  _##  Copyright (c) 2001-2006 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.   _##    _##  Stuttgart, Germany, Tue Nov 21 22:12:16 CET 2006   _##    _##########################################################################*//*===================================================================      U X S N M P . C P P      UXSNMP CLASS DECLARATION      Description:    HPUX version of Snmp class      Language:       ANSI C++      Author:         Peter E Mellquist=====================================================================*/char snmp_cpp_version[]="#(@) SNMP++ $Id: uxsnmp.cpp,v 1.33 2006/10/04 21:06:22 katz Exp $";/* CK Ng    added support for WIN32 in the whole file *///-----[ includes ]----------------------------------------------------#ifdef WIN32#include <winsock.h>#include <sys/types.h>     // system types#include <sys/timeb.h>     // _timeb and _ftime#else#include <unistd.h>        // unix#include <sys/socket.h>    // bsd socket stuff#include <netinet/in.h>    // network types#include <arpa/inet.h>     // arpa types#include <sys/types.h>     // system types#if !(defined CPU && CPU == PPC603)#include <sys/time.h>      // time stuff#endif#endif#ifdef _AIX#define ss_family __ss_family#endif#include <stdlib.h>        // need for malloc#include <errno.h>         // ux errs#define _INCLUDE_SNMP_ERR_STRINGS//----[ snmp++ includes ]----------------------------------------------#include "snmp_pp/uxsnmp.h"        // class def for this module#include "snmp_pp/oid_def.h"       // class def for well known trap oids#include "snmp_pp/v3.h"#include "snmp_pp/msgqueue.h"      // message queue#include "snmp_pp/notifyqueue.h"   // notification queue#include "snmp_pp/snmpmsg.h"       // asn serialization class#include "snmp_pp/eventlistholder.h"#include "snmp_pp/usm_v3.h"#include "snmp_pp/vb.h"#include "snmp_pp/log.h"#if defined (CPU) && CPU == PPC603#include <sockLib.h> #include <taskLib.h> #endif#ifdef SNMP_PP_NAMESPACEnamespace Snmp_pp {#endif//-----[ special includes ]-------------------------------------------extern "C"{  //------------[ if using Wind-U, then bring in the ms-windows header ]#ifndef WIN32#ifdef WU_APP  WORD app_hinst;#else  typedef short WORD;  typedef long DWORD;#endif#endif}//-----[ macros ]------------------------------------------------------#define DEFAULT_TIMEOUT 1000  // one second default timeout#define DEFAULT_RETRIES 1     // no retry default#define SNMP_PORT 161         // port # for SNMP#define SNMP_TRAP_PORT 162    // port # for SNMP traps#ifdef WIN32#ifdef __BCPLUSPLUS__#define _timeb timeb#define _ftime ftime#endif#define close closesocket#endif//--------[ globals ]---------------------------------------------------//--------------[ well known trap ids ]-----------------------------------const coldStartOid coldStart;const warmStartOid warmStart;const linkDownOid linkDown;const linkUpOid linkUp;const authenticationFailureOid authenticationFailure;const egpNeighborLossOid egpNeighborLoss;const snmpTrapEnterpriseOid snmpTrapEnterprise;#ifdef _SNMPv3void v3CallBack(int reason, Snmp *snmp, Pdu &pdu, SnmpTarget &target, void *v3cd){  Snmp::V3CallBackData *cbData;  cbData = (Snmp::V3CallBackData*)v3cd;  Vb tmpvb;  pdu.get_vb(tmpvb,0);  debugprintf(5, "v3CallBack: received oid: %s with value: %s",              tmpvb.get_printable_oid(), tmpvb.get_printable_value());  debugprintf(5, "v3CallBack: error_msg (%s), pdu_type (%i)",	      snmp->error_msg(tmpvb.get_oid()), pdu.get_type());  if ((pdu.get_type() == REPORT_MSG) &&      (((tmpvb.get_oid() == oidUsmStatsUnknownEngineIDs) &&	(cbData->reports_received == 0)) ||       ((tmpvb.get_oid() == oidUsmStatsNotInTimeWindows) &&	(cbData->reports_received <= 1)))) {    // hide those reports from user    int rc;    if ((cbData->pdu) && (cbData->target)) {      rc = snmp->snmp_engine(*(cbData->pdu), cbData->non_reps,                             cbData->max_reps, *(cbData->target),                             (snmp_callback)(cbData->oldCallback),                             (void *)cbData->cbd, INVALID_SOCKET,			     cbData->reports_received + 1);      debugprintf(3,"v3CallBack: snmp_engine called, rc (%i)", rc);    }    else      rc = SNMP_CLASS_ERROR;    if (rc != SNMP_CLASS_SUCCESS) {      // call callback if snmp_engine failed or pdu or target was 0      debugprintf(3,"v3CallBack: calling user callback");      snmp_callback tmp_callBack;      tmp_callBack = (snmp_callback)(cbData->oldCallback);      tmp_callBack(rc, snmp, pdu, target, (void *)cbData->cbd);    }  }  else {    debugprintf(3,"v3CallBack: calling user callback");    snmp_callback tmp_callBack;    tmp_callBack = (snmp_callback)(cbData->oldCallback);    tmp_callBack(reason, snmp, pdu, target, (void *)cbData->cbd);  }  // save to delete it here, because either snmp_engine created a new  // callback entry or the user specified callback has been called  if (cbData->pdu) {    delete cbData->pdu;    cbData->pdu = 0;  }  if (cbData->target) {    delete cbData->target;    cbData->target = 0;  }  delete cbData;  return;}#endif//--------[ make the pdu request id ]-----------------------------------// return a unique rid, clock can be too slow , so use current_ridlong Snmp::MyMakeReqId(){  long rid;  eventListHolder->snmpEventList()->lock();  do {    rid = ++current_rid;#ifdef INVALID_REQID    debugprintf(-10, "\nWARNING: Using constand RequestID!\n");    rid = 0xc0de;#endif    if ( current_rid > PDU_MAX_RID)    {      current_rid = rid = PDU_MIN_RID;      // let other tasks proceed      eventListHolder->snmpEventList()->unlock();      struct timeval tv;      tv.tv_sec = 0;      tv.tv_usec = 100;      select(0, 0, 0, 0, &tv);      eventListHolder->snmpEventList()->lock();    }  } while (eventListHolder->snmpEventList()->GetEntry(rid));  eventListHolder->snmpEventList()->unlock();  return rid;}//---------[ Send SNMP Request ]---------------------------------------// Send out a snmp requestDLLOPT int send_snmp_request(SnmpSocket sock, unsigned char *send_buf,                             size_t send_len, Address & address){  // UX only supports UDP type addresses (addr and port) right now  if (address.get_type() != Address::type_udp)    return -1;// unsupported address type  debugprintf(1, "++ SNMP++: sending to %s:",              ((UdpAddress &)address).UdpAddress::get_printable());  debughexprintf(5, send_buf, SAFE_UINT_CAST(send_len));  int send_result;  if (((UdpAddress &)address).get_ip_version() == Address::version_ipv4)  {    // prepare the destination address    struct sockaddr_in agent_addr;  // send socket struct    memset(&agent_addr, 0, sizeof(agent_addr));    agent_addr.sin_family = AF_INET;    agent_addr.sin_addr.s_addr              = inet_addr(((IpAddress &)address).IpAddress::get_printable());    agent_addr.sin_port = htons(((UdpAddress &)address).get_port());    send_result = sendto(sock, (char*) send_buf, SAFE_INT_CAST(send_len), 0,                         (struct sockaddr*) &agent_addr, sizeof(agent_addr));  }  else  {#ifdef SNMP_PP_IPv6    struct sockaddr_in6 agent_addr;    memset(&agent_addr, 0, sizeof(agent_addr));    inet_pton(AF_INET6, ((IpAddress &)address).IpAddress::get_printable(),              &agent_addr.sin6_addr);    agent_addr.sin6_family = AF_INET6;    agent_addr.sin6_port = htons(((UdpAddress &)address).get_port());    send_result = sendto( sock, (char*) send_buf, send_len, 0,                          (struct sockaddr*) &agent_addr, sizeof(agent_addr));#else    debugprintf(0, "User error: Enable IPv6 and recompile snmp++.");    return -1;#endif  }  if (send_result < 0)  {    debugprintf(0, "Error sending packet: %s", strerror(errno));    return -1; // send error!  }  return 0;}//---------[ receive a snmp response ]---------------------------------// Receive a response from the specified socket.// This function does not set the request id in the pdu if// any error occur in receiving or parsing.  This is important// because the caller initializes this to zero and checks it to// see whether it has been changed to a valid value.  The// return value is the normal PDU status or SNMP_CLASS_SUCCESS.// when we are successful in receiving a pdu.  Otherwise it// is an error status.int receive_snmp_response(SnmpSocket sock, Snmp &snmp_session,                          Pdu &pdu, UdpAddress &fromaddress,			  OctetStr &engine_id, bool process_msg = true){  unsigned char receive_buffer[MAX_SNMP_PACKET + 1];  long receive_buffer_len; // len of received data#ifdef SNMP_PP_IPv6  struct sockaddr_storage from_addr;#else  struct sockaddr_in from_addr;#endif#if !(defined (CPU) && CPU == PPC603) && (defined __GNUC__ || defined __FreeBSD__ || defined _AIX) && ! defined __MINGW32__  socklen_t fromlen;#else  int fromlen;#endif  fromlen = sizeof(from_addr);  memset(&from_addr, 0, sizeof(from_addr));  // do the read  do {    receive_buffer_len = (long) recvfrom(sock, (char *) receive_buffer,                                         MAX_SNMP_PACKET + 1, 0,                                         (struct sockaddr*) &from_addr,                                         &fromlen);    debugprintf(2, "++ SNMP++: something received...");  } while ((receive_buffer_len < 0) && (EINTR == errno));  if (receive_buffer_len < 0 )                // error or no data pending    return SNMP_CLASS_TL_FAILED;  debugprintf(6, "Length received %i from socket %i; fromlen %i",              receive_buffer_len, sock, fromlen);  if (receive_buffer_len == MAX_SNMP_PACKET + 1)  {    // Message is too long...    debugprintf(1, "Received message is ignored (packet too long)");    return SNMP_CLASS_ERROR;  }  if (((sockaddr_in&)from_addr).sin_family == AF_INET)  {    // IPv4    fromaddress = inet_ntoa(((sockaddr_in&)from_addr).sin_addr);    fromaddress.set_port(ntohs(((sockaddr_in&)from_addr).sin_port));  }#ifdef SNMP_PP_IPv6  else if (from_addr.ss_family == AF_INET6)  {    // IPv6    char tmp_buffer[INET6_ADDRSTRLEN+1];    inet_ntop(AF_INET6, &(((sockaddr_in6&)from_addr).sin6_addr),              tmp_buffer, INET6_ADDRSTRLEN);    fromaddress = tmp_buffer;    fromaddress.set_port(ntohs(((sockaddr_in6&)from_addr).sin6_port));  }#endif // SNMP_PP_IPv6  else  {    debugprintf(0, "Unknown socket address family (%i).",                ((sockaddr_in&)from_addr).sin_family);    return SNMP_CLASS_ERROR;  }  debugprintf(1, "++ SNMP++: data received from %s.",              fromaddress.get_printable());  debughexprintf(5, receive_buffer, receive_buffer_len);  if (process_msg == false)    return SNMP_CLASS_SUCCESS;   // return success  SnmpMessage snmpmsg;  if ( snmpmsg.load( receive_buffer, receive_buffer_len) != SNMP_CLASS_SUCCESS)    return SNMP_CLASS_ERROR;  OctetStr community_name;  snmp_version version;  OctetStr security_name;#ifdef _SNMPv3  long int security_model;  if (snmpmsg.is_v3_message() == TRUE)  {    int returncode = snmpmsg.unloadv3(pdu, version, engine_id,                                      security_name, security_model,                                      fromaddress, snmp_session);    if (returncode != SNMP_CLASS_SUCCESS)      return returncode;  }  else  {#endif    int returncode = snmpmsg.unload( pdu, community_name, version);    if (returncode != SNMP_CLASS_SUCCESS)      return SNMP_CLASS_ERROR;#ifdef _SNMPv3  }  if (version == version3)  {    debugprintf(4,"receive_snmp_response: engine_id (%s), security_name (%s), "		"security_model (%i), security_level (%i)",                engine_id.get_printable(), security_name.get_printable(),                security_model, pdu.get_security_level());    debugprintf(5," addtoengineidtable: (%s)",                (unsigned char*)fromaddress.get_printable());  }#endif  //-----[ check for error status stuff..]  // an error status is a valid pdu,  // the caller needs to know about it  if ( pdu.get_error_status() != 0)    return pdu.get_error_status();  debugprintf(5,"receive_snmp_response requestID = %li, "	      "returning SUCCESS.", pdu.get_request_id());  return SNMP_CLASS_SUCCESS;   // Success! return}//---------[ receive a snmp trap ]---------------------------------// Receive a trap from the specified socket// note: caller has to delete target!int receive_snmp_notification(SnmpSocket sock, Snmp &snmp_session,                              Pdu &pdu, SnmpTarget **target){  unsigned char receive_buffer[MAX_SNMP_PACKET + 1];  long receive_buffer_len; // len of received data#ifdef SNMP_PP_IPv6  struct sockaddr_storage from_addr;

⌨️ 快捷键说明

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