snmp.cpp

来自「HP公司的SNMP++的Win32版本源码」· C++ 代码 · 共 1,767 行 · 第 1/5 页

CPP
1,767
字号

   //------[ 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 Fail\n");
      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 Fail\n");
      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 Event\n");
   // 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 = 0\n");
      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 Fail\n");
     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 Fail\n");
      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 Fail\n");
      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 Callback\n");
   //------[ 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 Callback\n");
   }
   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 Callback\n");
				 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 Timeout\n");
			// 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 Resolution\n");
				// 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,

⌨️ 快捷键说明

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