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 + -
显示快捷键?