pdu_cont.cpp
上传用户:czjinwang
上传日期:2007-01-12
资源大小:2484k
文件大小:10k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*===================================================================
  2.   Copyright (c) 1999
  3.   Hewlett-Packard Company
  4.   ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  5.   Permission to use, copy, modify, distribute and/or sell this software 
  6.   and/or its documentation is hereby granted without fee. User agrees 
  7.   to display the above copyright notice and this license notice in all 
  8.   copies of the software and any documentation of the software. User 
  9.   agrees to assume all liability for the use of the software; Hewlett-Packard 
  10.   makes no representations about the suitability of this software for any 
  11.   purpose. It is provided "AS-IS without warranty of any kind,either express 
  12.   or implied. User hereby grants a royalty-free license to any and all 
  13.   derivatives based upon this software code base. 
  14.   
  15.   P D U _ C O N T . C P P
  16.   PDU CONTAINER CLASS IMPLEMENTATION
  17.   DESIGN:
  18.   Peter E Mellquist
  19.   AUTHOR:
  20.   Peter E Mellquist
  21.   DATE:
  22.   July 25, 1999
  23.   DESCRIPTION:
  24.   This module contains the implementation for the pdu
  25.   container class.  
  26.   LANGUAAGE:
  27.   ANSI C++
  28.   OPERATING SYSTEM(S):
  29.   Win32
  30. =====================================================================*/
  31. char pducls_cpp_version[]="#(@)SNMP++ 2.8 $Header: pdu_cont.cpp,v 1.10 96/03/16 16:02:46 hmgr Exp $";
  32. #include "pdu_cont.h"  // include file for pdu class
  33. #include "winsnmp.h"  // winsnmp include file
  34. #include "pdu.h"         // include pdu class definition
  35. #include "snmperrs.h"    // include snmp error messages
  36. #include "target.h"
  37. //--------------[  Pdu_Container::Pdu_Container() ]--------------------
  38. // constructor
  39. // initialize all the slots to not pending
  40. // clear all the statistic counters
  41. Pdu_Container::Pdu_Container()
  42. {
  43.   int z;
  44.   for (z=0;z<MAX_PDU_SLOTS;z++)
  45.      slots[z] = NULL;  
  46.   // init stats
  47.   pdus_sent = 0;
  48.   pdus_received = 0;
  49.   pdus_received_err = 0;
  50.   pdus_sent_err = 0;
  51.   timeout_count = 0;
  52.   max_queue_size = 0;
  53.   trap_count = 0;
  54.   trap_sent = 0;
  55.   decode_errors = 0;
  56.   stray_responses = 0;
  57.   invalid_pdu_types = 0;
  58.   current_request_id = MAX_REQUEST_ID;
  59. };
  60. // destructor
  61. Pdu_Container::~Pdu_Container()
  62. {
  63.    for (int z=0;z<MAX_PDU_SLOTS;z++)
  64.    delete slots[z];
  65. };
  66. //-------[ search for any dangling enteries
  67. //    for a given WinSNMP session
  68. void Pdu_Container::search_and_destroy( HSNMP_SESSION hSession, Snmp *snmp)
  69. {
  70.   int z;
  71.   for (z=0;z<MAX_PDU_SLOTS;z++)
  72.   {
  73.      if (( slots[z]!= NULL ) && ( slots[z]->hSession == hSession))
  74.      {
  75. if ( slots[z]->pdu_arrived )
  76. {
  77.     SNMPDEBUG("++ SNMP++, Search and Destroy Hitn");
  78.         // check to see if it was an async request then
  79.         // we need to inform the callback with the 
  80.         // SNMP_CLASS_SESSION_DESTROYED message
  81.         if ( slots[z]->callback != NULL)
  82.         {
  83.            // fire destroy message to the specified callback
  84.            SNMPDEBUG("++ SNMP++, Destroying Snmp Object Async Notifyn");
  85.            // we don't have the actual pdu, just the rid
  86.            Pdu pdu;
  87.            set_request_id( &pdu, slots[z]->RequestId); 
  88.            CTarget v1t;
  89.           (slots[z]->callback)( (int) SNMP_CLASS_SESSION_DESTROYED, // reason
  90.                        (Snmp*) snmp,                    // snmp++ session who own the req
  91.                (Pdu&) pdu,            // pdu
  92.                (SnmpTarget&) v1t,                  // target
  93.                (void*) slots[z]->callback_data);    // callback data
  94.         }
  95. // free up the WinSNMP variables
  96. SnmpFreeEntity( slots[z]->hSourceEntity);
  97. SnmpFreeEntity( slots[z]->hDestEntity);
  98. SnmpFreeContext( slots[z]->hRecContext);
  99. SnmpFreeVbl( slots[z]->hRecVbl);
  100. }
  101. // free up the slot
  102.         delete slots[z];
  103. slots[z] = NULL;   
  104.      }
  105.   };
  106. };
  107. //-------[ get a request id, don't save it in the pending table ]------
  108. long int Pdu_Container::get_request_id()
  109. {
  110.    current_request_id--;
  111.    if (current_request_id < MIN_REQUEST_ID)
  112.      current_request_id = MAX_REQUEST_ID;
  113.    return current_request_id;
  114. };
  115. //--------[ get a request is from the pdu container class ]---------
  116. // this one records the rid in the pending table
  117. long int Pdu_Container::get_request_id( HSNMP_SESSION hSession,
  118.     snmpcallback cb,
  119.                     void * cbd)
  120. {
  121.   int z=0;
  122.   while (z<MAX_PDU_SLOTS)
  123.   {
  124.      long int my_rid;
  125.      if ( slots[z] == NULL)
  126.      {
  127.        current_request_id--;
  128.        if (current_request_id < MIN_REQUEST_ID)
  129.       current_request_id = MAX_REQUEST_ID;
  130.        my_rid = current_request_id;
  131.        slots[z] = new Pdu_Slot;
  132.        if ( slots[z] == NULL)
  133.           return -1;
  134.        slots[z]->pending = TRUE;       // this request is pending
  135.        slots[z]->pdu_arrived = FALSE;   // response has not arrived
  136.        slots[z]->hSession = hSession;   // no session handle
  137.        slots[z]->request_id = my_rid;   // set rid pending
  138.        slots[z]->callback = cb;       // remember callback ptr
  139.        slots[z]->callback_data = cbd;   // remember callback data
  140.        set_max_queue( z);
  141.        return my_rid;
  142.      }
  143.      z++;
  144.   }
  145.   return -1;  // no slots available
  146. };
  147. //------------[ Pdu_Container::clear_request_id(long int rid) ]----------
  148. // clear the slot to make it available again
  149. void Pdu_Container::clear_request_id( const long int rid)
  150. {
  151.    int w=0;
  152.    while ( w < MAX_PDU_SLOTS)
  153.    {
  154.      if ((slots[w] != NULL) && ( slots[w]->request_id == rid))
  155.      {
  156.         delete slots[w];
  157.         slots[w] = NULL;
  158.     return;
  159.      }
  160.      w++;
  161.    }
  162. };
  163. //----------[ Pdu_Container::check_if_arrived( long int rid) ]----------
  164. // check if a pending pdu has arrived
  165. int Pdu_Container::check_if_arrived( const long int rid)
  166. {
  167.   int w=0;
  168.   // look through all the slots for a rid match
  169.   // and an arrival
  170.   while(w<MAX_PDU_SLOTS)
  171.   {
  172.      if (( slots[w] != NULL) &&( slots[w]->request_id == rid)&&(slots[w]->pdu_arrived))
  173.        return TRUE;
  174.      w++;
  175.   }
  176.   return FALSE;
  177. };
  178. //------[ Pdu_Container::check_if_pending( long int rid) ]-----------
  179. // determine if a pdu slot is pending
  180. // received pdus are only placed into a slot
  181. // if it is pending
  182. int Pdu_Container::check_if_pending( const long int rid, snmpcallback *cb)
  183. {
  184.   int w=0;
  185.   // look for a rid match and a pending request
  186.   // if found, return the callback ptr
  187.   while ( w<MAX_PDU_SLOTS)
  188.   {
  189.      if (( slots[w] != NULL) &&(slots[w]->request_id ==rid)&&(slots[w]->pending))
  190.      {
  191. *cb = slots[w]->callback;
  192. return TRUE;   // don't pull the data out, just report it there
  193.      }
  194.      w++;
  195.   }
  196.   *cb = 0;
  197.   return FALSE;
  198. };
  199. //---------[ Pdu_Container::set_slot ]----------------------------------
  200. // set a slot with an arrived pdu
  201. void Pdu_Container::set_slot( long int rid,  // slot to set as arrived
  202.  HSNMP_SESSION hSession,  // WinSnmp Session handle
  203.  HSNMP_ENTITY  hSourceEntity,  // Source Entity
  204.  HSNMP_ENTITY  hDestEntity,  // Destination Entity
  205.  HSNMP_CONTEXT hRecContext,  // Receive Context
  206.  smiINT        PduType,  // Type of pdu
  207.  smiINT        RequestId,  // Request ID
  208.  smiINT        ErrorStatus,  // Error Status
  209.  smiINT        ErrorIndex,  // Error Index
  210.  HSNMP_VBL     hRecVbl)  // Received Variable Binding List
  211. {
  212.     int w=0;
  213.     int z=-1;
  214.     SNMPDEBUG("++ SNMP++, in Set Slot n");
  215.     // find the slot
  216.     while (w<MAX_PDU_SLOTS)
  217.     {
  218.        if (( slots[w] != NULL) &&( slots[w]->request_id == rid))
  219.  z = w;
  220.        w++;
  221.     }
  222.     if ((z<0)||(z>=MAX_PDU_SLOTS)) return;
  223.     slots[z]->pdu_arrived = TRUE;       // mark as arrived
  224.     // fill in the params
  225.     slots[z]->hSession = hSession;
  226.     slots[z]->hSourceEntity = hSourceEntity;
  227.     slots[z]->hDestEntity = hDestEntity;
  228.     slots[z]->hRecContext = hRecContext;
  229.     slots[z]->PduType = PduType;
  230.     slots[z]->RequestId = RequestId;
  231.     slots[z]->ErrorStatus = ErrorStatus;
  232.     slots[z]->ErrorIndex = ErrorIndex;
  233.     slots[z]->hRecVbl = hRecVbl;
  234.     SNMPDEBUG("++ SNMP++, Out Set Slot n");
  235. };
  236. //------------[ Pdu_Container::get_slot ]------------------------------
  237. // get the data from a slot
  238. //
  239. void Pdu_Container::get_slot( long int rid, // for this rid
  240.     HSNMP_ENTITY  *hSrcRecvEnt,
  241.     HSNMP_ENTITY  *hDstRecvEnt,
  242.     HSNMP_CONTEXT *hRecvContext,
  243.     smiINT *lnRecvPduType,
  244.     smiINT *lnRecvRequestId,
  245.     smiINT *lnErrorStatus,
  246.     smiINT *lnErrorIndex,
  247.     snmpcallback *cb,
  248.     void * *cbd,
  249.     HSNMP_VBL *hRecvVbl)
  250. {
  251.     int w=0;
  252.     int z=-1;
  253.     // find the slot
  254.     while (w<MAX_PDU_SLOTS)
  255.     {
  256.        if ((slots[w] != NULL) &&( slots[w]->request_id == rid))
  257.  z = w;
  258.        w++;
  259.     }
  260.     if ((z<0)||(z>=MAX_PDU_SLOTS))
  261.        return;
  262.      // fill in the return variables
  263.      *hSrcRecvEnt = slots[z]->hSourceEntity;
  264.      *hDstRecvEnt = slots[z]->hDestEntity;
  265.      *hRecvContext = slots[z]->hRecContext;
  266.      *lnRecvPduType = slots[z]->PduType;
  267.      *lnRecvRequestId = slots[z]->RequestId;
  268.      *lnErrorStatus = slots[z]->ErrorStatus;
  269.      *lnErrorIndex = slots[z]->ErrorIndex;
  270.      *hRecvVbl = slots[z]->hRecVbl;
  271.      *cb = slots[z]->callback;
  272.      *cbd = slots[z]->callback_data;
  273.      // clear the slot
  274.      delete slots[z];
  275.      slots[z] = NULL;
  276. };
  277. // return the callback information for
  278. // a given request id
  279. int Pdu_Container::get_cb_info( long int rid,
  280.  snmpcallback *cb,
  281.  void * *cbd)
  282. {
  283.     int w=0;
  284.     int z=-1;
  285.     // find the slot
  286.     while (w<MAX_PDU_SLOTS)
  287.     {
  288.        if (( slots[w] != NULL ) &&( slots[w]->request_id == rid)&&( slots[w]->callback !=0))
  289.  z = w;
  290.        w++;
  291.     }
  292.     if ((z<0)||(z>=MAX_PDU_SLOTS))
  293.     {
  294.        *cb=0;
  295.        *cbd=0;
  296.        return FALSE;
  297.     }
  298.      // fill in the return variables
  299.      *cb = slots[z]->callback;
  300.      *cbd = slots[z]->callback_data;
  301.      delete slots[z];
  302.      slots[z] = NULL;
  303.      return TRUE;
  304. };