//=========================================================================== // $Name: cflowd-2-1-b1 $ // $Id: CflowdPacketQueue.hh,v 1.7 2000/10/24 16:18:55 dwm Exp $ //=========================================================================== // CAIDA Copyright Notice // // By accessing this software, cflowd++, you are duly informed // of and agree to be bound by the conditions described below in this // notice: // // This software product, cflowd++, is developed by Daniel W. McRobb, and // copyrighted(C) 1998 by the University of California, San Diego // (UCSD), with all rights reserved. UCSD administers the CAIDA grant, // NCR-9711092, under which part of this code was developed. // // There is no charge for cflowd++ software. You can redistribute it // and/or modify it under the terms of the GNU General Public License, // v. 2 dated June 1991 which is incorporated by reference herein. // cflowd++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use // of it will not infringe on any third party's intellectual property // rights. // // You should have received a copy of the GNU GPL along with cflowd++. // Copies can also be obtained from: // // http://www.gnu.org/copyleft/gpl.html // // or by writing to: // // University of California, San Diego // // SDSC/CAIDA // 9500 Gilman Dr., MS-0505 // La Jolla, CA 92093 - 0505 USA // // Or contact: // // info@caida.org //=========================================================================== #ifndef _CFLOWDPACKETQUEUE_HH_ #define _CFLOWDPACKETQUEUE_HH_ //--------------------------------------------------------------------------- // class CflowdPacketQueue //--------------------------------------------------------------------------- // This is really a low-level kind of packet queue interface, which // uses mmap() and semaphores. It still needs work and documentation. //--------------------------------------------------------------------------- class CflowdPacketQueue { public: static const int k_defaultSize = 2048 * 1024; //------------------------------------------------------------------------- // CflowdPacketQueue() //......................................................................... // constructor //------------------------------------------------------------------------- CflowdPacketQueue(); //------------------------------------------------------------------------- // ~CflowdPacketQueue() //......................................................................... // destructor //------------------------------------------------------------------------- ~CflowdPacketQueue(); //------------------------------------------------------------------------- // int Create(const char *name, int mapSize = k_defaultSize) //......................................................................... // Creates and opens a new queue in file named by name, with an // approximate size of mapSize. Returns 0 on success, -1 on failure. // This is used by cflowdmux to create the packet queue. //------------------------------------------------------------------------- int Create(const char *name, int mapSize = k_defaultSize); //------------------------------------------------------------------------- // int Destroy() //......................................................................... // Destroys the packet queue (but does *not* call the class // destructor). This is used to remove the shared memory segment, // and is essentially the complement of Create(). It should only be // called by cflowdmux. //------------------------------------------------------------------------- int Destroy(); //------------------------------------------------------------------------- // int Open(const char *name, int mapSize = k_defaultSize) //......................................................................... // Opens an already existent queue for reading. Returns 0 on // success, -1 on failure. //------------------------------------------------------------------------- int Open(const char *name, int mapSize = k_defaultSize); //------------------------------------------------------------------------- // int Close() //......................................................................... // Closes the queue. //------------------------------------------------------------------------- int Close(); //------------------------------------------------------------------------- // int Enqueue(ipv4addr_t ciscoIpAddr, // const unsigned char *pkt, int len) //......................................................................... // Puts a packet into the queue. Only used by cflowdmux! //------------------------------------------------------------------------- int Enqueue(ipv4addr_t ciscoIpAddr, const unsigned char *pkt, int len); //------------------------------------------------------------------------- // const char *GetPacket(ipv4addr_t & ciscoIpAddr) //......................................................................... // Returns a pointer to the next packet in the queue. This has // to be used with extreme care; you *must* get the lock first, // and GetPacket doesn't check for the lock (so it'll happily // read unlocked memory, which could lead to very unhappy // results). Also, GetPacket() doesn't do any other sanity checking // either; don't walk out of bounds with it. The way to use // this function is to lock the queue, get the number of packets // in the queue using NumPackets(), then walk through the queue // with GetPacket() exactly NumPackets() times, then release the // lock on the queue (and typically switch buffers with // ToggleBuffers()). //------------------------------------------------------------------------- const char *GetPacket(ipv4addr_t & ciscoIpAddr); //------------------------------------------------------------------------- // int ToggleBuffers(bool releaseCurrent = false) //......................................................................... // Switches to the other queue buffer. This is basically a // convenience routine for cflowdmux and cflowd to lock-step; they // each deal with an entire buffer at once and then switch to the // other one. If releaseCurrent is specified as true, ToggleBuffers // will release the lock on the current buffer before switching to // the other buffer. This should always be done for read clients. //------------------------------------------------------------------------- int ToggleBuffers(bool releaseCurrent = false); //------------------------------------------------------------------------- // int GetLock(uint8_t bufNum = 0xff) //......................................................................... // Locks the queue buffer. If bufNum is set to a value other than // 0xff, it is assumed to be a specific buffer (0 or 1) to lock, else // the current buffer is assumed. Returns 0 on success, -1 on failure. //------------------------------------------------------------------------- int GetLock(uint8_t bufNum = 0xff); //------------------------------------------------------------------------- // int ReleaseLock(uint8_t bufNum = 0xff) //......................................................................... //! Releases the lock on the queue buffer. If bufNum is set to a //! value other than 0xff, it is assumed to be a specific buffer (0 or //! 1) to release. If bufNum is 0xff, the current buffer is assumed. //! Returns 0 on success, -1 on failure. //------------------------------------------------------------------------- int ReleaseLock(uint8_t bufNum = 0xff); //------------------------------------------------------------------------- // int NumPackets() //......................................................................... // Returns the number of packets in the queue. //------------------------------------------------------------------------- int NumPackets(); //------------------------------------------------------------------------- // int NumPackets(int numPackets); //......................................................................... // Sets and returns the number of packets in the queue. WARNING! THIS // TRIES TO WRITE TO THE SHARED MEMORY REGION AND SHOULD ONLY BE CALLED // FROM cflowdmux!! //------------------------------------------------------------------------- int NumPackets(int numPackets); //------------------------------------------------------------------------- // inline time_t LastToggle() const //......................................................................... // Returns the time we last toggled buffers. //------------------------------------------------------------------------- inline time_t LastToggle() const { return(this->_lastToggle); } //-------------------------------------------------------------------------- // inline uint8_t CurrentBuffer() const //.......................................................................... //! Returns the current buffer number (0 or 1). //-------------------------------------------------------------------------- inline uint8_t CurrentBuffer() const { return(this->_currentBuffer); } private: caddr_t _mapAddr[2]; // 2 buffers int _mapLength; int _shmId; int _semId; caddr_t _writePtr; caddr_t _readPtr; uint8_t _currentBuffer; time_t _lastToggle; int GetSemaphore(const char *name); int CreateSemaphore(const char *name); }; #endif // _CFLOWDPACKETQUEUE_HH_