diff --git a/Pcap++/header/PcapFilter.h b/Pcap++/header/PcapFilter.h index e11a54a33d..caea80608c 100644 --- a/Pcap++/header/PcapFilter.h +++ b/Pcap++/header/PcapFilter.h @@ -79,30 +79,28 @@ namespace pcpp class BpfFilterWrapper { private: + using BpfProgramUPtr = std::unique_ptr; + std::string m_FilterStr; - LinkLayerType m_LinkType; - std::unique_ptr m_Program; + mutable LinkLayerType m_CachedProgramLinkType = LinkLayerType::LINKTYPE_ETHERNET; + mutable BpfProgramUPtr m_CachedProgram; - void freeProgram(); + static BpfProgramUPtr compileFilter(std::string const& filter, LinkLayerType linkType); public: - /// A c'tor for this class - BpfFilterWrapper(); + /// @brief Creates a new instance with no filter. + BpfFilterWrapper() = default; - /// A copy constructor for this class. - /// @param[in] other The instance to copy from BpfFilterWrapper(const BpfFilterWrapper& other); - - /// A copy assignment operator for this class. - /// @param[in] other An instance of IPNetwork to assign - /// @return A reference to the assignee + BpfFilterWrapper(BpfFilterWrapper&&) noexcept = default; BpfFilterWrapper& operator=(const BpfFilterWrapper& other); + BpfFilterWrapper& operator=(BpfFilterWrapper&&) noexcept = default; /// Set a filter. This method receives a filter in BPF syntax (https://biot.com/capstats/bpf.html) and an /// optional link type, compiles them, and if compilation is successful it stores the filter. /// @param[in] filter A filter in BPF syntax /// @param[in] linkType An optional parameter to set the filter's link type. The default is LINKTYPE_ETHERNET - /// @return True if compilation is successful and filter is stored in side this object, false otherwise + /// @return True if compilation is successful and filter is stored inside this object, false otherwise bool setFilter(const std::string& filter, LinkLayerType linkType = LINKTYPE_ETHERNET); /// Match a packet with the filter stored in this object. If the filter is empty the method returns "true". @@ -111,7 +109,7 @@ namespace pcpp /// @param[in] rawPacket A pointer to a raw packet which the filter will be matched against /// @return True if the filter matches (or if it's empty). False if the packet doesn't match or if the filter /// could not be compiled - bool matchPacketWithFilter(const RawPacket* rawPacket); + bool matchPacketWithFilter(const RawPacket* rawPacket) const; /// Match a packet data with the filter stored in this object. If the filter is empty the method returns "true". /// If the link type provided is different than the one set in setFilter(), the filter will be re-compiled @@ -123,7 +121,29 @@ namespace pcpp /// @return True if the filter matches (or if it's empty). False if the packet doesn't match or if the filter /// could not be compiled bool matchPacketWithFilter(const uint8_t* packetData, uint32_t packetDataLength, timespec packetTimestamp, - uint16_t linkType); + uint16_t linkType) const; + + /// @brief Match a packet with the filter stored in this object. + /// + /// If the filter is empty the method returns "true". + /// If the link type of the raw packet is different than the one set in setFilter() the filter will be + /// recompiled. + /// + /// @param[in] rawPacket The raw packet to match the filter against + /// @return True if the filter matches (or if it's empty). False otherwise + bool matches(const RawPacket& rawPacket) const; + + /// @brief Match a raw buffer of packet data against the filter stored in this object. + /// + /// If the filter is empty the method returns "true". + /// If the link type provided is different than the one set in setFilter() the filter will be recompiled. + /// + /// @param[in] packetData A pointer to the raw packet data + /// @param[in] packetDataLength The length of the raw packet data in bytes + /// @param[in] timestamp Timestamp to be associated with the packet + /// @param[in] linkType The link type of the packet + /// @return True if the filter matches (or if it's empty). False otherwise + bool matches(const uint8_t* packetData, uint32_t packetDataLength, timespec timestamp, uint16_t linkType) const; }; /// @class GeneralFilter @@ -132,25 +152,41 @@ namespace pcpp /// For deeper understanding of the filter concept please refer to PcapFilter.h class GeneralFilter { - protected: - BpfFilterWrapper m_BpfWrapper; + private: + mutable BpfFilterWrapper m_BpfWrapper; + mutable bool m_CachedFilter = false; public: + GeneralFilter() = default; + + /// Virtual destructor, frees the bpf program + virtual ~GeneralFilter() = default; + /// A method that parses the class instance into BPF string format /// @param[out] result An empty string that the parsing will be written into. If the string isn't empty, its /// content will be overridden - virtual void parseToString(std::string& result) = 0; + virtual void parseToString(std::string& result) const = 0; /// Match a raw packet with a given BPF filter. /// @param[in] rawPacket A pointer to the raw packet to match the BPF filter with /// @return True if a raw packet matches the BPF filter or false otherwise - bool matchPacketWithFilter(RawPacket* rawPacket); + bool matchPacketWithFilter(RawPacket* rawPacket) const; - GeneralFilter() - {} + /// @brief Match a raw packet against the filter. + /// @param rawPacket The raw packet to match against. + /// @return True if the filter matches (or if it's empty). False otherwise. + bool matches(RawPacket const& rawPacket) const; - /// Virtual destructor, frees the bpf program - virtual ~GeneralFilter() = default; + protected: + /// @brief Parse the filter and cache the compiled BPF program. + /// @return True if the filter was successfully parsed and cached, false otherwise. + bool cacheFilter() const; + + /// @brief Invalidate the cached BPF program. This method should be called whenever the filter changes. + void invalidateCache() const + { + m_CachedFilter = false; + }; }; /// @class BPFStringFilter @@ -170,7 +206,7 @@ namespace pcpp /// A method that parses the class instance into BPF string format /// @param[out] result An empty string that the parsing will be written into. If the string isn't empty, its /// content will be overridden If the filter is not valid the result will be an empty string - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Verify the filter is valid /// @return True if the filter is valid or false otherwise @@ -188,7 +224,7 @@ namespace pcpp Direction m_Dir; protected: - void parseDirection(std::string& directionAsString); + void parseDirection(std::string& directionAsString) const; Direction getDir() const { return m_Dir; @@ -204,6 +240,7 @@ namespace pcpp void setDirection(Direction dir) { m_Dir = dir; + invalidateCache(); } }; @@ -218,7 +255,7 @@ namespace pcpp FilterOperator m_Operator; protected: - std::string parseOperator(); + std::string parseOperator() const; FilterOperator getOperator() const { return m_Operator; @@ -234,6 +271,7 @@ namespace pcpp void setOperator(FilterOperator op) { m_Operator = op; + invalidateCache(); } }; @@ -324,7 +362,7 @@ namespace pcpp : IFilterWithDirection(dir), m_Address(network.getNetworkPrefix()), m_Network(network) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the network to build the filter with. /// @param[in] network The IP Network object to be used when building the filter. @@ -332,6 +370,7 @@ namespace pcpp { m_Network = network; m_Address = m_Network.getNetworkPrefix(); + invalidateCache(); } /// Set the IP address @@ -340,6 +379,7 @@ namespace pcpp void setAddr(const std::string& ipAddress) { this->setAddr(IPAddress(ipAddress)); + invalidateCache(); } /// Set the IP address @@ -357,6 +397,7 @@ namespace pcpp } m_Network = IPNetwork(m_Address, newPrefixLen); + invalidateCache(); } /// Set the subnet mask @@ -370,12 +411,14 @@ namespace pcpp void setMask(const std::string& netmask) { m_Network = IPNetwork(m_Address, netmask); + invalidateCache(); } /// Clears the subnet mask. void clearMask() { this->clearLen(); + invalidateCache(); } /// Set the subnet (IPv4) or prefix length (IPv6). @@ -385,12 +428,14 @@ namespace pcpp void setLen(const int len) { m_Network = IPNetwork(m_Address, len); + invalidateCache(); } /// Clears the subnet mask length. void clearLen() { m_Network = IPNetwork(m_Address); + invalidateCache(); } }; @@ -411,13 +456,14 @@ namespace pcpp IPv4IDFilter(uint16_t ipID, FilterOperator op) : IFilterWithOperator(op), m_IpID(ipID) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the IP ID to filter /// @param[in] ipID The IP ID to filter void setIpID(uint16_t ipID) { m_IpID = ipID; + invalidateCache(); } }; @@ -439,13 +485,14 @@ namespace pcpp : IFilterWithOperator(op), m_TotalLength(totalLength) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the total length value /// @param[in] totalLength The total length value to filter void setTotalLength(uint16_t totalLength) { m_TotalLength = totalLength; + invalidateCache(); } }; @@ -465,13 +512,14 @@ namespace pcpp /// @param[in] dir The port direction to filter (source or destination) PortFilter(uint16_t port, Direction dir); - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the port /// @param[in] port The port to create the filter with void setPort(uint16_t port) { portToString(port); + invalidateCache(); } }; @@ -496,13 +544,14 @@ namespace pcpp : IFilterWithDirection(dir), m_FromPort(fromPort), m_ToPort(toPort) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the lower end of the port range /// @param[in] fromPort The lower end of the port range void setFromPort(uint16_t fromPort) { m_FromPort = fromPort; + invalidateCache(); } /// Set the higher end of the port range @@ -510,6 +559,7 @@ namespace pcpp void setToPort(uint16_t toPort) { m_ToPort = toPort; + invalidateCache(); } }; @@ -530,13 +580,14 @@ namespace pcpp MacAddressFilter(MacAddress address, Direction dir) : IFilterWithDirection(dir), m_MacAddress(address) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the MAC address /// @param[in] address The MAC address to use for filtering void setMacAddress(MacAddress address) { m_MacAddress = address; + invalidateCache(); } }; @@ -556,13 +607,14 @@ namespace pcpp explicit EtherTypeFilter(uint16_t etherType) : m_EtherType(etherType) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the EtherType value /// @param[in] etherType The EtherType value to create the filter with void setEtherType(uint16_t etherType) { m_EtherType = etherType; + invalidateCache(); } }; @@ -589,6 +641,7 @@ namespace pcpp void addFilter(GeneralFilter* filter) { m_FilterList.push_back(filter); + invalidateCache(); } /// Removes the first matching filter from the composite filter @@ -603,6 +656,7 @@ namespace pcpp void clearAllFilters() { m_FilterList.clear(); + invalidateCache(); } }; @@ -642,7 +696,7 @@ namespace pcpp public: using CompositeFilter::CompositeFilter; - void parseToString(std::string& result) override + void parseToString(std::string& result) const override { result.clear(); for (auto it = m_FilterList.cbegin(); it != m_FilterList.cend(); ++it) @@ -693,13 +747,14 @@ namespace pcpp m_FilterToInverse = filterToInverse; } - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set a filter to create an inverse filter from /// @param[in] filterToInverse A pointer to filter which the created filter be the inverse of void setFilter(GeneralFilter* filterToInverse) { m_FilterToInverse = filterToInverse; + invalidateCache(); } }; @@ -730,7 +785,7 @@ namespace pcpp explicit ProtoFilter(ProtocolTypeFamily protoFamily) : m_ProtoFamily(protoFamily) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the protocol to filter with /// @param[in] proto The protocol to filter, only packets matching this protocol will be received. Please note @@ -738,6 +793,7 @@ namespace pcpp void setProto(ProtocolType proto) { m_ProtoFamily = proto; + invalidateCache(); } /// Set the protocol family to filter with @@ -747,6 +803,7 @@ namespace pcpp void setProto(ProtocolTypeFamily protoFamily) { m_ProtoFamily = protoFamily; + invalidateCache(); } }; @@ -766,13 +823,14 @@ namespace pcpp explicit ArpFilter(ArpOpcode opCode) : m_OpCode(opCode) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the ARP opcode /// @param[in] opCode The ARP opcode: ::ARP_REQUEST or ::ARP_REPLY void setOpCode(ArpOpcode opCode) { m_OpCode = opCode; + invalidateCache(); } }; @@ -792,13 +850,14 @@ namespace pcpp explicit VlanFilter(uint16_t vlanId) : m_VlanID(vlanId) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set the VLAN ID of the filter /// @param[in] vlanId The VLAN ID to use for the filter void setVlanID(uint16_t vlanId) { m_VlanID = vlanId; + invalidateCache(); } }; @@ -860,9 +919,10 @@ namespace pcpp { m_TcpFlagsBitMask = tcpFlagBitMask; m_MatchOption = matchOption; + invalidateCache(); } - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; }; /// @class TcpWindowSizeFilter @@ -882,13 +942,14 @@ namespace pcpp TcpWindowSizeFilter(uint16_t windowSize, FilterOperator op) : IFilterWithOperator(op), m_WindowSize(windowSize) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set window-size value /// @param[in] windowSize The window-size value that will be used in the filter void setWindowSize(uint16_t windowSize) { m_WindowSize = windowSize; + invalidateCache(); } }; @@ -909,13 +970,14 @@ namespace pcpp UdpLengthFilter(uint16_t length, FilterOperator op) : IFilterWithOperator(op), m_Length(length) {} - void parseToString(std::string& result) override; + void parseToString(std::string& result) const override; /// Set length value /// @param[in] length The length value that will be used in the filter void setLength(uint16_t length) { m_Length = length; + invalidateCache(); } }; } // namespace pcpp diff --git a/Pcap++/src/PcapFilter.cpp b/Pcap++/src/PcapFilter.cpp index 303ea76142..60b397a740 100644 --- a/Pcap++/src/PcapFilter.cpp +++ b/Pcap++/src/PcapFilter.cpp @@ -18,17 +18,6 @@ namespace pcpp static const int DEFAULT_SNAPLEN = 9000; - bool GeneralFilter::matchPacketWithFilter(RawPacket* rawPacket) - { - std::string filterStr; - parseToString(filterStr); - - if (!m_BpfWrapper.setFilter(filterStr)) - return false; - - return m_BpfWrapper.matchPacketWithFilter(rawPacket); - } - namespace internal { void BpfProgramDeleter::operator()(bpf_program* ptr) const noexcept @@ -38,17 +27,20 @@ namespace pcpp } } // namespace internal - BpfFilterWrapper::BpfFilterWrapper() : m_LinkType(LinkLayerType::LINKTYPE_ETHERNET) - {} - - BpfFilterWrapper::BpfFilterWrapper(const BpfFilterWrapper& other) : BpfFilterWrapper() + BpfFilterWrapper::BpfFilterWrapper(const BpfFilterWrapper& other) { - setFilter(other.m_FilterStr, other.m_LinkType); + if (!setFilter(other.m_FilterStr, other.m_CachedProgramLinkType)) + { + throw std::runtime_error("Couldn't compile BPF filter: '" + other.m_FilterStr + "'"); + } } BpfFilterWrapper& BpfFilterWrapper::operator=(const BpfFilterWrapper& other) { - setFilter(other.m_FilterStr, other.m_LinkType); + if (!setFilter(other.m_FilterStr, other.m_CachedProgramLinkType)) + { + throw std::runtime_error("Couldn't compile BPF filter: '" + other.m_FilterStr + "'"); + } return *this; } @@ -56,77 +48,145 @@ namespace pcpp { if (filter.empty()) { - freeProgram(); + m_CachedProgram = nullptr; + m_FilterStr.clear(); return true; } - if (filter != m_FilterStr || linkType != m_LinkType) + if (filter != m_FilterStr || linkType != m_CachedProgramLinkType) { - auto pcap = std::unique_ptr(pcap_open_dead(linkType, DEFAULT_SNAPLEN)); - if (pcap == nullptr) - { - return false; - } - - auto newProg = std::make_unique(); - int ret = pcap_compile(pcap.get(), newProg.get(), filter.c_str(), 1, 0); - if (ret < 0) + auto newProgram = compileFilter(filter, linkType); + if (newProgram == nullptr) { + PCPP_LOG_ERROR("Couldn't compile BPF filter: '" << filter << "'"); return false; } - // Reassigns ownership of the bpf program to a new unique_ptr with a custom deleter as it now requires - // specialized cleanup. - m_Program = std::unique_ptr(newProg.release()); m_FilterStr = filter; - m_LinkType = linkType; + m_CachedProgram = std::move(newProgram); + m_CachedProgramLinkType = linkType; } return true; } - void BpfFilterWrapper::freeProgram() + bool BpfFilterWrapper::matchPacketWithFilter(const RawPacket* rawPacket) const { - m_Program = nullptr; - m_FilterStr.clear(); + if (rawPacket == nullptr) + { + PCPP_LOG_ERROR("Raw packet pointer is null"); + return false; + } + + return matches(*rawPacket); } - bool BpfFilterWrapper::matchPacketWithFilter(const RawPacket* rawPacket) + bool BpfFilterWrapper::matchPacketWithFilter(const uint8_t* packetData, uint32_t packetDataLength, + timespec packetTimestamp, uint16_t linkType) const { - return matchPacketWithFilter(rawPacket->getRawData(), rawPacket->getRawDataLen(), - rawPacket->getPacketTimeStamp(), rawPacket->getLinkLayerType()); + return matches(packetData, packetDataLength, packetTimestamp, linkType); } - bool BpfFilterWrapper::matchPacketWithFilter(const uint8_t* packetData, uint32_t packetDataLength, - timespec packetTimestamp, uint16_t linkType) + bool BpfFilterWrapper::matches(const RawPacket& rawPacket) const + { + return matches(rawPacket.getRawData(), rawPacket.getRawDataLen(), rawPacket.getPacketTimeStamp(), + rawPacket.getLinkLayerType()); + } + + bool BpfFilterWrapper::matches(const uint8_t* packetData, uint32_t packetDataLength, timespec timestamp, + uint16_t linkType) const { if (m_FilterStr.empty()) return true; - if (!setFilter(std::string(m_FilterStr), static_cast(linkType))) + // Handle uncompiled program or link type mismatch + if (m_CachedProgram == nullptr || linkType != static_cast(m_CachedProgramLinkType)) { - return false; + auto newProgram = compileFilter(m_FilterStr, static_cast(linkType)); + if (newProgram == nullptr) + { + PCPP_LOG_ERROR("Couldn't compile BPF filter: '" << m_FilterStr << "' for link type: " << linkType); + return false; + } + m_CachedProgram = std::move(newProgram); + m_CachedProgramLinkType = static_cast(linkType); } - struct pcap_pkthdr pktHdr; + // Test the packet against the filter + pcap_pkthdr pktHdr; pktHdr.caplen = packetDataLength; pktHdr.len = packetDataLength; - pktHdr.ts = internal::toTimeval(packetTimestamp); + pktHdr.ts = internal::toTimeval(timestamp); + return (pcap_offline_filter(m_CachedProgram.get(), &pktHdr, packetData) != 0); + } - return (pcap_offline_filter(m_Program.get(), &pktHdr, packetData) != 0); + BpfFilterWrapper::BpfProgramUPtr BpfFilterWrapper::compileFilter(std::string const& filter, LinkLayerType linkType) + { + if (filter.empty()) + return nullptr; + + auto pcap = std::unique_ptr(pcap_open_dead(linkType, DEFAULT_SNAPLEN)); + if (pcap == nullptr) + { + return nullptr; + } + + auto newProg = std::make_unique(); + int ret = pcap_compile(pcap.get(), newProg.get(), filter.c_str(), 1, 0); + if (ret < 0) + { + return nullptr; + } + + // Reassigns ownership to a new unique_ptr with a custom deleter as it now requires specialized cleanup. + return BpfProgramUPtr(newProg.release()); + } + + bool GeneralFilter::matchPacketWithFilter(RawPacket* rawPacket) const + { + if (rawPacket == nullptr) + { + PCPP_LOG_ERROR("Raw packet pointer is null"); + return false; + } + + return matches(*rawPacket); + } + + bool GeneralFilter::matches(RawPacket const& rawPacket) const + { + if (!m_CachedFilter && !cacheFilter()) + { + return false; + } + + return m_BpfWrapper.matches(rawPacket); + } + + bool GeneralFilter::cacheFilter() const + { + std::string filterStr; + parseToString(filterStr); + if (!m_BpfWrapper.setFilter(filterStr)) + { + return false; + } + + m_CachedFilter = true; + return true; } - void BPFStringFilter::parseToString(std::string& result) + void BPFStringFilter::parseToString(std::string& result) const { result = m_FilterStr; } bool BPFStringFilter::verifyFilter() { - return m_BpfWrapper.setFilter(m_FilterStr); + return cacheFilter(); } - void IFilterWithDirection::parseDirection(std::string& directionAsString) + void IFilterWithDirection::parseDirection(std::string& directionAsString) const { switch (m_Dir) { @@ -142,7 +202,7 @@ namespace pcpp } } - std::string IFilterWithOperator::parseOperator() + std::string IFilterWithOperator::parseOperator() const { switch (m_Operator) { @@ -163,7 +223,7 @@ namespace pcpp } } - void IPFilter::parseToString(std::string& result) + void IPFilter::parseToString(std::string& result) const { std::string dir; std::string ipAddr = m_Network.toString(); @@ -179,7 +239,7 @@ namespace pcpp result += ipAddr; } - void IPv4IDFilter::parseToString(std::string& result) + void IPv4IDFilter::parseToString(std::string& result) const { std::string op = parseOperator(); std::ostringstream stream; @@ -187,7 +247,7 @@ namespace pcpp result = "ip[4:2] " + op + ' ' + stream.str(); } - void IPv4TotalLengthFilter::parseToString(std::string& result) + void IPv4TotalLengthFilter::parseToString(std::string& result) const { std::string op = parseOperator(); std::ostringstream stream; @@ -207,14 +267,14 @@ namespace pcpp portToString(port); } - void PortFilter::parseToString(std::string& result) + void PortFilter::parseToString(std::string& result) const { std::string dir; parseDirection(dir); result = dir + " port " + m_Port; } - void PortRangeFilter::parseToString(std::string& result) + void PortRangeFilter::parseToString(std::string& result) const { std::string dir; parseDirection(dir); @@ -227,7 +287,7 @@ namespace pcpp result = dir + " portrange " + fromPortStream.str() + '-' + toPortStream.str(); } - void MacAddressFilter::parseToString(std::string& result) + void MacAddressFilter::parseToString(std::string& result) const { if (getDir() != SRC_OR_DST) { @@ -239,7 +299,7 @@ namespace pcpp result = "ether host " + m_MacAddress.toString(); } - void EtherTypeFilter::parseToString(std::string& result) + void EtherTypeFilter::parseToString(std::string& result) const { std::ostringstream stream; stream << "0x" << std::hex << m_EtherType; @@ -256,6 +316,7 @@ namespace pcpp if (*it == filter) { m_FilterList.erase(it); + invalidateCache(); break; } } @@ -264,16 +325,17 @@ namespace pcpp void CompositeFilter::setFilters(const std::vector& filters) { m_FilterList = filters; + invalidateCache(); } - void NotFilter::parseToString(std::string& result) + void NotFilter::parseToString(std::string& result) const { std::string innerFilterAsString; m_FilterToInverse->parseToString(innerFilterAsString); result = "not (" + innerFilterAsString + ')'; } - void ProtoFilter::parseToString(std::string& result) + void ProtoFilter::parseToString(std::string& result) const { std::ostringstream stream; @@ -316,21 +378,21 @@ namespace pcpp } } - void ArpFilter::parseToString(std::string& result) + void ArpFilter::parseToString(std::string& result) const { std::ostringstream sstream; sstream << "arp[7] = " << m_OpCode; result += sstream.str(); } - void VlanFilter::parseToString(std::string& result) + void VlanFilter::parseToString(std::string& result) const { std::ostringstream stream; stream << m_VlanID; result = "vlan " + stream.str(); } - void TcpFlagsFilter::parseToString(std::string& result) + void TcpFlagsFilter::parseToString(std::string& result) const { if (m_TcpFlagsBitMask == 0) { @@ -365,14 +427,14 @@ namespace pcpp } } - void TcpWindowSizeFilter::parseToString(std::string& result) + void TcpWindowSizeFilter::parseToString(std::string& result) const { std::ostringstream stream; stream << m_WindowSize; result = "tcp[14:2] " + parseOperator() + ' ' + stream.str(); } - void UdpLengthFilter::parseToString(std::string& result) + void UdpLengthFilter::parseToString(std::string& result) const { std::ostringstream stream; stream << m_Length; diff --git a/Tests/Pcap++Test/Tests/FilterTests.cpp b/Tests/Pcap++Test/Tests/FilterTests.cpp index 1636458f3a..5a28409e17 100644 --- a/Tests/Pcap++Test/Tests/FilterTests.cpp +++ b/Tests/Pcap++Test/Tests/FilterTests.cpp @@ -10,6 +10,7 @@ #include "Packet.h" #include "PcapLiveDeviceList.h" #include "PcapFileDevice.h" +#include "Logger.h" #include "../Common/GlobalTestArgs.h" #include "../Common/PcapFileNamesDef.h" #include "../Common/TestUtils.h" @@ -208,7 +209,9 @@ PTF_TEST_CASE(TestPcapFilters_General_BPFStr) // Try to make an invalid filter pcpp::BPFStringFilter badFilter("This is not a valid filter"); + pcpp::Logger::getInstance().suppressLogs(); PTF_ASSERT_FALSE(badFilter.verifyFilter()); + pcpp::Logger::getInstance().enableLogs(); // Test stolen from MacAddress test below pcpp::MacAddress macAddr("00:13:c3:df:ae:18"); @@ -252,7 +255,9 @@ PTF_TEST_CASE(TestPcapFilters_MatchStatic) pcpp::BPFStringFilter emptyFilter(""); PTF_ASSERT_TRUE(emptyFilter.matchPacketWithFilter(*iter)); pcpp::BPFStringFilter wrongFilter("-"); + pcpp::Logger::getInstance().suppressLogs(); PTF_ASSERT_FALSE(wrongFilter.matchPacketWithFilter(*iter)); + pcpp::Logger::getInstance().enableLogs(); } rawPacketVec.clear();