snmp.cpp
资源名称:hp_snmp3.zip [点击查看]
上传用户:czjinwang
上传日期:2007-01-12
资源大小:2484k
文件大小:88k
源码类别:
SNMP编程
开发平台:
Visual C++
- /*===================================================================
- Copyright (c) 1999
- 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
- makes 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.
- S N M P . C P P
- SNMP CLASS IMPLEMENATION FOR WINDOWS WIN32
- DESCRIPTION:
- This module contains the implementation of the SNMP and
- transport init/deinit functions.
- LANGUAGE:
- ANSI C++
- OPERATING SYSTEM:
- Win32
- DESIGN:
- Peter E Mellquist
- AUTHOR:
- Peter E Mellquist
- =====================================================================*/
- char snmp_cpp_version[]="#(@)SNMP++ 2.8 $Header: snmp.cpp,v 1.25 96/09/11 14:02:06 hmgr Exp $";
- //-----[ External C includes ]-----------------------------------------
- extern "C"
- {
- #include "winsnmp.h" // winsnmp include file
- #include <stdio.h> // standard io
- }
- #define _INCLUDE_SNMP_ERR_STRINGS
- //-----[ SNMP++ Includes ]--------------------------------------------
- #include "oid.h" // class def for oids
- #include "vb.h" // class def for vbs
- #include "snmp_pp.h" // class def for this module
- #include "pdu_cont.h" // pdu container class def
- //-----[ macros ]------------------------------------------------------
- #define MAX_DOTTED_OID_SIZE 255 // maximum size for a dotted string
- #define SNMP_MSG WM_USER+176 // winsnmp callback msg
- #define SNMP_GWW_HINSTANCE -6 // gww instance
- //-----[ snmp engine variables ]---------------------------------------
- static char SzSnmpClass[] = "sppcls32"; // pdu handler registered name
- DLLOPT Pdu_Container *pdu_container; // pointer to pdu container class
- int pdu_ref_count=0; // reference count of transport
- int snmp_ref_count=0; // reference count for xport
- // mutual exclusion variables for thread safety
- CRITICAL_SECTION my_critical_section;
- #define SNMP_WAIT EnterCriticalSection( &my_critical_section)
- #define SNMP_SIGNAL LeaveCriticalSection( &my_critical_section)
- //-----[ Trap Builder API ]----------------------------------------
- typedef SNMPAPI_STATUS (PASCAL *functionTrap)( HSNMP_PDU, smiLPOID, smiLPIPADDR, smiLPINT, smiLPINT, smiLPTIMETICKS);
- //-----[ port setting API ]-----------------------------------------
- typedef SNMPAPI_STATUS (PASCAL *functionPortSet) (HSNMP_ENTITY hEntity,WORD port);
- //--------------[ well known trap ids ]-----------------------------------
- // SMI trap oid def
- class snmpTrapsOid: public Oid {
- public:
- snmpTrapsOid (void):Oid("1.3.6.1.6.3.1.1.5"){};
- };
- // SMI Enterprose Oid
- class snmpTrapEnterpriseOid: public Oid {
- public:
- snmpTrapEnterpriseOid(void):Oid("1.3.6.1.6.3.1.1.4.3.0"){};
- };
- // SMI Cold Start Oid
- class coldStartOid: public snmpTrapsOid {
- public:
- coldStartOid( void){*this+=".1";};
- };
- // SMI WarmStart Oid
- class warmStartOid: public snmpTrapsOid {
- public:
- warmStartOid( void){*this+=".2";};
- };
- // SMI LinkDown Oid
- class linkDownOid: public snmpTrapsOid {
- public:
- linkDownOid( void){*this+=".3";};
- };
- // SMI LinkUp Oid
- class linkUpOid: public snmpTrapsOid {
- public:
- linkUpOid( void){*this+=".4";};
- };
- // SMI Authentication Failure Oid
- class authenticationFailureOid: public snmpTrapsOid {
- public:
- authenticationFailureOid( void){*this+=".5";};
- };
- // SMI egpneighborloss Oid
- class egpNeighborLossOid: public snmpTrapsOid {
- public:
- egpNeighborLossOid( void){*this+=".6";};
- };
- const coldStartOid coldStart;
- const warmStartOid warmStart;
- const linkDownOid linkDown;
- const linkUpOid linkUp;
- const authenticationFailureOid authenticationFailure;
- const egpNeighborLossOid egpNeighborLoss;
- const snmpTrapEnterpriseOid snmpTrapEnterprise;
- //-----------------------------------------------------------------------
- //--------[ extract_from_varbindlist ]-----------------------------------
- //-----------------------------------------------------------------------
- // loop through all vbs in the VArbind list extracting each
- // vb into the SNMP++ Vb ojbects
- int extract_from_varbindlist( HSNMP_VBL hRecvVbl, // handle to winsnmp vbl
- Pdu &pdu) // Snmp++ Pdu to extract into
- {
- int z; // looping variable
- SNMPAPI_STATUS vb_status; // status of VB extract
- smiVALUE SnmpValue; // A received value
- smiOID RecvOid; // a received oid
- char stroid[MAX_DOTTED_OID_SIZE]; // string oid
- TimeTicks tt; // timeticks object
- Counter32 ctr; // counter object
- Gauge32 gge; // gauge object
- Vb tempvb; // temp vb object
- int vb_count; // count of pdu vbs
- //-----[ delete existing vblist from pdu ] --------------------------
- pdu.set_vblist(&tempvb, 0);
- //-----[ loop through and extract response vb's] --------------------
- SNMPDEBUG("++ SNMP++, In Extract From Vb List n");
- vb_count = SnmpCountVbl( hRecvVbl);
- for (z=1;z<=vb_count;z++)
- {
- // get the vb
- SNMPDEBUG("++ SNMP++, Get VB n");
- vb_status = SnmpGetVb( hRecvVbl,
- z,
- &RecvOid,
- &SnmpValue);
- // if it is a good status then extract
- // it into the vb object else the
- // error index should point to it
- // so we just skip it
- //
- // if the status was successful,
- // then we need to copy the oid
- // and value portions to the vb object
- // when finished, we need to free the oid
- // and the smivalue portion if its an oid or octet
- if ( vb_status == SNMPAPI_SUCCESS)
- {
- // copy the smivalue data into the vb object
- // to be returned
- SnmpOidToStr( &RecvOid,MAX_DOTTED_OID_SIZE,stroid);
- tempvb.set_oid(stroid);
- // clean up memory created by WinSnmp
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &RecvOid);
- switch( SnmpValue.syntax)
- {
- // null , do nothing
- case SNMP_SYNTAX_NULL:
- case SNMP_SYNTAX_NOSUCHOBJECT:
- case SNMP_SYNTAX_NOSUCHINSTANCE:
- case SNMP_SYNTAX_ENDOFMIBVIEW:
- break;
- // octects
- case SNMP_SYNTAX_OCTETS:
- case SNMP_SYNTAX_BITS:
- case SNMP_SYNTAX_OPAQUE:
- {
- OctetStr octetstr( (unsigned char far *) SnmpValue.value.string.ptr,
- ( size_t) SnmpValue.value.string.len);
- tempvb.set_value( octetstr);
- SnmpFreeDescriptor( SNMP_SYNTAX_OCTETS,
- (smiLPOPAQUE)&SnmpValue.value.string );
- }
- break;
- // ip addresses
- case SNMP_SYNTAX_IPADDR:
- {
- IpAddress ipa("0.0.0.0"); // make it valid first
- ipa[0] = SnmpValue.value.string.ptr[0];
- ipa[1] = SnmpValue.value.string.ptr[1];
- ipa[2] = SnmpValue.value.string.ptr[2];
- ipa[3] = SnmpValue.value.string.ptr[3];
- tempvb.set_value( ipa);
- SnmpFreeDescriptor( SNMP_SYNTAX_IPADDR,
- (smiLPIPADDR) &SnmpValue.value.string );
- }
- break;
- // oid
- case SNMP_SYNTAX_OID:
- {
- SnmpOidToStr( &SnmpValue.value.oid,MAX_DOTTED_OID_SIZE,stroid);
- Oid oidvb(stroid);
- tempvb.set_value( oidvb);
- SnmpFreeDescriptor( SNMP_SYNTAX_OID,
- (smiLPOPAQUE)&SnmpValue.value.oid );
- }
- break;
- // int 32
- case SNMP_SYNTAX_INT32:
- tempvb.set_value( (signed long int) SnmpValue.value.sNumber);
- break;
- // time ticks
- case SNMP_SYNTAX_TIMETICKS:
- tt = (unsigned long) SnmpValue.value.uNumber;
- tempvb.set_value( tt);
- break;
- // counter
- case SNMP_SYNTAX_CNTR32:
- ctr = (unsigned long) SnmpValue.value.uNumber;
- tempvb.set_value( ctr);
- break;
- // gauge
- case SNMP_SYNTAX_GAUGE32:
- gge = (unsigned long) SnmpValue.value.uNumber;
- tempvb.set_value( gge);
- break;
- // u int 32
- case SNMP_SYNTAX_UINT32:
- tempvb.set_value( (unsigned long int) SnmpValue.value.uNumber);
- break;
- // 64 bit counter
- case SNMP_SYNTAX_CNTR64:
- Counter64 c64( (unsigned long int) SnmpValue.value.hNumber.hipart,
- (unsigned long int) SnmpValue.value.hNumber.lopart);
- tempvb.set_value( c64);
- break;
- } // end switch
- } // end if vb status is good
- pdu += tempvb;
- } // end for all vb's
- SNMPDEBUG("++ SNMP++, End Extract From Vblist n");
- return 0;
- } // end extract_from_varbindlist
- //-------------------[ returns error string ]--------------------------
- char * Snmp::error_msg( const int c)
- {
- return ((c<0)?
- ((c<MAX_NEG_ERROR)?nErrs[-(MAX_NEG_ERROR)+1]:nErrs[-c]):
- ((c>MAX_POS_ERROR)?pErrs[MAX_POS_ERROR+1]:pErrs[c]));
- }
- //-----------------------------------------------------------------------
- //--------------------[ async handler ]----------------------------------
- //-----------------------------------------------------------------------
- // Prepares the async message to be callled to the
- // callback function
- void FAR process_async_event( int reason,
- long int lnRecvRequestId,
- HSNMP_SESSION session_handle,
- smiINT lnErrorStatus,
- smiINT lnErrorIndex,
- HSNMP_VBL hRecvVbl,
- HSNMP_CONTEXT hRecvContext,
- HSNMP_ENTITY hDstRecvEnt,
- Snmp* spp_session,
- snmp_callback callback,
- void * personality)
- {
- int vb_count; // number of vbs
- Vb* vbs; // vbs, dynamically instantiated
- SNMPAPI_STATUS gen_status; // status of getting a vb
- unsigned char agent_addr[40]; // agent address space
- smiOCTETS octet_community; // octet community name
- unsigned char community_name[255]; // community name for async passing
- CTarget v1target; // v1 target to use
- Pdu pdu; // instantiated pdu object
- // get the var bind list from WinSnmp
- // if vb count is zero then nothing to
- // do return out;
- vb_count = (int) SnmpCountVbl( hRecvVbl);
- if ( vb_count == 0)
- {
- SNMPDEBUG("-- SNMP++, Async Handler Vb count = 0n");
- (callback)( reason, // reason
- (Snmp*) spp_session, // snmp++ session who own the req
- (Pdu&) pdu, // pdu
- (SnmpTarget&) v1target, // target
- (void*) personality); // callback data
- return;
- }
- // dynamically instantiate a list of
- // Vb obejcts
- // return if new error
- vbs = new Vb[vb_count];
- if ( vbs == 0)
- {
- SNMPDEBUG("-- SNMP++, Async Handler new Vb Failn");
- return; // if new error then return
- }
- // stuff them into the pdu
- pdu.set_vblist( (Vb*) vbs, vb_count);
- // extract vbs from WinSNMP var bind list into
- // Snmp++ pdu objects
- extract_from_varbindlist( hRecvVbl, pdu);
- //------[ prepare the agent address ]-------------------------------------
- gen_status = SnmpEntityToStr( hDstRecvEnt,40, (char *) agent_addr);
- if ( gen_status == SNMPAPI_FAILURE)
- {
- delete [] vbs; // free the snmp++ vbs
- SNMPDEBUG("-- SNMP++, Async Handler SnmpEntityToStr Failn");
- return; // error case, don't call callback
- }
- //-----[ prepare the agents context ]-------------------------------------
- gen_status = SnmpContextToStr( hRecvContext, &octet_community);
- if ( gen_status == SNMPAPI_FAILURE)
- {
- delete [] vbs; // free the snmp++ vbs
- SNMPDEBUG("-- SNMP++, Async Handler SnmpContextToStr Failn");
- return; // error case, don't call callback
- }
- //----[ copy SMI octet community into an unsigned char community ]
- // protect againt over running the target string
- MEMCPY( community_name,
- octet_community.ptr,
- (size_t) min(octet_community.len,40));
- //------[ make an target object for the callback ]----------------------
- // set the address portion of the target
- IpxAddress ipxaddress( (char*) agent_addr);
- if ( ipxaddress.valid())
- v1target.set_address( ipxaddress);
- else {
- IpAddress ipaddress( (char*) agent_addr);
- if( ipaddress.valid())
- v1target.set_address( ipaddress);
- else
- return; //unknown address format
- }
- // fill in the community names
- OctetStr rc( (const unsigned char *) octet_community.ptr, octet_community.len);
- v1target.set_readcommunity( rc);
- v1target.set_writecommunity( rc);
- //------[ make up a pdu onject ]------------------------------------------
- set_request_id( &pdu, lnRecvRequestId); // friend function call
- set_error_status( &pdu, (int) lnErrorStatus);
- set_error_index( &pdu, (int) lnErrorIndex);
- // change the pdu type for responses
- if ( reason == SNMP_CLASS_ASYNC_RESPONSE)
- pdu.set_type( SNMP_PDU_RESPONSE);
- //------[ call into the callback function ]-------------------------------
- (callback)( reason, // reason
- (Snmp*) spp_session, // snmp++ session who own the req
- (Pdu&) pdu, // pdu
- (SnmpTarget&) v1target, // target
- (void*) personality); // callback data
- //------[ free up the vbs ]
- delete [] vbs;
- //------[ free up winsnmp vars ]------------------------------------------
- SnmpFreeDescriptor( SNMP_SYNTAX_OCTETS, (smiLPOPAQUE) &octet_community);
- };
- //-----------------------------------------------------------------------
- //--------------------[ trap handler ]----------------------------------
- //-----------------------------------------------------------------------
- // Prepares the trap message to be callled to the
- // trap callback function
- void FAR process_trap_event( int reason,
- long int lnRecvRequestId,
- HSNMP_SESSION session_handle,
- smiINT lnErrorStatus,
- smiINT lnErrorIndex,
- HSNMP_VBL hRecvVbl,
- HSNMP_CONTEXT hRecvContext,
- HSNMP_ENTITY hDstRecvEnt,
- Snmp* spp_session,
- snmp_callback callback,
- void * personality)
- {
- int vb_count; // number of vbs
- Vb* vbs; // vbs, dynamically instantiated
- SNMPAPI_STATUS gen_status; // status of getting a vb
- unsigned char agent_addr[40]; // agent address space
- smiOCTETS octet_community; // octet community name
- unsigned char community_name[255]; // community name for async passing
- CTarget target; // v1 target to use
- Pdu pdu,sendpdu; // instantiated pdu object
- TimeTicks timestamp; // timestamp on trap
- Oid trapid; // type of trap
- Oid enterprise; // enterprise of a trap
- SNMPDEBUG("++ SNMP++, In Process Trap Eventn");
- // get the var bind list from WinSnmp
- // if vb count is zero then nothing to
- // do return out;
- vb_count = (int) SnmpCountVbl( hRecvVbl);
- if ( vb_count == 0)
- {
- SNMPDEBUG("-- SNMP++, Trap Handler Vb count = 0n");
- return;
- }
- // dynamically instantiate a list of
- // Vb obejcts
- // return if new error
- vbs = new Vb[vb_count];
- if ( vbs == 0)
- {
- SNMPDEBUG("-- SNMP++, Trap Handler new Vb Failn");
- return; // if new error then return
- }
- // stuff them into the pdu
- pdu.set_vblist( (Vb*) vbs, vb_count);
- // extract vbs from WinSNMP var bind list into
- // Snmp++ pdu objects
- extract_from_varbindlist( hRecvVbl, pdu);
- // build up the timeticks and trapid portions
- Vb tempvb;
- //skip the first two vbs in the list
- for ( int w=2;w<pdu.get_vb_count();w++)
- {
- pdu.get_vb(tempvb,w);
- sendpdu += tempvb;
- }
- // get the timestamp found in vb #1
- pdu.get_vb(tempvb,0);
- tempvb.get_value( timestamp);
- // get the trapid found in vb #2
- pdu.get_vb( tempvb,1);
- tempvb.get_value( trapid);
- // patch for incorrect ".0" on trap is in WinSNMP
- if ( trapid[ (int) (trapid.len()-1)] == (unsigned long) 0)
- trapid.trim(1);
- // try to pull off the enterprise
- // if its there it will the last vb in the pdu
- Vb enterprise_vb;
- Oid e_oid;
- sendpdu.get_vb( enterprise_vb, sendpdu.get_vb_count() -1);
- enterprise_vb.get_oid( e_oid);
- if ( e_oid == "1.3.6.1.6.3.1.1.4.3.0")
- {
- enterprise_vb.get_value( enterprise);
- sendpdu.trim();
- }
- //------[ prepare the agent address ]-------------------------------------
- gen_status = SnmpEntityToStr( hDstRecvEnt,40, (char *) agent_addr);
- if ( gen_status == SNMPAPI_FAILURE)
- {
- delete [] vbs; // free the snmp++ vbs
- SNMPDEBUG("-- SNMP++, Trap Handler SnmpEntityToStr Failn");
- return; // error case, don't call callback
- }
- //-----[ prepare the agents context ]-------------------------------------
- gen_status = SnmpContextToStr( hRecvContext, &octet_community);
- if ( gen_status == SNMPAPI_FAILURE)
- {
- delete [] vbs; // free the snmp++ vbs
- SNMPDEBUG("-- SNMP++, Trap Handler SnmpContextToStr Failn");
- return; // error case, don't call callback
- }
- //----[ copy SMI octet community into an unsigned char community ]
- // protect againt over running the target string
- MEMCPY( community_name,
- octet_community.ptr,
- (size_t) min(octet_community.len,40));
- //------[ make an target object for the callback ]----------------------
- // set the address portion of the target
- GenAddress address( (char *) agent_addr);
- if ( !address.valid())
- return;
- target.set_address( address);
- // fill in the community names
- OctetStr rc( (const unsigned char *) octet_community.ptr, octet_community.len);
- target.set_readcommunity( rc);
- target.set_writecommunity( rc);
- //------[ make up a pdu onject ]------------------------------------------
- set_request_id( &pdu, lnRecvRequestId); // friend function call
- set_error_status( &pdu, (int) lnErrorStatus);
- set_error_index( &pdu, (int) lnErrorIndex);
- // change the pdu type for responses
- if ( reason == SNMP_CLASS_ASYNC_RESPONSE)
- pdu.set_type( SNMP_PDU_RESPONSE);
- //------[ load up the trap id and timestamp ]-----------------------------
- sendpdu.set_notify_id( trapid);
- sendpdu.set_notify_timestamp( timestamp);
- sendpdu.set_notify_enterprise( enterprise);
- //------[ determine if we should call into the callback ]-----------------
- OidCollection trapids;
- TargetCollection targets;
- spp_session->get_notify_filter( trapids, targets);
- SNMPDEBUG("++ SNMP++, Trap Handler Fire Callbackn");
- //------[ call into the callback function ]-------------------------------
- if (trapids.size()==0)
- {
- (callback)( reason, // reason
- (Snmp*) spp_session, // snmp++ session who own the req
- (Pdu&) sendpdu, // pdu
- (SnmpTarget&) target, // target
- (void*) personality); // callback data
- SNMPDEBUG("++ SNMP++, Empty Collection, Back From Trap Handler Fire Callbackn");
- }
- else
- {
- Oid cur_id;
- int n = trapids.size();
- for (int z=1;z<=n;z++)
- {
- trapids.get_element( cur_id,z-1);
- if ( cur_id.nCompare( cur_id.len(), trapid)==0)
- {
- (callback)( reason, // reason
- (Snmp*) spp_session, // snmp++ session who own the req
- (Pdu&) sendpdu, // pdu
- (SnmpTarget&) target, // target
- (void*) personality); // callback data
- SNMPDEBUG("++ SNMP++, Explict collection Hit,Back From Trap Handler Fire Callbackn");
- z= n+1; // stop the loop
- } // end if
- } // end for
- } // end else
- //------[ free up the vbs ]
- delete [] vbs;
- //------[ free up winsnmp vars ]------------------------------------------
- SnmpFreeDescriptor( SNMP_SYNTAX_OCTETS, (smiLPOPAQUE) &octet_community);
- };
- //---------------------------------------------------------------------
- //----[ pdu receiver ]-------------------------------------------------
- //---------------------------------------------------------------------
- // - Receives pdus for all sessions
- // - When each session is created, the session handle is set into
- // the WndExtra portion of the created instance. When the WinSnmp
- // dll calls this Windproc its session is extracted via GetWindowWord
- // and is then used to read and decode the pdu. The pdu is registered
- // to the container only if a matching Request id is pending.
- //
- long FAR PASCAL XPORT SnmpWndProc(HWND hWnd,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- HSNMP_SESSION session_handle; // winsnmp session handle
- HSNMP_PDU hRecvPdu; // received pdu
- HSNMP_ENTITY hDstRecvEnt, // received destination
- hSrcRecvEnt; // received source
- HSNMP_CONTEXT hRecvContext; // received context
- SNMPAPI_STATUS Wstatus; // snmp api status
- smiINT lnRecvPduType; // received pdu type
- smiINT lnRecvRequestId; // received pcu status
- smiINT lnErrorStatus; // received error status
- smiINT lnErrorIndex; // received error index
- HSNMP_VBL hRecvVbl; // received variable binding list
- snmp_callback callback; // callback for async calls
- void * personality; // personality
- Snmp* spp_session; // snmp++ session handle
- SNMPAPI_STATUS last_error; // last WinSnmp error to occur
- int status;
- switch (message)
- {
- // called when window is created
- case WM_CREATE:
- return 0;
- break;
- // called when a pdu is received
- // the session handle is in the WndExtra portion
- // and needs to be extracted
- case SNMP_MSG:
- //-------------------------------------------------------------
- // win32 window handles are 32 bits wide, use GetWindowLong()
- // WinSNMP session handle
- session_handle = (HSNMP_SESSION) GetWindowLong( hWnd,0);
- // snmp++ session
- spp_session = ( Snmp*) GetWindowLong( hWnd,
- sizeof( HWND));
- //--------------------------------------------------------------
- // ACE*COMM specific timeout procesing JR-9/18/97
- if ( wParam == SNMPAPI_TL_TIMEOUT)
- {
- SNMPDEBUG("SNMP++, ACE*COMM DLL Timeoutn");
- // rid is in the lParam
- SNMP_WAIT;
- pdu_container->timeout();
- // check to make sure that this was a
- // pending async request
- status = pdu_container->get_cb_info( (long int) lParam,
- &callback,
- &personality);
- SNMP_SIGNAL;
- if ( status)
- {
- SNMPDEBUG("SNMP++, Found Rid for callback Resolutionn");
- // inform the users callback of the timeout
- // this was the initial request
- process_async_event( (int) SNMP_CLASS_TIMEOUT,
- lParam,
- session_handle,
- 0, // error status
- 0, // error index
- 0,
- 0,
- 0,
- spp_session,
- callback,
- personality);
- }
- return 0;
- }
- // end ACE*COMM msg check
- //-------------------------------------------------------------
- SNMPDEBUG("++ SNMP++, Receive msg n");
- // recieve the pdu
- Wstatus = SnmpRecvMsg(session_handle,
- &hSrcRecvEnt,
- &hDstRecvEnt,
- &hRecvContext,
- &hRecvPdu);
- // if successful process it, else throw it away
- if ( Wstatus != SNMPAPI_FAILURE)
- {
- SNMPDEBUG("++ SNMP++, Get PDU Data n");
- Wstatus = SnmpGetPduData( hRecvPdu,
- &lnRecvPduType,
- &lnRecvRequestId,
- &lnErrorStatus,
- &lnErrorIndex,
- &hRecvVbl );
- // if the decode was successful stuff it
- // into the pdu container else throw it away
- if ( Wstatus == SNMPAPI_SUCCESS)
- {
- switch( lnRecvPduType)
- {
- //----[ response ]-----------------
- case SNMP_PDU_RESPONSE:
- SNMP_WAIT;
- status = pdu_container->check_if_pending( (long int) lnRecvRequestId,
- &callback);
- SNMP_SIGNAL;
- if ( status)
- {
- if ( callback ==0)
- { // blocking response
- // memory is freed when extracted using get_slot
- SNMPDEBUG("++ SNMP++, Process Blocked MSG n");
- SNMP_WAIT;
- pdu_container->set_slot( (long int) lnRecvRequestId,
- session_handle,
- hSrcRecvEnt,
- hDstRecvEnt,
- hRecvContext,
- lnRecvPduType,
- lnRecvRequestId,
- lnErrorStatus,
- lnErrorIndex,
- hRecvVbl);
- SNMPDEBUG("++ SNMP++, Free PDU n");
- SnmpFreePdu( hRecvPdu);
- // update the pdu count
- pdu_container->pdu_received();
- SNMP_SIGNAL;
- }
- else
- { // async response
- SNMPDEBUG("++ SNMP++, Process Async Msg n");
- // if we can find the request in the pdu container
- // then get the callback information and process it
- SNMP_WAIT;
- status = pdu_container->get_cb_info( (long int) lnRecvRequestId,
- &callback,
- &personality);
- SNMP_SIGNAL;
- if ( status)
- process_async_event( (int) SNMP_CLASS_ASYNC_RESPONSE,
- lnRecvRequestId,
- session_handle,
- lnErrorStatus,
- lnErrorIndex,
- hRecvVbl,
- hRecvContext,
- hSrcRecvEnt,
- spp_session,
- callback,
- personality);
- else {
- SNMP_WAIT;
- pdu_container->stray_response();
- SNMP_SIGNAL;
- }
- SNMPDEBUG("++ SNMP++, Free Vars After process_asyncn");
- SnmpFreeVbl( hRecvVbl);
- SnmpFreeEntity( hSrcRecvEnt);
- SnmpFreeContext( hRecvContext);
- SnmpFreeEntity( hDstRecvEnt); // don't need
- SnmpFreePdu( hRecvPdu); // don't need
- // update the pdu count
- SNMP_WAIT;
- pdu_container->pdu_received();
- SNMP_SIGNAL;
- }
- }
- else // not a pending response, toss it
- {
- SNMPDEBUG("++ SNMP++, Stray Message n");
- SnmpFreeEntity( hSrcRecvEnt);
- SnmpFreeEntity( hDstRecvEnt);
- SnmpFreeContext( hRecvContext);
- SnmpFreePdu( hRecvPdu);
- SnmpFreeVbl( hRecvVbl);
- SNMP_WAIT;
- pdu_container->stray_response();
- SNMP_SIGNAL;
- }
- break;
- //---[ trap ]----------------------
- case SNMP_PDU_TRAP:
- SNMP_WAIT;
- pdu_container->trap_received();
- SNMP_SIGNAL;
- SNMPDEBUG("++ SNMP++, TRAP Received n");
- if ( spp_session->get_notify_callback() != 0)
- process_trap_event( (int) SNMP_CLASS_NOTIFICATION,
- lnRecvRequestId,
- session_handle,
- lnErrorStatus,
- lnErrorIndex,
- hRecvVbl,
- hRecvContext,
- hSrcRecvEnt,
- spp_session,
- spp_session->get_notify_callback(),
- spp_session->get_notify_callback_data());
- SNMPDEBUG("++ SNMP++, Free Entity and PDU n");
- SnmpFreeEntity( hSrcRecvEnt);
- SnmpFreeEntity( hDstRecvEnt);
- SnmpFreeContext( hRecvContext);
- SnmpFreePdu( hRecvPdu);
- SnmpFreeVbl( hRecvVbl);
- break;
- //----[ unidentified message ]---------------
- default:
- {
- SNMPDEBUG("++ SNMP++, unidentified Message n");
- SNMP_WAIT;
- pdu_container->stray_response();
- SnmpFreeEntity( hSrcRecvEnt);
- SnmpFreeEntity( hDstRecvEnt);
- SnmpFreeContext( hRecvContext);
- SnmpFreePdu( hRecvPdu);
- SnmpFreeVbl( hRecvVbl);
- pdu_container->invalid_resp_pdu();
- SNMP_SIGNAL;
- }
- }; // end switch
- }
- else //error getting pdu data, so we need to free the vars
- {
- SNMPDEBUG("++ SNMP++, GET PDU ERROR n");
- SNMP_WAIT;
- SnmpFreeEntity( hSrcRecvEnt);
- SnmpFreeEntity( hDstRecvEnt);
- SnmpFreeContext( hRecvContext);
- SnmpFreePdu( hRecvPdu);
- pdu_container->decode_err();
- SNMP_SIGNAL;
- }
- } // end if recv success
- else
- {
- SNMPDEBUG("++ SNMP++, Receive MSG Fail n");
- // receive message fail, look for timeout case
- last_error = SnmpGetLastError( session_handle);
- if ( last_error == SNMPAPI_TL_TIMEOUT)
- {
- SNMPDEBUG("++ SNMP++, WinSNMP TimeOut Notify n");
- // process a async timeout event
- // we only care about async ones
- // handles from receive message are valid
- SNMPDEBUG("++ SNMP++, Get PDU Data n");
- Wstatus = SnmpGetPduData( hRecvPdu,
- &lnRecvPduType,
- &lnRecvRequestId,
- &lnErrorStatus,
- &lnErrorIndex,
- &hRecvVbl );
- if ( Wstatus == SNMPAPI_SUCCESS)
- {
- SNMP_WAIT;
- pdu_container->timeout();
- // check to make sure that this was a
- // pending async request
- status = pdu_container->get_cb_info( (long int) lnRecvRequestId,
- &callback,
- &personality);
- SNMP_SIGNAL;
- if ( status)
- {
- // clear the request from the pdu container
- SNMP_WAIT;
- pdu_container->clear_request_id( (long int) lnRecvRequestId);
- SNMP_SIGNAL;
- // inform the users callback of the timeout
- // this was the initial request
- process_async_event( (int) SNMP_CLASS_TIMEOUT,
- lnRecvRequestId,
- session_handle,
- 0, // error status
- 0, // error index
- hRecvVbl,
- hRecvContext,
- hSrcRecvEnt,
- spp_session,
- callback,
- personality);
- }
- SnmpFreeVbl( hRecvVbl);
- }
- // free up the get message vars
- // these are valid on a timeout
- SnmpFreeEntity( hSrcRecvEnt);
- SnmpFreeEntity( hDstRecvEnt);
- SnmpFreeContext( hRecvContext);
- SnmpFreePdu( hRecvPdu);
- }
- else {
- SNMP_WAIT;
- pdu_container->receive_err();
- SNMP_SIGNAL;
- }
- }
- return 0;
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- };
- //----------------------------------------------------------------------
- //--------[ transport layer start up ]----------------------------------
- //----------------------------------------------------------------------
- // Private function, not exposed to the outside
- int transport_start_up( )
- {
- SNMPAPI_STATUS status;
- WNDCLASS snmpc;
- #ifndef _DLL_ATTACH_OPTION
- smiUINT32 nMajVer, nMinVer, nLevel, nTrans, nReTrans;
- #endif
- SNMPDEBUG("++ SNMP++, Transport Start UP n");
- // set translation mode to v1
- SnmpSetTranslateMode( SNMPAPI_UNTRANSLATED_V1);
- // register the snmp class
- snmpc.style = 0;
- snmpc.lpfnWndProc = SnmpWndProc;
- snmpc.cbClsExtra = 0;
- snmpc.cbWndExtra = sizeof( HWND) + // WinSnmp Session
- sizeof( Snmp*); // Snmp++ session
- snmpc.hInstance = NULL;
- snmpc.hIcon = NULL;
- snmpc.hCursor = NULL;
- snmpc.hbrBackground = NULL;
- snmpc.lpszMenuName = NULL;
- snmpc.lpszClassName = SzSnmpClass;
- // register will fail if the class
- // already exists, in this case
- // we don't care
- // This may happen is someone inadvertently
- // calls transport_start_up more than once!
- status = RegisterClass( &snmpc);
- if ( status == 0)
- {
- SNMPDEBUG("-- SNMP++, CLASS REGISTER FAIL n");
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- }
- SNMPDEBUG("++ SNMP++, Done Xport Start Up n");
- // create the pdu container class
- // here, multiple pdu container objects per app
- // should not be created
- pdu_ref_count++; // up the ref count
- if ( pdu_ref_count ==1)
- {
- SNMPDEBUG("++ SNMP++, New PDU Container n");
- pdu_container = new Pdu_Container();
- if ( pdu_container == NULL)
- {
- SNMPDEBUG("-- SNMP++, Pdu Container Create Fail n");
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- }
- else
- {
- #ifndef _DLL_ATTACH_OPTION
- // start up WinSNMP
- status = SnmpStartup(&nMajVer,
- &nMinVer,
- &nLevel,
- &nTrans,
- &nReTrans);
- if ( status != SNMPAPI_SUCCESS ) {
- SNMPDEBUG("Unable to Startup WinSNMP!n");
- return 0;
- }
- SNMPDEBUG("Startup WinSNMP OKn");
- #endif
- return SNMP_CLASS_SUCCESS;
- }
- }
- else
- {
- #ifndef _DLL_ATTACH_OPTION
- // start up WinSNMP
- status = SnmpStartup(&nMajVer,
- &nMinVer,
- &nLevel,
- &nTrans,
- &nReTrans);
- if ( status != SNMPAPI_SUCCESS ) {
- SNMPDEBUG("Unable to Startup WinSNMP!n");
- return 0;
- }
- SNMPDEBUG("Startup WinSNMP OKn");
- #endif
- return SNMP_CLASS_SUCCESS; // we already have a good pdu object
- }
- };
- //-----------------------------------------------------------------------
- //----------[ transport layer shut down ]--------------------------------
- //-----------------------------------------------------------------------
- // Private function
- int transport_shut_down( )
- {
- int unreg_status;
- SNMPDEBUG("++ SNMP++, Transport Shut Down n");
- // delete the pdu container only when the ref
- // count reaches 0
- pdu_ref_count--;
- if ( pdu_ref_count == 0)
- {
- SNMPDEBUG("++ SNMP++, Destroy PDU Container n");
- delete pdu_container;
- }
- // protect against running counter < 0
- // this allows a new transport_start_up to
- // resume
- if ( pdu_ref_count < 0) pdu_ref_count = 0;
- unreg_status = UnregisterClass( SzSnmpClass,NULL);
- if ( unreg_status == FALSE) {
- SNMPDEBUG("-- SNMP++, UnRegister Class Fail n");
- }
- #ifndef _DLL_ATTACH_OPTION
- SnmpCleanup();
- #endif
- return SNMP_CLASS_SUCCESS;
- };
- //----------------------------------------------------------------------
- //------[ Snmp Class Constructor ]--------------------------------------
- //----------------------------------------------------------------------
- Snmp::Snmp( int &status, unsigned short agent_port) // status of construction
- {
- SNMPDEBUG("++ SNMP++, SNMP Constructor n");
- SNMPAPI_STATUS WinSnmpStatus; // return status for snmp calls
- SNMP_WAIT;
- // call transport start up if it hasn't been called before
- construct_status = SNMP_CLASS_SUCCESS;
- if ( snmp_ref_count == 0)
- {
- status = transport_start_up();
- construct_status = status;
- if ( status != SNMP_CLASS_SUCCESS)
- {
- SNMPDEBUG("-- SNMP++, Transport Start Up Failure n");
- SNMP_SIGNAL;
- return;
- }
- }
- snmp_ref_count++; // bump up the ref count
- pdu_handler = CreateWindow( SzSnmpClass, // name of class
- NULL, // window text
- WS_POPUP, // window style
- 0, // xpos
- 0, // ypos
- 0, // width
- 0, // hieght
- 0, // parent window handle, none for popup
- 0 , // window id
- 0, // parent instance
- 0); // pointer to construct data
- if ( pdu_handler == NULL)
- {
- status = SNMP_CLASS_RESOURCE_UNAVAIL;
- SNMPDEBUG("-- SNMP++, Hidden Window Create Failure n");
- construct_status = status;
- SNMP_SIGNAL;
- return;
- }
- else
- {
- // create a winsnmp session
- iv_snmp_session = (SNMPHANDLE) SnmpOpen( pdu_handler , SNMP_MSG);
- if ( iv_snmp_session == SNMPAPI_FAILURE) {
- WinSnmpStatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- if (SNMPAPI_ALLOC_ERROR == WinSnmpStatus)
- status = SNMP_CLASS_RESOURCE_UNAVAIL;
- else if (SNMPAPI_OTHER_ERROR == WinSnmpStatus)
- status = SNMP_CLASS_ERROR;
- else
- status = SNMP_CLASS_INTERNAL_ERROR;
- SNMPDEBUG("-- SNMP++, WinSNMP Session Create Failure n");
- construct_status = status;
- SNMP_SIGNAL;
- return;
- }
- else {
- // set the pdu handler extra data to the session handle value
- // WinSnmp session
- SetWindowLong( pdu_handler,
- 0,
- (LONG) iv_snmp_session);
- // snmp++ session
- SetWindowLong( pdu_handler,
- 0 + sizeof( HWND),
- (LONG) this);
- // intialize all the trap receiving member variables
- notify_targets = 0;
- notify_ids = 0;
- listen_addresses = 0;
- notifycallback = 0;
- notifycallback_data = 0;
- // success
- status = SNMP_CLASS_SUCCESS;
- SNMP_SIGNAL;
- return;
- }
- }
- };
- //--------------------------------------------------------------------
- //---------[ Snmp Class Destructor ]----------------------------------
- //--------------------------------------------------------------------
- // destroys instance
- Snmp::~Snmp()
- {
- SNMPAPI_STATUS status;
- SNMP_WAIT;
- // if we failed during construction then don't try
- // to free stuff up that was not allocated
- if ( construct_status != SNMP_CLASS_SUCCESS) {
- SNMP_SIGNAL;
- return;
- }
- // shut down trap reception if used
- notify_unregister();
- // terminate the session
- pdu_container->search_and_destroy( (HSNMP_SESSION) iv_snmp_session, this);
- status = SnmpClose( (HSNMP_SESSION) iv_snmp_session);
- status = DestroyWindow( (HWND) pdu_handler);
- snmp_ref_count--;
- if (snmp_ref_count <0) snmp_ref_count = 0;
- if ( snmp_ref_count == 0)
- transport_shut_down( );
- SNMPDEBUG("++ SNMP++, Exit From ~Snmp n");
- SNMP_SIGNAL;
- };
- //-----------------------[ access the trap reception info ]---------------
- snmp_callback Snmp::get_notify_callback()
- { return notifycallback; };
- void * Snmp::get_notify_callback_data()
- { return notifycallback_data; };
- //-----------------------[ get notify filters ]---------------------------
- // return back the currently set notification filters
- // if they are not defined then return back empty collections
- //
- int Snmp::get_notify_filter( OidCollection &trapids,
- TargetCollection &targets)
- {
- if (notify_ids != 0)
- trapids = *notify_ids;
- if ( notify_targets != 0)
- targets = *notify_targets;
- return SNMP_CLASS_SUCCESS;
- };
- //-----------------------[ register to get traps]-------------------------
- // alternate form for local listen specification
- int Snmp::notify_register( const OidCollection &trapids,
- const TargetCollection &targets,
- const AddressCollection &listen_addresses,
- const snmp_callback callback,
- const void *callback_data)
- {
- return notify_register( trapids,
- targets,
- callback,
- callback_data);
- };
- //-----------------------[ register to get traps]-------------------------
- int Snmp::notify_register( const OidCollection &trapids,
- const TargetCollection &targets,
- const snmp_callback callback,
- const void *callback_data)
- {
- SNMPAPI_STATUS status;
- SNMPAPI_STATUS WinSnmpStatus; // return status for snmp calls
- int return_status = 0;
- int already_on = FALSE;
- // free up local collections
- if ( notify_targets != 0)
- delete notify_targets;
- if ( notify_ids != 0) {
- delete notify_ids;
- already_on = TRUE;
- }
- // null out callback information
- notifycallback = 0;
- notifycallback_data = 0;
- //-------------------------------------------------------------------------
- //-----------[ assign new trap filtering info ]----------------------------
- //-------------------------------------------------------------------------
- // create a new collection using param passed in
- notify_targets = new TargetCollection ( targets);
- // delete current trapid collection if defined
- // create a new collection using param passed in
- notify_ids = new OidCollection( trapids);
- // assign callback and callback data info
- notifycallback = callback;
- notifycallback_data = (void*) callback_data;
- //--------------------------------------------------------------------
- //-----------[ Turn the traps on using new info ]---------------------
- //--------------------------------------------------------------------
- if ( !already_on) {
- // listen for everything
- status = SnmpRegister( (HSNMP_SESSION)iv_snmp_session,// session to use
- NULL, // source entity
- NULL, // destination entity, don't care where its directed
- NULL, // handle send context, don't care what the community name is
- NULL, // oid mask
- SNMPAPI_ON);
- }
- else
- return SNMP_CLASS_SUCCESS;
- if ( status == SNMPAPI_FAILURE) {
- WinSnmpStatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- if (SNMPAPI_ALLOC_ERROR == WinSnmpStatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else if (SNMPAPI_OTHER_ERROR == WinSnmpStatus) {
- return SNMP_CLASS_ERROR;
- } else if (SNMPAPI_TL_IN_USE == WinSnmpStatus) {
- return SNMP_CLASS_TL_IN_USE;
- } else if (SNMPAPI_TL_NOT_AVAILABLE == WinSnmpStatus) {
- return SNMP_CLASS_TL_UNSUPPORTED;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- return SNMP_CLASS_SUCCESS;
- };
- //-----------------------[ un-register to get traps]----------------------
- int Snmp::notify_unregister()
- {
- SNMPAPI_STATUS Wstatus;
- // free up local collections
- if ( notify_targets != 0)
- delete notify_targets;
- if ( notify_ids != 0)
- delete notify_ids;
- // null out callback information
- notifycallback = 0;
- notifycallback_data = 0;
- // invoke WinSNMP register to turn it off
- Wstatus = SnmpRegister((HSNMP_SESSION)iv_snmp_session, // session to use
- NULL, // source entity
- NULL, // destination entity, don't care where its directed
- NULL, // handle send context, don't care what the community name is
- NULL, // oid mask
- SNMPAPI_OFF);
- if ( Wstatus == SNMPAPI_FAILURE) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- return SNMP_CLASS_SUCCESS;
- };
- //----------------------[ cancel a pending request ]--------------------
- // cancel a pending request
- // only cancels async requests
- // returns true is canceled and false if nothing to cancel
- int Snmp::cancel( const unsigned long rid)
- {
- snmpcallback callback;
- SNMP_WAIT;
- if ( pdu_container->check_if_pending( (long int) rid, &callback))
- {
- if ( callback != 0)
- {
- pdu_container->clear_request_id( rid);
- SNMP_SIGNAL;
- return SNMP_CLASS_SUCCESS;
- }
- }
- SNMP_SIGNAL;
- return SNMP_CLASS_INVALID_REQID; // no requests pending for this rid
- };
- //------------------------[ get ]---------------------------------------
- int Snmp::get( Pdu &pdu, // pdu to use
- SnmpTarget &target) // get target
- {
- pdu.set_type( sNMP_PDU_GET);
- return snmp_engine( pdu, // get pdu
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- NULL, // callback for async only
- 0); // callback data
- };
- //------------------------[ get async ]----------------------------------
- int Snmp::get( Pdu &pdu, // pdu to use
- SnmpTarget &target, // destination target
- const snmp_callback callback, // async callback
- const void * callback_data) // callback data
- {
- if ( ! callback )
- return SNMP_CLASS_INVALID_CALLBACK;
- pdu.set_type( sNMP_PDU_GET);
- return snmp_engine( pdu, // get async pdu
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- callback, // callback to use
- callback_data); // callback data
- };
- //------------------------[ get next ]-----------------------------------
- int Snmp::get_next( Pdu &pdu, // pdu to use
- SnmpTarget &target) // get target
- {
- pdu.set_type( sNMP_PDU_GETNEXT);
- return snmp_engine( pdu, // pdu to get next
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- NULL, // callback for async only
- 0); // callback data for async only
- };
- //------------------------[ get next async ]-----------------------------
- int Snmp::get_next( Pdu &pdu, // pdu to use
- SnmpTarget &target, // destination target
- const snmp_callback callback, // callback to use
- const void *callback_data) // callback data
- {
- if ( ! callback )
- return SNMP_CLASS_INVALID_CALLBACK;
- pdu.set_type( sNMP_PDU_GETNEXT);
- return snmp_engine( pdu, // pdu to get next
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- callback, // callback
- callback_data); // callback data
- };
- //-------------------------[ set ]---------------------------------------
- int Snmp::set( Pdu &pdu, // pdu to use
- SnmpTarget &target) // target address
- {
- pdu.set_type( sNMP_PDU_SET);
- return snmp_engine( pdu, // pdu to set
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- NULL, // callback for async only
- 0); // callback data
- };
- //------------------------[ set async ]----------------------------------
- int Snmp::set( Pdu &pdu, // pdu to use
- SnmpTarget &target, // destination target
- const snmp_callback callback, // callback to use
- const void * callback_data) // callback data
- {
- if ( ! callback )
- return SNMP_CLASS_INVALID_CALLBACK;
- pdu.set_type( sNMP_PDU_SET);
- return snmp_engine( pdu, // pdu to set
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- callback, // callback function
- callback_data); // callback data
- };
- //-----------------------[ get bulk ]------------------------------------
- int Snmp::get_bulk( Pdu &pdu, // pdu to use
- SnmpTarget &target, // destination target
- const int non_repeaters, // number of non repeaters
- const int max_reps) // maximum number of repetitions
- {
- pdu.set_type( sNMP_PDU_GETBULK);
- return snmp_engine( pdu, // pdu to use
- non_repeaters, // # of non repeaters
- max_reps, // max repititions
- target, // target
- NULL, // callback for async only
- 0); // callback data
- };
- //-----------------------[ get bulk async ]------------------------------
- int Snmp::get_bulk( Pdu &pdu, // pdu to use
- SnmpTarget &target, // destination target
- const int non_repeaters, // number of non repeaters
- const int max_reps, // maximum number of repetitions
- const snmp_callback callback, // callback to use
- const void *callback_data) // callback data
- {
- if ( ! callback )
- return SNMP_CLASS_INVALID_CALLBACK;
- pdu.set_type( sNMP_PDU_GETBULK);
- return snmp_engine( pdu, // pdu to use
- non_repeaters, // # of non repeaters
- max_reps, // max repititions
- target, // target
- callback, // callback function
- callback_data); // callback data
- };
- //----------------------[ blocking inform, V2 only]------------------------
- int Snmp::inform( Pdu &pdu, // pdu to send
- SnmpTarget &target) // destination target
- {
- pdu.set_type( sNMP_PDU_INFORM);
- return snmp_engine( pdu, // get pdu
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- NULL, // callback for async only
- 0); // callback data
- };
- //----------------------[ asynch inform, V2 only]------------------------
- int Snmp::inform( Pdu &pdu, // pdu to send
- SnmpTarget &target, // destination target
- const snmp_callback callback, // callback function
- const void * callback_data) // callback data
- {
- if ( ! callback )
- return SNMP_CLASS_INVALID_CALLBACK;
- pdu.set_type( sNMP_PDU_INFORM_ASYNC);
- return snmp_engine( pdu, // pdu to set
- 0, // max repeaters
- 0, // non repeaters
- target, // target
- callback, // callback function
- callback_data); // callback data
- };
- //---------------------[ send a trap ]------------------------------------------
- int Snmp::trap( Pdu &pdu, // pdu to send
- SnmpTarget &target) // destination target
- {
- int status;
- long int request_id; // unique request id
- SNMPDEBUG("++ SNMP++, Send a Trapn");
- //---------[ make sure pdu is valid ]--------------------------
- if ( !pdu.valid())
- return SNMP_CLASS_INVALID_PDU;
- pdu.set_type( sNMP_PDU_TRAP);
- SNMP_WAIT;
- //-----[ get a request id to use ]-------------------------
- request_id = pdu_container->get_request_id();
- SNMP_SIGNAL;
- //-----[ send it out ]----------------------------------------------
- status = sendMsg(target, pdu,0,0,request_id);
- // verify the send status
- if (status != SNMP_CLASS_SUCCESS) {
- SNMPDEBUG("-- SNMP++, Failure Sending Trap Pdun");
- return status; // fail on send message
- }
- SNMP_WAIT;
- pdu_container->traps_sent();
- SNMP_SIGNAL;
- return SNMP_CLASS_SUCCESS;
- };
- //------------[ convert SNMP++ VB to WinSNMP smiVALUE ]----------------
- int convertVbToSmival( Vb &tempvb, smiVALUE *smival )
- {
- smival->syntax = tempvb.get_syntax();
- switch ( smival->syntax ) {
- // case sNMP_SYNTAX_INT32:
- case sNMP_SYNTAX_INT:
- tempvb.get_value(smival->value.sNumber);
- break;
- // case sNMP_SYNTAX_UINT32:
- case sNMP_SYNTAX_GAUGE32:
- case sNMP_SYNTAX_CNTR32:
- case sNMP_SYNTAX_TIMETICKS:
- tempvb.get_value(smival->value.uNumber);
- break;
- // case Counter64
- case sNMP_SYNTAX_CNTR64:
- {
- Counter64 c64;
- tempvb.get_value(c64);
- smival->value.hNumber.hipart = c64.high();
- smival->value.hNumber.lopart = c64.low();
- }
- break;
- case sNMP_SYNTAX_BITS:
- case sNMP_SYNTAX_OCTETS:
- case sNMP_SYNTAX_IPADDR:
- {
- OctetStr os;
- tempvb.get_value(os);
- smival->value.string.ptr = NULL;
- smival->value.string.len = os.len();
- if ( smival->value.string.len > 0 )
- {
- smival->value.string.ptr = (SmiLPBYTE) new unsigned char [smival->value.string.len];
- if ( smival->value.string.ptr )
- {
- for (int i=0; i<(int) smival->value.string.len ; i++)
- smival->value.string.ptr[i] = os[i];
- }
- else
- {
- smival->syntax = sNMP_SYNTAX_NULL; // invalidate the smival
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- }
- }
- }
- break;
- case sNMP_SYNTAX_OID:
- {
- Oid oid;
- tempvb.get_value(oid);
- smival->value.oid.ptr = NULL;
- smival->value.oid.len = oid.len();
- if ( smival->value.oid.len > 0 )
- {
- smival->value.oid.ptr = (SmiLPUINT32) new unsigned long [ smival->value.oid.len];
- if ( smival->value.oid.ptr )
- {
- for (int i=0; i<(int)smival->value.oid.len ; i++)
- smival->value.oid.ptr[i] = oid[i];
- }
- else
- {
- smival->syntax = sNMP_SYNTAX_NULL; // invalidate the smival
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- }
- }
- }
- break;
- default:
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- return SNMP_CLASS_SUCCESS;
- }
- //------------[ free WinSNMP smiVALUE descriptors ]---------------------
- void freeSmivalDescriptor( smiVALUE *smival )
- {
- switch ( smival->syntax ) {
- case SNMP_SYNTAX_OCTETS:
- case SNMP_SYNTAX_OPAQUE:
- case SNMP_SYNTAX_IPADDR:
- case SNMP_SYNTAX_NSAPADDR: // obsoleted in SNMPv2 Draft Std
- case SNMP_SYNTAX_BITS: // obsoleted in SNMPv2 Draft Std
- delete [] smival->value.string.ptr;
- break;
- case SNMP_SYNTAX_OID:
- delete [] smival->value.oid.ptr;
- break;
- }
- smival->syntax = SNMP_SYNTAX_NULL;
- }
- //----------------------[ load_varbindlist ]----------------------------
- // load the WinSNMP varbind list with the Snmp++ Vb objects
- int load_varbindlist(HSNMP_SESSION session_handle,
- HSNMP_VBL hvbl, // handle to WinSNMP vbl
- Pdu &pdu) // pdu to use
- {
- int z; // looping variable
- Oid current_oid; // current oid object
- smiOID smioid; // winsnmp oid variable
- smiVALUE smival; // winsnmp smi value
- SNMPAPI_STATUS Wstatus; // return status for snmp calls
- Vb tempvb; // temp vb to use
- int vb_count; // count of vbs in pdu
- unsigned short action; // type of pdu
- int rc; // snmp++ result code
- TimeTicks timestamp; // timestamp for traps
- SNMPDEBUG("++ SNMP++, In load var bind list n");
- vb_count = pdu.get_vb_count();
- action = pdu.get_type();
- //------------------------------------------------
- // if its a trap then build up trap timestamp and id
- if ( action == sNMP_PDU_TRAP) {
- // timestamp
- tempvb.set_oid( (Oid) "1.3.6.1.2.1.1.3.0");
- pdu.get_notify_timestamp( timestamp);
- if ( timestamp <= 0)
- timestamp = ( long) GetTickCount();
- tempvb.set_value( timestamp);
- Wstatus = SnmpStrToOid( tempvb.get_printable_oid(),&smioid);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- if (SNMPAPI_OID_INVALID == Wstatus)
- return SNMP_CLASS_INVALID_OID;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- rc = convertVbToSmival(tempvb, &smival);
- if ( rc != SNMP_CLASS_SUCCESS )
- {
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- return rc;
- }
- Wstatus = SnmpSetVb( hvbl,0,&smioid,&smival);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- freeSmivalDescriptor( &smival);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- freeSmivalDescriptor(&smival);
- // free the smioid descriptor
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- // trap id
- tempvb.set_oid( (Oid) "1.3.6.1.6.3.1.1.4.1.0");
- pdu.get_notify_id( current_oid);
- tempvb.set_value( current_oid);
- Wstatus = SnmpStrToOid( tempvb.get_printable_oid(),&smioid);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- if (SNMPAPI_OID_INVALID == Wstatus)
- return SNMP_CLASS_INVALID_OID;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- rc = convertVbToSmival(tempvb, &smival);
- if ( rc != SNMP_CLASS_SUCCESS )
- {
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- return rc;
- }
- Wstatus = SnmpSetVb( hvbl,0,&smioid,&smival);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- freeSmivalDescriptor( &smival);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- freeSmivalDescriptor(&smival);
- // free the smioid descriptor
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- };
- //------------------------------------------------
- // set all vb's into the vbl for all vb objects
- for (z=0;z<vb_count;z++)
- {
- SNMPDEBUG("++ SNMP++, Loading a Var Bind");
- // get a vb from the pdu
- pdu.get_vb( tempvb,z);
- // extract the oid request from the vb object
- // put it into a smi oid object
- tempvb.get_oid( current_oid);
- Wstatus = SnmpStrToOid( current_oid.get_printable(),&smioid);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- if (SNMPAPI_OID_INVALID == Wstatus)
- return SNMP_CLASS_INVALID_OID;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- // based on the action set the vb into the vbl
- // differently
- switch( action)
- {
- //-----[ get action ]
- // for gets we only need to put the oid portion in
- // we will get the value portion back
- case sNMP_PDU_GET:
- case sNMP_PDU_GETNEXT:
- case sNMP_PDU_GETBULK:
- SNMPDEBUG("++ SNMP++, Loading a Var Bind Oid portion only");
- Wstatus = SnmpSetVb( hvbl,0,&smioid,NULL);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- break;
- //-----[ set and notification actions ]
- // for sets and notifications, we need to put the smivalue portion
- // as well as the oid portion into the varbind
- case sNMP_PDU_SET:
- case sNMP_PDU_TRAP:
- case sNMP_PDU_INFORM:
- SNMPDEBUG("++ SNMP++, Loading a Var Bind Oid and Value portion");
- rc = convertVbToSmival(tempvb, &smival);
- if ( rc != SNMP_CLASS_SUCCESS )
- {
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- return rc;
- }
- Wstatus = SnmpSetVb( hvbl,0,&smioid,&smival);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- freeSmivalDescriptor( &smival);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- freeSmivalDescriptor(&smival);
- break;
- default: // Internal error
- SNMPDEBUG("++ SNMP++, Invalid PDU Type loading a Var Bind list");
- return SNMP_CLASS_INTERNAL_ERROR;
- break;
- } // end switch
- // free the smioid descriptor
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- } //end for z
- //-----------------------------------------------------------------
- // check for trap enterprise addition
- if ( action == sNMP_PDU_TRAP) {
- tempvb.set_oid( snmpTrapEnterprise);
- pdu.get_notify_enterprise( current_oid);
- // enterprise has to be valid
- if ( current_oid.valid() ) {
- tempvb.set_value( current_oid);
- Wstatus = SnmpStrToOid( tempvb.get_printable_oid(),&smioid);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- if (SNMPAPI_OID_INVALID == Wstatus)
- return SNMP_CLASS_INVALID_OID;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- rc = convertVbToSmival(tempvb, &smival);
- if ( rc != SNMP_CLASS_SUCCESS )
- {
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- return rc;
- }
- Wstatus = SnmpSetVb( hvbl,0,&smioid,&smival);
- if ( Wstatus == SNMPAPI_FAILURE)
- {
- Wstatus = SnmpGetLastError(NULL);
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- freeSmivalDescriptor( &smival);
- if (SNMPAPI_ALLOC_ERROR == Wstatus)
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- else
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- freeSmivalDescriptor(&smival);
- // free the smioid descriptor
- SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE) &smioid);
- } // end if enterprise valid
- }
- SNMPDEBUG("++ SNMP++, Out Load VarBind List n");
- return SNMP_CLASS_SUCCESS;
- }; // end function
- //---------------[ yield pump ]-----------------------
- int yield_pump()
- {
- MSG msg; // message var for blocking
- // while there are messages, pump em
- // just look at the message without removing it first
- while ( PeekMessage( &msg, (HWND) NULL,0,0, PM_NOREMOVE ))
- {
- // get the message
- GetMessage( &msg, (HWND) NULL,0,0);
- // check for shutdown
- if ( msg.message == SNMP_SHUTDOWN_MSG)
- return SNMP_CLASS_SHUTDOWN;
- // translate it
- TranslateMessage( &msg);
- // dispath it
- DispatchMessage( &msg);
- } // end while
- return SNMP_CLASS_SUCCESS;
- };
- //----------------------------------------------------------------------
- //---------[ snmp++ engine ]--------------------------------------------
- //----------------------------------------------------------------------
- // Snmp engine used for all requests, async and blocked
- // build up the request as a WinSNMP request
- // send it out
- // if it was a async request then return out
- // otherwise wait for response while pumping messages
- // while waiting
- // if request arrived then unload request into snmp++ vb format
- //
- int Snmp::snmp_engine( Pdu &pdu, // pdu to use
- long int non_reps, // # of non repititions
- long int max_reps, // # of max repititions
- SnmpTarget &target, // from this target
- const snmp_callback cb, // callback for async calls
- const void * cbd) // callback data
- {
- long int request_id; // unique request id
- int blocked; // blocking variable
- unsigned long start_time; // starting time of wait
- HSNMP_ENTITY hDstRecvEnt, // received destination
- hSrcRecvEnt; // received source
- HSNMP_CONTEXT hRecvContext; // received context
- smiINT lnRecvPduType; // received pdu type
- smiINT lnRecvRequestId; // received pcu status
- smiINT lnErrorStatus; // received error status
- smiINT lnErrorIndex; // received error index
- HSNMP_VBL hRecvVbl; // received variable binding list
- int return_status; // return status
- int error_status; // pdu error status
- unsigned long my_timeout; // target specific timeout
- int my_retry; // target specific retry
- int yield_value;
- OctetStr my_get_community;
- OctetStr my_set_community;
- snmp_callback my_callback;
- void * my_callback_data;
- unsigned long wait_time;
- GenAddress address;
- unsigned char version;
- int status;
- //---------[ make sure target is valid ]-------------------------
- // make sure that the target is valid
- if ( ! target.valid()) {
- SNMPDEBUG("-- SNMP++, Target Object Invalidn");
- return SNMP_CLASS_INVALID_TARGET;
- }
- // try to resolve the target as a v1 target instead
- if ( !target.resolve_to_C( my_get_community,
- my_set_community,
- address,
- my_timeout,
- my_retry,
- version)) {
- SNMPDEBUG("-- SNMP++, V1 Resolve Failn");
- return SNMP_CLASS_INVALID_TARGET;
- }
- //---------[ make sure pdu is valid ]--------------------------
- if ( !pdu.valid())
- return SNMP_CLASS_INVALID_PDU;
- //----[ build a unique request id ]---------------------------------
- // each rid is unique by querying the pdu container class for an
- // available slot. Once an id is issued, no other request can use
- // it until it is removed from the container
- SNMP_WAIT;
- request_id = (smiINT) pdu_container->get_request_id( (HSNMP_SESSION) iv_snmp_session,
- cb,
- (void *) cbd);
- SNMP_SIGNAL;
- if ( request_id == -1) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- };
- //-------[ Send out the PDU ]------------------------------------------
- SNMPDEBUG("++ SNMP++, Send PDU n");
- return_status = sendMsg( target, pdu, non_reps, max_reps, request_id);
- // update
- SNMP_WAIT;
- pdu_container->pdu_sent();
- SNMP_SIGNAL;
- // verify the send status
- if (return_status != SNMP_CLASS_SUCCESS) {
- SNMP_WAIT;
- pdu_container->clear_request_id( (int) request_id);
- pdu_container->sent_err();
- SNMP_SIGNAL;
- return return_status; // fail on send message
- }
- //---------[ if this was an async call then return out ]
- // presence of a non-null callback function indicates this is async
- if ( cb )
- return SNMP_CLASS_SUCCESS;
- //---------[ otherwise we sit and wait for the response pdu ]
- //---------[ peek and loop until response has arrived or timeout]
- // Note, the WinSNMP timeout notification is ignored because there
- // is no support for blocking-mode timeout notification in the
- // SnmpWndProc. Therefore, the following loop checks when the
- // projected timeout would occur.
- blocked = TRUE;
- start_time = GetTickCount();
- wait_time = ( unsigned int) my_timeout * (my_retry+1) * 10;
- while (( blocked) && ( (GetTickCount() - start_time) < wait_time))
- {
- //--------------[ yield to windows ]---------------------------
- // allow other windows messages to be processed
- yield_value = yield_pump();
- // after processing any messages, look for responce pdu
- // did the response pdu arrive?
- SNMP_WAIT;
- status = pdu_container->check_if_arrived( (int) request_id);
- SNMP_SIGNAL;
- if ( status)
- {
- SNMPDEBUG("++ SNMP++, Extract From PDU Cont n");
- blocked = FALSE; // no longer blocked on this request
- // pick up the data
- SNMP_WAIT;
- pdu_container->get_slot( (int) request_id, // for this rid
- &hSrcRecvEnt, // this source entity
- &hDstRecvEnt, // this dest entity
- &hRecvContext, // this community
- &lnRecvPduType, // this pdu type
- &lnRecvRequestId, // rid returned
- &lnErrorStatus, // error status
- &lnErrorIndex, // error index
- &my_callback, // callback function
- &my_callback_data, // callback data
- &hRecvVbl); // vbl returned
- SNMP_SIGNAL;
- SNMPDEBUG("++ SNMP++, Get VB Count n");
- // extract the snmp++ vbs from the winsnmp varbindlist
- extract_from_varbindlist( hRecvVbl, pdu);
- // set return error status vals
- error_status = ( int) lnErrorStatus;
- set_error_status( &pdu, error_status);
- set_error_index( &pdu, (int) lnErrorIndex);
- SNMPDEBUG("++ SNMP++, Free Vbl, Ent, Ent, Context n");
- // free up the receive resources
- SnmpFreeVbl( hRecvVbl);
- SnmpFreeEntity( hSrcRecvEnt);
- SnmpFreeEntity( hDstRecvEnt);
- SnmpFreeContext( hRecvContext);
- SNMP_WAIT;
- pdu_container->clear_request_id( (int) request_id);
- SNMP_SIGNAL;
- } // end if pdu_received
- //----------[ did the yield find a stop ]----------------
- if ( yield_value != SNMP_CLASS_SUCCESS)
- {
- SNMP_WAIT;
- pdu_container->clear_request_id( (int) request_id);
- SNMP_SIGNAL;
- return yield_value;
- };
- Sleep(1);
- } // end while blocked & ! timeout
- //------[ determine if blocked ]-----------------------------
- // if we are blocked then its a timeout;
- // otherwise, it a response. In the response case,
- // we return a "warning" if pdu.error_status is set
- // by the agent.
- if ( blocked)
- {
- SNMP_WAIT;
- pdu_container->clear_request_id( (int) request_id);
- SNMP_SIGNAL;
- return_status = SNMP_CLASS_TIMEOUT;
- }
- else
- {
- if ( error_status == 0)
- return_status = SNMP_CLASS_SUCCESS;
- else
- return_status = SNMP_CLASS_ERR_STATUS_SET;
- }
- return return_status;
- };
- //-----------------------------------------------------------------
- //--------[ sendMsg ]----------------------------------------------
- //-----------------------------------------------------------------
- int Snmp::sendMsg( SnmpTarget &target, // target of send
- Pdu &pdu, // the pdu to send
- long int non_reps, // # of non repititions
- long int max_reps, // # of max repititions
- long int request_id) // unique request id
- {
- SNMPAPI_STATUS Wstatus; // return status for snmp calls
- HSNMP_PDU hSendPdu;
- HSNMP_ENTITY hDstEntity; // destination entity
- HSNMP_ENTITY hSrcEntity; // source entity
- HSNMP_CONTEXT hSendContext; // send context
- unsigned long my_timeout; // target specific timeout
- int my_retry; // target specific retry
- SmiOCTETS my_community_name; // community name to use
- int return_status;
- OctetStr my_get_community, my_set_community;
- unsigned short action;
- GenAddress address;
- HSNMP_VBL hvbl;
- unsigned char version;
- //---------[ make sure pdu is valid ]---------------------------------
- if ( !pdu.valid()) {
- SNMPDEBUG("-- SNMP++, PDU Object Invalidn");
- return SNMP_CLASS_INVALID_PDU;
- }
- //---------[ make sure target is valid ]-------------------------
- // make sure that the target is valid
- if ( ! target.valid()) {
- SNMPDEBUG("-- SNMP++, Target Object Invalidn");
- return SNMP_CLASS_INVALID_TARGET;
- }
- //---------[ get the action from the pdu ]---------------------
- action = pdu.get_type();
- // try to resolve the target as a community-based target
- if ( !target.resolve_to_C(my_get_community,
- my_set_community,
- address,
- my_timeout,
- my_retry,
- version)) {
- SNMPDEBUG("-- SNMP++, CTarget Resolve Failn");
- return SNMP_CLASS_INVALID_TARGET;
- }
- //-----[ set the translation mode to no translation based on the target type ]
- Wstatus = SnmpSetTranslateMode( version == version1 ? SNMPAPI_UNTRANSLATED_V1 : SNMPAPI_UNTRANSLATED_V2);
- if ( Wstatus != SNMPAPI_SUCCESS) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Failure setting UNTRANSLATED_V1 moden");
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- SNMPDEBUG("++ SNMP++, Make Entities, Context & PDU n");
- //-----[ set destination entity ]--------------------------------
- // Determine set the port or socket that we should be
- // sending to.
- unsigned int port = 0xffff;
- char * addrStr;
- int addrType = address.get_type();
- switch (addrType) {
- case type_udp:
- {
- UdpAddress udpAddr(address);
- port = udpAddr.get_port();
- addrStr = udpAddr.IpAddress::get_printable();
- break;
- }
- case type_ipxsock:
- {
- IpxSockAddress ipxsockAddr(address);
- port = ipxsockAddr.get_socket();
- addrStr = ipxsockAddr.IpxAddress::get_printable();
- break;
- }
- default:
- // Otherwise we will be sending to the default.
- addrStr = address.get_printable();
- break;
- }
- hDstEntity = SnmpStrToEntity( (HSNMP_SESSION) iv_snmp_session, addrStr);
- if ( hDstEntity == SNMPAPI_FAILURE) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Fail Maiking Dest Entityn");
- if (SNMPAPI_ENTITY_UNKNOWN == Wstatus) {
- return SNMP_CLASS_TL_UNSUPPORTED;
- } else if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- if (port != 0xffff) {
- HMODULE hModule;
- functionPortSet portbuilder;
- hModule = GetModuleHandle("WSNMP32");
- portbuilder = (functionPortSet) GetProcAddress( hModule,"SnmpSetPort");
- if ( portbuilder != NULL) {
- Wstatus = (portbuilder)(hDstEntity, port);
- if ( Wstatus != SNMPAPI_SUCCESS) {
- SNMPDEBUG("-- SNMP++, Failure Setting Dest Entity Portn");
- SnmpFreeEntity ( hDstEntity);
- return SNMP_CLASS_INVALID_ADDRESS; // cannot set alt port
- }
- }
- }
- hSrcEntity = SnmpStrToEntity( (HSNMP_SESSION) iv_snmp_session, addrStr);
- if ( hSrcEntity == SNMPAPI_FAILURE) {
- SNMPDEBUG("-- SNMP++, Fail Making Source Entityn");
- SnmpFreeEntity ( hDstEntity);
- if (SNMPAPI_ENTITY_UNKNOWN == Wstatus) {
- return SNMP_CLASS_TL_UNSUPPORTED;
- } else if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- if (action != sNMP_PDU_TRAP ) {
- // set the retransmit mode on
- Wstatus = SnmpSetRetransmitMode( SNMPAPI_ON);
- if ( Wstatus != SNMPAPI_SUCCESS) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Fail setting RETRANSMIT_MODE=ONn");
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- // set the timeout
- Wstatus = SnmpSetTimeout( hDstEntity, (SmiTIMETICKS) my_timeout);
- if ( Wstatus != SNMPAPI_SUCCESS) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Fail setting timeout n");
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- // set the retry
- Wstatus = SnmpSetRetry( hDstEntity, (SmiUINT32) my_retry);
- if ( Wstatus != SNMPAPI_SUCCESS) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Fail setting retry n");
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- }
- //------[ build the context ]--------------------------------------
- // v1 context is the community name in WinSnmp
- // use the commnuty from the Target ovject
- // depending on the action use either the get or set
- // community name
- //
- if ( action == sNMP_PDU_SET) {
- my_community_name.ptr = (unsigned char *) my_set_community.data();
- my_community_name.len = my_set_community.len();
- } else {
- my_community_name.ptr = (unsigned char *) my_get_community.data();
- my_community_name.len = my_get_community.len();
- }
- hSendContext = SnmpStrToContext( (HSNMP_SESSION) iv_snmp_session,(smiLPOCTETS)&my_community_name);
- if ( hSendContext == SNMPAPI_FAILURE) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, FailMaiking Contextn");
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- //-------[ make a WinSNMP vbl without the oid ]---------------------
- hvbl = SnmpCreateVbl( (HSNMP_SESSION) iv_snmp_session, NULL, NULL);
- if ( hvbl == SNMPAPI_FAILURE) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Fail Making Vbln");
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- SnmpFreeContext( hSendContext);
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- //-------[ load WinSNMP varbind list using Snmp++ Vbs ]----------
- return_status = load_varbindlist( (HSNMP_SESSION) iv_snmp_session, hvbl, pdu);
- if ( return_status != SNMP_CLASS_SUCCESS) {
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- SnmpFreeContext( hSendContext);
- SnmpFreeVbl( hvbl);
- SNMPDEBUG("-- SNMP++, Fail Loading Vbln");
- return return_status;
- }
- //-----[ make the WinSNMP pdu ]---------------------------------------
- hSendPdu = SnmpCreatePdu( (HSNMP_SESSION) iv_snmp_session, // for this session
- (smiINT) action, // defined action
- request_id, // request id
- (action == sNMP_PDU_GETBULK) ? (smiINT) non_reps : NULL, // non repeaters
- (action == sNMP_PDU_GETBULK) ? (smiINT) max_reps :NULL, // max repetitions
- pdu.get_vb_count() ? hvbl : NULL ); // vbl to send
- if ( hSendPdu == SNMPAPI_FAILURE) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Failure Making Pdun");
- SnmpFreeVbl( hvbl);
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- SnmpFreeContext( hSendContext);
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else {
- return SNMP_CLASS_INTERNAL_ERROR;
- }
- }
- //-------[ Send out the PDU ]------------------------------------------
- SNMPDEBUG("++ SNMP++, Send PDU n");
- Wstatus = SnmpSendMsg(
- (HSNMP_SESSION) iv_snmp_session, // handle to session
- hSrcEntity, // handle to source destination
- hDstEntity, // handle to destination entity
- hSendContext, // handle to context
- hSendPdu ); // the pdu to send
- //-----[ free everything up ]---------------------------------------
- SnmpFreePdu( hSendPdu);
- SnmpFreeVbl( hvbl);
- SnmpFreeEntity ( hDstEntity);
- SnmpFreeEntity ( hSrcEntity);
- SnmpFreeContext( hSendContext);
- if (Wstatus == SNMPAPI_FAILURE) {
- Wstatus = SnmpGetLastError( (HSNMP_SESSION) iv_snmp_session);
- SNMPDEBUG("-- SNMP++, Failure Sending Pdun");
- if (SNMPAPI_ALLOC_ERROR == Wstatus) {
- return SNMP_CLASS_RESOURCE_UNAVAIL;
- } else if (SNMPAPI_TL_NOT_SUPPORTED == Wstatus) {
- return SNMP_CLASS_TL_UNSUPPORTED;
- } else if (SNMPAPI_OPERATION_INVALID == Wstatus) {
- return SNMP_CLASS_INVALID_OPERATION;
- } else if (SNMPAPI_OTHER_ERROR == Wstatus) {
- return SNMP_CLASS_ERROR;
- } else if (SNMPAPI_SESSION_INVALID == Wstatus ||
- SNMPAPI_ENTITY_INVALID == Wstatus ||
- SNMPAPI_CONTEXT_INVALID == Wstatus ||
- SNMPAPI_PDU_INVALID == Wstatus ||
- SNMPAPI_NOT_INITIALIZED == Wstatus) {
- return SNMP_CLASS_INTERNAL_ERROR;
- } else {
- // The rest of the Wstatus codes are pathalogical
- // transport layer failures
- return SNMP_CLASS_TL_FAILED;
- }
- } else {
- return SNMP_CLASS_SUCCESS;
- }
- }