⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 notifyqueue.cpp

📁 SNMP++程序源码 for ll .8snmp++2_8.tar.Z 嵌入式linux环境下的SNMP开发代码
💻 CPP
字号:
/*===================================================================  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.      U S E R T I M E O U T . C P P               CNotifyEventQueue CLASS DEFINITION             COPYRIGHT HEWLETT PACKARD COMPANY 1999            INFORMATION NETWORKS DIVISION            NETWORK MANAGEMENT SECTION                  VERSION:        $Revision: 1.12 $             DESIGN:        Tom Murray                      AUTHOR:        Tom Murray            DATE:        Sept 12, 1999            LANGUAGE:        ANSI C++             OPERATING SYSTEMS:        DOS/WINDOWS 3.1        BSD UNIX            DESCRIPTION:        Queue for holding callback associated with user defined         timeouts            COMPILER DIRECTIVES:        UNIX - For UNIX build              CHANGE HISTORY:=====================================================================*/char notifyqueue_version[]="$Header: notifyqueue.cpp,v 1.12 97/03/26 09:18:43 hmgr Exp $";// For debuggin cout's#include <iostream.h>#ifdef sun#include <stdio.h>#include <errno.h>#include <collect.h>#include <oid.h>#endif//-----[ includes ]----------------------------------------------------extern "C"{#include <errno.h>}//----[ snmp++ includes ]----------------------------------------------      #include "notifyqueue.h"	// queue for holding sessions waiting for async notifications//--------[ globals ]---------------------------------------------------CNotifyEventQueue *notifyEventList;//--------[ forwards ]--------------------------------------------------//--------[ externs ]---------------------------------------------------//-----[ macros ]------------------------------------------------------// should be in snmp.h...#define SNMP_PORT 161	      // standard port # for SNMP#define SNMP_TRAP_PORT 162    // standard port # for SNMP traps//----[ CNotifyEvent class ]------------------------------------------------ CNotifyEvent::CNotifyEvent(Snmp * snmp, 			   const OidCollection &trapids,			   const TargetCollection &targets, 			   const AddressCollection &addresses) {  m_snmp = snmp;  // create new collections using parms passed in  notify_ids = new OidCollection( trapids);  notify_targets = new TargetCollection ( targets);  notify_addresses = new AddressCollection ( addresses); }CNotifyEvent::~CNotifyEvent() {  // free up local collections  if ( notify_ids != 0)    delete notify_ids;  notify_ids = NULL;  if ( notify_targets != 0)    delete notify_targets;  notify_targets = NULL;    if ( notify_addresses != 0)    delete notify_addresses;  notify_addresses = NULL;}Snmp * CNotifyEvent::GetId() {   return(m_snmp);}int CNotifyEvent::notify_filter(const Oid &trapid, const SnmpTarget &target) const{  int target_count, has_target = FALSE, target_matches = FALSE;  int trapid_count, has_trapid = FALSE, trapid_matches = FALSE;  GenAddress targetaddr, tmpaddr;  // figure out how many targets, handle empty case as all targets  if ((notify_targets) && (target_count = notify_targets->size())) {    CTarget * ctarget = (CTarget *) &target;    CTarget tmptarget;    has_target = TRUE;    ctarget->get_address(targetaddr);    if (targetaddr.valid()) {      // loop through all targets in the collection      for ( int x=1;x<=target_count; x++)       // for all targets      {	if (notify_targets->get_element(tmptarget, x-1))	  continue;	tmptarget.get_address(tmpaddr);	if ((tmpaddr.valid()) &&	    (targetaddr == tmpaddr) &&	    (!strcmp(ctarget->get_readcommunity(), 		     tmptarget.get_readcommunity()))) {	  target_matches = TRUE;	  break;	}      }    }  }  // else no targets means all targets  // figure out how many trapids, handle empty case as all trapids  if ((notify_ids) && (trapid_count = notify_ids->size())) {    Oid tmpoid;    has_trapid = TRUE;    // loop through all trapids in the collection    for ( int y=1;y<=trapid_count; y++)       // for all trapids    {      if (notify_ids->get_element(tmpoid, y-1))	continue;      if (trapid == tmpoid) {	trapid_matches = TRUE;	break;      }    }  }  // else no trapids means all traps  // Make the callback if the trap passed the filters  if ((has_target && !target_matches) || (has_trapid && !trapid_matches)) {    return FALSE;  }  else {    return TRUE;  }}int CNotifyEvent::Callback(SnmpTarget & target, Pdu & pdu, 			   int status) {  Oid trapid;  int reason;  pdu.get_notify_id(trapid);  // Make the callback if the trap passed the filters  if ((m_snmp) && (notify_filter(trapid, target))) {          if (SNMP_CLASS_TL_FAILED == status) {      reason = SNMP_CLASS_TL_FAILED;    } else {      reason = SNMP_CLASS_NOTIFICATION;    }    //------[ call into the callback function ]-------------------------    (m_snmp->get_notify_callback())(       reason,      m_snmp,			// snmp++ session who owns the req      pdu,			// trap pdu      target,			// target      m_snmp->get_notify_callback_data()); // callback data  }    return SNMP_CLASS_SUCCESS;}//----[ CNotifyEventQueueElt class ]-------------------------------------- CNotifyEventQueueElt::CNotifyEventQueueElt(CNotifyEvent *notifyevent,					   CNotifyEventQueueElt *next,					   CNotifyEventQueueElt *previous):  m_notifyevent(notifyevent), m_next(next), m_previous(previous){    /*------------------------------------------*/    /* Finish insertion into doubly linked list */    /*------------------------------------------*/  if (m_next)    m_next->m_previous = this;  if (m_previous)    m_previous->m_next = this;}CNotifyEventQueueElt::~CNotifyEventQueueElt(){    /*-------------------------------------*/    /* Do deletion form doubly linked list */    /*-------------------------------------*/  if (m_next)    m_next->m_previous = m_previous;  if (m_previous)    m_previous->m_next = m_next;  if (m_notifyevent)    delete m_notifyevent;}CNotifyEventQueueElt *CNotifyEventQueueElt::GetNext() {   return(m_next);}CNotifyEvent *CNotifyEventQueueElt::GetNotifyEvent() {   return(m_notifyevent);}CNotifyEvent *CNotifyEventQueueElt::TestId(Snmp *snmp){  if (m_notifyevent && (m_notifyevent->GetId() == snmp))    return(m_notifyevent);  else    return(NULL);}//----[ CNotifyEventQueue class ]-------------------------------------- CNotifyEventQueue::CNotifyEventQueue():   m_head(NULL,NULL,NULL), m_msgCount(0), m_notify_fd(-1) {//TM: could do the trap registration setup here but seems better to//wait until the app actually requests trap receives by calling//notify_register().}CNotifyEventQueue::~CNotifyEventQueue(){  CNotifyEventQueueElt *leftOver;    /*--------------------------------------------------------*/    /* walk the list deleting any elements still on the queue */    /*--------------------------------------------------------*/  while (leftOver = m_head.GetNext())    delete leftOver;}int CNotifyEventQueue::AddEntry(Snmp * snmp, 				const OidCollection &trapids,				const TargetCollection &targets,				const AddressCollection &addresses) {   if (!m_msgCount) {    // This is the first request to receive notifications    // Set up the socekt for the snmp trap port (162)    struct sockaddr_in mgr_addr;    // open a socket to be used for the session    if (( m_notify_fd = (int) socket( AF_INET, SOCK_DGRAM,0)) < 0)      return SNMP_CLASS_TL_FAILED;    else    {      // set up the manager socket attributes      memset(&mgr_addr, 0, sizeof(mgr_addr));      mgr_addr.sin_family = AF_INET;      mgr_addr.sin_addr.s_addr = htonl( INADDR_ANY);      mgr_addr.sin_port = htons( SNMP_TRAP_PORT);      // bind the socket      if ( bind( (int) m_notify_fd,		 (sockaddr*)&mgr_addr,		 sizeof(mgr_addr)) < 0) {perror("bind");	// TM: should probably check this...	return SNMP_CLASS_TL_IN_USE;      }#ifdef SNMPX11      // Tell X11 to watch our file descriptor      SnmpX11AddInput( m_notify_fd, m_inputId);#endif // SNMPX11    }  }      CNotifyEvent *newEvent = new CNotifyEvent(snmp, trapids, targets, addresses);    /*---------------------------------------------------------*/    /* Insert entry at head of list, done automagically by the */    /* constructor function, so don't use the return value.    */    /*---------------------------------------------------------*/  (void) new CNotifyEventQueueElt(newEvent, m_head.GetNext(), &m_head);  m_msgCount++;  return SNMP_CLASS_SUCCESS;}CNotifyEvent *CNotifyEventQueue::GetEntry(Snmp * snmp){  CNotifyEventQueueElt *msgEltPtr = m_head.GetNext();  CNotifyEvent *returnVal = NULL;  while (msgEltPtr){    if (returnVal = msgEltPtr->TestId(snmp))      return(returnVal);    msgEltPtr = msgEltPtr->GetNext();  }  return (NULL);}void CNotifyEventQueue::DeleteEntry(Snmp * snmp){  CNotifyEventQueueElt *msgEltPtr = m_head.GetNext();  CNotifyEvent *returnVal = NULL;  while (msgEltPtr){    if (returnVal = msgEltPtr->TestId(snmp)){      delete msgEltPtr;      m_msgCount--;      break;    }    msgEltPtr = msgEltPtr->GetNext();  }  // shut down the trap socket (if valid) if not using it.  if ((m_msgCount <= 0) && (m_notify_fd >= 0)) {    close(m_notify_fd);    m_notify_fd = 0;#ifdef SNMPX11    // Tell X11 to stop watching our file descriptor    SnmpX11RemoveInput(m_inputId);#endif // SNMPX11  }}int CNotifyEventQueue::GetNextTimeout(msec &/*sendTime*/) {  // we never have any timeouts  return 1;}void CNotifyEventQueue::GetFdSets(int &maxfds, 				  fd_set &readfds, 				  fd_set &/*writefds*/, 				  fd_set &/*exceptfds*/) {  if (m_notify_fd >= 0) {    FD_SET(m_notify_fd, &readfds);    if (maxfds < (m_notify_fd+1))      maxfds = m_notify_fd+1;  }  return;}int CNotifyEventQueue::GetCount() {  return m_msgCount;}extern int receive_snmp_notification(int sock,Pdu &pdu, CTarget &target); int CNotifyEventQueue::HandleEvents(const int /*maxfds*/, 				    const fd_set &readfds, 				    const fd_set &/*writefds*/, 				    const fd_set &/*exceptfds*/) {  Pdu pdu;  CTarget target;  CNotifyEventQueueElt *notifyEltPtr = m_head.GetNext();  int status = SNMP_CLASS_SUCCESS;  // pull the notifiaction off the socket  if (FD_ISSET(m_notify_fd, &readfds)) {    status = receive_snmp_notification(m_notify_fd, pdu,target);    if (SNMP_CLASS_SUCCESS == status ||	SNMP_CLASS_TL_FAILED == status) {      // If we have transport layer failure, the app will want to      // know about it.      // Go through each snmp object and check the filters, making      // callbacks as necessary       while (notifyEltPtr){ 	notifyEltPtr->GetNotifyEvent()->Callback(target, pdu, 						 status);	notifyEltPtr = notifyEltPtr->GetNext();         } // for each snmp object    }  }  return status;}int CNotifyEventQueue::DoRetries(const msec &/*sendtime*/) {  // nothing to retry  return 0;}int CNotifyEventQueue::Done() {  // we are never done  return 0;}

⌨️ 快捷键说明

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