From 21b80a73707754d7bbeba36ef71eb517efd8e447 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Wed, 24 Jul 2013 23:32:33 -0300 Subject: [PATCH] BaseSniffer is now iterable. --- include/sniffer.h | 93 +++++++++++++++++++++++++++++++++++++++++++++++ src/sniffer.cpp | 8 ++++ 2 files changed, 101 insertions(+) diff --git a/include/sniffer.h b/include/sniffer.h index f098b28..6d5bafd 100644 --- a/include/sniffer.h +++ b/include/sniffer.h @@ -36,6 +36,7 @@ #include #include #include +#include #include "pdu.h" #include "ethernetII.h" #include "radiotap.h" @@ -48,6 +49,8 @@ #include "exceptions.h" namespace Tins { + class SnifferIterator; + /** * \class BaseSniffer * \brief Base class for sniffers. @@ -60,6 +63,11 @@ namespace Tins { */ class BaseSniffer { public: + /** + * The iterator type. + */ + typedef SnifferIterator iterator; + #if TINS_IS_CXX11 /** * \brief Move constructor. @@ -178,6 +186,16 @@ namespace Tins { * \brief Gets the file descriptor associated with the sniffer. */ int get_fd(); + + /** + * Retrieves an iterator to the next packet in this sniffer. + */ + iterator begin(); + + /** + * Retrieves an end iterator. + */ + iterator end(); protected: /** * Default constructor. @@ -353,6 +371,81 @@ namespace Tins { { return HandlerProxy(ptr, function); } + + /** + * \brief Iterates over packets sniffed by a BaseSniffer. + */ + class SnifferIterator : public std::iterator { + public: + /** + * Constructs a SnifferIterator. + * \param sniffer The sniffer to iterate. + */ + SnifferIterator(BaseSniffer *sniffer = 0) + : sniffer(sniffer) + { + if(sniffer) + advance(); + } + + /** + * Advances the iterator. + */ + SnifferIterator& operator++() { + advance(); + return *this; + } + + /** + * Advances the iterator. + */ + SnifferIterator operator++(int) { + SnifferIterator other(*this); + advance(); + return other; + } + + /** + * Dereferences the iterator. + * \return references to the current packet. + */ + PDU &operator*() { + return *pkt.pdu(); + } + + /** + * Dereferences the iterator. + * \return pointer to the current packet. + */ + PDU *operator->() { + return &(**this); + } + + /** + * Compares this iterator for equality. + * \param rhs The iterator to be compared to. + */ + bool operator==(const SnifferIterator &rhs) { + return sniffer == rhs.sniffer; + } + + /** + * Compares this iterator for in-equality. + * \param rhs The iterator to be compared to. + */ + bool operator!=(const SnifferIterator &rhs) { + return !(*this == rhs); + } + private: + void advance() { + pkt = sniffer->next_packet(); + if(!pkt) + sniffer = 0; + } + + BaseSniffer *sniffer; + Packet pkt; + }; } #endif // TINS_SNIFFER_H diff --git a/src/sniffer.cpp b/src/sniffer.cpp index c39b297..a18a8e3 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -101,6 +101,14 @@ int BaseSniffer::get_fd() { return pcap_get_selectable_fd(handle); } +BaseSniffer::iterator BaseSniffer::begin() { + return iterator(this); +} + +BaseSniffer::iterator BaseSniffer::end() { + return iterator(0); +} + bool BaseSniffer::set_filter(const std::string &filter) { if(actual_filter.bf_insns) pcap_freecode(&actual_filter);