diff --git a/Pcap++/header/Device.h b/Pcap++/header/Device.h index c5a321027..ad4c2b4c5 100644 --- a/Pcap++/header/Device.h +++ b/Pcap++/header/Device.h @@ -53,22 +53,38 @@ namespace pcpp /// received /// @param[in] filter The filter to be set in PcapPlusPlus' GeneralFilter format /// @return True if filter set successfully, false otherwise - virtual bool setFilter(GeneralFilter& filter) + bool setFilter(GeneralFilter& filter) { std::string filterAsString; filter.parseToString(filterAsString); - return setFilter(filterAsString); + return doUpdateFilter(filterAsString); } /// Set a filter for the device. When implemented by the device, only packets that match the filter will be - /// received + /// processed. /// @param[in] filterAsString The filter to be set in Berkeley Packet Filter (BPF) syntax /// (http://biot.com/capstats/bpf.html) /// @return True if filter set successfully, false otherwise - virtual bool setFilter(std::string filterAsString) = 0; + bool setFilter(std::string const& filterAsString) + { + return doUpdateFilter(filterAsString); + } /// Clear the filter currently set on the device /// @return True if filter was removed successfully or if no filter was set, false otherwise - virtual bool clearFilter() = 0; + bool clearFilter() + { + return doUpdateFilter(""); + } + + protected: + /// @brief Updates the filter on the device with a BPF string. + /// + /// Only packets that match the filter should be processed by the device after this method is called. + /// An empty string is synonymous with ANY filter (i.e., no filtering). + /// + /// @param filterAsString A string representing the filter in BPF syntax (http://biot.com/capstats/bpf.html). + /// @return True if the operation was successful, false otherwise. + virtual bool doUpdateFilter(std::string const& filterAsString) = 0; }; } // namespace pcpp diff --git a/Pcap++/header/PcapDevice.h b/Pcap++/header/PcapDevice.h index 68d73eddf..da28371db 100644 --- a/Pcap++/header/PcapDevice.h +++ b/Pcap++/header/PcapDevice.h @@ -164,20 +164,7 @@ namespace pcpp PCPP_DEPRECATED("Prefer GeneralFilter::matches(...) method directly.") static bool matchPacketWithFilter(GeneralFilter& filter, RawPacket* rawPacket); - // implement abstract methods - - using IFilterableDevice::setFilter; - - /// Set a filter for the device. When implemented by the device, only packets that match the filter will be - /// received. Please note that when the device is closed the filter is reset so when reopening the device you - /// need to call this method again in order to reactivate the filter - /// @param[in] filterAsString The filter to be set in Berkeley Packet Filter (BPF) syntax - /// (http://biot.com/capstats/bpf.html) - /// @return True if filter set successfully, false otherwise - bool setFilter(std::string filterAsString) override; - - /// Clear the filter currently set on device - /// @return True if filter was removed successfully or if no filter was set, false otherwise - bool clearFilter() override; + protected: + bool doUpdateFilter(std::string const& filterAsString) override; }; } // namespace pcpp diff --git a/Pcap++/header/PcapFileDevice.h b/Pcap++/header/PcapFileDevice.h index 61513d560..bb06941fe 100644 --- a/Pcap++/header/PcapFileDevice.h +++ b/Pcap++/header/PcapFileDevice.h @@ -363,21 +363,18 @@ namespace pcpp /// @param[out] rawPacket A reference for an empty RawPacket where the packet will be written /// @return True if a packet was read successfully. False will be returned if the file isn't opened (also, an /// error log will be printed) or if reached end-of-file - bool getNextPacket(RawPacket& rawPacket); + bool getNextPacket(RawPacket& rawPacket) override; /// Open the file name which path was specified in the constructor in a read-only mode /// @return True if file was opened successfully or if file is already opened. False if opening the file failed /// for some reason (for example: file path does not exist) - bool open(); - - /// Set a filter for PcapNG reader device. Only packets that match the filter will be received - /// @param[in] filterAsString The filter to be set in Berkeley Packet Filter (BPF) syntax - /// (http://biot.com/capstats/bpf.html) - /// @return True if filter set successfully, false otherwise - bool setFilter(std::string filterAsString); + bool open() override; /// Close the pacp-ng file - void close(); + void close() override; + + protected: + bool doUpdateFilter(std::string const& filter) override; }; /// @class PcapNgFileWriterDevice @@ -476,11 +473,8 @@ namespace pcpp /// Flush and close the pcap-ng file void close() override; - /// Set a filter for PcapNG writer device. Only packets that match the filter will be persisted - /// @param[in] filterAsString The filter to be set in Berkeley Packet Filter (BPF) syntax - /// (http://biot.com/capstats/bpf.html) - /// @return True if filter set successfully, false otherwise - bool setFilter(std::string filterAsString) override; + protected: + bool doUpdateFilter(std::string const& filterAsString) override; private: /// @struct PcapNgMetadata diff --git a/Pcap++/header/PfRingDevice.h b/Pcap++/header/PfRingDevice.h index 716f91ef1..37096d5c5 100644 --- a/Pcap++/header/PfRingDevice.h +++ b/Pcap++/header/PfRingDevice.h @@ -315,15 +315,12 @@ namespace pcpp return m_DeviceOpened; } - using IFilterableDevice::setFilter; + protected: + bool doUpdateFilter(std::string const& filterAsString) override; - /// Sets a BPF filter to the device - /// @param[in] filterAsString The BPF filter in string format - bool setFilter(std::string filterAsString); - - /// Remove a filter if currently set - /// @return True if filter was removed successfully or if no filter was set, false otherwise - bool clearFilter(); + private: + bool removeFilterForAllChannels(); + bool setFilterForAllChannels(std::string const& filterAsString); }; } // namespace pcpp diff --git a/Pcap++/src/PcapDevice.cpp b/Pcap++/src/PcapDevice.cpp index 616d76ce3..b3c03f58b 100644 --- a/Pcap++/src/PcapDevice.cpp +++ b/Pcap++/src/PcapDevice.cpp @@ -133,7 +133,7 @@ namespace pcpp return stats; } - bool IPcapDevice::setFilter(std::string filterAsString) + bool IPcapDevice::doUpdateFilter(std::string const& filterAsString) { PCPP_LOG_DEBUG("Filter to be set: '" << filterAsString << "'"); if (!isOpened()) @@ -142,12 +142,14 @@ namespace pcpp return false; } - return m_PcapDescriptor.setFilter(filterAsString); - } - - bool IPcapDevice::clearFilter() - { - return m_PcapDescriptor.clearFilter(); + if (filterAsString.empty()) + { + return m_PcapDescriptor.clearFilter(); + } + else + { + return m_PcapDescriptor.setFilter(filterAsString); + } } bool IPcapDevice::matchPacketWithFilter(GeneralFilter& filter, RawPacket* rawPacket) diff --git a/Pcap++/src/PcapFileDevice.cpp b/Pcap++/src/PcapFileDevice.cpp index ee7cbd009..fe987d0d7 100644 --- a/Pcap++/src/PcapFileDevice.cpp +++ b/Pcap++/src/PcapFileDevice.cpp @@ -624,7 +624,7 @@ namespace pcpp return getNextPacket(rawPacket, temp); } - bool PcapNgFileReaderDevice::setFilter(std::string filterAsString) + bool PcapNgFileReaderDevice::doUpdateFilter(std::string const& filterAsString) { return m_BpfWrapper.setFilter(filterAsString); } @@ -876,7 +876,7 @@ namespace pcpp PCPP_LOG_DEBUG("File writer closed for file '" << m_FileName << "'"); } - bool PcapNgFileWriterDevice::setFilter(std::string filterAsString) + bool PcapNgFileWriterDevice::doUpdateFilter(std::string const& filterAsString) { return m_BpfWrapper.setFilter(filterAsString); } diff --git a/Pcap++/src/PfRingDevice.cpp b/Pcap++/src/PfRingDevice.cpp index 0638c40e7..cf6992332 100644 --- a/Pcap++/src/PfRingDevice.cpp +++ b/Pcap++/src/PfRingDevice.cpp @@ -366,7 +366,7 @@ namespace pcpp return SystemCores::IdToSystemCore[sched_getcpu()]; } - bool PfRingDevice::setFilter(std::string filterAsString) + bool PfRingDevice::doUpdateFilter(std::string const& filterAsString) { if (!m_DeviceOpened) { @@ -374,6 +374,18 @@ namespace pcpp return false; } + if (filterAsString.empty()) + { + return removeFilterForAllChannels(); + } + else + { + return setFilterForAllChannels(filterAsString); + } + } + + bool PfRingDevice::setFilterForAllChannels(std::string const& filterAsString) + { for (pfring* rxChannel : m_PfRingDescriptors) { int res = pfring_set_bpf_filter(rxChannel, (char*)filterAsString.c_str()); @@ -394,7 +406,7 @@ namespace pcpp return true; } - bool PfRingDevice::clearFilter() + bool PfRingDevice::removeFilterForAllChannels() { if (!m_IsFilterCurrentlySet) return true;