diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index c28480d3a9..6218c64511 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -36,7 +36,7 @@ jobs: apk update && apk add cppcheck python3-dev python3 -m venv .venv . .venv/bin/activate - python3 -m pip install pre-commit setuptools clang-format==18.1.6 clang-tidy==18.1.8 + python3 -m pip install pre-commit setuptools clang-format==19.1.6 clang-tidy==18.1.8 - name: Run pre-commit run: | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 578a5390fb..69530d8268 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ Every code contribution to this project is highly valued and appreciated. I enco - For Windows (using `choco`) `choco install cppcheck --version=2.7` - For Windows (MSI install): https://github.com/danmar/cppcheck/releases/download/2.7/cppcheck-2.7-x64-Setup.msi - Build from source: https://github.com/danmar/cppcheck/releases/tag/2.7 - - `clang-format`: `pip install clang-format==18.1.6` + - `clang-format`: `pip install clang-format==19.1.6` - After you commit the code and push it to GitHub, before creating the pull request please make sure that: - You merge all new code from **dev** to your fork - CI passes on all platforms diff --git a/Common++/header/IpAddress.h b/Common++/header/IpAddress.h index 6cafb2ed7d..29096b524a 100644 --- a/Common++/header/IpAddress.h +++ b/Common++/header/IpAddress.h @@ -707,18 +707,9 @@ namespace pcpp /// @return A reference to the assignee IPNetwork& operator=(const IPv4Network& other) { - if (m_IPv4Network) - { - m_IPv4Network = nullptr; - } - - if (m_IPv6Network) - { - m_IPv6Network = nullptr; - } - + // Create the new instance first to maintain strong exception guarantee. m_IPv4Network = std::unique_ptr(new IPv4Network(other)); - + m_IPv6Network = nullptr; return *this; } @@ -727,18 +718,9 @@ namespace pcpp /// @return A reference to the assignee IPNetwork& operator=(const IPv6Network& other) { - if (m_IPv4Network) - { - m_IPv4Network = nullptr; - } - - if (m_IPv6Network) - { - m_IPv6Network = nullptr; - } - + // Create the new instance first to maintain strong exception guarantee. m_IPv6Network = std::unique_ptr(new IPv6Network(other)); - + m_IPv4Network = nullptr; return *this; } diff --git a/Packet++/src/DnsResourceData.cpp b/Packet++/src/DnsResourceData.cpp index e735d447de..5365954639 100644 --- a/Packet++/src/DnsResourceData.cpp +++ b/Packet++/src/DnsResourceData.cpp @@ -204,8 +204,7 @@ namespace pcpp { if (m_DataLen == 0 || m_Data == nullptr) { - PCPP_LOG_ERROR("Input data is null or illegal" - << "|m_DataLen:" << m_DataLen); + PCPP_LOG_ERROR("Input data is null or illegal" << "|m_DataLen:" << m_DataLen); return false; } diff --git a/Packet++/src/VrrpLayer.cpp b/Packet++/src/VrrpLayer.cpp index c56cd7f058..8f391155a7 100644 --- a/Packet++/src/VrrpLayer.cpp +++ b/Packet++/src/VrrpLayer.cpp @@ -485,8 +485,7 @@ namespace pcpp auto* ipLayer = m_Packet->getLayerOfType(); if (ipLayer == nullptr) { - PCPP_LOG_ERROR("Calculate checksum failed, for can not get IPLayer" - << ""); + PCPP_LOG_ERROR("Calculate checksum failed, for can not get IPLayer" << ""); return 0; } diff --git a/Pcap++/header/Device.h b/Pcap++/header/Device.h index d8ba547076..ac493066e7 100644 --- a/Pcap++/header/Device.h +++ b/Pcap++/header/Device.h @@ -6,20 +6,16 @@ #include "RawPacket.h" #include "PcapFilter.h" -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** A vector of pointers to RawPacket */ + /// A vector of pointers to RawPacket typedef PointerVector RawPacketVector; - /** - * @class IDevice - * An abstract interface representing all packet processing devices. It stands as the root class for all devices. - * This is an abstract class that cannot be instantiated - */ + /// @class IDevice + /// An abstract interface representing all packet processing devices. It stands as the root class for all devices. + /// This is an abstract class that cannot be instantiated class IDevice { protected: @@ -33,49 +29,37 @@ namespace pcpp virtual ~IDevice() {} - /** - * Open the device - * @return True if device was opened successfully, false otherwise - */ + /// Open the device + /// @return True if device was opened successfully, false otherwise virtual bool open() = 0; - /** - * Close the device - */ + /// Close the device virtual void close() = 0; - /** - * @return True if the file is opened, false otherwise - */ + /// @return True if the file is opened, false otherwise inline bool isOpened() { return m_DeviceOpened; } }; - /** - * @class IFilterableDevice - * An abstract interface representing all devices that have BPF (Berkeley Packet Filter) filtering capabilities, - * meaning devices that can filter packets based on the BPF filtering syntax. - * This is an abstract class that cannot be instantiated - */ + /// @class IFilterableDevice + /// An abstract interface representing all devices that have BPF (Berkeley Packet Filter) filtering capabilities, + /// meaning devices that can filter packets based on the BPF filtering syntax. + /// This is an abstract class that cannot be instantiated class IFilterableDevice { protected: // c'tor should not be public - IFilterableDevice() - {} + IFilterableDevice() = default; public: - virtual ~IFilterableDevice() - {} + virtual ~IFilterableDevice() = default; - /** - * Set a filter for the device. When implemented by the device, only packets that match the filter will be - * received - * @param[in] filter The filter to be set in PcapPlusPlus' GeneralFilter format - * @return True if filter set successfully, false otherwise - */ + /// Set a filter for the device. When implemented by the device, only packets that match the filter will be + /// 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) { std::string filterAsString; @@ -83,19 +67,15 @@ namespace pcpp return setFilter(filterAsString); } - /** - * Set a filter for the device. When implemented by the 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 - */ + /// Set a filter for the device. When implemented by the 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 virtual bool setFilter(std::string filterAsString) = 0; - /** - * Clear the filter currently set on the device - * @return True if filter was removed successfully or if no filter was set, false otherwise - */ + /// 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; }; } // namespace pcpp diff --git a/Pcap++/header/DeviceUtils.h b/Pcap++/header/DeviceUtils.h index b453eb3d97..d5525defe5 100644 --- a/Pcap++/header/DeviceUtils.h +++ b/Pcap++/header/DeviceUtils.h @@ -6,17 +6,17 @@ #include "IpAddress.h" #include "PcapUtils.h" +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { /// @cond PCPP_INTERNAL namespace internal { - /** - * Fetches a list of all network devices on the local machine that LibPcap/WinPcap/NPcap can find. - * @return A smart pointer to an interface list structure. - * @throws std::runtime_error The system encountered an error fetching the devices. - */ + /// Fetches a list of all network devices on the local machine that LibPcap/WinPcap/NPcap can find. + /// @return A smart pointer to an interface list structure. + /// @throws std::runtime_error The system encountered an error fetching the devices. std::unique_ptr getAllLocalPcapDevices(); } // namespace internal diff --git a/Pcap++/header/DpdkDevice.h b/Pcap++/header/DpdkDevice.h index 946c701074..0d011b483e 100644 --- a/Pcap++/header/DpdkDevice.h +++ b/Pcap++/header/DpdkDevice.h @@ -10,63 +10,59 @@ #include "Device.h" #include "MBufRawPacket.h" -/** - * @file - * This file and DpdkDeviceList.h provide PcapPlusPlus C++ wrapper for DPDK (stands for data-plan development kit). What - * is DPDK? as quoting from http://dpdk.org: "DPDK is a set of libraries and drivers for fast packet processing... These - * libraries can be used to: receive and send packets within the minimum number of CPU cycles (usually less than 80 - * cycles)... develop fast packet capture algorithms (tcpdump-like)... run third-party fast path stacks... Some packet - * processing functions have been benchmarked up to hundreds million frames per second, using 64-byte packets with a - * PCIe NIC"
As DPDK API is written in C, PcapPlusPlus wraps the main functionality in a C++ easy-to-use classes - * which should have minimum affect on performance and packet processing rate. In addition it brings DPDK to the - * PcapPlusPlus framework and API so you can use DPDK together with other PcapPlusPlus features such as packet parsing - * and editing, etc.
So how DPDK basically works? in order to boost packet processing performance on a commodity - * server DPDK is bypassing the Linux kernel. All the packet processing activity happens in the user space so basically - * packets are delivered from NIC hardware queues directly to user-space shared memory without going through the kernel. - * In addition DPDK uses polling instead of handling interrupts for each arrived packet (as interrupts create some - * delays). Other methods to boost packets processing implemented by DPDK are using Hugepages to decrease the size of - * TLB that results in a much faster virtual to physical page conversion, thread affinity to bind threads to a specific - * core, lock-free user-space multi-core synchronization using rings data structures and NUMA awareness to avoid - * expensive data transfers between sockets.
Not every NIC supports kernel-bypass capabilities so DPDK cannot work - * with any NIC. The list of supported NICs are in DPDK's web-site http://dpdk.org/doc/nics . For each such NIC the DPDK - * framework provides a module that called poll-mode-driver (PMD in short) that enables this NIC to the working with - * DPDK. PcapPlusPlus wasn't tested with most PMDs but all of them should theoretically work as PcapPlusPlus doesn't - * change the PMD behavior
DPDK has another basic data-structure called mbuf. An mbuf is DPDK wrapper struct for - * network packets. When working with packets in DPDK you actually work with mbufs. The mbuf contains the packet data - * (obviously) but also some metadata on the packet such as the DPDK port it was captured on, packet ref-count (which - * allows it to be referenced by several objects), etc. One important concept is that DPDK doesn't allocate mbufs - * on-the-fly but uses mbuf pools. These pools is allocated on application startup and used throughout the application. - * The goal of this, of course, is increasing packet processing performance as allocating memory has its cost. So pool - * size is important and varies between applications. For example: an application that stores packets in memory has to - * have a large pool of mbufs so mbufs doesn't run-out. PcapPlusPlus enables to choose the pool size at startup

- * PcapPlusPlus main wrapper classes for DPDK are: - * - DpdkDevice - a class that wraps a DPDK port and provides all capabilities of receiving and sending packets to - * this port - * - DpdkDeviceList - a singleton class that initializes the DPDK infrastructure and creates DpdkDevice instances to - * all available ports. In addition it allows starting and stopping of worker threads - * - MBufRawPacket - a child class to RawPacket which customizes it for working with mbuf - * - In addition PcapPlusPlus provides a shell script to initialize DPDK prerequisites: setup_dpdk.py. This is an - * easy-to-use script that sets up huge-pages, loads DPDK kernel module and sets up the NICs that will be used by - * DPDK. This script must run before an application that uses DPDK runs. If you forgot to run it the application - * will fail with an appropriate error that will remind - * - * DPDK initialization using PcapPlusPlus: - * - Before application runs: run the setup_dpdk.py script - * - On application startup call DpdkDeviceList#initDpdk() static method to initialize DPDK infrastructure and - * DpdkDevice instances - * - Open the relevant DpdkDevice(s) - * - Send & receive packets... - */ +/// @file +/// This file and DpdkDeviceList.h provide PcapPlusPlus C++ wrapper for DPDK (stands for data-plan development kit). +/// What is DPDK? as quoting from http://dpdk.org: "DPDK is a set of libraries and drivers for fast packet processing... +/// These libraries can be used to: receive and send packets within the minimum number of CPU cycles (usually less than +/// 80 cycles)... develop fast packet capture algorithms (tcpdump-like)... run third-party fast path stacks... Some +/// packet processing functions have been benchmarked up to hundreds million frames per second, using 64-byte packets +/// with a PCIe NIC"
As DPDK API is written in C, PcapPlusPlus wraps the main functionality in a C++ easy-to-use +/// classes which should have minimum affect on performance and packet processing rate. In addition it brings DPDK to +/// the PcapPlusPlus framework and API so you can use DPDK together with other PcapPlusPlus features such as packet +/// parsing and editing, etc.
So how DPDK basically works? in order to boost packet processing performance on a +/// commodity server DPDK is bypassing the Linux kernel. All the packet processing activity happens in the user space so +/// basically packets are delivered from NIC hardware queues directly to user-space shared memory without going through +/// the kernel. In addition DPDK uses polling instead of handling interrupts for each arrived packet (as interrupts +/// create some delays). Other methods to boost packets processing implemented by DPDK are using Hugepages to decrease +/// the size of TLB that results in a much faster virtual to physical page conversion, thread affinity to bind threads +/// to a specific core, lock-free user-space multi-core synchronization using rings data structures and NUMA awareness +/// to avoid expensive data transfers between sockets.
Not every NIC supports kernel-bypass capabilities so DPDK +/// cannot work with any NIC. The list of supported NICs are in DPDK's web-site http://dpdk.org/doc/nics . For each such +/// NIC the DPDK framework provides a module that called poll-mode-driver (PMD in short) that enables this NIC to the +/// working with DPDK. PcapPlusPlus wasn't tested with most PMDs but all of them should theoretically work as +/// PcapPlusPlus doesn't change the PMD behavior
DPDK has another basic data-structure called mbuf. An mbuf is DPDK +/// wrapper struct for network packets. When working with packets in DPDK you actually work with mbufs. The mbuf +/// contains the packet data (obviously) but also some metadata on the packet such as the DPDK port it was captured on, +/// packet ref-count (which allows it to be referenced by several objects), etc. One important concept is that DPDK +/// doesn't allocate mbufs on-the-fly but uses mbuf pools. These pools is allocated on application startup and used +/// throughout the application. The goal of this, of course, is increasing packet processing performance as allocating +/// memory has its cost. So pool size is important and varies between applications. For example: an application that +/// stores packets in memory has to have a large pool of mbufs so mbufs doesn't run-out. PcapPlusPlus enables to choose +/// the pool size at startup

PcapPlusPlus main wrapper classes for DPDK are: +/// - DpdkDevice - a class that wraps a DPDK port and provides all capabilities of receiving and sending packets to +/// this port +/// - DpdkDeviceList - a singleton class that initializes the DPDK infrastructure and creates DpdkDevice instances to +/// all available ports. In addition it allows starting and stopping of worker threads +/// - MBufRawPacket - a child class to RawPacket which customizes it for working with mbuf +/// - In addition PcapPlusPlus provides a shell script to initialize DPDK prerequisites: setup_dpdk.py. This is an +/// easy-to-use script that sets up huge-pages, loads DPDK kernel module and sets up the NICs that will be used by +/// DPDK. This script must run before an application that uses DPDK runs. If you forgot to run it the application +/// will fail with an appropriate error that will remind +/// +/// DPDK initialization using PcapPlusPlus: +/// - Before application runs: run the setup_dpdk.py script +/// - On application startup call DpdkDeviceList#initDpdk() static method to initialize DPDK infrastructure and +/// DpdkDevice instances +/// - Open the relevant DpdkDevice(s) +/// - Send & receive packets... struct rte_mbuf; struct rte_mempool; struct rte_eth_conf; struct rte_eth_dev_tx_buffer; -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { @@ -77,230 +73,206 @@ namespace pcpp class DpdkDeviceList; class DpdkDevice; - /** - * An enum describing all PMD (poll mode driver) types supported by DPDK. For more info about these PMDs please - * visit the DPDK web-site - */ + /// An enum describing all PMD (poll mode driver) types supported by DPDK. For more info about these PMDs please + /// visit the DPDK web-site enum DpdkPMDType { - /** Unknown PMD type */ + /// Unknown PMD type PMD_UNKNOWN, - /** Link Bonding for 1GbE and 10GbE ports to allow the aggregation of multiple (slave) NICs into a single - * logical interface*/ + /// Link Bonding for 1GbE and 10GbE ports to allow the aggregation of multiple (slave) NICs into a single + /// logical interface PMD_BOND, - /** Intel E1000 PMD */ + /// Intel E1000 PMD PMD_E1000EM, - /** Intel 1GbE PMD */ + /// Intel 1GbE PMD PMD_IGB, - /** Intel 1GbE virtual function PMD */ + /// Intel 1GbE virtual function PMD PMD_IGBVF, - /** Cisco enic (UCS Virtual Interface Card) PMD */ + /// Cisco enic (UCS Virtual Interface Card) PMD PMD_ENIC, - /** Intel fm10k PMD */ + /// Intel fm10k PMD PMD_FM10K, - /** Intel 40GbE PMD */ + /// Intel 40GbE PMD PMD_I40E, - /** Intel 40GbE virtual function PMD */ + /// Intel 40GbE virtual function PMD PMD_I40EVF, - /** Intel 10GbE PMD */ + /// Intel 10GbE PMD PMD_IXGBE, - /** Intel 10GbE virtual function PMD */ + /// Intel 10GbE virtual function PMD PMD_IXGBEVF, - /** Mellanox ConnectX-3, ConnectX-3 Pro PMD */ + /// Mellanox ConnectX-3, ConnectX-3 Pro PMD PMD_MLX4, - /** Null PMD */ + /// Null PMD PMD_NULL, - /** pcap file PMD */ + /// pcap file PMD PMD_PCAP, - /** ring-based (memory) PMD */ + /// ring-based (memory) PMD PMD_RING, - /** VirtIO PMD */ + /// VirtIO PMD PMD_VIRTIO, - /** VMWare VMXNET3 PMD */ + /// VMWare VMXNET3 PMD PMD_VMXNET3, - /** Xen Project PMD */ + /// Xen Project PMD PMD_XENVIRT, - /** AF_PACKET PMD */ + /// AF_PACKET PMD PMD_AF_PACKET }; - /** - * @typedef OnDpdkPacketsArriveCallback - * A callback that is called when a burst of packets are captured by DpdkDevice - * @param[in] packets A pointer to an array of MBufRawPacket - * @param[in] numOfPackets The length of the array - * @param[in] threadId The thread/core ID who captured the packets - * @param[in] device A pointer to the DpdkDevice who captured the packets - * @param[in] userCookie The user cookie assigned by the user in DpdkDevice#startCaptureSingleThread() or - * DpdkDevice#startCaptureMultiThreads - */ + /// @typedef OnDpdkPacketsArriveCallback + /// A callback that is called when a burst of packets are captured by DpdkDevice + /// @param[in] packets A pointer to an array of MBufRawPacket + /// @param[in] numOfPackets The length of the array + /// @param[in] threadId The thread/core ID who captured the packets + /// @param[in] device A pointer to the DpdkDevice who captured the packets + /// @param[in] userCookie The user cookie assigned by the user in DpdkDevice#startCaptureSingleThread() or + /// DpdkDevice#startCaptureMultiThreads typedef void (*OnDpdkPacketsArriveCallback)(MBufRawPacket* packets, uint32_t numOfPackets, uint8_t threadId, DpdkDevice* device, void* userCookie); - /** - * @class DpdkDevice - * Encapsulates a DPDK port and enables receiving and sending packets using DPDK as well as getting interface info & - * status, packet statistics, etc. This class has no public c'tor as it's constructed by DpdkDeviceList during - * initialization.
- * - * __RX/TX queues__: modern NICs provide hardware load-balancing for packets. This means that each packet received - * by the NIC is hashed by one or more parameter (IP address, port, etc.) and goes into one of several RX queues - * provided by the NIC. This enables applications to work in a multi-core environment where each core can read - * packets from different RX queue(s). Same goes for TX queues: it's possible to write packets to different TX - * queues and the NIC is taking care of sending them to the network. Different NICs provide different number of RX - * and TX queues. DPDK supports this capability and enables the user to open the DPDK port (DpdkDevice) with a - * single or multiple RX and TX queues. When receiving packets the user can decide from which RX queue to read from, - * and when transmitting packets the user can decide to which TX queue to send them to. RX/TX queues are configured - * when opening the DpdkDevice (see openMultiQueues())
- * - * __Capturing packets__: there are two ways to capture packets using DpdkDevice: - * - using worker threads (see DpdkDeviceList#startDpdkWorkerThreads() ). When using this method the worker - * should use the DpdkDevice#receivePackets() methods to get packets from the DpdkDevice - * - by setting a callback which is invoked each time a burst of packets arrives. For more details see - * DpdkDevice#startCaptureSingleThread() - * - * __Sending packets:__ DpdkDevice has various methods for sending packets. They enable sending raw packets, parsed - * packets, etc. for all opened TX queues. Also, DPDK provides an option to buffer TX packets and send them only - * when reaching a certain threshold (you can read more about it here: - * http://dpdk.org/doc/api/rte__ethdev_8h.html#a0e941a74ae1b1b886764bc282458d946). DpdkDevice supports that option - * as well. See DpdkDevice#sendPackets()
- * - * __Get interface info__: DpdkDevice provides all kind of information on the interface/device such as MAC address, - * MTU, link status, PCI address, PMD (poll-mode-driver) used for this port, etc. In addition it provides RX/TX - * statistics when receiving or sending packets
- * - * __Known limitations:__ - * - BPF filters are currently not supported by this device (as opposed to other PcapPlusPlus device types. This - * means that the device cannot filter packets before they get to the user - * - It's not possible to set or change NIC load-balancing method. DPDK provides this capability but it's still - * not supported by DpdkDevice - */ + /// @class DpdkDevice + /// Encapsulates a DPDK port and enables receiving and sending packets using DPDK as well as getting interface info + /// & status, packet statistics, etc. This class has no public c'tor as it's constructed by DpdkDeviceList during + /// initialization.
+ /// + /// __RX/TX queues__: modern NICs provide hardware load-balancing for packets. This means that each packet received + /// by the NIC is hashed by one or more parameter (IP address, port, etc.) and goes into one of several RX queues + /// provided by the NIC. This enables applications to work in a multi-core environment where each core can read + /// packets from different RX queue(s). Same goes for TX queues: it's possible to write packets to different TX + /// queues and the NIC is taking care of sending them to the network. Different NICs provide different number of RX + /// and TX queues. DPDK supports this capability and enables the user to open the DPDK port (DpdkDevice) with a + /// single or multiple RX and TX queues. When receiving packets the user can decide from which RX queue to read + /// from, and when transmitting packets the user can decide to which TX queue to send them to. RX/TX queues are + /// configured when opening the DpdkDevice (see openMultiQueues())
+ /// + /// __Capturing packets__: there are two ways to capture packets using DpdkDevice: + /// - using worker threads (see DpdkDeviceList#startDpdkWorkerThreads() ). When using this method the worker + /// should use the DpdkDevice#receivePackets() methods to get packets from the DpdkDevice + /// - by setting a callback which is invoked each time a burst of packets arrives. For more details see + /// DpdkDevice#startCaptureSingleThread() + /// + /// __Sending packets:__ DpdkDevice has various methods for sending packets. They enable sending raw packets, parsed + /// packets, etc. for all opened TX queues. Also, DPDK provides an option to buffer TX packets and send them only + /// when reaching a certain threshold (you can read more about it here: + /// http://dpdk.org/doc/api/rte__ethdev_8h.html#a0e941a74ae1b1b886764bc282458d946). DpdkDevice supports that option + /// as well. See DpdkDevice#sendPackets()
+ /// + /// __Get interface info__: DpdkDevice provides all kind of information on the interface/device such as MAC address, + /// MTU, link status, PCI address, PMD (poll-mode-driver) used for this port, etc. In addition it provides RX/TX + /// statistics when receiving or sending packets
+ /// + /// __Known limitations:__ + /// - BPF filters are currently not supported by this device (as opposed to other PcapPlusPlus device types. This + /// means that the device cannot filter packets before they get to the user + /// - It's not possible to set or change NIC load-balancing method. DPDK provides this capability but it's still + /// not supported by DpdkDevice class DpdkDevice : public IDevice { friend class DpdkDeviceList; friend class MBufRawPacket; public: - /** - * An enum describing all RSS (Receive Side Scaling) hash functions supported in DPDK. Notice not all - * PMDs support all types of hash functions - */ + /// An enum describing all RSS (Receive Side Scaling) hash functions supported in DPDK. Notice not all + /// PMDs support all types of hash functions enum DpdkRssHashFunction { - /** No RSS */ + /// No RSS RSS_NONE = 0, - /** IPv4 based flow */ + /// IPv4 based flow RSS_IPV4 = 0x1, - /** Fragmented IPv4 based flow */ + /// Fragmented IPv4 based flow RSS_FRAG_IPV4 = 0x2, - /** Non-fragmented IPv4 + TCP flow */ + /// Non-fragmented IPv4 + TCP flow RSS_NONFRAG_IPV4_TCP = 0x4, - /** Non-fragmented IPv4 + UDP flow */ + /// Non-fragmented IPv4 + UDP flow RSS_NONFRAG_IPV4_UDP = 0x8, - /** Non-fragmented IPv4 + SCTP flow */ + /// Non-fragmented IPv4 + SCTP flow RSS_NONFRAG_IPV4_SCTP = 0x10, - /** Non-fragmented IPv4 + non TCP/UDP/SCTP flow */ + /// Non-fragmented IPv4 + non TCP/UDP/SCTP flow RSS_NONFRAG_IPV4_OTHER = 0x20, - /** IPv6 based flow */ + /// IPv6 based flow RSS_IPV6 = 0x40, - /** Fragmented IPv6 based flow */ + /// Fragmented IPv6 based flow RSS_FRAG_IPV6 = 0x80, - /** Non-fragmented IPv6 + TCP flow */ + /// Non-fragmented IPv6 + TCP flow RSS_NONFRAG_IPV6_TCP = 0x100, - /** Non-fragmented IPv6 + UDP flow */ + /// Non-fragmented IPv6 + UDP flow RSS_NONFRAG_IPV6_UDP = 0x200, - /** Non-fragmented IPv6 + SCTP flow */ + /// Non-fragmented IPv6 + SCTP flow RSS_NONFRAG_IPV6_SCTP = 0x400, - /** Non-fragmented IPv6 + non TCP/UDP/SCTP flow */ + /// Non-fragmented IPv6 + non TCP/UDP/SCTP flow RSS_NONFRAG_IPV6_OTHER = 0x800, - /** L2 payload based flow */ + /// L2 payload based flow RSS_L2_PAYLOAD = 0x1000, - /** IPv6 Ex based flow */ + /// IPv6 Ex based flow RSS_IPV6_EX = 0x2000, - /** IPv6 + TCP Ex based flow */ + /// IPv6 + TCP Ex based flow RSS_IPV6_TCP_EX = 0x4000, - /** IPv6 + UDP Ex based flow */ + /// IPv6 + UDP Ex based flow RSS_IPV6_UDP_EX = 0x8000, - /** Consider device port number as a flow differentiator */ + /// Consider device port number as a flow differentiator RSS_PORT = 0x10000, - /** VXLAN protocol based flow */ + /// VXLAN protocol based flow RSS_VXLAN = 0x20000, - /** GENEVE protocol based flow */ + /// GENEVE protocol based flow RSS_GENEVE = 0x40000, - /** NVGRE protocol based flow */ + /// NVGRE protocol based flow RSS_NVGRE = 0x80000, - /** All RSS functions supported by the device */ + /// All RSS functions supported by the device RSS_ALL_SUPPORTED = -1, - /** A default set of RSS functions supported by the device */ + /// A default set of RSS functions supported by the device RSS_DEFAULT = PCPP_RSS_HASH_MAGIC_NUMBER }; - /** - * @struct DpdkDeviceConfiguration - * A struct that contains user configurable parameters for opening a DpdkDevice. All of these parameters have - * default values so the user doesn't have to use these parameters or understand exactly what is their effect - */ + /// @struct DpdkDeviceConfiguration + /// A struct that contains user configurable parameters for opening a DpdkDevice. All of these parameters have + /// default values so the user doesn't have to use these parameters or understand exactly what is their effect struct DpdkDeviceConfiguration { - /** - * When configuring a DPDK RX queue, DPDK creates descriptors it will use for receiving packets from the - * network to this RX queue. This parameter enables to configure the number of descriptors that will be - * created for each RX queue - */ + /// When configuring a DPDK RX queue, DPDK creates descriptors it will use for receiving packets from the + /// network to this RX queue. This parameter enables to configure the number of descriptors that will be + /// created for each RX queue uint16_t receiveDescriptorsNumber; - /** - * When configuring a DPDK TX queue, DPDK creates descriptors it will use for transmitting packets to the - * network through this TX queue. This parameter enables to configure the number of descriptors that will be - * created for each TX queue - */ + /// When configuring a DPDK TX queue, DPDK creates descriptors it will use for transmitting packets to the + /// network through this TX queue. This parameter enables to configure the number of descriptors that will + /// be created for each TX queue uint16_t transmitDescriptorsNumber; - /** - * Set the TX buffer flush timeout in millisecond (only relevant if sending packets using DPDK TX buffer - * mechanism). A value of zero means no timeout - */ + /// Set the TX buffer flush timeout in millisecond (only relevant if sending packets using DPDK TX buffer + /// mechanism). A value of zero means no timeout uint16_t flushTxBufferTimeout; - /** - * When configuring a DPDK device, DPDK supports to activate the Receive Side Scaling (RSS) feature to - * distribute traffic between the RX queues This parameter points to an array holding the RSS key to use for - * hashing specific header fields of received packets. The length of this array should be indicated by - * rssKeyLength below. Supplying a nullptr value causes a default random hash key to be used by the device - * driver - */ + /// When configuring a DPDK device, DPDK supports to activate the Receive Side Scaling (RSS) feature to + /// distribute traffic between the RX queues This parameter points to an array holding the RSS key to use + /// for hashing specific header fields of received packets. The length of this array should be indicated by + /// rssKeyLength below. Supplying a nullptr value causes a default random hash key to be used by the device + /// driver uint8_t* rssKey; - /** - * This parameter indicates the length in bytes of the array pointed by rssKey. - * This length will be checked in i40e only. Others assume 40 bytes to be used. - */ + /// This parameter indicates the length in bytes of the array pointed by rssKey. + /// This length will be checked in i40e only. Others assume 40 bytes to be used. uint8_t rssKeyLength; - /** - * This parameter enables to configure the types of packets to which the RSS hashing must be applied. The - * value is a mask composed of hash functions described in DpdkRssHashFunction enum. Supplying a value equal - * to zero disables the RSS feature. Supplying a value equal to -1 enables all hash functions supported by - * this PMD - */ + /// This parameter enables to configure the types of packets to which the RSS hashing must be applied. The + /// value is a mask composed of hash functions described in DpdkRssHashFunction enum. Supplying a value + /// equal to zero disables the RSS feature. Supplying a value equal to -1 enables all hash functions + /// supported by this PMD uint64_t rssHashFunction; - /** - * A c'tor for this struct - * @param[in] receiveDescriptorsNumber An optional parameter for defining the number of RX descriptors that - * will be allocated for each RX queue. Default value is 128 - * @param[in] transmitDescriptorsNumber An optional parameter for defining the number of TX descriptors that - * will be allocated for each TX queue. Default value is 512 - * @param[in] flushTxBufferTimeout An optional parameter for setting TX buffer timeout in usec. Default - * value is 100 usec - * @param[in] rssHashFunction This parameter enable to configure the types of packets to which the RSS - * hashing must be applied. The value provided here should be a mask composed of hash functions described in - * DpdkRssHashFunction enum. The default value is RSS_DEFAULT. - * @param[in] rssKey A pointer to an array holding the RSS key to use for hashing specific header of - * received packets. If not specified, there is a default key defined inside DpdkDevice - * @param[in] rssKeyLength The length in bytes of the array pointed by rssKey. Default value is the length - * of default rssKey - */ + /// A c'tor for this struct + /// @param[in] receiveDescriptorsNumber An optional parameter for defining the number of RX descriptors that + /// will be allocated for each RX queue. Default value is 128 + /// @param[in] transmitDescriptorsNumber An optional parameter for defining the number of TX descriptors + /// that will be allocated for each TX queue. Default value is 512 + /// @param[in] flushTxBufferTimeout An optional parameter for setting TX buffer timeout in usec. Default + /// value is 100 usec + /// @param[in] rssHashFunction This parameter enable to configure the types of packets to which the RSS + /// hashing must be applied. The value provided here should be a mask composed of hash functions described + /// in DpdkRssHashFunction enum. The default value is RSS_DEFAULT. + /// @param[in] rssKey A pointer to an array holding the RSS key to use for hashing specific header of + /// received packets. If not specified, there is a default key defined inside DpdkDevice + /// @param[in] rssKeyLength The length in bytes of the array pointed by rssKey. Default value is the length + /// of default rssKey explicit DpdkDeviceConfiguration(uint16_t receiveDescriptorsNumber = 128, uint16_t transmitDescriptorsNumber = 512, uint16_t flushTxBufferTimeout = 100, @@ -316,538 +288,447 @@ namespace pcpp } }; - /** - * @struct LinkStatus - * A struct that contains the link status of a DpdkDevice (DPDK port). Returned from DpdkDevice#getLinkStatus() - */ + /// @struct LinkStatus + /// A struct that contains the link status of a DpdkDevice (DPDK port). Returned from DpdkDevice#getLinkStatus() struct LinkStatus { - /** Enum for describing link duplex */ + /// Enum for describing link duplex enum LinkDuplex { - /** Full duplex */ + /// Full duplex FULL_DUPLEX, - /** Half duplex */ + /// Half duplex HALF_DUPLEX }; - /** True if link is up, false if it's down */ + /// True if link is up, false if it's down bool linkUp; - /** Link speed in Mbps (for example: 10Gbe will show 10000) */ + /// Link speed in Mbps (for example: 10Gbe will show 10000) int linkSpeedMbps; - /** Link duplex (half/full duplex) */ + /// Link duplex (half/full duplex) LinkDuplex linkDuplex; }; - /** - * @struct RxTxStats - * A container for RX/TX statistics - */ + /// @struct RxTxStats + /// A container for RX/TX statistics struct RxTxStats { - /** Total number of packets */ + /// Total number of packets uint64_t packets; - /** Total number of successfully received bytes */ + /// Total number of successfully received bytes uint64_t bytes; - /** Packets per second */ + /// Packets per second uint64_t packetsPerSec; - /** Bytes per second */ + /// Bytes per second uint64_t bytesPerSec; }; - /** - * @struct DpdkDeviceStats - * A container for DpdkDevice statistics - */ + /// @struct DpdkDeviceStats + /// A container for DpdkDevice statistics struct DpdkDeviceStats { - /** DpdkDevice ID */ + /// DpdkDevice ID uint8_t devId; - /** The timestamp of when the stats were written */ + /// The timestamp of when the stats were written timespec timestamp; - /** RX statistics per RX queue */ + /// RX statistics per RX queue RxTxStats rxStats[DPDK_MAX_RX_QUEUES]; - /** TX statistics per TX queue */ + /// TX statistics per TX queue RxTxStats txStats[DPDK_MAX_RX_QUEUES]; - /** RX statistics, aggregated for all RX queues */ + /// RX statistics, aggregated for all RX queues RxTxStats aggregatedRxStats; - /** TX statistics, aggregated for all TX queues */ + /// TX statistics, aggregated for all TX queues RxTxStats aggregatedTxStats; - /** Total number of RX packets dropped by H/W because there are no available buffers (i.e RX queues are - * full) */ + /// Total number of RX packets dropped by H/W because there are no available buffers (i.e RX queues are + /// full) uint64_t rxPacketsDroppedByHW; - /** Total number of erroneous packets */ + /// Total number of erroneous packets uint64_t rxErroneousPackets; - /** Total number of RX mbuf allocation failures */ + /// Total number of RX mbuf allocation failures uint64_t rxMbufAlocFailed; }; virtual ~DpdkDevice(); - /** - * @return The device ID (DPDK port ID) - */ + /// @return The device ID (DPDK port ID) int getDeviceId() const { return m_Id; } - /** - * @return The device name which is in the format of 'DPDK_[PORT-ID]' - */ + /// @return The device name which is in the format of 'DPDK_[PORT-ID]' std::string getDeviceName() const { return m_DeviceName; } - /** - * @return The MAC address of the device (DPDK port) - */ + /// @return The MAC address of the device (DPDK port) MacAddress getMacAddress() const { return m_MacAddress; } - /** - * @return The name of the PMD (poll mode driver) DPDK is using for this device. You can read about PMDs in the - * DPDK documentation: http://dpdk.org/doc/guides/prog_guide/poll_mode_drv.html - */ + /// @return The name of the PMD (poll mode driver) DPDK is using for this device. You can read about PMDs in the + /// DPDK documentation: http://dpdk.org/doc/guides/prog_guide/poll_mode_drv.html std::string getPMDName() const { return m_PMDName; } - /** - * @return The enum type of the PMD (poll mode driver) DPDK is using for this device. You can read about PMDs in - * the DPDK documentation: http://dpdk.org/doc/guides/prog_guide/poll_mode_drv.html - */ + /// @return The enum type of the PMD (poll mode driver) DPDK is using for this device. You can read about PMDs + /// in the DPDK documentation: http://dpdk.org/doc/guides/prog_guide/poll_mode_drv.html DpdkPMDType getPMDType() const { return m_PMDType; } - /** - * @return The PCI address of the device - */ + /// @return The PCI address of the device std::string getPciAddress() const { return m_PciAddress; } - /** - * @return The device's maximum transmission unit (MTU) in bytes - */ + /// @return The device's maximum transmission unit (MTU) in bytes uint16_t getMtu() const { return m_DeviceMtu; } - /** - * Set a new maximum transmission unit (MTU) for this device - * @param[in] newMtu The new MTU in bytes - * @return True if MTU was set successfully, false if operation failed or if PMD doesn't support changing the - * MTU - */ + /// Set a new maximum transmission unit (MTU) for this device + /// @param[in] newMtu The new MTU in bytes + /// @return True if MTU was set successfully, false if operation failed or if PMD doesn't support changing the + /// MTU bool setMtu(uint16_t newMtu); - /** - * @return True if this device is a virtual interface (such as VMXNET3, 1G/10G virtual function, etc.), false - * otherwise - */ + /// @return True if this device is a virtual interface (such as VMXNET3, 1G/10G virtual function, etc.), false + /// otherwise bool isVirtual() const; - /** - * Get the link status (link up/down, link speed and link duplex) - * @param[out] linkStatus A reference to object the result shall be written to - */ + /// Get the link status (link up/down, link speed and link duplex) + /// @param[out] linkStatus A reference to object the result shall be written to void getLinkStatus(LinkStatus& linkStatus) const; - /** - * @return The core ID used in this context - */ + /// @return The core ID used in this context uint32_t getCurrentCoreId() const; - /** - * @return The number of RX queues currently opened for this device (as configured in openMultiQueues() ) - */ + /// @return The number of RX queues currently opened for this device (as configured in openMultiQueues() ) uint16_t getNumOfOpenedRxQueues() const { return m_NumOfRxQueuesOpened; } - /** - * @return The number of TX queues currently opened for this device (as configured in openMultiQueues() ) - */ + /// @return The number of TX queues currently opened for this device (as configured in openMultiQueues() ) uint16_t getNumOfOpenedTxQueues() const { return m_NumOfTxQueuesOpened; } - /** - * @return The total number of RX queues available on this device - */ + /// @return The total number of RX queues available on this device uint16_t getTotalNumOfRxQueues() const { return m_TotalAvailableRxQueues; } - /** - * @return The total number of TX queues available on this device - */ + /// @return The total number of TX queues available on this device uint16_t getTotalNumOfTxQueues() const { return m_TotalAvailableTxQueues; } - /** - * Receive raw packets from the network - * @param[out] rawPacketsArr A vector where all received packets will be written into - * @param[in] rxQueueId The RX queue to receive packets from - * @return The number of packets received. If an error occurred 0 will be returned and the error will be printed - * to log - */ + /// Receive raw packets from the network + /// @param[out] rawPacketsArr A vector where all received packets will be written into + /// @param[in] rxQueueId The RX queue to receive packets from + /// @return The number of packets received. If an error occurred 0 will be returned and the error will be + /// printed to log uint16_t receivePackets(MBufRawPacketVector& rawPacketsArr, uint16_t rxQueueId) const; - /** - * Receive raw packets from the network. Please notice that in terms of performance, this is the best method to - * use for receiving packets because out of all receivePackets overloads this method requires the least overhead - * and is almost as efficient as receiving packets directly through DPDK. So if performance is a critical factor - * in your application, please use this method - * @param[out] rawPacketsArr A pointer to an array of MBufRawPacket pointers where all received packets will be - * written into. The array is expected to be allocated by the user and its length should be provided in - * rawPacketArrLength. Number of packets received will be returned. Notice it's the user responsibility to free - * the array and its content when done using it - * @param[out] rawPacketArrLength The length of MBufRawPacket pointers array - * @param[in] rxQueueId The RX queue to receive packets from - * @return The number of packets received. If an error occurred 0 will be returned and the error will be printed - * to log - */ + /// Receive raw packets from the network. Please notice that in terms of performance, this is the best method to + /// use for receiving packets because out of all receivePackets overloads this method requires the least + /// overhead and is almost as efficient as receiving packets directly through DPDK. So if performance is a + /// critical factor in your application, please use this method + /// @param[out] rawPacketsArr A pointer to an array of MBufRawPacket pointers where all received packets will be + /// written into. The array is expected to be allocated by the user and its length should be provided in + /// rawPacketArrLength. Number of packets received will be returned. Notice it's the user responsibility to free + /// the array and its content when done using it + /// @param[out] rawPacketArrLength The length of MBufRawPacket pointers array + /// @param[in] rxQueueId The RX queue to receive packets from + /// @return The number of packets received. If an error occurred 0 will be returned and the error will be + /// printed to log uint16_t receivePackets(MBufRawPacket** rawPacketsArr, uint16_t rawPacketArrLength, uint16_t rxQueueId) const; - /** - * Receive parsed packets from the network - * @param[out] packetsArr A pointer to an allocated array of Packet pointers where all received packets will be - * written into. The array is expected to be allocated by the user and its length should be provided in - * packetsArrLength. Number of packets received will be returned. Notice it's the user responsibility to free - * the array and its content when done using it - * @param[out] packetsArrLength The length of Packet pointers array - * @param[in] rxQueueId The RX queue to receive packets from - * @return The number of packets received. If an error occurred 0 will be returned and the error will be printed - * to log - */ + /// Receive parsed packets from the network + /// @param[out] packetsArr A pointer to an allocated array of Packet pointers where all received packets will be + /// written into. The array is expected to be allocated by the user and its length should be provided in + /// packetsArrLength. Number of packets received will be returned. Notice it's the user responsibility to free + /// the array and its content when done using it + /// @param[out] packetsArrLength The length of Packet pointers array + /// @param[in] rxQueueId The RX queue to receive packets from + /// @return The number of packets received. If an error occurred 0 will be returned and the error will be + /// printed to log uint16_t receivePackets(Packet** packetsArr, uint16_t packetsArrLength, uint16_t rxQueueId) const; - /** - * Send an array of MBufRawPacket to the network. Please notice the following:
- * - In terms of performance, this is the best method to use for sending packets because out of all sendPackets - * overloads this method requires the least overhead and is almost as efficient as sending the packets - * directly through DPDK. So if performance is a critical factor in your application, please use this method - * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is - * typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let - * the TX descriptors clean - * - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK - *

- * @param[in] rawPacketsArr A pointer to an array of MBufRawPacket - * @param[in] arrLength The length of the array - * @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. The - * default is TX queue 0 - * @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about - * DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use - * this mechanism) - * @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't open, - * 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be - * actually sent - */ + /// Send an array of MBufRawPacket to the network. Please notice the following:
+ /// - In terms of performance, this is the best method to use for sending packets because out of all sendPackets + /// overloads this method requires the least overhead and is almost as efficient as sending the packets + /// directly through DPDK. So if performance is a critical factor in your application, please use this method + /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is + /// typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let + /// the TX descriptors clean + /// - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK + ///

+ /// @param[in] rawPacketsArr A pointer to an array of MBufRawPacket + /// @param[in] arrLength The length of the array + /// @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. + /// The default is TX queue 0 + /// @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about + /// DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use + /// this mechanism) + /// @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't + /// open, 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be + /// actually sent uint16_t sendPackets(MBufRawPacket** rawPacketsArr, uint16_t arrLength, uint16_t txQueueId = 0, bool useTxBuffer = false); - /** - * Send an array of parsed packets to the network. Please notice the following:
- * - If some or all of the packets contain raw packets which aren't of type MBufRawPacket, a new temp - * MBufRawPacket instances will be created and packet data will be copied to them. This is necessary to - * allocate mbufs which will store the data to be sent. If performance is a critical factor please make sure - * you send parsed packets that contain only raw packets of type MBufRawPacket - * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is - * typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let - * the TX descriptors clean - * - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed by - * DPDK

- * @param[in] packetsArr A pointer to an array of parsed packet pointers - * @param[in] arrLength The length of the array - * @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. The - * default is TX queue 0 - * @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about - * DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use - * this mechanism) - * @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't open, - * 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be - * actually sent - */ + /// Send an array of parsed packets to the network. Please notice the following:
+ /// - If some or all of the packets contain raw packets which aren't of type MBufRawPacket, a new temp + /// MBufRawPacket instances will be created and packet data will be copied to them. This is necessary to + /// allocate mbufs which will store the data to be sent. If performance is a critical factor please make sure + /// you send parsed packets that contain only raw packets of type MBufRawPacket + /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is + /// typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let + /// the TX descriptors clean + /// - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed + /// by DPDK

+ /// @param[in] packetsArr A pointer to an array of parsed packet pointers + /// @param[in] arrLength The length of the array + /// @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. + /// The default is TX queue 0 + /// @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about + /// DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use + /// this mechanism) + /// @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't + /// open, 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be + /// actually sent uint16_t sendPackets(Packet** packetsArr, uint16_t arrLength, uint16_t txQueueId = 0, bool useTxBuffer = false); - /** - * Send a vector of MBufRawPacket pointers to the network. Please notice the following:
- * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is - * typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let - * the TX descriptors clean - * - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK - *

- * @param[in] rawPacketsVec The vector of raw packet - * @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. The - * default is TX queue 0 - * @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about - * DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use - * this mechanism) - * @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't open, - * 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be - * actually sent - */ + /// Send a vector of MBufRawPacket pointers to the network. Please notice the following:
+ /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is + /// typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let + /// the TX descriptors clean + /// - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK + ///

+ /// @param[in] rawPacketsVec The vector of raw packet + /// @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. + /// The default is TX queue 0 + /// @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about + /// DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use + /// this mechanism) + /// @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't + /// open, 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be + /// actually sent uint16_t sendPackets(MBufRawPacketVector& rawPacketsVec, uint16_t txQueueId = 0, bool useTxBuffer = false); - /** - * Send a vector of RawPacket pointers to the network. Please notice the following:
- * - If some or all of the raw packets aren't of type MBufRawPacket, a new temp MBufRawPacket instances will be - * created and packet data will be copied to them. This is necessary to allocate mbufs which will store the - * data to be sent. If performance is a critical factor please make sure you send only raw packets of type - * MBufRawPacket (or use the sendPackets overload that sends MBufRawPacketVector) - * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is - * typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let - * the TX descriptors clean - * - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed by - * DPDK

- * @param[in] rawPacketsVec The vector of raw packet - * @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. The - * default is TX queue 0 - * @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about - * DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use - * this mechanism) - * @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't open, - * 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be - * actually sent - */ + /// Send a vector of RawPacket pointers to the network. Please notice the following:
+ /// - If some or all of the raw packets aren't of type MBufRawPacket, a new temp MBufRawPacket instances will be + /// created and packet data will be copied to them. This is necessary to allocate mbufs which will store the + /// data to be sent. If performance is a critical factor please make sure you send only raw packets of type + /// MBufRawPacket (or use the sendPackets overload that sends MBufRawPacketVector) + /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - If the number of packets to send is higher than a threshold of 80% of total TX descriptors (which is + /// typically around 400 packets), then after reaching this threshold there is a built-in 0.2 sec sleep to let + /// the TX descriptors clean + /// - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed + /// by + /// DPDK

+ /// @param[in] rawPacketsVec The vector of raw packet + /// @param[in] txQueueId An optional parameter which indicates to which TX queue the packets will be sent to. + /// The default is TX queue 0 + /// @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about + /// DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use + /// this mechanism) + /// @return The number of packets actually and successfully sent. If device is not opened or TX queue isn't + /// open, 0 will be returned. Also, if TX buffer is being used and packets are buffered, some or all may not be + /// actually sent uint16_t sendPackets(RawPacketVector& rawPacketsVec, uint16_t txQueueId = 0, bool useTxBuffer = false); - /** - * Send a raw packet to the network. Please notice that if the raw packet isn't of type MBufRawPacket, a new - * temp MBufRawPacket will be created and the data will be copied to it. This is necessary to allocate an mbuf - * which will store the data to be sent. If performance is a critical factor please make sure you send a raw - * packet of type MBufRawPacket. Please also notice that the mbuf used or allocated in this method isn't freed - * by this method, it will be transparently freed by DPDK - * @param[in] rawPacket The raw packet to send - * @param[in] txQueueId An optional parameter which indicates to which TX queue the packet will be sent to. The - * default is TX queue 0 - * @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about - * DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use - * this mechanism) - * @return True if packet was sent successfully or false if device is not opened, TX queue isn't opened, or if - * the packet wasn't sent for any other reason. Please notice that when using TX buffers the packet may be - * buffered and not sent immediately, which may also result in returning false - */ + /// Send a raw packet to the network. Please notice that if the raw packet isn't of type MBufRawPacket, a new + /// temp MBufRawPacket will be created and the data will be copied to it. This is necessary to allocate an mbuf + /// which will store the data to be sent. If performance is a critical factor please make sure you send a raw + /// packet of type MBufRawPacket. Please also notice that the mbuf used or allocated in this method isn't freed + /// by this method, it will be transparently freed by DPDK + /// @param[in] rawPacket The raw packet to send + /// @param[in] txQueueId An optional parameter which indicates to which TX queue the packet will be sent to. The + /// default is TX queue 0 + /// @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about + /// DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use + /// this mechanism) + /// @return True if packet was sent successfully or false if device is not opened, TX queue isn't opened, or if + /// the packet wasn't sent for any other reason. Please notice that when using TX buffers the packet may be + /// buffered and not sent immediately, which may also result in returning false bool sendPacket(RawPacket& rawPacket, uint16_t txQueueId = 0, bool useTxBuffer = false); - /** - * Send a MBufRawPacket to the network. Please notice that the mbuf used in this method isn't freed by this - * method, it will be transparently freed by DPDK - * @param[in] rawPacket The MBufRawPacket to send - * @param[in] txQueueId An optional parameter which indicates to which TX queue the packet will be sent to. The - * default is TX queue 0 - * @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about - * DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use - * this mechanism) - * @return True if packet was sent successfully or false if device is not opened, TX queue isn't opened, or if - * the packet wasn't sent for any other reason. Please notice that when using TX buffers the packet may be - * buffered and not sent immediately, which may also result in returning false - */ + /// Send a MBufRawPacket to the network. Please notice that the mbuf used in this method isn't freed by this + /// method, it will be transparently freed by DPDK + /// @param[in] rawPacket The MBufRawPacket to send + /// @param[in] txQueueId An optional parameter which indicates to which TX queue the packet will be sent to. The + /// default is TX queue 0 + /// @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about + /// DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use + /// this mechanism) + /// @return True if packet was sent successfully or false if device is not opened, TX queue isn't opened, or if + /// the packet wasn't sent for any other reason. Please notice that when using TX buffers the packet may be + /// buffered and not sent immediately, which may also result in returning false bool sendPacket(MBufRawPacket& rawPacket, uint16_t txQueueId = 0, bool useTxBuffer = false); - /** - * Send a parsed packet to the network. Please notice that the mbuf used or allocated in this method isn't freed - * by this method, it will be transparently freed by DPDK - * @param[in] packet The parsed packet to send. Please notice that if the packet contains a raw packet which - * isn't of type MBufRawPacket, a new temp MBufRawPacket will be created and the data will be copied to it. This - * is necessary to allocate an mbuf which will store the data to be sent. If performance is a critical factor - * please make sure you send a parsed packet that contains a raw packet of type MBufRawPacket - * @param[in] txQueueId An optional parameter which indicates to which TX queue the packet will be sent on. The - * default is TX queue 0 - * @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about - * DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use - * this mechanism) - * @return True if packet was sent successfully or false if device is not opened, TX queue isn't opened, or if - * the packet wasn't sent for any other reason. Please notice that when using TX buffers the packet may be - * buffered and not sent immediately, which may also result in returning false - */ + /// Send a parsed packet to the network. Please notice that the mbuf used or allocated in this method isn't + /// freed by this method, it will be transparently freed by DPDK + /// @param[in] packet The parsed packet to send. Please notice that if the packet contains a raw packet which + /// isn't of type MBufRawPacket, a new temp MBufRawPacket will be created and the data will be copied to it. + /// This is necessary to allocate an mbuf which will store the data to be sent. If performance is a critical + /// factor please make sure you send a parsed packet that contains a raw packet of type MBufRawPacket + /// @param[in] txQueueId An optional parameter which indicates to which TX queue the packet will be sent on. The + /// default is TX queue 0 + /// @param[in] useTxBuffer A flag which indicates whether to use TX buffer mechanism or not. To read more about + /// DPDK's TX buffer mechanism please refer to DpdkDevice class description. Default value is false (don't use + /// this mechanism) + /// @return True if packet was sent successfully or false if device is not opened, TX queue isn't opened, or if + /// the packet wasn't sent for any other reason. Please notice that when using TX buffers the packet may be + /// buffered and not sent immediately, which may also result in returning false bool sendPacket(Packet& packet, uint16_t txQueueId = 0, bool useTxBuffer = false); - /** - * Overridden method from IPcapDevice. __BPF filters are currently not implemented for DpdkDevice__ - * @param[in] filter Not used in this method - * @return Always false with a "Filters aren't supported in DPDK device" error message - */ + /// Overridden method from IPcapDevice. __BPF filters are currently not implemented for DpdkDevice__ + /// @param[in] filter Not used in this method + /// @return Always false with a "Filters aren't supported in DPDK device" error message bool setFilter(GeneralFilter& filter); - /** - * Overridden method from IPcapDevice. __BPF filters are currently not implemented for DpdkDevice__ - * @param[in] filterAsString Not used in this method - * @return Always false with a "Filters aren't supported in DPDK device" error message - */ + /// Overridden method from IPcapDevice. __BPF filters are currently not implemented for DpdkDevice__ + /// @param[in] filterAsString Not used in this method + /// @return Always false with a "Filters aren't supported in DPDK device" error message bool setFilter(std::string filterAsString); - /** - * Open the DPDK device. Notice opening the device only makes it ready to use, it doesn't start packet - * capturing. This method initializes RX and TX queues, configures the DPDK port and starts it. Call close() to - * close the device. The device is opened in promiscuous mode - * @param[in] numOfRxQueuesToOpen Number of RX queues to setup. This number must be smaller or equal to the - * return value of getTotalNumOfRxQueues() - * @param[in] numOfTxQueuesToOpen Number of TX queues to setup. This number must be smaller or equal to the - * return value of getTotalNumOfTxQueues() - * @param[in] config Optional parameter for defining special port configuration parameters such as number of - * receive/transmit descriptors. If not set the default parameters will be set (see DpdkDeviceConfiguration) - * @return True if the device was opened successfully, false if device is already opened, if RX/TX queues - * configuration failed or of DPDK port configuration and startup failed - */ + /// Open the DPDK device. Notice opening the device only makes it ready to use, it doesn't start packet + /// capturing. This method initializes RX and TX queues, configures the DPDK port and starts it. Call close() to + /// close the device. The device is opened in promiscuous mode + /// @param[in] numOfRxQueuesToOpen Number of RX queues to setup. This number must be smaller or equal to the + /// return value of getTotalNumOfRxQueues() + /// @param[in] numOfTxQueuesToOpen Number of TX queues to setup. This number must be smaller or equal to the + /// return value of getTotalNumOfTxQueues() + /// @param[in] config Optional parameter for defining special port configuration parameters such as number of + /// receive/transmit descriptors. If not set the default parameters will be set (see DpdkDeviceConfiguration) + /// @return True if the device was opened successfully, false if device is already opened, if RX/TX queues + /// configuration failed or of DPDK port configuration and startup failed bool openMultiQueues(uint16_t numOfRxQueuesToOpen, uint16_t numOfTxQueuesToOpen, const DpdkDeviceConfiguration& config = DpdkDeviceConfiguration()); - /** - * There are two ways to capture packets using DpdkDevice: one of them is using worker threads (see - * DpdkDeviceList#startDpdkWorkerThreads() ) and the other way is setting a callback which is invoked each time - * a burst of packets is captured. This method implements the second way. After invoking this method the - * DpdkDevice enters capture mode and starts capturing packets. This method assumes there is only 1 RX queue - * opened for this device, otherwise an error is returned. It then allocates a core and creates 1 thread that - * runs in an endless loop and tries to capture packets using DPDK. Each time a burst of packets is captured the - * user callback is invoked with the user cookie as a parameter. This loop continues until stopCapture() is - * called. Notice: since the callback is invoked for every packet burst using this method can be slower than - * using worker threads. On the other hand, it's a simpler way comparing to worker threads - * @param[in] onPacketsArrive The user callback which will be invoked each time a packet burst is captured by - * the device - * @param[in] onPacketsArriveUserCookie The user callback is invoked with this cookie as a parameter. It can be - * used to pass information from the user application to the callback - * @return True if capture thread started successfully or false if device is already in capture mode, number of - * opened RX queues isn't equal to 1, if the method couldn't find an available core to allocate for the capture - * thread, or if thread invocation failed. In all of these cases an appropriate error message will be printed - */ + /// There are two ways to capture packets using DpdkDevice: one of them is using worker threads (see + /// DpdkDeviceList#startDpdkWorkerThreads() ) and the other way is setting a callback which is invoked each time + /// a burst of packets is captured. This method implements the second way. After invoking this method the + /// DpdkDevice enters capture mode and starts capturing packets. This method assumes there is only 1 RX queue + /// opened for this device, otherwise an error is returned. It then allocates a core and creates 1 thread that + /// runs in an endless loop and tries to capture packets using DPDK. Each time a burst of packets is captured + /// the user callback is invoked with the user cookie as a parameter. This loop continues until stopCapture() is + /// called. Notice: since the callback is invoked for every packet burst using this method can be slower than + /// using worker threads. On the other hand, it's a simpler way comparing to worker threads + /// @param[in] onPacketsArrive The user callback which will be invoked each time a packet burst is captured by + /// the device + /// @param[in] onPacketsArriveUserCookie The user callback is invoked with this cookie as a parameter. It can be + /// used to pass information from the user application to the callback + /// @return True if capture thread started successfully or false if device is already in capture mode, number of + /// opened RX queues isn't equal to 1, if the method couldn't find an available core to allocate for the capture + /// thread, or if thread invocation failed. In all of these cases an appropriate error message will be printed bool startCaptureSingleThread(OnDpdkPacketsArriveCallback onPacketsArrive, void* onPacketsArriveUserCookie); - /** - * This method does exactly what startCaptureSingleThread() does, but with more than one RX queue / capturing - * thread. It's called with a core mask as a parameter and creates a packet capture thread on every core. Each - * capturing thread is assigned with a specific RX queue. This method assumes all cores in the core-mask are - * available and there are enough opened RX queues to match for each thread. If these assumptions are not true - * an error is returned. After invoking all threads, all of them run in an endless loop and try to capture - * packets from their designated RX queues. Each time a burst of packets is captured the callback is invoked - * with the user cookie and the thread ID that captured the packets - * @param[in] onPacketsArrive The user callback which will be invoked each time a burst of packets is captured - * by the device - * @param[in] onPacketsArriveUserCookie The user callback is invoked with this cookie as a parameter. It can be - * used to pass information from the user application to the callback - * @param coreMask The core-mask for creating the capture threads - * @return True if all capture threads started successfully or false if device is already in capture mode, not - * all cores in the core-mask are available to DPDK, there are not enough opened RX queues to match all cores in - * the core-mask, or if thread invocation failed. In all of these cases an appropriate error message will be - * printed - */ + /// This method does exactly what startCaptureSingleThread() does, but with more than one RX queue / capturing + /// thread. It's called with a core mask as a parameter and creates a packet capture thread on every core. Each + /// capturing thread is assigned with a specific RX queue. This method assumes all cores in the core-mask are + /// available and there are enough opened RX queues to match for each thread. If these assumptions are not true + /// an error is returned. After invoking all threads, all of them run in an endless loop and try to capture + /// packets from their designated RX queues. Each time a burst of packets is captured the callback is invoked + /// with the user cookie and the thread ID that captured the packets + /// @param[in] onPacketsArrive The user callback which will be invoked each time a burst of packets is captured + /// by the device + /// @param[in] onPacketsArriveUserCookie The user callback is invoked with this cookie as a parameter. It can be + /// used to pass information from the user application to the callback + /// @param coreMask The core-mask for creating the capture threads + /// @return True if all capture threads started successfully or false if device is already in capture mode, not + /// all cores in the core-mask are available to DPDK, there are not enough opened RX queues to match all cores + /// in the core-mask, or if thread invocation failed. In all of these cases an appropriate error message will be + /// printed bool startCaptureMultiThreads(OnDpdkPacketsArriveCallback onPacketsArrive, void* onPacketsArriveUserCookie, CoreMask coreMask); - /** - * If device is in capture mode started by invoking startCaptureSingleThread() or startCaptureMultiThreads(), - * this method will stop all capturing threads and set the device to non-capturing mode - */ + /// If device is in capture mode started by invoking startCaptureSingleThread() or startCaptureMultiThreads(), + /// this method will stop all capturing threads and set the device to non-capturing mode void stopCapture(); - /** - * @return The number of free mbufs in device's mbufs pool - */ + /// @return The number of free mbufs in device's mbufs pool int getAmountOfFreeMbufs() const; - /** - * @return The number of mbufs currently in use in device's mbufs pool - */ + /// @return The number of mbufs currently in use in device's mbufs pool int getAmountOfMbufsInUse() const; - /** - * Retrieve RX/TX statistics from device - * @param[out] stats A reference to a DpdkDeviceStats object where stats will be written into - */ + /// Retrieve RX/TX statistics from device + /// @param[out] stats A reference to a DpdkDeviceStats object where stats will be written into void getStatistics(DpdkDeviceStats& stats) const; - /** - * Clear device statistics - */ + /// Clear device statistics void clearStatistics(); - /** - * DPDK supports an option to buffer TX packets and send them only when reaching a certain threshold. This - * method enables the user to flush a TX buffer for certain TX queue and send the packets stored in it (you can - * read about it here: http://dpdk.org/doc/api/rte__ethdev_8h.html#a0e941a74ae1b1b886764bc282458d946). It has - * the option to flush only when timeout that was set in DpdkDeviceConfiguration#flushTxBufferTimeout expired or - * flush immediately regardless of the timeout. The usage of this method can be in the main loop where you can - * call this method once every a couple of iterations to make sure TX buffers are flushed - * @param[in] flushOnlyIfTimeoutExpired When set to true, flush will happen only if the timeout defined in - * DpdkDeviceConfiguration#flushTxBufferTimeout expired. If set to false flush will happen immediately. Default - * value is false - * @param[in] txQueueId The TX queue ID to flush its buffer. Default is 0 - * @return The number of packets sent after buffer was flushed - */ + /// DPDK supports an option to buffer TX packets and send them only when reaching a certain threshold. This + /// method enables the user to flush a TX buffer for certain TX queue and send the packets stored in it (you can + /// read about it here: http://dpdk.org/doc/api/rte__ethdev_8h.html#a0e941a74ae1b1b886764bc282458d946). It has + /// the option to flush only when timeout that was set in DpdkDeviceConfiguration#flushTxBufferTimeout expired + /// or flush immediately regardless of the timeout. The usage of this method can be in the main loop where you + /// can call this method once every a couple of iterations to make sure TX buffers are flushed + /// @param[in] flushOnlyIfTimeoutExpired When set to true, flush will happen only if the timeout defined in + /// DpdkDeviceConfiguration#flushTxBufferTimeout expired. If set to false flush will happen immediately. Default + /// value is false + /// @param[in] txQueueId The TX queue ID to flush its buffer. Default is 0 + /// @return The number of packets sent after buffer was flushed uint16_t flushTxBuffer(bool flushOnlyIfTimeoutExpired = false, uint16_t txQueueId = 0); - /** - * Check whether a specific RSS hash function is supported by this device (PMD) - * @param[in] rssHF RSS hash function to check - * @return True if this hash function is supported, false otherwise - */ + /// Check whether a specific RSS hash function is supported by this device (PMD) + /// @param[in] rssHF RSS hash function to check + /// @return True if this hash function is supported, false otherwise bool isDeviceSupportRssHashFunction(DpdkRssHashFunction rssHF) const; - /** - * Check whether a mask of RSS hash functions is supported by this device (PMD) - * @param[in] rssHFMask RSS hash functions mask to check. This mask should be built from values in - * DpdkRssHashFunction enum - * @return True if all hash functions in this mask are supported, false otherwise - */ + /// Check whether a mask of RSS hash functions is supported by this device (PMD) + /// @param[in] rssHFMask RSS hash functions mask to check. This mask should be built from values in + /// DpdkRssHashFunction enum + /// @return True if all hash functions in this mask are supported, false otherwise bool isDeviceSupportRssHashFunction(uint64_t rssHFMask) const; - /** - * @return A mask of all RSS hash functions supported by this device (PMD). This mask is built from values in - * DpdkRssHashFunction enum. Value of zero means RSS is not supported by this device - */ + /// @return A mask of all RSS hash functions supported by this device (PMD). This mask is built from values in + /// DpdkRssHashFunction enum. Value of zero means RSS is not supported by this device uint64_t getSupportedRssHashFunctions() const; - /** - * @return The RSS hash function mask configured for this device (PMD) - */ + /// @return The RSS hash function mask configured for this device (PMD) uint64_t getConfiguredRssHashFunction() const; - /** - * Translate RSS hash function mask to a list of their string representation - * @param rssHFMask RSS hash function mask - * @return RSS hash functions as strings - */ + /// Translate RSS hash function mask to a list of their string representation + /// @param rssHFMask RSS hash function mask + /// @return RSS hash functions as strings std::vector rssHashFunctionMaskToString(uint64_t rssHFMask) const; // overridden methods - /** - * Overridden method from IPcapDevice. It calls openMultiQueues() with 1 RX queue and 1 TX queue. - * Notice opening the device only makes it ready to use, it doesn't start packet capturing. The device is opened - * in promiscuous mode - * @return True if the device was opened successfully, false if device is already opened, if RX/TX queues - * configuration failed or of DPDK port configuration and startup failed - */ + /// Overridden method from IPcapDevice. It calls openMultiQueues() with 1 RX queue and 1 TX queue. + /// Notice opening the device only makes it ready to use, it doesn't start packet capturing. The device is + /// opened in promiscuous mode + /// @return True if the device was opened successfully, false if device is already opened, if RX/TX queues + /// configuration failed or of DPDK port configuration and startup failed bool open() override { return openMultiQueues(1, 1); }; - /** - * Close the DpdkDevice. When device is closed it's not possible work with it - */ + /// Close the DpdkDevice. When device is closed it's not possible work with it void close() override; private: diff --git a/Pcap++/header/DpdkDeviceList.h b/Pcap++/header/DpdkDeviceList.h index 7711b2a2ae..2d91f91ef7 100644 --- a/Pcap++/header/DpdkDeviceList.h +++ b/Pcap++/header/DpdkDeviceList.h @@ -7,71 +7,53 @@ #include "Logger.h" #include -/** - * @file - * For details about PcapPlusPlus support for DPDK see DpdkDevice.h file description - */ - -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @file +/// For details about PcapPlusPlus support for DPDK see DpdkDevice.h file description + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class DpdkWorkerThread - * There are two ways to capture packets using DpdkDevice: one of them is using worker threads and the other way is - * using a callback which is invoked on each a burst of packets are captured (see - * DpdkDevice#startCaptureSingleThread() ). This class is a base class for implementing workers. A worker is - * basically a class that is activated by DpdkDeviceList#startDpdkWorkerThreads() and runs on a designated core. - * When it runs it can do whatever the user wants it to do. The most common use it running in an endless loop and - * receive, analyze and send packets using one or more DpdkDevice instances. It can do all kinds of processing for - * these packets. The only restriction for a worker class is that it must implement the 3 abstract methods stated in - * this class-interface for start running, stop running and get the core ID the worker is running on. - */ + /// @class DpdkWorkerThread + /// There are two ways to capture packets using DpdkDevice: one of them is using worker threads and the other way is + /// using a callback which is invoked on each a burst of packets are captured (see + /// DpdkDevice#startCaptureSingleThread() ). This class is a base class for implementing workers. A worker is + /// basically a class that is activated by DpdkDeviceList#startDpdkWorkerThreads() and runs on a designated core. + /// When it runs it can do whatever the user wants it to do. The most common use it running in an endless loop and + /// receive, analyze and send packets using one or more DpdkDevice instances. It can do all kinds of processing for + /// these packets. The only restriction for a worker class is that it must implement the 3 abstract methods stated + /// in this class-interface for start running, stop running and get the core ID the worker is running on. class DpdkWorkerThread { public: - /** - * A virtual d'tor. Can be overridden by child class if needed - */ - virtual ~DpdkWorkerThread() - {} - - /** - * An abstract method that must be implemented by child class. It's the indication for the worker to start - * running - * @param[in] coreId The core ID the worker is running on (should be returned in getCoreId() ) - * @return True if all went well or false otherwise - */ + /// A virtual d'tor. Can be overridden by child class if needed + virtual ~DpdkWorkerThread() = default; + + /// An abstract method that must be implemented by child class. It's the indication for the worker to start + /// running + /// @param[in] coreId The core ID the worker is running on (should be returned in getCoreId() ) + /// @return True if all went well or false otherwise virtual bool run(uint32_t coreId) = 0; - /** - * An abstract method that must be implemented by child class. It's the indication for the worker to stop - * running. After this method is called the caller expects the worker to stop running as fast as possible - */ + /// An abstract method that must be implemented by child class. It's the indication for the worker to stop + /// running. After this method is called the caller expects the worker to stop running as fast as possible virtual void stop() = 0; - /** - * An abstract method that must be implemented by child class. Get the core ID the worker is running on (as sent - * to the run() method as a parameter) - * @return The core ID the worker is running on - */ + /// An abstract method that must be implemented by child class. Get the core ID the worker is running on (as + /// sent to the run() method as a parameter) + /// @return The core ID the worker is running on virtual uint32_t getCoreId() const = 0; }; class KniDeviceList; - /** - * @class DpdkDeviceList - * A singleton class that encapsulates DPDK initialization and holds the list of DpdkDevice instances. As it's a - * singleton, it has only one active instance doesn't have a public c'tor. This class has several main uses: - * - it contains the initDpdk() static method which initializes the DPDK infrastructure. It should be called once - * in every application at its startup process - * - it contains the list of DpdkDevice instances and enables access to them - * - it has methods to start and stop worker threads. See more details in startDpdkWorkerThreads() - */ + /// @class DpdkDeviceList + /// A singleton class that encapsulates DPDK initialization and holds the list of DpdkDevice instances. As it's a + /// singleton, it has only one active instance doesn't have a public c'tor. This class has several main uses: + /// - it contains the initDpdk() static method which initializes the DPDK infrastructure. It should be called + /// once in every application at its startup process + /// - it contains the list of DpdkDevice instances and enables access to them + /// - it has methods to start and stop worker threads. See more details in startDpdkWorkerThreads() class DpdkDeviceList { friend class KniDeviceList; @@ -99,12 +81,10 @@ namespace pcpp public: ~DpdkDeviceList(); - /** - * As DpdkDeviceList is a singleton, this is the static getter to retrieve its instance. Note that if the static - * method initDpdk() was not called or returned false this instance won't be initialized and DpdkDevices won't - * be initialized either - * @return The singleton instance of DpdkDeviceList - */ + /// As DpdkDeviceList is a singleton, this is the static getter to retrieve its instance. Note that if the + /// static method initDpdk() was not called or returned false this instance won't be initialized and DpdkDevices + /// won't be initialized either + /// @return The singleton instance of DpdkDeviceList static DpdkDeviceList& getInstance() { static DpdkDeviceList instance; @@ -114,112 +94,92 @@ namespace pcpp return instance; } - /** - * A static method that has to be called once at the startup of every application that uses DPDK. It does - * several things: - * - verifies huge-pages are set and DPDK kernel module is loaded, unless specifically asked not to (these are - * set by the setup_dpdk.py external script that has to be run before application is started) - * - initializes the DPDK infrastructure - * - creates DpdkDevice instances for all ports available for DPDK - * - * @param[in] coreMask The cores to initialize DPDK with. After initialization, DPDK will only be able to use - * these cores for its work. The core mask should have a bit set for every core to use. For example: if the user - * want to use cores 1,2 the core mask should be 6 (binary: 110) - * @param[in] mBufPoolSizePerDevice The mbuf pool size each DpdkDevice will have. This has to be a number which - * is a power of 2 minus 1, for example: 1023 (= 2^10-1) or 4,294,967,295 (= 2^32-1), etc. This is a DPDK - * limitation, not PcapPlusPlus. The size of the mbuf pool size dictates how many packets can be handled by the - * application at the same time. For example: if pool size is 1023 it means that no more than 1023 packets can - * be handled or stored in application memory at every point in time - * @param[in] mBufDataSize The size of data buffer in each mbuf. If this value is less than 1, we will use - * RTE_MBUF_DEFAULT_BUF_SIZE. - * @param[in] masterCore The core DPDK will use as master to control all worker thread. The default, unless set - * otherwise, is 0 - * @param[in] initDpdkArgc Number of optional arguments - * @param[in] initDpdkArgv Optional arguments - * @param[in] appName Program name to be provided for the DPDK - * @param[in] verifyHugePagesAndDriver Verify huge-pages are set and DPDK kernel module is loaded. The default - * value it true - * @return True if initialization succeeded or false if huge-pages or DPDK kernel driver are not loaded, if - * mBufPoolSizePerDevice isn't power of 2 minus 1, if DPDK infra initialization failed or if DpdkDevice - * initialization failed. Anyway, if this method returned false it's impossible to use DPDK with PcapPlusPlus. - * You can get some more details about mbufs and pools in DpdkDevice.h file description or in DPDK web site - */ + /// A static method that has to be called once at the startup of every application that uses DPDK. It does + /// several things: + /// - verifies huge-pages are set and DPDK kernel module is loaded, unless specifically asked not to (these are + /// set by the setup_dpdk.py external script that has to be run before application is started) + /// - initializes the DPDK infrastructure + /// - creates DpdkDevice instances for all ports available for DPDK + /// + /// @param[in] coreMask The cores to initialize DPDK with. After initialization, DPDK will only be able to use + /// these cores for its work. The core mask should have a bit set for every core to use. For example: if the + /// user want to use cores 1,2 the core mask should be 6 (binary: 110) + /// @param[in] mBufPoolSizePerDevice The mbuf pool size each DpdkDevice will have. This has to be a number which + /// is a power of 2 minus 1, for example: 1023 (= 2^10-1) or 4,294,967,295 (= 2^32-1), etc. This is a DPDK + /// limitation, not PcapPlusPlus. The size of the mbuf pool size dictates how many packets can be handled by the + /// application at the same time. For example: if pool size is 1023 it means that no more than 1023 packets can + /// be handled or stored in application memory at every point in time + /// @param[in] mBufDataSize The size of data buffer in each mbuf. If this value is less than 1, we will use + /// RTE_MBUF_DEFAULT_BUF_SIZE. + /// @param[in] masterCore The core DPDK will use as master to control all worker thread. The default, unless set + /// otherwise, is 0 + /// @param[in] initDpdkArgc Number of optional arguments + /// @param[in] initDpdkArgv Optional arguments + /// @param[in] appName Program name to be provided for the DPDK + /// @param[in] verifyHugePagesAndDriver Verify huge-pages are set and DPDK kernel module is loaded. The default + /// value it true + /// @return True if initialization succeeded or false if huge-pages or DPDK kernel driver are not loaded, if + /// mBufPoolSizePerDevice isn't power of 2 minus 1, if DPDK infra initialization failed or if DpdkDevice + /// initialization failed. Anyway, if this method returned false it's impossible to use DPDK with PcapPlusPlus. + /// You can get some more details about mbufs and pools in DpdkDevice.h file description or in DPDK web site static bool initDpdk(CoreMask coreMask, uint32_t mBufPoolSizePerDevice, uint16_t mBufDataSize = 0, uint8_t masterCore = 0, uint32_t initDpdkArgc = 0, char** initDpdkArgv = nullptr, const std::string& appName = "pcapplusplusapp", bool verifyHugePagesAndDriver = true); - /** - * Get a DpdkDevice by port ID - * @param[in] portId The port ID - * @return A pointer to the DpdkDevice or nullptr if no such device is found - */ + /// Get a DpdkDevice by port ID + /// @param[in] portId The port ID + /// @return A pointer to the DpdkDevice or nullptr if no such device is found DpdkDevice* getDeviceByPort(int portId) const; - /** - * Get a DpdkDevice by port PCI address - * @param[in] pciAddr The port PCI address - * @return A pointer to the DpdkDevice or nullptr if no such device is found - */ + /// Get a DpdkDevice by port PCI address + /// @param[in] pciAddr The port PCI address + /// @return A pointer to the DpdkDevice or nullptr if no such device is found DpdkDevice* getDeviceByPciAddress(const std::string& pciAddr) const; - /** - * @return A vector of all DpdkDevice instances - */ + /// @return A vector of all DpdkDevice instances const std::vector& getDpdkDeviceList() const { return m_DpdkDeviceList; } - /** - * @return DPDK master core which is the core that initializes the application - */ + /// @return DPDK master core which is the core that initializes the application SystemCore getDpdkMasterCore() const; - /** - * Change the log level of all modules of DPDK - * @param[in] logLevel The log level to set. Logger#Info is RTE_LOG_NOTICE and Logger#Debug is RTE_LOG_DEBUG - */ + /// Change the log level of all modules of DPDK + /// @param[in] logLevel The log level to set. Logger#Info is RTE_LOG_NOTICE and Logger#Debug is RTE_LOG_DEBUG void setDpdkLogLevel(Logger::LogLevel logLevel); - /** - * @return The current DPDK log level. RTE_LOG_NOTICE and lower are considered as Logger#Info. RTE_LOG_INFO or - * RTE_LOG_DEBUG are considered as Logger#Debug - */ + /// @return The current DPDK log level. RTE_LOG_NOTICE and lower are considered as Logger#Info. RTE_LOG_INFO or + /// RTE_LOG_DEBUG are considered as Logger#Debug Logger::LogLevel getDpdkLogLevel() const; - /** - * Order DPDK to write all its logs to a file - * @param[in] logFile The file to write to - * @return True if action succeeded, false otherwise - */ + /// Order DPDK to write all its logs to a file + /// @param[in] logFile The file to write to + /// @return True if action succeeded, false otherwise bool writeDpdkLogToFile(FILE* logFile); - /** - * There are two ways to capture packets using DpdkDevice: one of them is using worker threads and the other way - * is setting a callback which is invoked each time a burst of packets is captured (see - * DpdkDevice#startCaptureSingleThread() ). This method implements the first way. See a detailed description of - * workers in DpdkWorkerThread class description. This method gets a vector of workers (classes that implement - * the DpdkWorkerThread interface) and a core mask and starts a worker thread on each core (meaning - call the - * worker's DpdkWorkerThread#run() method). Workers usually run in an endless loop and will be ordered to stop - * by calling stopDpdkWorkerThreads().
Note that number of cores in the core mask must be equal to the - * number of workers. In addition it's impossible to run a worker thread on DPDK master core, so the core mask - * shouldn't include the master core (you can find the master core by calling getDpdkMasterCore() ). - * @param[in] coreMask The bitmask of cores to run worker threads on. This list shouldn't include DPDK master - * core - * @param[in] workerThreadsVec A vector of worker instances to run (classes who implement the DpdkWorkerThread - * interface). Number of workers in this vector must be equal to the number of cores in the core mask. Notice - * that the instances of DpdkWorkerThread shouldn't be freed until calling stopDpdkWorkerThreads() as these - * instances are running - * @return True if all worker threads started successfully or false if: DPDK isn't initialized (initDpdk() - * wasn't called or returned false), number of cores differs from number of workers, core mask includes DPDK - * master core or if one of the worker threads couldn't be run - */ + /// There are two ways to capture packets using DpdkDevice: one of them is using worker threads and the other + /// way is setting a callback which is invoked each time a burst of packets is captured (see + /// DpdkDevice#startCaptureSingleThread() ). This method implements the first way. See a detailed description of + /// workers in DpdkWorkerThread class description. This method gets a vector of workers (classes that implement + /// the DpdkWorkerThread interface) and a core mask and starts a worker thread on each core (meaning - call the + /// worker's DpdkWorkerThread#run() method). Workers usually run in an endless loop and will be ordered to stop + /// by calling stopDpdkWorkerThreads().
Note that number of cores in the core mask must be equal to the + /// number of workers. In addition it's impossible to run a worker thread on DPDK master core, so the core mask + /// shouldn't include the master core (you can find the master core by calling getDpdkMasterCore() ). + /// @param[in] coreMask The bitmask of cores to run worker threads on. This list shouldn't include DPDK master + /// core + /// @param[in] workerThreadsVec A vector of worker instances to run (classes who implement the DpdkWorkerThread + /// interface). Number of workers in this vector must be equal to the number of cores in the core mask. Notice + /// that the instances of DpdkWorkerThread shouldn't be freed until calling stopDpdkWorkerThreads() as these + /// instances are running + /// @return True if all worker threads started successfully or false if: DPDK isn't initialized (initDpdk() + /// wasn't called or returned false), number of cores differs from number of workers, core mask includes DPDK + /// master core or if one of the worker threads couldn't be run bool startDpdkWorkerThreads(CoreMask coreMask, std::vector& workerThreadsVec); - /** - * Assuming worker threads are running, this method orders them to stop by calling DpdkWorkerThread#stop(). Then - * it waits until they stop running - */ + /// Assuming worker threads are running, this method orders them to stop by calling DpdkWorkerThread#stop(). + /// Then it waits until they stop running void stopDpdkWorkerThreads(); }; diff --git a/Pcap++/header/KniDevice.h b/Pcap++/header/KniDevice.h index 40e04a947b..64d3099e15 100644 --- a/Pcap++/header/KniDevice.h +++ b/Pcap++/header/KniDevice.h @@ -10,632 +10,518 @@ #include "MBufRawPacket.h" #include "LinuxNicInformationSocket.h" -/** - * @file - * @brief This file and KniDeviceList.h provide PcapPlusPlus C++ wrapper - * for DPDK KNI (Kernel Network Interface) library (librte_kni). - * The main propose of the rte_kni library is to provide a way to forward - * packets received by DPDK application to Linux kernel (a.e. to processes that - * have opened some kind of a net socket) for further processing and to obtain - * packets from Linux kernel. The KNI device is the bridge that accomplish the - * translation between DPDK packets (mbuf) and Linux kernel/socket packets - * (skbuf). Currently KNI devices report speeds up to 10 GBit/s.
- * KNI device is a virtual network interface so it can be created and destroyed - * programmatically at will. As a real network interface KNI deivice must - * be managed appropriately like other interfaces. To start operate it MUST be - * given an IP address for example by the means of ip a command and - * MUST be put up for example by ip l set [interface] up.
- * Additionally KNI interfaces support 4 other settings (depends on DPDK - * version used): - * - change link state: ip l set [interface] up/down - * - change MTU: ip l set dev [interface] mtu [mtu_count] - * - change MAC address: ip l set [interface] address [new_mac] - * - change promiscuous mode: ip l set [interface] promisc on/off - * - * Changes of each of this settings generates an event/request that must be - * handled by an application that have created the KNI device in 3 second - * period or it will be rejected and Linux kernel will not apply the change. - * The way that this requests MUST be handled is defined by DPDK and so for - * each type of request the application that creates the KNI device must provide - * the callback function to call. This callbacks are set in time of KNI device - * creation via KniIoctlCallbacks or KniOldIoctlCallbacks structures (the - * structure used is dependent on DPDK version).
- * There is a way to enable ethtool on KNI devices that include - * recompilation of DPDK and strict correspondence between KNI port id and DPDK - * port id, but it is not currently supported by PcapPlusPlus.
- * - * Known issues: - * - KNI device may not be able to set/update it's link status up - * (LINK_ERROR returned): - * The problem is laying in DPDK in rte_kni_update_link function - * (it is DPDK BUG if rte_kni_update_link is __rte_experimental). - * It is recommended to load rte_kni.ko module with "carrier=on" DPDK - * default is "carrier=off", provided setup_dpdk.py by default loads with - * "carrier=on" if Your DPDK version supports it. The good indication of - * this issue are "DPDK KNI Failed to update links state for device" - * messages when Pcap++Test application is being run. - * - Packets may not be seen by applications that have open sockets on KNI - * device: - * Check your iptables settings and other packet filters - KNI device - * is traditional network device so all caveats apply; - * - I see a lot of unknown traffic - what is it? - * This must be Linux kernel trying to communicate with other devices from - * KNI device and it will do so as long as You give the KNI device any IP - * address via ip command or by record in /etc/networking/interfaces; - * - On old versions of DPDK only 4 KNI devices may be created: - * Yep this is a limitation. You can change MAX_KNI_DEVICES constant in - * KniDeviceList.cpp to unlock this limit; - * - Any set* method never succeeds: - * You may forgot that they generate KNI requests that Your application MUST - * handle. Just use KniDevice#startRequestHandlerThread to handle all - * requests automatically. Or user running the application don't have - * suitable access rights (must have CAP_NET_ADMIN). - * - * Useful links: - * - KNI interface concept DPDK - * documentation - * - KNI PMD - * - KNI DPDK sample application - * - KNI DPDK test plan - */ - +/// @file +/// @brief This file and KniDeviceList.h provide PcapPlusPlus C++ wrapper +/// for DPDK KNI (Kernel Network Interface) library (librte_kni). +/// The main propose of the rte_kni library is to provide a way to forward +/// packets received by DPDK application to Linux kernel (a.e. to processes that +/// have opened some kind of a net socket) for further processing and to obtain +/// packets from Linux kernel. The KNI device is the bridge that accomplish the +/// translation between DPDK packets (mbuf) and Linux kernel/socket packets +/// (skbuf). Currently KNI devices report speeds up to 10 GBit/s.
+/// KNI device is a virtual network interface so it can be created and destroyed +/// programmatically at will. As a real network interface KNI deivice must +/// be managed appropriately like other interfaces. To start operate it MUST be +/// given an IP address for example by the means of ip a command and +/// MUST be put up for example by ip l set [interface] up.
+/// Additionally KNI interfaces support 4 other settings (depends on DPDK +/// version used): +/// - change link state: ip l set [interface] up/down +/// - change MTU: ip l set dev [interface] mtu [mtu_count] +/// - change MAC address: ip l set [interface] address [new_mac] +/// - change promiscuous mode: ip l set [interface] promisc on/off +/// +/// Changes of each of this settings generates an event/request that must be +/// handled by an application that have created the KNI device in 3 second +/// period or it will be rejected and Linux kernel will not apply the change. +/// The way that this requests MUST be handled is defined by DPDK and so for +/// each type of request the application that creates the KNI device must provide +/// the callback function to call. This callbacks are set in time of KNI device +/// creation via KniIoctlCallbacks or KniOldIoctlCallbacks structures (the +/// structure used is dependent on DPDK version).
+/// There is a way to enable ethtool on KNI devices that include +/// recompilation of DPDK and strict correspondence between KNI port id and DPDK +/// port id, but it is not currently supported by PcapPlusPlus.
+/// +/// Known issues: +/// - KNI device may not be able to set/update it's link status up +/// (LINK_ERROR returned): +/// The problem is laying in DPDK in rte_kni_update_link function +/// (it is DPDK BUG if rte_kni_update_link is __rte_experimental). +/// It is recommended to load rte_kni.ko module with "carrier=on" DPDK +/// default is "carrier=off", provided setup_dpdk.py by default loads with +/// "carrier=on" if Your DPDK version supports it. The good indication of +/// this issue are "DPDK KNI Failed to update links state for device" +/// messages when Pcap++Test application is being run. +/// - Packets may not be seen by applications that have open sockets on KNI +/// device: +/// Check your iptables settings and other packet filters - KNI device +/// is traditional network device so all caveats apply; +/// - I see a lot of unknown traffic - what is it? +/// This must be Linux kernel trying to communicate with other devices from +/// KNI device and it will do so as long as You give the KNI device any IP +/// address via ip command or by record in /etc/networking/interfaces; +/// - On old versions of DPDK only 4 KNI devices may be created: +/// Yep this is a limitation. You can change MAX_KNI_DEVICES constant in +/// KniDeviceList.cpp to unlock this limit; +/// - Any set* method never succeeds: +/// You may forgot that they generate KNI requests that Your application MUST +/// handle. Just use KniDevice#startRequestHandlerThread to handle all +/// requests automatically. Or user running the application don't have +/// suitable access rights (must have CAP_NET_ADMIN). +/// +/// Useful links: +/// - KNI interface concept DPDK +/// documentation +/// - KNI PMD +/// - KNI DPDK sample application +/// - KNI DPDK test plan struct rte_kni; -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { class KniDevice; class KniDeviceList; - /** - * Defines the signature callback used by capturing API on KNI device - */ + /// Defines the signature callback used by capturing API on KNI device typedef bool (*OnKniPacketArriveCallback)(MBufRawPacket* packets, uint32_t numOfPackets, KniDevice* device, void* userCookie); - /** - * @class KniDevice - * This class represents special kind of DPDK devices called KNI - Kernel Network Interface - * that are used to exchange DPDK mbuf packets with Linux kernel network stack. - * This devices have only one RX and one TX queue so MT receiving or MT sending is not - * safe but simultaneous receiving and sending packets is MT safe. - * The RX queue of KNI device is pointed from kernel to application and TX queue is - * pointed in opposite direction - from application to kernel. So receive* methods will - * obtain packets from kernel and send* methods will send them to kernel.
- * The lifecycle of the KNI device is as follows: - * - KniDeviceConfiguration structure is created by user and filled with device settings; - * - The KniDeviceList#getInstance method is called to initialize the KNI module and - * obtain the KniDeviceList singleton; - * - KniDeviceList#createDevice method of the singleton is called to allocate new KNI device; - * - Device then must be opened by calling KniDevice#open; - * - During lifetime the application must handle the requests from kernel either by calling - * KniDevice#handleRequests to handle them synchronously or by starting separate thread - * to do this by calling KniDevice#startRequestHandlerThread; - * - During lifetime the packets may be send to/received from KNI device via - * calls to synchronous API (send/receive methods) or asynchronously by - * running capturing thread using KniDevice#startCapture; - * - KNI device will be destroyed or implicitly on application exit. User must assure - * that NO OTHER linux application is using KNI device when and after it is being - * destroyed otherwise Linux kernel may crush dramatically. - */ + /// @class KniDevice + /// This class represents special kind of DPDK devices called KNI - Kernel Network Interface + /// that are used to exchange DPDK mbuf packets with Linux kernel network stack. + /// This devices have only one RX and one TX queue so MT receiving or MT sending is not + /// safe but simultaneous receiving and sending packets is MT safe. + /// The RX queue of KNI device is pointed from kernel to application and TX queue is + /// pointed in opposite direction - from application to kernel. So receive* methods will + /// obtain packets from kernel and send* methods will send them to kernel.
+ /// The lifecycle of the KNI device is as follows: + /// - KniDeviceConfiguration structure is created by user and filled with device settings; + /// - The KniDeviceList#getInstance method is called to initialize the KNI module and + /// obtain the KniDeviceList singleton; + /// - KniDeviceList#createDevice method of the singleton is called to allocate new KNI device; + /// - Device then must be opened by calling KniDevice#open; + /// - During lifetime the application must handle the requests from kernel either by calling + /// KniDevice#handleRequests to handle them synchronously or by starting separate thread + /// to do this by calling KniDevice#startRequestHandlerThread; + /// - During lifetime the packets may be send to/received from KNI device via + /// calls to synchronous API (send/receive methods) or asynchronously by + /// running capturing thread using KniDevice#startCapture; + /// - KNI device will be destroyed or implicitly on application exit. User must assure + /// that NO OTHER linux application is using KNI device when and after it is being + /// destroyed otherwise Linux kernel may crush dramatically. class KniDevice : public IDevice { friend class KniDeviceList; friend class MBufRawPacket; public: - /** - * Various link related constants for KNI device - */ + /// Various link related constants for KNI device enum KniLinkState { - /** Returned by KNI functions if DPDK version used don't support link setup capability */ + /// Returned by KNI functions if DPDK version used don't support link setup capability LINK_NOT_SUPPORTED = -2, - /** Returned by KNI functions if link changing function meets an error */ + /// Returned by KNI functions if link changing function meets an error LINK_ERROR = -1, - /** Used to put link status on KNI device DOWN */ + /// Used to put link status on KNI device DOWN LINK_DOWN = 0, - /** Used to put link status on KNI device UP */ + /// Used to put link status on KNI device UP LINK_UP = 1 }; - /** - * Various information related constants for KNI device - */ + /// Various information related constants for KNI device enum KniInfoState { - /** Used to identify intent to obtain cached version of KNI device information */ + /// Used to identify intent to obtain cached version of KNI device information INFO_CACHED = 0, - /** Used to identify intent to renew/update KNI device information */ + /// Used to identify intent to renew/update KNI device information INFO_RENEW = 1 }; - /** - * Promiscuous mode related constants for KNI device - */ + /// Promiscuous mode related constants for KNI device enum KniPromiscuousMode { - /** Used to DISABLE promiscuous mode on KNI device */ + /// Used to DISABLE promiscuous mode on KNI device PROMISC_DISABLE = 0, - /** Used to ENABLE promiscuous mode on KNI device */ + /// Used to ENABLE promiscuous mode on KNI device PROMISC_ENABLE = 1 }; - /** - * @brief New callbacks for KNI device events. - * This structure MUST be used ONLY when KniDeviceList#callbackVersion returns - * KniDeviceList#KniCallbackVersion#CALLBACKS_NEW. - * Or if You are sure that DPDK version used is 17.11 or higher. - * If some callback is not provided (nullptr) the request will always succeeds - * if other is not specified in callback description. - * @note This callbacks are direct copy of one defined in rte_kni_ops. Future - * maintainers of KNI device feature MUST refer to rte_kni_ops structure in - * rte_kni.h header file of DPDK to track the difference in signatures - */ + /// @brief New callbacks for KNI device events. + /// This structure MUST be used ONLY when KniDeviceList#callbackVersion returns + /// KniDeviceList#KniCallbackVersion#CALLBACKS_NEW. + /// Or if You are sure that DPDK version used is 17.11 or higher. + /// If some callback is not provided (nullptr) the request will always succeeds + /// if other is not specified in callback description. + /// @note This callbacks are direct copy of one defined in rte_kni_ops. Future + /// maintainers of KNI device feature MUST refer to rte_kni_ops structure in + /// rte_kni.h header file of DPDK to track the difference in signatures struct KniIoctlCallbacks { - /** - * Pointer to function of changing MTU. - * Must return 0 in case of success or negative error code - */ + /// Pointer to function of changing MTU. + /// Must return 0 in case of success or negative error code int (*change_mtu)(uint16_t port_id, unsigned int new_mtu); - /** - * Pointer to function of configuring network interface. - * Must return 0 in case of success or negative error code - */ + /// Pointer to function of configuring network interface. + /// Must return 0 in case of success or negative error code int (*config_network_if)(uint16_t port_id, uint8_t if_up); - /** - * Pointer to function of configuring mac address. - * If callback is not provided and port_id of KNI device is not UINT16_MAX - * then DPDK will use predefined callback witch sets MAC address of - * DPDK port port_id via rte_eth_dev_default_mac_addr_set. - * Must return 0 in case of success or negative error code - */ + /// Pointer to function of configuring mac address. + /// If callback is not provided and port_id of KNI device is not UINT16_MAX + /// then DPDK will use predefined callback witch sets MAC address of + /// DPDK port port_id via rte_eth_dev_default_mac_addr_set. + /// Must return 0 in case of success or negative error code int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]); - /** - * Pointer to function of configuring promiscuous mode. - * If callback is not provided and port_id of KNI device is not UINT16_MAX - * then DPDK will use predefined callback witch sets promiscuous mode of - * DPDK port port_id via rte_eth_promiscuous_enable/rte_eth_promiscuous_disable. - * Must return 0 in case of success or negative error code - */ + /// Pointer to function of configuring promiscuous mode. + /// If callback is not provided and port_id of KNI device is not UINT16_MAX + /// then DPDK will use predefined callback witch sets promiscuous mode of + /// DPDK port port_id via rte_eth_promiscuous_enable/rte_eth_promiscuous_disable. + /// Must return 0 in case of success or negative error code int (*config_promiscusity)(uint16_t port_id, uint8_t to_on); }; - /** - * @brief Old callbacks for KNI device events. - * This structure MUST be used ONLY when KniDeviceList#callbackVersion returns - * KniDeviceList#KniCallbackVersion#CALLBACKS_OLD. - * Or if You are sure that DPDK version used is lower than 17.11. - * If some callback is not provided (nullptr) the request will always succeeds. - */ + /// @brief Old callbacks for KNI device events. + /// This structure MUST be used ONLY when KniDeviceList#callbackVersion returns + /// KniDeviceList#KniCallbackVersion#CALLBACKS_OLD. + /// Or if You are sure that DPDK version used is lower than 17.11. + /// If some callback is not provided (nullptr) the request will always succeeds. struct KniOldIoctlCallbacks { - /** - * Pointer to function of changing MTU. - * Must return 0 in case of success or negative error code - */ + /// Pointer to function of changing MTU. + /// Must return 0 in case of success or negative error code int (*change_mtu)(uint8_t port_id, unsigned int new_mtu); - /** - * Pointer to function of configuring network interface. - * Must return 0 in case of success or negative error code - */ + /// Pointer to function of configuring network interface. + /// Must return 0 in case of success or negative error code int (*config_network_if)(uint8_t port_id, uint8_t if_up); }; - /** - * @brief KNI device initialization data. - * Used to create new KNI device. - * Usage of callbacks member or oldCallbacks member is defined by - * result of KniDeviceList#callbackVersion - */ + /// @brief KNI device initialization data. + /// Used to create new KNI device. + /// Usage of callbacks member or oldCallbacks member is defined by + /// result of KniDeviceList#callbackVersion struct KniDeviceConfiguration { - /** - * Name used to display device in system. - * Must not interfere with already existing network interfaces. - * Must be less than or equal to IFNAMSIZ (16 chars including \0 on most systems) - */ + /// Name used to display device in system. + /// Must not interfere with already existing network interfaces. + /// Must be less than or equal to IFNAMSIZ (16 chars including \0 on most systems) std::string name; union { KniIoctlCallbacks* callbacks; KniOldIoctlCallbacks* oldCallbacks; }; - /** - * MAC (ETHERNET) address of new KNI device. - * If MacAddress::Zero is provided then - * some valid address will be automatically generated. - * If provided (not MacAddress::Zero) will be cached by new KNI device info structure. - */ + /// MAC (ETHERNET) address of new KNI device. + /// If MacAddress::Zero is provided then + /// some valid address will be automatically generated. + /// If provided (not MacAddress::Zero) will be cached by new KNI device info structure. MacAddress mac; - /** - * Used in same way as DPDK port id. - * If some new callbacks are omitted then have separate meaning - * (see KniIoctlCallbacks#config_mac_address and KniIoctlCallbacks#config_promiscusity). - * Can be set to UINT16_MAX. - */ + /// Used in same way as DPDK port id. + /// If some new callbacks are omitted then have separate meaning + /// (see KniIoctlCallbacks#config_mac_address and KniIoctlCallbacks#config_promiscusity). + /// Can be set to UINT16_MAX. uint16_t portId; - /** MTU of new KNI device. Will be cached by new KNI device info structure */ + /// MTU of new KNI device. Will be cached by new KNI device info structure uint16_t mtu; - /** - * If set forces to bind KNI Linux kernel thread (NOT userspace thread) to specific core. - * If rte_kni kernel module is loaded with "kthread_mode=single" then - - * rebinds kernel thread used for all KNI devices to specified core. - * If rte_kni kernel module is loaded with "kthread_mode=multiple" then - - * binds new kernel thread for this device to specified core. - */ + /// If set forces to bind KNI Linux kernel thread (NOT userspace thread) to specific core. + /// If rte_kni kernel module is loaded with "kthread_mode=single" then - + /// rebinds kernel thread used for all KNI devices to specified core. + /// If rte_kni kernel module is loaded with "kthread_mode=multiple" then - + /// binds new kernel thread for this device to specified core. bool bindKthread; - /** ID of core to bind Linux kernel thread to (same as DPDK cores IDs) */ + /// ID of core to bind Linux kernel thread to (same as DPDK cores IDs) uint32_t kthreadCoreId; }; private: - /** All instances of this class MUST be produced by KniDeviceList class */ + /// All instances of this class MUST be produced by KniDeviceList class KniDevice(const KniDeviceConfiguration& conf, size_t mempoolSize, int unique); - /** This class is not copyable */ + /// This class is not copyable KniDevice(const KniDevice&); - /** This class is not copyable */ + /// This class is not copyable KniDevice& operator=(const KniDevice&); - /** All instances of this class MUST be destroyed by KniDeviceList class */ + /// All instances of this class MUST be destroyed by KniDeviceList class ~KniDevice(); public: - /* Information getters */ - - /** - * Indicates whether the KNI device was initialized successfully - */ + /// Indicates whether the KNI device was initialized successfully inline bool isInitialized() const { return !(m_Device == nullptr || m_MBufMempool == nullptr); } - /** - * Obtains name of KNI device in form of C++ string - */ + /// Obtains name of KNI device in form of C++ string inline std::string getName() const { return std::string(m_DeviceInfo.name); } - /** - * Obtains port ID of KNI device - */ + /// Obtains port ID of KNI device inline uint16_t getPort() const { return m_DeviceInfo.portId; } - /** - * @brief Obtains link status of KNI device. - * If called with INFO_CACHED - returns cached data about link state (SUPER FAST may be INACCURATE). - * If called with INFO_RENEW - makes system call to Linux to obtain - * link information and caches it (VERY SLOW but ACCURATE). - * @param[in] state Defines information relevance level - * @return LINK_UP, LINK_DOWN, LINK_NOT_SUPPORTED if device is not initialized, some times LINK_ERROR - */ + /// @brief Obtains link status of KNI device. + /// If called with INFO_CACHED - returns cached data about link state (SUPER FAST may be INACCURATE). + /// If called with INFO_RENEW - makes system call to Linux to obtain + /// link information and caches it (VERY SLOW but ACCURATE). + /// @param[in] state Defines information relevance level + /// @return LINK_UP, LINK_DOWN, LINK_NOT_SUPPORTED if device is not initialized, some times LINK_ERROR KniLinkState getLinkState(KniInfoState state = INFO_CACHED); - /** - * @brief Obtains MAC address of KNI device. - * If called with INFO_CACHED - returns cached data about MAC address (SUPER FAST may be INACCURATE). - * If called with INFO_RENEW - makes system call to Linux to obtain - * MAC address and caches it (VERY SLOW but ACCURATE). - * @param[in] state Defines information relevance level - * @return Known MAC address of KNI interface - */ + /// @brief Obtains MAC address of KNI device. + /// If called with INFO_CACHED - returns cached data about MAC address (SUPER FAST may be INACCURATE). + /// If called with INFO_RENEW - makes system call to Linux to obtain + /// MAC address and caches it (VERY SLOW but ACCURATE). + /// @param[in] state Defines information relevance level + /// @return Known MAC address of KNI interface MacAddress getMacAddress(KniInfoState state = INFO_CACHED); - /** - * @brief Obtains MTU of KNI device. - * If called with INFO_CACHED - returns cached data about MTU (SUPER FAST may be INACCURATE). - * If called with INFO_RENEW - makes system call to Linux to obtain - * MTU and caches it (VERY SLOW but ACCURATE). - * @param[in] state Defines information relevance level - * @return Known MTU of KNI interface - */ + /// @brief Obtains MTU of KNI device. + /// If called with INFO_CACHED - returns cached data about MTU (SUPER FAST may be INACCURATE). + /// If called with INFO_RENEW - makes system call to Linux to obtain + /// MTU and caches it (VERY SLOW but ACCURATE). + /// @param[in] state Defines information relevance level + /// @return Known MTU of KNI interface uint16_t getMtu(KniInfoState state = INFO_CACHED); - /** - * @brief Obtains information about promiscuous mode of KNI device. - * If called with INFO_CACHED - returns cached data about promiscuous mode (SUPER FAST may be INACCURATE). - * If called with INFO_RENEW - makes system call to Linux to obtain - * promiscuous mode and caches it (VERY SLOW but ACCURATE). - * @param[in] state Defines information relevance level - * @return Known promiscuous mode of KNI interface - */ + /// @brief Obtains information about promiscuous mode of KNI device. + /// If called with INFO_CACHED - returns cached data about promiscuous mode (SUPER FAST may be INACCURATE). + /// If called with INFO_RENEW - makes system call to Linux to obtain + /// promiscuous mode and caches it (VERY SLOW but ACCURATE). + /// @param[in] state Defines information relevance level + /// @return Known promiscuous mode of KNI interface KniPromiscuousMode getPromiscuous(KniInfoState state = INFO_CACHED); - /* Information setters */ - - /** - * @brief Sets link state of KNI device. - * Firstly the link information is updated as by call to getLinkState(INFO_RENEW). - * Then link state is set only if obtained state differs from provided. - * New link state of KNI device is cached. - * @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function - * @note Generates change link state request - * @param[in] state Must be LINK_UP or LINK_DOWN - * @return true if desired link state of KNI device is set (was as provided or set successfully), - * false if some error occurred (debug info is printed) - */ + /// @brief Sets link state of KNI device. + /// Firstly the link information is updated as by call to getLinkState(INFO_RENEW). + /// Then link state is set only if obtained state differs from provided. + /// New link state of KNI device is cached. + /// @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function + /// @note Generates change link state request + /// @param[in] state Must be LINK_UP or LINK_DOWN + /// @return true if desired link state of KNI device is set (was as provided or set successfully), + /// false if some error occurred (debug info is printed) bool setLinkState(KniLinkState state); - /** - * @brief Sets MAC address of KNI device. - * Unconditionally changes MAC of KNI device. - * If MAC is updated successfully then it is cached. - * @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function - * @note Generates change mac request - * @param[in] mac New MAC address of KNI device - * @return true if desired MAC address is set, false if not and some error occurred (debug info is printed) - */ + /// @brief Sets MAC address of KNI device. + /// Unconditionally changes MAC of KNI device. + /// If MAC is updated successfully then it is cached. + /// @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function + /// @note Generates change mac request + /// @param[in] mac New MAC address of KNI device + /// @return true if desired MAC address is set, false if not and some error occurred (debug info is printed) bool setMacAddress(const MacAddress& mac); - /** - * @brief Sets MTU of KNI device. - * Unconditionally changes MTU of KNI device. - * If MTU is updated successfully then it is cached. - * @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function - * @note Generates change mtu request - * @warning Low MTU values may crush Linux kernel. Follow Your kernel version documentation for details - * @param[in] mtu New MTU address of KNI device - * @return true if desired MTU is set, false if not and some error occurred (debug info is printed) - */ + /// @brief Sets MTU of KNI device. + /// Unconditionally changes MTU of KNI device. + /// If MTU is updated successfully then it is cached. + /// @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function + /// @note Generates change mtu request + /// @warning Low MTU values may crush Linux kernel. Follow Your kernel version documentation for details + /// @param[in] mtu New MTU address of KNI device + /// @return true if desired MTU is set, false if not and some error occurred (debug info is printed) bool setMtu(uint16_t mtu); - /** - * @brief Sets promiscuous mode of KNI device. - * Firstly the promiscuous mode information is updated as by call to getPromiscuous(INFO_RENEW). - * Then promiscuous mode is set only if obtained mode differs from provided. - * New promiscuous mode of KNI device is cached. - * @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function - * @note Generates promiscuous mode request - * @param[in] mode Must be PROMISC_DISABLE or PROMISC_ENABLE - * @return true if desired promiscuous mode of KNI device is set (was as provided or set successfully), - * false if some error occurred (debug info is printed) - */ + /// @brief Sets promiscuous mode of KNI device. + /// Firstly the promiscuous mode information is updated as by call to getPromiscuous(INFO_RENEW). + /// Then promiscuous mode is set only if obtained mode differs from provided. + /// New promiscuous mode of KNI device is cached. + /// @note You must be using sudo or be root or have CAP_NET_ADMIN capability to use this function + /// @note Generates promiscuous mode request + /// @param[in] mode Must be PROMISC_DISABLE or PROMISC_ENABLE + /// @return true if desired promiscuous mode of KNI device is set (was as provided or set successfully), + /// false if some error occurred (debug info is printed) bool setPromiscuous(KniPromiscuousMode mode); - /** - * @brief Updates link state of KNI device. - * Unconditionally updates link state of KNI device via call to DPDK librte_kni API. - * FASTER THAN setLinkState(state) but may not be supported or may fail. - * If link state is updated successfully then it is cached. - * @param[in] state New link state of KNI device - * @return LINK_NOT_SUPPORTED if this capability is not supported by DPDK version used (DPDK ver < 18.11), - * LINK_ERROR if attempt to set link state failed (may always fail on some systems see class description) - * LINK_DOWN - previous link state was DOWN, state is successfully updated to provided one - * LINK_UP - previous link state was UP, state is successfully updated to provided one - */ + /// @brief Updates link state of KNI device. + /// Unconditionally updates link state of KNI device via call to DPDK librte_kni API. + /// FASTER THAN setLinkState(state) but may not be supported or may fail. + /// If link state is updated successfully then it is cached. + /// @param[in] state New link state of KNI device + /// @return LINK_NOT_SUPPORTED if this capability is not supported by DPDK version used (DPDK ver < 18.11), + /// LINK_ERROR if attempt to set link state failed (may always fail on some systems see class description) + /// LINK_DOWN - previous link state was DOWN, state is successfully updated to provided one + /// LINK_UP - previous link state was UP, state is successfully updated to provided one KniLinkState updateLinkState(KniLinkState state); - /* Requests */ - - /** - * @brief Handle requests from Linux kernel synchronously in calling thread. - * When one of events which is needed application attention occurres it must be handled by calling this - * function (or by running RequestHandlerThread for this device). - * Until the request is handled the Linux kernel thread that manages this KNI is blocked. - * If it is not handled by application in 3 seconds the request is reported to kernel as failed one. - * Current known requests are: - * - change link state: ip l set [interface] up/down - * - change mtu: ip l set dev [interface] mtu [mtu_count] - * - change mac: ip l set [interface] address [new_mac] - * - change promiscuous mode: ip l set [interface] promisc on/off - * @warning Functions setLinkState, setMacAddress, setMtu and setPromiscuous will generate this requests. - * @note Callbacks provided for this KNI device will be called synchronously in calling thread during execution - * of this function - * @return true if no error happened during request handling false otherwise - */ + /// @brief Handle requests from Linux kernel synchronously in calling thread. + /// When one of events which is needed application attention occurres it must be handled by calling this + /// function (or by running RequestHandlerThread for this device). + /// Until the request is handled the Linux kernel thread that manages this KNI is blocked. + /// If it is not handled by application in 3 seconds the request is reported to kernel as failed one. + /// Current known requests are: + /// - change link state: ip l set [interface] up/down + /// - change mtu: ip l set dev [interface] mtu [mtu_count] + /// - change mac: ip l set [interface] address [new_mac] + /// - change promiscuous mode: ip l set [interface] promisc on/off + /// @warning Functions setLinkState, setMacAddress, setMtu and setPromiscuous will generate this requests. + /// @note Callbacks provided for this KNI device will be called synchronously in calling thread during execution + /// of this function + /// @return true if no error happened during request handling false otherwise bool handleRequests(); - /** - * @brief Starts new thread (using pthread) to asynchronously handle KNI device requests. - * See description of handleRequests() about requests. - * New thread is detached using pthread_detach. - * This thread can be stopped explicitly by calling stopRequestHandlerThread() or - * implicitly on KNI device destruction. - * Linux nanosleep() function is used for - * sleeping. - * @note Callbacks provided for this KNI device will be called asynchronously in new thread - * @param[in] sleepSeconds Sleeping time in seconds - * @param[in] sleepNanoSeconds Sleeping time in nanoseconds - * @return true if new thread is started successfully false otherwise - */ + /// @brief Starts new thread (using pthread) to asynchronously handle KNI device requests. + /// See description of handleRequests() about requests. + /// New thread is detached using pthread_detach. + /// This thread can be stopped explicitly by calling stopRequestHandlerThread() or + /// implicitly on KNI device destruction. + /// Linux nanosleep() function is used for + /// sleeping. + /// @note Callbacks provided for this KNI device will be called asynchronously in new thread + /// @param[in] sleepSeconds Sleeping time in seconds + /// @param[in] sleepNanoSeconds Sleeping time in nanoseconds + /// @return true if new thread is started successfully false otherwise bool startRequestHandlerThread(long sleepSeconds, long sleepNanoSeconds = 0); - /** - * @brief Explicitly stops request thread for this device if it was running. - * See description of handleRequests() about requests. - * @warning There may be a rare error when request thread handles requests on already - * destroyed device. It occurres only because request thread is detached one but it is really really rare. - * In case of this error occurring (must be SIGSEGV) change type of created thread in startRequestHandlerThread - * function from DETACHED to JOINABLE. - */ + /// @brief Explicitly stops request thread for this device if it was running. + /// See description of handleRequests() about requests. + /// @warning There may be a rare error when request thread handles requests on already + /// destroyed device. It occurres only because request thread is detached one but it is really really rare. + /// In case of this error occurring (must be SIGSEGV) change type of created thread in startRequestHandlerThread + /// function from DETACHED to JOINABLE. void stopRequestHandlerThread(); - /* Packet receive */ - - /** - * @brief Receive raw packets from kernel. - * @param[out] rawPacketsArr A vector where all received packets will be written into - * @return The number of packets received. If an error occurred 0 will be returned and the error will be printed - * to log - */ + /// @brief Receive raw packets from kernel. + /// @param[out] rawPacketsArr A vector where all received packets will be written into + /// @return The number of packets received. If an error occurred 0 will be returned and the error will be + /// printed to log uint16_t receivePackets(MBufRawPacketVector& rawPacketsArr); - /** - * @brief Receive raw packets from kernel. - * Please notice that in terms of performance, this is the best method to use - * for receiving packets because out of all receivePackets overloads this method requires the least overhead and - * is almost as efficient as receiving packets directly through DPDK. So if performance is a critical factor in - * your application, please use this method - * @param[out] rawPacketsArr A pointer to an array of MBufRawPacket pointers where all received packets will be - * written into. The array is expected to be allocated by the user and its length should be provided in - * rawPacketArrLength. Number of packets received will be returned. Notice it's the user responsibility to free - * the array and its content when done using it - * @param[out] rawPacketArrLength The length of MBufRawPacket pointers array - * @return The number of packets received. If an error occurred 0 will be returned and the error will be printed - * to log - */ + /// @brief Receive raw packets from kernel. + /// Please notice that in terms of performance, this is the best method to use + /// for receiving packets because out of all receivePackets overloads this method requires the least overhead + /// and is almost as efficient as receiving packets directly through DPDK. So if performance is a critical + /// factor in your application, please use this method + /// @param[out] rawPacketsArr A pointer to an array of MBufRawPacket pointers where all received packets will be + /// written into. The array is expected to be allocated by the user and its length should be provided in + /// rawPacketArrLength. Number of packets received will be returned. Notice it's the user responsibility to free + /// the array and its content when done using it + /// @param[out] rawPacketArrLength The length of MBufRawPacket pointers array + /// @return The number of packets received. If an error occurred 0 will be returned and the error will be + /// printed to log uint16_t receivePackets(MBufRawPacket** rawPacketsArr, uint16_t rawPacketArrLength); - /** - * @brief Receive parsed packets from kernel. - * @param[out] packetsArr A pointer to an allocated array of Packet pointers where all received packets will be - * written into. The array is expected to be allocated by the user and its length should be provided in - * packetsArrLength. Number of packets received will be returned. Notice it's the user responsibility to free - * the array and its content when done using it - * @param[out] packetsArrLength The length of Packet pointers array - * @return The number of packets received. If an error occurred 0 will be returned and the error will be printed - * to log - */ + /// @brief Receive parsed packets from kernel. + /// @param[out] packetsArr A pointer to an allocated array of Packet pointers where all received packets will be + /// written into. The array is expected to be allocated by the user and its length should be provided in + /// packetsArrLength. Number of packets received will be returned. Notice it's the user responsibility to free + /// the array and its content when done using it + /// @param[out] packetsArrLength The length of Packet pointers array + /// @return The number of packets received. If an error occurred 0 will be returned and the error will be + /// printed to log uint16_t receivePackets(Packet** packetsArr, uint16_t packetsArrLength); - /* Packet send */ - - /** - * @brief Send an array of MBufRawPacket to kernel. - * Please notice the following:
- * - In terms of performance, this is the best method to use for sending packets because out of all sendPackets - * overloads this method requires the least overhead and is almost as efficient as sending the packets - * directly through DPDK. So if performance is a critical factor in your application, please use this method - * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK - *

- * @param[in] rawPacketsArr A pointer to an array of MBufRawPacket - * @param[in] arrLength The length of the array - * @return The number of packets actually and successfully sent - */ + /// @brief Send an array of MBufRawPacket to kernel. + /// Please notice the following:
+ /// - In terms of performance, this is the best method to use for sending packets because out of all sendPackets + /// overloads this method requires the least overhead and is almost as efficient as sending the packets + /// directly through DPDK. So if performance is a critical factor in your application, please use this method + /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK + ///

+ /// @param[in] rawPacketsArr A pointer to an array of MBufRawPacket + /// @param[in] arrLength The length of the array + /// @return The number of packets actually and successfully sent uint16_t sendPackets(MBufRawPacket** rawPacketsArr, uint16_t arrLength); - /** - * @brief Send an array of parsed packets to kernel. - * Please notice the following:
- * - If some or all of the packets contain raw packets which aren't of type MBufRawPacket, a new temp - * MBufRawPacket instances will be created and packet data will be copied to them. This is necessary to - * allocate mbufs which will store the data to be sent. If performance is a critical factor please make sure - * you send parsed packets that contain only raw packets of type MBufRawPacket - * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed by - * DPDK

- * @param[in] packetsArr A pointer to an array of parsed packet pointers - * @param[in] arrLength The length of the array - * @return The number of packets actually and successfully sent - */ + /// @brief Send an array of parsed packets to kernel. + /// Please notice the following:
+ /// - If some or all of the packets contain raw packets which aren't of type MBufRawPacket, a new temp + /// MBufRawPacket instances will be created and packet data will be copied to them. This is necessary to + /// allocate mbufs which will store the data to be sent. If performance is a critical factor please make sure + /// you send parsed packets that contain only raw packets of type MBufRawPacket + /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed + /// by DPDK

+ /// @param[in] packetsArr A pointer to an array of parsed packet pointers + /// @param[in] arrLength The length of the array + /// @return The number of packets actually and successfully sent uint16_t sendPackets(Packet** packetsArr, uint16_t arrLength); - /** - * @brief Send a vector of MBufRawPacket pointers to kernel. - * Please notice the following:
- * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK - *

- * @param[in] rawPacketsVec The vector of raw packet - * @return The number of packets actually and successfully sent - */ + /// @brief Send a vector of MBufRawPacket pointers to kernel. + /// Please notice the following:
+ /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - The mbufs used in this method aren't freed by this method, they will be transparently freed by DPDK + ///

+ /// @param[in] rawPacketsVec The vector of raw packet + /// @return The number of packets actually and successfully sent uint16_t sendPackets(MBufRawPacketVector& rawPacketsVec); - /** - * @brief Send a vector of RawPacket pointers to kernel. - * Please notice the following:
- * - If some or all of the raw packets aren't of type MBufRawPacket, a new temp MBufRawPacket instances will be - * created and packet data will be copied to them. This is necessary to allocate mbufs which will store the - * data to be sent. If performance is a critical factor please make sure you send only raw packets of type - * MBufRawPacket (or use the sendPackets overload that sends MBufRawPacketVector) - * - If the number of packets to send is higher than 64 this method will run multiple iterations of sending - * packets to DPDK, each iteration of 64 packets - * - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed by - * DPDK

- * @param[in] rawPacketsVec The vector of raw packet - * @return The number of packets actually and successfully sent - */ + /// @brief Send a vector of RawPacket pointers to kernel. + /// Please notice the following:
+ /// - If some or all of the raw packets aren't of type MBufRawPacket, a new temp MBufRawPacket instances will be + /// created and packet data will be copied to them. This is necessary to allocate mbufs which will store the + /// data to be sent. If performance is a critical factor please make sure you send only raw packets of type + /// MBufRawPacket (or use the sendPackets overload that sends MBufRawPacketVector) + /// - If the number of packets to send is higher than 64 this method will run multiple iterations of sending + /// packets to DPDK, each iteration of 64 packets + /// - The mbufs used or allocated in this method aren't freed by this method, they will be transparently freed + /// by DPDK

+ /// @param[in] rawPacketsVec The vector of raw packet + /// @return The number of packets actually and successfully sent uint16_t sendPackets(RawPacketVector& rawPacketsVec); - /** - * @brief Send a raw packet to kernel. - * Please notice that if the raw packet isn't of type MBufRawPacket, a new temp MBufRawPacket - * will be created and the data will be copied to it. This is necessary to allocate an mbuf which will store the - * data to be sent. If performance is a critical factor please make sure you send a raw packet of type - * MBufRawPacket. Please also notice that the mbuf used or allocated in this method isn't freed by this method, - * it will be transparently freed by DPDK - * @param[in] rawPacket The raw packet to send - * @return True if packet was sent successfully or false if the packet wasn't sent for any other reason - */ + /// @brief Send a raw packet to kernel. + /// Please notice that if the raw packet isn't of type MBufRawPacket, a new temp MBufRawPacket + /// will be created and the data will be copied to it. This is necessary to allocate an mbuf which will store + /// the data to be sent. If performance is a critical factor please make sure you send a raw packet of type + /// MBufRawPacket. Please also notice that the mbuf used or allocated in this method isn't freed by this method, + /// it will be transparently freed by DPDK + /// @param[in] rawPacket The raw packet to send + /// @return True if packet was sent successfully or false if the packet wasn't sent for any other reason bool sendPacket(RawPacket& rawPacket); - /** - * @brief Send a MBufRawPacket to kernel. - * Please notice that the mbuf used in this method isn't freed by this method, it will be transparently freed by - * DPDK - * @param[in] rawPacket The MBufRawPacket to send - * @return True if packet was sent successfully or false if device is not opened or if the packet wasn't sent - * for any other reason - */ + /// @brief Send a MBufRawPacket to kernel. + /// Please notice that the mbuf used in this method isn't freed by this method, it will be transparently freed + /// by DPDK + /// @param[in] rawPacket The MBufRawPacket to send + /// @return True if packet was sent successfully or false if device is not opened or if the packet wasn't sent + /// for any other reason bool sendPacket(MBufRawPacket& rawPacket); - /** - * @brief Send a parsed packet to kernel. - * Please notice that the mbuf used or allocated in this method isn't freed by this method, it will be - * transparently freed by DPDK - * @param[in] packet The parsed packet to send. Please notice that if the packet contains a raw packet which - * isn't of type MBufRawPacket, a new temp MBufRawPacket will be created and the data will be copied to it. This - * is necessary to allocate an mbuf which will store the data to be sent. If performance is a critical factor - * please make sure you send a parsed packet that contains a raw packet of type MBufRawPacket - * @return True if packet was sent successfully or false if device is not opened or if the packet wasn't sent - * for any other reason - */ + /// @brief Send a parsed packet to kernel. + /// Please notice that the mbuf used or allocated in this method isn't freed by this method, it will be + /// transparently freed by DPDK + /// @param[in] packet The parsed packet to send. Please notice that if the packet contains a raw packet which + /// isn't of type MBufRawPacket, a new temp MBufRawPacket will be created and the data will be copied to it. + /// This is necessary to allocate an mbuf which will store the data to be sent. If performance is a critical + /// factor please make sure you send a parsed packet that contains a raw packet of type MBufRawPacket + /// @return True if packet was sent successfully or false if device is not opened or if the packet wasn't sent + /// for any other reason bool sendPacket(Packet& packet); - /* Packet capture */ - - /** - * @brief Start capturing packets asynchronously on this KNI interface. - * Each time a burst of packets is captured the onPacketArrives callback is called. - * The capture is done on a new thread created by this method, meaning all callback - * calls are done in a thread other than the caller thread. - * Capture process will stop and this capture thread will be terminated when calling stopCapture(). - * This method must be called after the device is opened (i.e the open() method was called), otherwise an error - * will be returned. Capturing thread will be terminated automatically on KNI device destruction or when close() - * is called. - * @param[in] onPacketArrives A callback that is called each time a burst of packets is captured - * @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to - * the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that - * give context to the capture callback, for example: objects that counts packets, manages flow state or manages - * the application state according to the packet that was captured - * @return True if capture started successfully, false if (relevant log error is printed in any case): - * - Capture is already running - * - Device is not opened - * - Capture thread could not be created - */ + /// @brief Start capturing packets asynchronously on this KNI interface. + /// Each time a burst of packets is captured the onPacketArrives callback is called. + /// The capture is done on a new thread created by this method, meaning all callback + /// calls are done in a thread other than the caller thread. + /// Capture process will stop and this capture thread will be terminated when calling stopCapture(). + /// This method must be called after the device is opened (i.e the open() method was called), otherwise an error + /// will be returned. Capturing thread will be terminated automatically on KNI device destruction or when + /// close() is called. + /// @param[in] onPacketArrives A callback that is called each time a burst of packets is captured + /// @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to + /// the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects + /// that give context to the capture callback, for example: objects that counts packets, manages flow state or + /// manages the application state according to the packet that was captured + /// @return True if capture started successfully, false if (relevant log error is printed in any case): + /// - Capture is already running + /// - Device is not opened + /// - Capture thread could not be created bool startCapture(OnKniPacketArriveCallback onPacketArrives, void* onPacketArrivesUserCookie); - /** - * @brief Start capturing packets synchronously on this KNI interface in blocking mode. - * Blocking mode means that this method block and won't return until the user frees the blocking - * (via onPacketArrives callback) or until a user defined timeout expires. - * Whenever a burst of packets is captured the onPacketArrives callback is called and lets the user handle the - * packet. In each callback call the user should return true if he wants to release the block or false if it - * wants it to keep blocking. Regardless of this callback a timeout is defined when stop capturing. When this - * timeout expires the method will return.
Please notice that stopCapture() isn't needed here because when - * the method returns (after timeout or per user decision) capturing on the device is stopped. - * @param[in] onPacketArrives A callback given by the user for handling incoming packets. After handling each - * burst of packets the user needs to return a boolean value. True value indicates stop capturing and stop - * blocking and false value indicates continue capturing and blocking - * @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to - * the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that - * give context to the capture callback, for example: objects that counts packets, manages flow state or manages - * the application state according to the packet that was captured - * @param[in] timeout A timeout in seconds for the blocking to stop even if the user didn't return "true" in the - * onPacketArrives callback If this timeout is set to 0 or less the timeout will be ignored, meaning the method - * will keep blocking until the user frees it via the onPacketArrives callback - * @return -1 if timeout expired, 1 if blocking was stopped via onPacketArrives callback or 0 if an error - * occurred (such as device not open etc.). When returning 0 an appropriate error message is printed to log - */ + /// @brief Start capturing packets synchronously on this KNI interface in blocking mode. + /// Blocking mode means that this method block and won't return until the user frees the blocking + /// (via onPacketArrives callback) or until a user defined timeout expires. + /// Whenever a burst of packets is captured the onPacketArrives callback is called and lets the user handle the + /// packet. In each callback call the user should return true if he wants to release the block or false if it + /// wants it to keep blocking. Regardless of this callback a timeout is defined when stop capturing. When this + /// timeout expires the method will return.
Please notice that stopCapture() isn't needed here because when + /// the method returns (after timeout or per user decision) capturing on the device is stopped. + /// @param[in] onPacketArrives A callback given by the user for handling incoming packets. After handling each + /// burst of packets the user needs to return a boolean value. True value indicates stop capturing and stop + /// blocking and false value indicates continue capturing and blocking + /// @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to + /// the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects + /// that give context to the capture callback, for example: objects that counts packets, manages flow state or + /// manages the application state according to the packet that was captured + /// @param[in] timeout A timeout in seconds for the blocking to stop even if the user didn't return "true" in + /// the onPacketArrives callback If this timeout is set to 0 or less the timeout will be ignored, meaning the + /// method will keep blocking until the user frees it via the onPacketArrives callback + /// @return -1 if timeout expired, 1 if blocking was stopped via onPacketArrives callback or 0 if an error + /// occurred (such as device not open etc.). When returning 0 an appropriate error message is printed to log + int startCaptureBlockingMode(OnKniPacketArriveCallback onPacketArrives, void* onPacketArrivesUserCookie, int timeout); - /** - * Stop a currently running asynchronous packet capture. - */ + /// Stop a currently running asynchronous packet capture. void stopCapture(); - /* Device control */ - - /** - * Takes appropriate actions for opening KNI device. - * @return true if the device was opened successfully, false if device is already opened, - * or KNI device configuration and startup failed - */ + /// Takes appropriate actions for opening KNI device. + /// @return true if the device was opened successfully, false if device is already opened, + /// or KNI device configuration and startup failed bool open(); - /** - * @brief Close the KNI device. - * When device is closed it's not possible to work with it. - * Stops asynchronous packet capture if it is running. - */ + /// @brief Close the KNI device. + /// When device is closed it's not possible to work with it. + /// Stops asynchronous packet capture if it is running. void close(); private: diff --git a/Pcap++/header/KniDeviceList.h b/Pcap++/header/KniDeviceList.h index ed5e737a97..bfd2386fd6 100644 --- a/Pcap++/header/KniDeviceList.h +++ b/Pcap++/header/KniDeviceList.h @@ -7,122 +7,93 @@ #include "KniDevice.h" #include "DpdkDeviceList.h" -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class KniDeviceList - * A singleton class that encapsulates DPDK KNI module initialization - * and holds the list of KniDevice instances. - * As it's a singleton, it has only one active instance doesn't have a public c'tor. - */ + /// @class KniDeviceList + /// A singleton class that encapsulates DPDK KNI module initialization + /// and holds the list of KniDevice instances. + /// As it's a singleton, it has only one active instance doesn't have a public c'tor. class KniDeviceList { KniDeviceList(); - /** - * @brief Explicit destruction of KNI device. - * After this call device is no longer available for external (by Linux) - * or internal (by application) usage. - * All threads running on this device are stopped (request and/or capturing). - * The device can no longer be found by it's name or id. - * @warning NOT MT SAFE - * @warning This method is forbidden as the result of discussion about packet memory pool - * lifetime made here. - * If You feel safe to use it please do, but no guarantee is provided. - * @param[in] kniDevice KNI device to be destroyed explicitly - */ + /// @brief Explicit destruction of KNI device. + /// After this call device is no longer available for external (by Linux) + /// or internal (by application) usage. + /// All threads running on this device are stopped (request and/or capturing). + /// The device can no longer be found by it's name or id. + /// @warning NOT MT SAFE + /// @warning This method is forbidden as the result of discussion about packet memory pool + /// lifetime made here. + /// If You feel safe to use it please do, but no guarantee is provided. + /// @param[in] kniDevice KNI device to be destroyed explicitly void destroyDevice(KniDevice* kniDevice); public: - /** - * Callback related constants for KNI device - */ + /// Callback related constants for KNI device enum KniCallbackVersion { - /** Reports that DPDK supports only KniDevice#KniIoctlCallbacks callback structure */ + /// Reports that DPDK supports only KniDevice#KniIoctlCallbacks callback structure CALLBACKS_NEW = 0, - /** Reports that DPDK supports only KniDevice#KniOldIoctlCallbacks callback structure */ + /// Reports that DPDK supports only KniDevice#KniOldIoctlCallbacks callback structure CALLBACKS_OLD = 1 }; - /** - * Various callback types supported by KNI device - */ + /// Various callback types supported by KNI device enum KniCallbackType { - /** KniDevice#KniIoctlCallbacks#change_mtu and KniDevice#KniOldIoctlCallbacks#change_mtu callback */ + /// KniDevice#KniIoctlCallbacks#change_mtu and KniDevice#KniOldIoctlCallbacks#change_mtu callback CALLBACK_MTU, - /** KniDevice#KniIoctlCallbacks#config_network_if and KniDevice#KniOldIoctlCallbacks#config_network_if - * callback */ + /// KniDevice#KniIoctlCallbacks#config_network_if and KniDevice#KniOldIoctlCallbacks#config_network_if + /// callback CALLBACK_LINK, - /** KniDevice#KniIoctlCallbacks#config_mac_address callback */ + /// KniDevice#KniIoctlCallbacks#config_mac_address callback CALLBACK_MAC, - /** KniDevice#KniIoctlCallbacks#config_promiscusity callback */ + /// KniDevice#KniIoctlCallbacks#config_promiscusity callback CALLBACK_PROMISC }; ~KniDeviceList(); - /** - * @brief Getter for singleton - * @warning Initialization of Kni module depends on initialization of DPDK made by DpdkDeviceList - * @return The singleton instance of KniDeviceList - */ + /// @brief Getter for singleton + /// @warning Initialization of Kni module depends on initialization of DPDK made by DpdkDeviceList + /// @return The singleton instance of KniDeviceList static KniDeviceList& getInstance(); - /** - * @return true if KNI module was initialized successfully false otherwise - */ + /// @return true if KNI module was initialized successfully false otherwise inline bool isInitialized() { return m_Initialized; } - /* Device manipulation */ - - /** - * @brief Factory method for KNI devices. - * Newly created device is remembered under portId and name provided in config and can be found later by them. - * If KNI device is not destroyed explicitly thru KniDeviceList#destroyDevice - * then it will be destroyed implicitly by the time application exits. - * @warning NOT MT SAFE - * @param[in] config KNI device configuration structure - * @param[in] mempoolSize Size of packet mempool used by this device - * @return Pointer to new KNI device or nullptr in case of error - */ + /// @brief Factory method for KNI devices. + /// Newly created device is remembered under portId and name provided in config and can be found later by them. + /// If KNI device is not destroyed explicitly thru KniDeviceList#destroyDevice + /// then it will be destroyed implicitly by the time application exits. + /// @warning NOT MT SAFE + /// @param[in] config KNI device configuration structure + /// @param[in] mempoolSize Size of packet mempool used by this device + /// @return Pointer to new KNI device or nullptr in case of error KniDevice* createDevice(const KniDevice::KniDeviceConfiguration& config, const size_t mempoolSize); - /** - * @brief Returns KNI device with specified portId. - * @note MT SAFE if createDevice or destroyDevice is not called concurrently - * @param[in] portId ID of KNI device to find - * @return Pointer to KNI device or nullptr if device not found - */ + /// @brief Returns KNI device with specified portId. + /// @note MT SAFE if createDevice or destroyDevice is not called concurrently + /// @param[in] portId ID of KNI device to find + /// @return Pointer to KNI device or nullptr if device not found KniDevice* getDeviceByPort(const uint16_t portId); - /** - * @brief Returns KNI device with specified name. - * @note MT SAFE if createDevice or destroyDevice is not called concurrently - * @param[in] name Name of KNI device to find - * @return Pointer to KNI device or nullptr if device not found - */ + /// @brief Returns KNI device with specified name. + /// @note MT SAFE if createDevice or destroyDevice is not called concurrently + /// @param[in] name Name of KNI device to find + /// @return Pointer to KNI device or nullptr if device not found KniDevice* getDeviceByName(const std::string& name); - /* Static information */ - - /** - * Returns KniCallbackVersion#CALLBACKS_NEW or - * KniCallbackVersion#CALLBACKS_OLD based on DPDK version used - * @note MT SAFE - */ + /// Returns KniCallbackVersion#CALLBACKS_NEW or + /// KniCallbackVersion#CALLBACKS_OLD based on DPDK version used + /// @note MT SAFE static KniCallbackVersion callbackVersion(); - /** - * Returns true if provided callback type is supported by used DPDK version - * @note MT SAFE - * @param[in] cbType One of KniCallbackType enum values - */ + /// Returns true if provided callback type is supported by used DPDK version + /// @note MT SAFE + /// @param[in] cbType One of KniCallbackType enum values static bool isCallbackSupported(const KniCallbackType cbType); private: diff --git a/Pcap++/header/LinuxNicInformationSocket.h b/Pcap++/header/LinuxNicInformationSocket.h index 2eb2b0dc47..8d29e22f97 100644 --- a/Pcap++/header/LinuxNicInformationSocket.h +++ b/Pcap++/header/LinuxNicInformationSocket.h @@ -2,71 +2,57 @@ struct ifreq; -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class LinuxNicInformationSocket - * Simple wrapper over Linux socket for making the information - * requests about NICs or making some changes in NICs setup. - * All possible requests are described in - * netdevice(7). - * The instance of this class handles underlying socket during its lifetime - * and takes an appropriate actions to close socket on destruction. - * The user must call LinuxNicInformationSocket#makeRequest method with - * known ioctl type and properly filled ifreq structure for this ioctl type. - * Filling of ifr_name may be omitted as it will be done automatically from - * provided NIC name. - * @note Usage of this class requires the inclusion of and Linux headers - */ + /// @class LinuxNicInformationSocket + /// Simple wrapper over Linux socket for making the information + /// requests about NICs or making some changes in NICs setup. + /// All possible requests are described in + /// netdevice(7). + /// The instance of this class handles underlying socket during its lifetime + /// and takes an appropriate actions to close socket on destruction. + /// The user must call LinuxNicInformationSocket#makeRequest method with + /// known ioctl type and properly filled ifreq structure for this ioctl type. + /// Filling of ifr_name may be omitted as it will be done automatically from + /// provided NIC name. + /// @note Usage of this class requires the inclusion of and Linux headers class LinuxNicInformationSocket { public: - /** - * Simple type rename for convenience - */ + /// Simple type rename for convenience typedef int LinuxSocket; - /** - * Simple type rename for convenience - */ + /// Simple type rename for convenience typedef unsigned long IoctlType; - /** - * Tries to open handled socket on construction. - * If fails prints the debug message - */ + /// Tries to open handled socket on construction. + /// If fails prints the debug message LinuxNicInformationSocket(); - /** - * Closes handled socket on destruction. - * If no socket was opened prints the debug message - */ + /// Closes handled socket on destruction. + /// If no socket was opened prints the debug message ~LinuxNicInformationSocket(); - /** - * @brief Makes request to socket. - * Firstly tries to open socket if it is not opened. - * Then makes an ioctl(2) request to handled socket with provided request structure. - * See: netdevice(7) - * for description of possible values of ioctlType and content of request. - * @note User have no need to fill ifr_name field of request. It will be filled - * automatically from provided nicName argument. - * @param[in] nicName Name of internet controller as displayed by Linux - * @param[in] ioctlType Value of ioctl to make - * @param[in,out] request Pointer to ifreq structure that contains some information - * or will be used for obtaining the information (depends on ioctlType) - * @return false if request was not made or socket can't be opened otherwise true - * @warning For some types of requests to succeed You need to be a root - * or have the CAP_NET_ADMIN capability. - */ + /// @brief Makes request to socket. + /// Firstly tries to open socket if it is not opened. + /// Then makes an ioctl(2) request to handled socket with provided request structure. + /// See: netdevice(7) + /// for description of possible values of ioctlType and content of request. + /// @note User have no need to fill ifr_name field of request. It will be filled + /// automatically from provided nicName argument. + /// @param[in] nicName Name of internet controller as displayed by Linux + /// @param[in] ioctlType Value of ioctl to make + /// @param[in,out] request Pointer to ifreq structure that contains some information + /// or will be used for obtaining the information (depends on ioctlType) + /// @return false if request was not made or socket can't be opened otherwise true + /// @warning For some types of requests to succeed You need to be a root + /// or have the CAP_NET_ADMIN capability. bool makeRequest(const char* nicName, const IoctlType ioctlType, ifreq* request); private: - /* Hidden copy constructor. This structure is not copyable */ + /// Hidden copy constructor. This structure is not copyable LinuxNicInformationSocket(const LinuxNicInformationSocket&); - /* Hidden copy assignment operator. This structure is not copyable */ + /// Hidden copy assignment operator. This structure is not copyable LinuxNicInformationSocket operator=(const LinuxNicInformationSocket&); LinuxSocket m_Socket; }; diff --git a/Pcap++/header/MBufRawPacket.h b/Pcap++/header/MBufRawPacket.h index 51e024cbed..4568ee9d46 100644 --- a/Pcap++/header/MBufRawPacket.h +++ b/Pcap++/header/MBufRawPacket.h @@ -9,10 +9,8 @@ struct rte_mbuf; struct rte_mempool; -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { @@ -23,28 +21,26 @@ namespace pcpp #define MBUFRAWPACKET_OBJECT_TYPE 1 - /** - * @class MBufRawPacket - * A class that inherits RawPacket and wraps DPDK's mbuf object (see some info about mbuf in DpdkDevice.h) but is - * compatible with PcapPlusPlus framework. Using MBufRawPacket is be almost similar to using RawPacket, the - * implementation differences are encapsulated in the class implementation. For example: user can create and - * manipulate a Packet object from MBufRawPacket the same way it is done with RawPacket; User can use - * PcapFileWriterDevice to save MBufRawPacket to pcap the same way it's used with RawPacket; etc.
The main - * difference is that RawPacket contains a pointer to the data itself and MBufRawPacket is holding a pointer to an - * mbuf object which contains a pointer to the data. This implies that MBufRawPacket without an mbuf allocated to it - * is not usable. Getting instances of MBufRawPacket can be done in one to the following ways: - * - Receiving packets from DpdkDevice. In this case DpdkDevice takes care of getting the mbuf from DPDK and - * wrapping it with MBufRawPacket - * - Creating MBufRawPacket from scratch (in order to send it with DpdkDevice, for example). In this case the - * user should call the init() method after constructing the object in order to allocate a new mbuf from DPDK - * port pool (encapsulated by DpdkDevice) - * - * Limitations of this class: - * - Currently chained mbufs are not supported. An mbuf has the capability to be linked to another mbuf and - * create a linked list of mbufs. This is good for Jumbo packets or other uses. MBufRawPacket doesn't support - * this capability so there is no way to access the mbufs linked to the mbuf wrapped by MBufRawPacket instance. - * I hope I'll be able to add this support in the future - */ + /// @class MBufRawPacket + /// A class that inherits RawPacket and wraps DPDK's mbuf object (see some info about mbuf in DpdkDevice.h) but is + /// compatible with PcapPlusPlus framework. Using MBufRawPacket is be almost similar to using RawPacket, the + /// implementation differences are encapsulated in the class implementation. For example: user can create and + /// manipulate a Packet object from MBufRawPacket the same way it is done with RawPacket; User can use + /// PcapFileWriterDevice to save MBufRawPacket to pcap the same way it's used with RawPacket; etc.
The main + /// difference is that RawPacket contains a pointer to the data itself and MBufRawPacket is holding a pointer to an + /// mbuf object which contains a pointer to the data. This implies that MBufRawPacket without an mbuf allocated to + /// it is not usable. Getting instances of MBufRawPacket can be done in one to the following ways: + /// - Receiving packets from DpdkDevice. In this case DpdkDevice takes care of getting the mbuf from DPDK and + /// wrapping it with MBufRawPacket + /// - Creating MBufRawPacket from scratch (in order to send it with DpdkDevice, for example). In this case the + /// user should call the init() method after constructing the object in order to allocate a new mbuf from DPDK + /// port pool (encapsulated by DpdkDevice) + /// + /// Limitations of this class: + /// - Currently chained mbufs are not supported. An mbuf has the capability to be linked to another mbuf and + /// create a linked list of mbufs. This is good for Jumbo packets or other uses. MBufRawPacket doesn't support + /// this capability so there is no way to access the mbufs linked to the mbuf wrapped by MBufRawPacket + /// instance. I hope I'll be able to add this support in the future class MBufRawPacket : public RawPacket { friend class DpdkDevice; @@ -63,86 +59,70 @@ namespace pcpp bool initFromRawPacket(const RawPacket* rawPacket, struct rte_mempool* mempool); public: - /** - * A default c'tor for this class. Constructs an instance of this class without an mbuf attached to it. In order - * to allocate an mbuf the user should call the init() method. Without calling init() the instance of this class - * is not usable. This c'tor can be used for initializing an array of MBufRawPacket (which requires an empty - * c'tor) - */ + /// A default c'tor for this class. Constructs an instance of this class without an mbuf attached to it. In + /// order to allocate an mbuf the user should call the init() method. Without calling init() the instance of + /// this class is not usable. This c'tor can be used for initializing an array of MBufRawPacket (which requires + /// an empty c'tor) MBufRawPacket() : RawPacket(), m_MBuf(nullptr), m_Mempool(nullptr), m_MbufDataSize(0), m_FreeMbuf(true) { m_DeleteRawDataAtDestructor = false; } - /** - * A d'tor for this class. Once called it frees the mbuf attached to it (returning it back to the mbuf pool it - * was allocated from) - */ + /// A d'tor for this class. Once called it frees the mbuf attached to it (returning it back to the mbuf pool it + /// was allocated from) virtual ~MBufRawPacket(); - /** - * A copy c'tor for this class. The copy c'tor allocates a new mbuf from the same pool the original mbuf was - * allocated from, attaches the new mbuf to this instance of MBufRawPacket and copies the data from the original - * mbuf to the new mbuf - * @param[in] other The MBufRawPacket instance to copy from - */ + /// A copy c'tor for this class. The copy c'tor allocates a new mbuf from the same pool the original mbuf was + /// allocated from, attaches the new mbuf to this instance of MBufRawPacket and copies the data from the + /// original mbuf to the new mbuf + /// @param[in] other The MBufRawPacket instance to copy from MBufRawPacket(const MBufRawPacket& other); - /** - * @brief Initialize an instance of this class from DpdkDevice. - * Initialization includes allocating an mbuf from the pool that resides in DpdkDevice. - * The user should call this method only once per instance. - * Calling it more than once will result with an error - * @param[in] device The DpdkDevice which has the pool to allocate the mbuf from - * @return True if initialization succeeded and false if this method was already called for this instance (and - * an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason - */ + /// @brief Initialize an instance of this class from DpdkDevice. + /// Initialization includes allocating an mbuf from the pool that resides in DpdkDevice. + /// The user should call this method only once per instance. + /// Calling it more than once will result with an error + /// @param[in] device The DpdkDevice which has the pool to allocate the mbuf from + /// @return True if initialization succeeded and false if this method was already called for this instance (and + /// an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason bool init(DpdkDevice* device); #ifdef USE_DPDK_KNI - /** - * @brief Initialize an instance of this class from KniDevice. - * Initialization includes allocating an mbuf from the pool that resides in KniDevice. - * The user should call this method only once per instance. - * Calling it more than once will result with an error - * @param[in] device The KniDevice which has the pool to allocate the mbuf from - * @return True if initialization succeeded and false if this method was already called for this instance (and - * an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason - */ + /// @brief Initialize an instance of this class from KniDevice. + /// Initialization includes allocating an mbuf from the pool that resides in KniDevice. + /// The user should call this method only once per instance. + /// Calling it more than once will result with an error + /// @param[in] device The KniDevice which has the pool to allocate the mbuf from + /// @return True if initialization succeeded and false if this method was already called for this instance (and + /// an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason bool init(KniDevice* device); #endif - /** - * @brief Initialize an instance of this class and copies the content of a RawPacket object. - * Initialization includes allocating an mbuf from the pool that resides in provided DpdkDevice, - * and copying the data from the input RawPacket object into this mBuf. - * The user should call this method only once per instance. - * Calling it more than once will result with an error - * @param[in] rawPacket A pointer to a RawPacket object from which data will be copied - * @param[in] device The DpdkDevice which has the pool to allocate the mbuf from - * @return True if initialization succeeded and false if this method was already called for this instance (and - * an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason - */ + /// @brief Initialize an instance of this class and copies the content of a RawPacket object. + /// Initialization includes allocating an mbuf from the pool that resides in provided DpdkDevice, + /// and copying the data from the input RawPacket object into this mBuf. + /// The user should call this method only once per instance. + /// Calling it more than once will result with an error + /// @param[in] rawPacket A pointer to a RawPacket object from which data will be copied + /// @param[in] device The DpdkDevice which has the pool to allocate the mbuf from + /// @return True if initialization succeeded and false if this method was already called for this instance (and + /// an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason bool initFromRawPacket(const RawPacket* rawPacket, DpdkDevice* device); #ifdef USE_DPDK_KNI - /** - * @brief Initialize an instance of this class and copies the content of a RawPacket object. - * Initialization includes allocating an mbuf from the pool that resides in provided KniDevice, - * and copying the data from the input RawPacket object into this mBuf. - * The user should call this method only once per instance. - * Calling it more than once will result with an error - * @param[in] rawPacket A pointer to a RawPacket object from which data will be copied - * @param[in] device The KniDevice which has the pool to allocate the mbuf from - * @return True if initialization succeeded and false if this method was already called for this instance (and - * an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason - */ + /// @brief Initialize an instance of this class and copies the content of a RawPacket object. + /// Initialization includes allocating an mbuf from the pool that resides in provided KniDevice, + /// and copying the data from the input RawPacket object into this mBuf. + /// The user should call this method only once per instance. + /// Calling it more than once will result with an error + /// @param[in] rawPacket A pointer to a RawPacket object from which data will be copied + /// @param[in] device The KniDevice which has the pool to allocate the mbuf from + /// @return True if initialization succeeded and false if this method was already called for this instance (and + /// an mbuf is already attached) or if allocating an mbuf from the pool failed for some reason bool initFromRawPacket(const RawPacket* rawPacket, KniDevice* device); #endif - /** - * @return A pointer to the DPDK mbuf stored in this object - */ + /// @return A pointer to the DPDK mbuf stored in this object inline rte_mbuf* getMBuf() { return m_MBuf; @@ -150,109 +130,87 @@ namespace pcpp // overridden methods - /** - * @return MBufRawPacket object type - */ + /// @return MBufRawPacket object type inline uint8_t getObjectType() const override { return MBUFRAWPACKET_OBJECT_TYPE; } - /** - * An assignment operator for this class. Copies the data from the mbuf attached to the other MBufRawPacket to - * the mbuf attached to this instance. If instance is not initialized (meaning no mbuf is attached) nothing will - * be copied and instance will remain uninitialized (also, an error will be printed) - * @param[in] other The MBufRawPacket to assign data from - */ + /// An assignment operator for this class. Copies the data from the mbuf attached to the other MBufRawPacket to + /// the mbuf attached to this instance. If instance is not initialized (meaning no mbuf is attached) nothing + /// will be copied and instance will remain uninitialized (also, an error will be printed) + /// @param[in] other The MBufRawPacket to assign data from MBufRawPacket& operator=(const MBufRawPacket& other); - /** - * @brief Clone this MBufRawPacket object. See copy constructor for details. - * The caller is responsible for the deallocation of the returned pointer. - * @return A pointer to the new MBufRawPacket object which is a clone of this object - */ + /// @brief Clone this MBufRawPacket object. See copy constructor for details. + /// The caller is responsible for the deallocation of the returned pointer. + /// @return A pointer to the new MBufRawPacket object which is a clone of this object MBufRawPacket* clone() const override; - /** - * Set raw data to the mbuf by copying the data to it. In order to stay compatible with the ancestor method - * which takes control of the data pointer and frees it when RawPacket is destroyed, this method frees this - * pointer right away after data is copied to the mbuf. So when using this method please notice that after it's - * called pRawData memory is free, don't use this pointer again. In addition, if raw packet isn't initialized - * (mbuf is nullptr), this method will call the init() method - * @param[in] pRawData A pointer to the new raw data - * @param[in] rawDataLen The new raw data length in bytes - * @param[in] timestamp The timestamp packet was received by the NIC - * @param[in] layerType The link layer type for this raw data. Default is Ethernet - * @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the - * actual packet length. This parameter represents the packet length. This parameter is optional, if not set or - * set to -1 it is assumed both lengths are equal - * @return True if raw data was copied to the mbuf successfully, false if rawDataLen is larger than mbuf max - * size, if initialization failed or if copying the data to the mbuf failed. In all of these cases an error will - * be printed to log - */ + /// Set raw data to the mbuf by copying the data to it. In order to stay compatible with the ancestor method + /// which takes control of the data pointer and frees it when RawPacket is destroyed, this method frees this + /// pointer right away after data is copied to the mbuf. So when using this method please notice that after it's + /// called pRawData memory is free, don't use this pointer again. In addition, if raw packet isn't initialized + /// (mbuf is nullptr), this method will call the init() method + /// @param[in] pRawData A pointer to the new raw data + /// @param[in] rawDataLen The new raw data length in bytes + /// @param[in] timestamp The timestamp packet was received by the NIC + /// @param[in] layerType The link layer type for this raw data. Default is Ethernet + /// @param[in] frameLength When reading from pcap files, sometimes the captured length is different from the + /// actual packet length. This parameter represents the packet length. This parameter is optional, if not set or + /// set to -1 it is assumed both lengths are equal + /// @return True if raw data was copied to the mbuf successfully, false if rawDataLen is larger than mbuf max + /// size, if initialization failed or if copying the data to the mbuf failed. In all of these cases an error + /// will be printed to log bool setRawData(const uint8_t* pRawData, int rawDataLen, timespec timestamp, LinkLayerType layerType = LINKTYPE_ETHERNET, int frameLength = -1); - /** - * Clears the object and frees the mbuf - */ + /// Clears the object and frees the mbuf void clear(); - /** - * Append packet data at the end of current data. This method uses the same mbuf already allocated and tries to - * append more space and copy the data to it. If MBufRawPacket is not initialize (mbuf is nullptr) or mbuf - * append failed an error is printed to log - * @param[in] dataToAppend A pointer to the data to append - * @param[in] dataToAppendLen Length in bytes of dataToAppend - */ + /// Append packet data at the end of current data. This method uses the same mbuf already allocated and tries to + /// append more space and copy the data to it. If MBufRawPacket is not initialize (mbuf is nullptr) or mbuf + /// append failed an error is printed to log + /// @param[in] dataToAppend A pointer to the data to append + /// @param[in] dataToAppendLen Length in bytes of dataToAppend void appendData(const uint8_t* dataToAppend, size_t dataToAppendLen); - /** - * Insert raw data at some index of the current data and shift the remaining data to the end. This method uses - * the same mbuf already allocated and tries to append more space to it. Then it just copies dataToAppend at the - * relevant index and shifts the remaining data to the end. If MBufRawPacket is not initialize (mbuf is nullptr) - * or mbuf append failed an error is printed to log - * @param[in] atIndex The index to insert the new data to - * @param[in] dataToInsert A pointer to the new data to insert - * @param[in] dataToInsertLen Length in bytes of dataToInsert - */ + /// Insert raw data at some index of the current data and shift the remaining data to the end. This method uses + /// the same mbuf already allocated and tries to append more space to it. Then it just copies dataToAppend at + /// the relevant index and shifts the remaining data to the end. If MBufRawPacket is not initialize (mbuf is + /// nullptr) or mbuf append failed an error is printed to log + /// @param[in] atIndex The index to insert the new data to + /// @param[in] dataToInsert A pointer to the new data to insert + /// @param[in] dataToInsertLen Length in bytes of dataToInsert void insertData(int atIndex, const uint8_t* dataToInsert, size_t dataToInsertLen); - /** - * Remove certain number of bytes from current raw data buffer. All data after the removed bytes will be shifted - * back. This method uses the mbuf already allocated and tries to trim space from it - * @param[in] atIndex The index to start removing bytes from - * @param[in] numOfBytesToRemove Number of bytes to remove - * @return True if all bytes were removed successfully, or false if MBufRawPacket is not initialize (mbuf is - * nullptr), mbuf trim failed or logatIndex+numOfBytesToRemove is out-of-bounds of the raw data buffer. In all - * of these cases an error is printed to log - */ + /// Remove certain number of bytes from current raw data buffer. All data after the removed bytes will be + /// shifted back. This method uses the mbuf already allocated and tries to trim space from it + /// @param[in] atIndex The index to start removing bytes from + /// @param[in] numOfBytesToRemove Number of bytes to remove + /// @return True if all bytes were removed successfully, or false if MBufRawPacket is not initialize (mbuf is + /// nullptr), mbuf trim failed or logatIndex+numOfBytesToRemove is out-of-bounds of the raw data buffer. In all + /// of these cases an error is printed to log bool removeData(int atIndex, size_t numOfBytesToRemove); - /** - * This overridden method,in contrast to its ancestor RawPacket#reallocateData() doesn't need to do anything - * because mbuf is already allocated to its maximum extent. So it only performs a check to verify the size after - * re-allocation doesn't exceed mbuf max size - * @param[in] newBufferLength The new buffer length as required by the user - * @return True if new size is larger than current size but smaller than mbuf max size, false otherwise - */ + /// This overridden method,in contrast to its ancestor RawPacket#reallocateData() doesn't need to do anything + /// because mbuf is already allocated to its maximum extent. So it only performs a check to verify the size + /// after re-allocation doesn't exceed mbuf max size + /// @param[in] newBufferLength The new buffer length as required by the user + /// @return True if new size is larger than current size but smaller than mbuf max size, false otherwise bool reallocateData(size_t newBufferLength); - /** - * Set an indication whether to free the mbuf when done using it or not ("done using it" means setting another - * mbuf or class d'tor). Default value is true. - * @param[in] val The value to set. True means free the mbuf when done using it. Default it True - */ + /// Set an indication whether to free the mbuf when done using it or not ("done using it" means setting another + /// mbuf or class d'tor). Default value is true. + /// @param[in] val The value to set. True means free the mbuf when done using it. Default it True inline void setFreeMbuf(bool val = true) { m_FreeMbuf = val; } }; - /** - * @typedef MBufRawPacketVector - * A vector of pointers to MBufRawPacket - */ + /// @typedef MBufRawPacketVector + /// A vector of pointers to MBufRawPacket typedef PointerVector MBufRawPacketVector; } // namespace pcpp diff --git a/Pcap++/header/NetworkUtils.h b/Pcap++/header/NetworkUtils.h index 7df6b397a3..d6aebd50b9 100644 --- a/Pcap++/header/NetworkUtils.h +++ b/Pcap++/header/NetworkUtils.h @@ -6,88 +6,75 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class NetworkUtils - * This class bundles several network utilities that are very common and useful. These utilities use Pcap++ and - * Packet++ packet crafting and processing capabilities. This class is a singleton and can be access by - * getInstance() only - */ + /// @class NetworkUtils + /// This class bundles several network utilities that are very common and useful. These utilities use Pcap++ and + /// Packet++ packet crafting and processing capabilities. This class is a singleton and can be access by + /// getInstance() only class NetworkUtils { public: - /** - * The access method to the singleton - * @return The singleton instance of this class - */ + /// The access method to the singleton + /// @return The singleton instance of this class static NetworkUtils& getInstance() { static NetworkUtils instance; return instance; } - /** - * Default timeout used for several utilities. Currently set to 5 seconds - */ + /// Default timeout used for several utilities. Currently set to 5 seconds static const int DefaultTimeout; - /** - * Resolve the MAC address for a given IPv4 address. It's done using the ARP protocol: send an ARP request and - * interpret the response - * @param[in] ipAddr The IPv4 address to resolve MAC address to - * @param[in] device The interface to send and receive the ARP packets on - * @param[out] arpResponseTimeMS An output parameter that will contain the time in milliseconds that took the - * ARP response to arrive - * @param[in] sourceMac An optional parameter to set the source MAC address that will be sent with the ARP - * request if this parameter isn't set or set with MacAddress#Zero the MAC address of the interface will be used - * @param[in] sourceIP An optional parameter to set the source IPv4 address that will be sent with the ARP - * request if this parameter isn't set or set with IPv4Address#Zero the default IPv4 address of the interface - * will be used - * @param[in] arpTimeout An optional parameter to set the timeout to wait for the ARP response to return. - * If this parameter isn't set or set with a number smaller than 0, a default timeout of 5 seconds will be set - * @return The resolved MAC address or MacAddress#Zero if an error occurred or address could not be resolved. - * Errors will be printed to log - */ + /// Resolve the MAC address for a given IPv4 address. It's done using the ARP protocol: send an ARP request and + /// interpret the response + /// @param[in] ipAddr The IPv4 address to resolve MAC address to + /// @param[in] device The interface to send and receive the ARP packets on + /// @param[out] arpResponseTimeMS An output parameter that will contain the time in milliseconds that took the + /// ARP response to arrive + /// @param[in] sourceMac An optional parameter to set the source MAC address that will be sent with the ARP + /// request if this parameter isn't set or set with MacAddress#Zero the MAC address of the interface will be + /// used + /// @param[in] sourceIP An optional parameter to set the source IPv4 address that will be sent with the ARP + /// request if this parameter isn't set or set with IPv4Address#Zero the default IPv4 address of the interface + /// will be used + /// @param[in] arpTimeout An optional parameter to set the timeout to wait for the ARP response to return. + /// If this parameter isn't set or set with a number smaller than 0, a default timeout of 5 seconds will be set + /// @return The resolved MAC address or MacAddress#Zero if an error occurred or address could not be resolved. + /// Errors will be printed to log MacAddress getMacAddress(IPv4Address ipAddr, PcapLiveDevice* device, double& arpResponseTimeMS, MacAddress sourceMac = MacAddress::Zero, IPv4Address sourceIP = IPv4Address::Zero, int arpTimeout = -1) const; - /** - * Resolve an IPv4 address for a given hostname. Resolving is done in multiple phases: first resolving the LAN - * gateway MAC address (or default gateway if a gateway isn't provided) using ARP protocol (by using - * NetworkUtils#getMacAddress() ). Then a DNS request is sent to a DNS server (if specified) or to the LAN - * gateway (if DNS server is not specified). The DNS response is decoded and the IPv4 address is determined. In - * addition the method outputs the time it took the DNS response to arrive and the DNS TTL written on the DNS - * response. If DNS response doesn't contain an IPv4 address resolving an IPv4Address#Zero will be returned. - * @param[in] hostname The hostname to resolve - * @param[in] device The interface to send and receive packets on - * @param[out] dnsResponseTimeMS When method returns successfully will contain the time it took to receive the - * DNS response (in milli-seconds) - * @param[out] dnsTTL When method returns successfully will contain The DNS TTL written in the DNS response - * @param[in] dnsTimeout An optional parameter to specify the timeout to wait for a DNS response. If not - * specified the default timeout is 5 sec - * @param[in] dnsServerIP An optional parameter to specify the DNS server IP to send the DNS request to. If not - * specified or specified with IPv4Address#Zero the DNS request will be sent to the default DNS server - * configured in the system - * @param[in] gatewayIP An optional parameter to specify the LAN gateway to send the DNS request through. If not - * specified or specified with IPv4Address#Zero the interface's default gateway will be used - * @return The resolved IPv4 address or IPv4Address#Zero if something went wrong (in this case an error will be - * printed to log) - */ + /// Resolve an IPv4 address for a given hostname. Resolving is done in multiple phases: first resolving the LAN + /// gateway MAC address (or default gateway if a gateway isn't provided) using ARP protocol (by using + /// NetworkUtils#getMacAddress() ). Then a DNS request is sent to a DNS server (if specified) or to the LAN + /// gateway (if DNS server is not specified). The DNS response is decoded and the IPv4 address is determined. In + /// addition the method outputs the time it took the DNS response to arrive and the DNS TTL written on the DNS + /// response. If DNS response doesn't contain an IPv4 address resolving an IPv4Address#Zero will be returned. + /// @param[in] hostname The hostname to resolve + /// @param[in] device The interface to send and receive packets on + /// @param[out] dnsResponseTimeMS When method returns successfully will contain the time it took to receive the + /// DNS response (in milli-seconds) + /// @param[out] dnsTTL When method returns successfully will contain The DNS TTL written in the DNS response + /// @param[in] dnsTimeout An optional parameter to specify the timeout to wait for a DNS response. If not + /// specified the default timeout is 5 sec + /// @param[in] dnsServerIP An optional parameter to specify the DNS server IP to send the DNS request to. If not + /// specified or specified with IPv4Address#Zero the DNS request will be sent to the default DNS server + /// configured in the system + /// @param[in] gatewayIP An optional parameter to specify the LAN gateway to send the DNS request through. If + /// not specified or specified with IPv4Address#Zero the interface's default gateway will be used + /// @return The resolved IPv4 address or IPv4Address#Zero if something went wrong (in this case an error will be + /// printed to log) IPv4Address getIPv4Address(const std::string& hostname, PcapLiveDevice* device, double& dnsResponseTimeMS, uint32_t& dnsTTL, int dnsTimeout = -1, IPv4Address dnsServerIP = IPv4Address::Zero, IPv4Address gatewayIP = IPv4Address::Zero) const; private: // private c'tor - NetworkUtils() - {} + NetworkUtils() = default; }; } // namespace pcpp diff --git a/Pcap++/header/PcapDevice.h b/Pcap++/header/PcapDevice.h index 6c5d2ac84c..08176196ef 100644 --- a/Pcap++/header/PcapDevice.h +++ b/Pcap++/header/PcapDevice.h @@ -9,10 +9,8 @@ struct pcap_pkthdr; /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { // Forward Declaration - required for IPcapDevice::matchPacketWithFilter @@ -20,22 +18,16 @@ namespace pcpp namespace internal { - /** - * @class PcapHandle - * @brief A wrapper class for pcap_t* which is the libpcap packet capture descriptor. - * This class is used to manage the lifecycle of the pcap_t* object - */ + /// @class PcapHandle + /// @brief A wrapper class for pcap_t* which is the libpcap packet capture descriptor. + /// This class is used to manage the lifecycle of the pcap_t* object class PcapHandle { public: - /** - * @brief Creates an empty handle. - */ + /// @brief Creates an empty handle. constexpr PcapHandle() noexcept = default; - /** - * @brief Creates a handle from the provided pcap descriptor. - * @param pcapDescriptor The pcap descriptor to wrap. - */ + /// @brief Creates a handle from the provided pcap descriptor. + /// @param pcapDescriptor The pcap descriptor to wrap. explicit PcapHandle(pcap_t* pcapDescriptor) noexcept; PcapHandle(const PcapHandle&) = delete; @@ -47,45 +39,33 @@ namespace pcpp ~PcapHandle(); - /** - * @return True if the handle is not null, false otherwise. - */ + /// @return True if the handle is not null, false otherwise. bool isValid() const noexcept { return m_PcapDescriptor != nullptr; } - /** - * @return The underlying pcap descriptor. - */ + /// @return The underlying pcap descriptor. pcap_t* get() const noexcept { return m_PcapDescriptor; } - /** - * @brief Releases ownership of the handle and returns the pcap descriptor. - * @return The pcap descriptor or nullptr if no handle is owned. - */ + /// @brief Releases ownership of the handle and returns the pcap descriptor. + /// @return The pcap descriptor or nullptr if no handle is owned. pcap_t* release() noexcept; - /** - * @brief Replaces the managed handle with the provided one. - * @param pcapDescriptor A new pcap descriptor to manage. - * @remarks If the handle contains a non-null descriptor it will be closed. - */ + /// @brief Replaces the managed handle with the provided one. + /// @param pcapDescriptor A new pcap descriptor to manage. + /// @remarks If the handle contains a non-null descriptor it will be closed. void reset(pcap_t* pcapDescriptor = nullptr) noexcept; - /** - * @brief Helper function to retrieve a view of the last error string for this handle. - * @return A null-terminated view of the last error string. - * @remarks The returned view is only valid until the next call to a pcap function. - */ + /// @brief Helper function to retrieve a view of the last error string for this handle. + /// @return A null-terminated view of the last error string. + /// @remarks The returned view is only valid until the next call to a pcap function. char const* getLastError() const noexcept; - /** - * @return True if the handle is not null, false otherwise. - */ + /// @return True if the handle is not null, false otherwise. explicit operator bool() const noexcept { return isValid(); @@ -105,11 +85,9 @@ namespace pcpp }; } // namespace internal - /** - * @class IPcapDevice - * An abstract class representing all libpcap-based packet capturing devices: files, libPcap, WinPcap/Npcap and - * RemoteCapture. This class is abstract and cannot be instantiated - */ + /// @class IPcapDevice + /// An abstract class representing all libpcap-based packet capturing devices: files, libPcap, WinPcap/Npcap and + /// RemoteCapture. This class is abstract and cannot be instantiated class IPcapDevice : public IDevice, public IFilterableDevice { protected: @@ -120,63 +98,50 @@ namespace pcpp {} public: - /** - * @struct PcapStats - * A container for pcap device statistics - */ + /// @struct PcapStats + /// A container for pcap device statistics struct PcapStats { - /** Number of packets received */ + /// Number of packets received uint64_t packetsRecv; - /** Number of packets dropped */ + /// Number of packets dropped uint64_t packetsDrop; - /** number of packets dropped by interface (not supported on all platforms) */ + /// number of packets dropped by interface (not supported on all platforms) uint64_t packetsDropByInterface; }; virtual ~IPcapDevice(); - /** - * Get statistics from the device - * @param[out] stats An object containing the stats - */ + /// Get statistics from the device + /// @param[out] stats An object containing the stats virtual void getStatistics(PcapStats& stats) const = 0; - /** - * A static method for retrieving pcap lib (libpcap/WinPcap/etc.) version information. This method is actually - * a wrapper for [pcap_lib_version()](https://www.tcpdump.org/manpages/pcap_lib_version.3pcap.html) - * @return A string containing the pcap lib version information - */ + /// A static method for retrieving pcap lib (libpcap/WinPcap/etc.) version information. This method is actually + /// a wrapper for [pcap_lib_version()](https://www.tcpdump.org/manpages/pcap_lib_version.3pcap.html) + /// @return A string containing the pcap lib version information static std::string getPcapLibVersionInfo(); - /** - * Match a raw packet with a given BPF filter. Notice this method is static which means you don't need any - * device instance in order to perform this match - * @param[in] filter A filter class to test against - * @param[in] rawPacket A pointer to the raw packet to match the filter with - * @return True if raw packet matches the filter or false otherwise - */ + /// Match a raw packet with a given BPF filter. Notice this method is static which means you don't need any + /// device instance in order to perform this match + /// @param[in] filter A filter class to test against + /// @param[in] rawPacket A pointer to the raw packet to match the filter with + /// @return True if raw packet matches the filter or false otherwise 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 - */ + /// 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 virtual bool setFilter(std::string filterAsString); - /** - * Clear the filter currently set on device - * @return True if filter was removed successfully or if no filter was set, false otherwise - */ + /// Clear the filter currently set on device + /// @return True if filter was removed successfully or if no filter was set, false otherwise bool clearFilter(); }; - } // namespace pcpp diff --git a/Pcap++/header/PcapFileDevice.h b/Pcap++/header/PcapFileDevice.h index 89dd8c7b12..a6172d5792 100644 --- a/Pcap++/header/PcapFileDevice.h +++ b/Pcap++/header/PcapFileDevice.h @@ -10,17 +10,13 @@ typedef struct pcap_dumper pcap_dumper_t; /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @enum FileTimestampPrecision - * An enumeration representing the precision of timestamps in a pcap file. - * The precision can be Unknown, Micro, or Nano. - */ + /// @enum FileTimestampPrecision + /// An enumeration representing the precision of timestamps in a pcap file. + /// The precision can be Unknown, Micro, or Nano. enum class FileTimestampPrecision : int8_t { /// Precision is unknown or not set/determined @@ -31,10 +27,8 @@ namespace pcpp Nanoseconds = 1 }; - /** - * @class IFileDevice - * An abstract class (cannot be instantiated, has a private c'tor) which is the parent class for all file devices - */ + /// @class IFileDevice + /// An abstract class (cannot be instantiated, has a private c'tor) which is the parent class for all file devices class IFileDevice : public IPcapDevice { protected: @@ -44,74 +38,56 @@ namespace pcpp virtual ~IFileDevice(); public: - /** - * @return The name of the file - */ + /// @return The name of the file std::string getFileName() const; // override methods - /** - * Close the file - */ + /// Close the file void close() override; }; - /** - * @class IFileReaderDevice - * An abstract class (cannot be instantiated, has a private c'tor) which is the parent class for file reader devices - */ + /// @class IFileReaderDevice + /// An abstract class (cannot be instantiated, has a private c'tor) which is the parent class for file reader + /// devices class IFileReaderDevice : public IFileDevice { protected: uint32_t m_NumOfPacketsRead; uint32_t m_NumOfPacketsNotParsed; - /** - * A constructor for this class that gets the pcap full path file name to open. Notice that after calling this - * constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() - * @param[in] fileName The full path of the file to read - */ + /// A constructor for this class that gets the pcap full path file name to open. Notice that after calling this + /// constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() + /// @param[in] fileName The full path of the file to read IFileReaderDevice(const std::string& fileName); public: - /** - * A destructor for this class - */ - virtual ~IFileReaderDevice() - {} + /// A destructor for this class + virtual ~IFileReaderDevice() = default; - /** - * @return The file size in bytes - */ + /// @return The file size in bytes uint64_t getFileSize() const; virtual bool getNextPacket(RawPacket& rawPacket) = 0; - /** - * Read the next N packets into a raw packet vector - * @param[out] packetVec The raw packet vector to read packets into - * @param[in] numOfPacketsToRead Number of packets to read. If value <0 all remaining packets in the file will - * be read into the raw packet vector (this is the default value) - * @return The number of packets actually read - */ + /// Read the next N packets into a raw packet vector + /// @param[out] packetVec The raw packet vector to read packets into + /// @param[in] numOfPacketsToRead Number of packets to read. If value <0 all remaining packets in the file will + /// be read into the raw packet vector (this is the default value) + /// @return The number of packets actually read int getNextPackets(RawPacketVector& packetVec, int numOfPacketsToRead = -1); - /** - * A static method that creates an instance of the reader best fit to read the file. It decides by the file - * extension: for .pcapng files it returns an instance of PcapNgFileReaderDevice and for all other extensions it - * returns an instance of PcapFileReaderDevice - * @param[in] fileName The file name to open - * @return An instance of the reader to read the file. Notice you should free this instance when done using it - */ + /// A static method that creates an instance of the reader best fit to read the file. It decides by the file + /// extension: for .pcapng files it returns an instance of PcapNgFileReaderDevice and for all other extensions + /// it returns an instance of PcapFileReaderDevice + /// @param[in] fileName The file name to open + /// @return An instance of the reader to read the file. Notice you should free this instance when done using it static IFileReaderDevice* getReader(const std::string& fileName); }; - /** - * @class PcapFileReaderDevice - * A class for opening a pcap file in read-only mode. This class enable to open the file and read all packets, - * packet-by-packet - */ + /// @class PcapFileReaderDevice + /// A class for opening a pcap file in read-only mode. This class enable to open the file and read all packets, + /// packet-by-packet class PcapFileReaderDevice : public IFileReaderDevice { private: @@ -123,83 +99,62 @@ namespace pcpp PcapFileReaderDevice& operator=(const PcapFileReaderDevice& other); public: - /** - * A constructor for this class that gets the pcap full path file name to open. Notice that after calling this - * constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() - * @param[in] fileName The full path of the file to read - */ + /// A constructor for this class that gets the pcap full path file name to open. Notice that after calling this + /// constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() + /// @param[in] fileName The full path of the file to read PcapFileReaderDevice(const std::string& fileName) : IFileReaderDevice(fileName), m_Precision(FileTimestampPrecision::Unknown), m_PcapLinkLayerType(LINKTYPE_ETHERNET) {} - /** - * A destructor for this class - */ - virtual ~PcapFileReaderDevice() - {} + /// A destructor for this class + virtual ~PcapFileReaderDevice() = default; - /** - * @return The link layer type of this file - */ + /// @return The link layer type of this file LinkLayerType getLinkLayerType() const { return m_PcapLinkLayerType; } - /** - * @return The precision of the timestamps in the file. If the platform supports nanosecond precision, this - * method will return nanoseconds even if the file has microseconds since libpcap scales timestamps before - * supply. Otherwise, it will return microseconds. - */ + /// @return The precision of the timestamps in the file. If the platform supports nanosecond precision, this + /// method will return nanoseconds even if the file has microseconds since libpcap scales timestamps before + /// supply. Otherwise, it will return microseconds. FileTimestampPrecision getTimestampPrecision() const { return m_Precision; } - /** - * A static method that checks if nano-second precision is supported in the current platform and environment - * @return True if nano-second precision is supported, false otherwise - */ + /// A static method that checks if nano-second precision is supported in the current platform and environment + /// @return True if nano-second precision is supported, false otherwise static bool isNanoSecondPrecisionSupported(); // overridden methods - /** - * Read the next packet from the file. Before using this method please verify the file is opened using open() - * @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 - */ + /// Read the next packet from the file. Before using this method please verify the file is opened using open() + /// @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); - /** - * 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) - */ + /// 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(); - /** - * Get statistics of packets read so far. In the PcapStats struct, only the packetsRecv member is relevant. The - * rest of the members will contain 0 - * @param[out] stats The stats struct where stats are returned - */ + /// Get statistics of packets read so far. In the PcapStats struct, only the packetsRecv member is relevant. The + /// rest of the members will contain 0 + /// @param[out] stats The stats struct where stats are returned void getStatistics(PcapStats& stats) const; }; - /** - * @class SnoopFileReaderDevice - * A class for opening a snoop file in read-only mode. This class enable to open the file and read all packets, - * packet-by-packet - */ + /// @class SnoopFileReaderDevice + /// A class for opening a snoop file in read-only mode. This class enable to open the file and read all packets, + /// packet-by-packet class SnoopFileReaderDevice : public IFileReaderDevice { private: #pragma pack(1) - /* - * File format header. - */ + /// File format header. typedef struct { uint64_t identification_pattern; @@ -207,17 +162,15 @@ namespace pcpp uint32_t datalink_type; } snoop_file_header_t; - /* - * Packet record header. - */ + /// Packet record header. typedef struct { - uint32_t original_length; /* original packet length */ - uint32_t included_length; /* saved packet length */ - uint32_t packet_record_length; /* total record length */ - uint32_t ndrops_cumulative; /* cumulative drops */ - uint32_t time_sec; /* timestamp */ - uint32_t time_usec; /* microsecond timestamp */ + uint32_t original_length; ///< original packet length + uint32_t included_length; ///< saved packet length + uint32_t packet_record_length; ///< total record length + uint32_t ndrops_cumulative; ///< cumulative drops + uint32_t time_sec; ///< timestamp + uint32_t time_usec; ///< microsecond timestamp } snoop_packet_header_t; #pragma pack() @@ -229,23 +182,17 @@ namespace pcpp SnoopFileReaderDevice& operator=(const PcapFileReaderDevice& other); public: - /** - * A constructor for this class that gets the snoop full path file name to open. Notice that after calling this - * constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() - * @param[in] fileName The full path of the file to read - */ + /// A constructor for this class that gets the snoop full path file name to open. Notice that after calling this + /// constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() + /// @param[in] fileName The full path of the file to read SnoopFileReaderDevice(const std::string& fileName) : IFileReaderDevice(fileName), m_PcapLinkLayerType(LINKTYPE_ETHERNET) {} - /** - * A destructor for this class - */ + /// A destructor for this class virtual ~SnoopFileReaderDevice(); - /** - * @return The link layer type of this file - */ + /// @return The link layer type of this file LinkLayerType getLinkLayerType() const { return m_PcapLinkLayerType; @@ -253,39 +200,29 @@ namespace pcpp // overridden methods - /** - * Read the next packet from the file. Before using this method please verify the file is opened using open() - * @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 - */ + /// Read the next packet from the file. Before using this method please verify the file is opened using open() + /// @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); - /** - * 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) - */ + /// 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(); - /** - * Get statistics of packets read so far. In the PcapStats struct, only the packetsRecv member is relevant. The - * rest of the members will contain 0 - * @param[out] stats The stats struct where stats are returned - */ + /// Get statistics of packets read so far. In the PcapStats struct, only the packetsRecv member is relevant. The + /// rest of the members will contain 0 + /// @param[out] stats The stats struct where stats are returned void getStatistics(PcapStats& stats) const; - /** - * Close the snoop file - */ + /// Close the snoop file void close(); }; - /** - * @class PcapNgFileReaderDevice - * A class for opening a pcap-ng file in read-only mode. This class enable to open the file and read all packets, - * packet-by-packet - */ + /// @class PcapNgFileReaderDevice + /// A class for opening a pcap-ng file in read-only mode. This class enable to open the file and read all packets, + /// packet-by-packet class PcapNgFileReaderDevice : public IFileReaderDevice { private: @@ -297,105 +234,80 @@ namespace pcpp PcapNgFileReaderDevice& operator=(const PcapNgFileReaderDevice& other); public: - /** - * A constructor for this class that gets the pcap-ng full path file name to open. Notice that after calling - * this constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() - * @param[in] fileName The full path of the file to read - */ + /// A constructor for this class that gets the pcap-ng full path file name to open. Notice that after calling + /// this constructor the file isn't opened yet, so reading packets will fail. For opening the file call open() + /// @param[in] fileName The full path of the file to read PcapNgFileReaderDevice(const std::string& fileName); - /** - * A destructor for this class - */ + /// A destructor for this class virtual ~PcapNgFileReaderDevice() { close(); } - /** - * The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string - * specifying the operating system that was used for capturing the packets. This method reads this string from - * the metadata (if exists) and returns it - * @return The operating system string if exists, or an empty string otherwise - */ + /// The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string + /// specifying the operating system that was used for capturing the packets. This method reads this string from + /// the metadata (if exists) and returns it + /// @return The operating system string if exists, or an empty string otherwise std::string getOS() const; - /** - * The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string - * specifying the hardware that was used for capturing the packets. This method reads this string from the - * metadata (if exists) and returns it - * @return The hardware string if exists, or an empty string otherwise - */ + /// The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string + /// specifying the hardware that was used for capturing the packets. This method reads this string from the + /// metadata (if exists) and returns it + /// @return The hardware string if exists, or an empty string otherwise std::string getHardware() const; - /** - * The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string - * specifying the capture application that was used for capturing the packets. This method reads this string - * from the metadata (if exists) and returns it - * @return The capture application string if exists, or an empty string otherwise - */ + /// The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string + /// specifying the capture application that was used for capturing the packets. This method reads this string + /// from the metadata (if exists) and returns it + /// @return The capture application string if exists, or an empty string otherwise std::string getCaptureApplication() const; - /** - * The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string - * containing a user-defined comment (can be any string). This method reads this string from the metadata (if - * exists) and returns it - * @return The comment written inside the file if exists, or an empty string otherwise - */ + /// The pcap-ng format allows storing metadata at the header of the file. Part of this metadata is a string + /// containing a user-defined comment (can be any string). This method reads this string from the metadata (if + /// exists) and returns it + /// @return The comment written inside the file if exists, or an empty string otherwise std::string getCaptureFileComment() const; - /** - * The pcap-ng format allows storing a user-defined comment for every packet (besides the comment per-file). - * This method reads the next packet and the comment attached to it (if such comment exists), and returns them - * both - * @param[out] rawPacket A reference for an empty RawPacket where the packet will be written - * @param[out] packetComment The comment attached to the packet or an empty string if no comment exists - * @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 - */ + /// The pcap-ng format allows storing a user-defined comment for every packet (besides the comment per-file). + /// This method reads the next packet and the comment attached to it (if such comment exists), and returns them + /// both + /// @param[out] rawPacket A reference for an empty RawPacket where the packet will be written + /// @param[out] packetComment The comment attached to the packet or an empty string if no comment exists + /// @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, std::string& packetComment); // overridden methods - /** - * Read the next packet from the file. Before using this method please verify the file is opened using open() - * @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 - */ + /// Read the next packet from the file. Before using this method please verify the file is opened using open() + /// @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); - /** - * 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) - */ + /// 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(); - /** - * Get statistics of packets read so far. - * @param[out] stats The stats struct where stats are returned - */ + /// Get statistics of packets read so far. + /// @param[out] stats The stats struct where stats are returned void getStatistics(PcapStats& stats) const; - /** - * 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 - */ + /// 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); - /** - * Close the pacp-ng file - */ + /// Close the pacp-ng file void close(); }; - /** - * @class IFileWriterDevice - * An abstract class (cannot be instantiated, has a private c'tor) which is the parent class for file writer devices - */ + /// @class IFileWriterDevice + /// An abstract class (cannot be instantiated, has a private c'tor) which is the parent class for file writer + /// devices class IFileWriterDevice : public IFileDevice { protected: @@ -405,9 +317,7 @@ namespace pcpp IFileWriterDevice(const std::string& fileName); public: - /** - * A destructor for this class - */ + /// A destructor for this class virtual ~IFileWriterDevice() {} @@ -419,12 +329,10 @@ namespace pcpp virtual bool open(bool appendMode) = 0; }; - /** - * @class PcapFileWriterDevice - * A class for opening a pcap file for writing or create a new pcap file and write packets to it. This class adds - * a unique capability that isn't supported in WinPcap and in older libpcap versions which is to open a pcap file - * in append mode where packets are written at the end of the pcap file instead of running it over - */ + /// @class PcapFileWriterDevice + /// A class for opening a pcap file for writing or create a new pcap file and write packets to it. This class adds + /// a unique capability that isn't supported in WinPcap and in older libpcap versions which is to open a pcap file + /// in append mode where packets are written at the end of the pcap file instead of running it over class PcapFileWriterDevice : public IFileWriterDevice { private: @@ -441,107 +349,84 @@ namespace pcpp void closeFile(); public: - /** - * A constructor for this class that gets the pcap full path file name to open for writing or create. Notice - * that after calling this constructor the file isn't opened yet, so writing packets will fail. For opening the - * file call open() - * @param[in] fileName The full path of the file - * @param[in] linkLayerType The link layer type all packet in this file will be based on. The default is - * Ethernet - * @param[in] nanosecondsPrecision A boolean indicating whether to write timestamps in nano-precision. If set to - * false, timestamps will be written in micro-precision - */ + /// A constructor for this class that gets the pcap full path file name to open for writing or create. Notice + /// that after calling this constructor the file isn't opened yet, so writing packets will fail. For opening the + /// file call open() + /// @param[in] fileName The full path of the file + /// @param[in] linkLayerType The link layer type all packet in this file will be based on. The default is + /// Ethernet + /// @param[in] nanosecondsPrecision A boolean indicating whether to write timestamps in nano-precision. If set + /// to false, timestamps will be written in micro-precision PcapFileWriterDevice(const std::string& fileName, LinkLayerType linkLayerType = LINKTYPE_ETHERNET, bool nanosecondsPrecision = false); - /** - * A destructor for this class - */ + /// A destructor for this class ~PcapFileWriterDevice() { PcapFileWriterDevice::close(); } - /** - * Write a RawPacket to the file. Before using this method please verify the file is opened using open(). This - * method won't change the written packet - * @param[in] packet A reference for an existing RawPcket to write to the file - * @return True if a packet was written successfully. False will be returned if the file isn't opened - * or if the packet link layer type is different than the one defined for the file - * (in all cases, an error will be printed to log) - */ + /// Write a RawPacket to the file. Before using this method please verify the file is opened using open(). This + /// method won't change the written packet + /// @param[in] packet A reference for an existing RawPcket to write to the file + /// @return True if a packet was written successfully. False will be returned if the file isn't opened + /// or if the packet link layer type is different than the one defined for the file + /// (in all cases, an error will be printed to log) bool writePacket(RawPacket const& packet) override; - /** - * Write multiple RawPacket to the file. Before using this method please verify the file is opened using open(). - * This method won't change the written packets or the RawPacketVector instance - * @param[in] packets A reference for an existing RawPcketVector, all of its packets will be written to the file - * @return True if all packets were written successfully to the file. False will be returned if the file isn't - * opened (also, an error log will be printed) or if at least one of the packets wasn't written successfully to - * the file - */ + /// Write multiple RawPacket to the file. Before using this method please verify the file is opened using + /// open(). This method won't change the written packets or the RawPacketVector instance + /// @param[in] packets A reference for an existing RawPcketVector, all of its packets will be written to the + /// file + /// @return True if all packets were written successfully to the file. False will be returned if the file isn't + /// opened (also, an error log will be printed) or if at least one of the packets wasn't written successfully to + /// the file bool writePackets(const RawPacketVector& packets) override; - /** - * @return The precision of the timestamps in the file. - */ + /// @return The precision of the timestamps in the file. FileTimestampPrecision getTimestampPrecision() const { return m_Precision; } - /** - * A static method that checks if nano-second precision is supported in the current platform and environment - * @return True if nano-second precision is supported, false otherwise - */ + /// A static method that checks if nano-second precision is supported in the current platform and environment + /// @return True if nano-second precision is supported, false otherwise static bool isNanoSecondPrecisionSupported(); // override methods - /** - * Open the file in a write mode. If file doesn't exist, it will be created. If it does exist it will be - * overwritten, meaning all its current content will be deleted - * @return True if file was opened/created successfully or if file is already opened. False if opening the file - * failed for some reason (an error will be printed to log) - */ + /// Open the file in a write mode. If file doesn't exist, it will be created. If it does exist it will be + /// overwritten, meaning all its current content will be deleted + /// @return True if file was opened/created successfully or if file is already opened. False if opening the file + /// failed for some reason (an error will be printed to log) bool open() override; - /** - * Same as open(), but enables to open the file in append mode in which packets will be appended to the file - * instead of overwrite its current content. In append mode file must exist, otherwise opening will fail - * @param[in] appendMode A boolean indicating whether to open the file in append mode or not. If set to false - * this method will act exactly like open(). If set to true, file will be opened in append mode - * @return True of managed to open the file successfully. In case appendMode is set to true, false will be - * returned if file wasn't found or couldn't be read, if file type is not pcap, or if link type specified in - * c'tor is different from current file link type. In case appendMode is set to false, please refer to open() - * for return values - */ + /// Same as open(), but enables to open the file in append mode in which packets will be appended to the file + /// instead of overwrite its current content. In append mode file must exist, otherwise opening will fail + /// @param[in] appendMode A boolean indicating whether to open the file in append mode or not. If set to false + /// this method will act exactly like open(). If set to true, file will be opened in append mode + /// @return True of managed to open the file successfully. In case appendMode is set to true, false will be + /// returned if file wasn't found or couldn't be read, if file type is not pcap, or if link type specified in + /// c'tor is different from current file link type. In case appendMode is set to false, please refer to open() + /// for return values bool open(bool appendMode) override; - /** - * Flush and close the pacp file - */ + /// Flush and close the pacp file void close() override; - /** - * Flush packets to disk. - */ + /// Flush packets to disk. void flush(); - /** - * Get statistics of packets written so far. - * @param[out] stats The stats struct where stats are returned - */ + /// Get statistics of packets written so far. + /// @param[out] stats The stats struct where stats are returned void getStatistics(PcapStats& stats) const override; }; - /** - * @class PcapNgFileWriterDevice - * A class for opening a pcap-ng file for writing or creating a new pcap-ng file and write packets to it. This class - * adds unique capabilities such as writing metadata attributes into the file header, adding comments per packet and - * opening the file in append mode where packets are added to a file instead of overriding it. This capabilities are - * part of the pcap-ng standard but aren't supported in most tools and libraries - */ + /// @class PcapNgFileWriterDevice + /// A class for opening a pcap-ng file for writing or creating a new pcap-ng file and write packets to it. This + /// class adds unique capabilities such as writing metadata attributes into the file header, adding comments per + /// packet and opening the file in append mode where packets are added to a file instead of overriding it. This + /// capabilities are part of the pcap-ng standard but aren't supported in most tools and libraries class PcapNgFileWriterDevice : public IFileWriterDevice { private: @@ -554,116 +439,93 @@ namespace pcpp PcapNgFileWriterDevice& operator=(const PcapNgFileWriterDevice& other); public: - /** - * A constructor for this class that gets the pcap-ng full path file name to open for writing or create. Notice - * that after calling this constructor the file isn't opened yet, so writing packets will fail. For opening the - * file call open() - * @param[in] fileName The full path of the file - * @param[in] compressionLevel The compression level to use when writing the file, use 0 to disable compression - * or 10 for max compression. Default is 0 - */ + /// A constructor for this class that gets the pcap-ng full path file name to open for writing or create. Notice + /// that after calling this constructor the file isn't opened yet, so writing packets will fail. For opening the + /// file call open() + /// @param[in] fileName The full path of the file + /// @param[in] compressionLevel The compression level to use when writing the file, use 0 to disable compression + /// or 10 for max compression. Default is 0 PcapNgFileWriterDevice(const std::string& fileName, int compressionLevel = 0); - /** - * A destructor for this class - */ + /// A destructor for this class virtual ~PcapNgFileWriterDevice() { close(); } - /** - * Open the file in a write mode. If file doesn't exist, it will be created. If it does exist it will be - * overwritten, meaning all its current content will be deleted. As opposed to open(), this method also allows - * writing several metadata attributes that will be stored in the header of the file - * @param[in] os A string describing the operating system that was used to capture the packets. If this string - * is empty or null it will be ignored - * @param[in] hardware A string describing the hardware that was used to capture the packets. If this string is - * empty or null it will be ignored - * @param[in] captureApp A string describing the application that was used to capture the packets. If this - * string is empty or null it will be ignored - * @param[in] fileComment A string containing a user-defined comment that will be part of the metadata of the - * file. If this string is empty or null it will be ignored - * @return True if file was opened/created successfully or if file is already opened. False if opening the file - * failed for some reason (an error will be printed to log) - */ + /// Open the file in a write mode. If file doesn't exist, it will be created. If it does exist it will be + /// overwritten, meaning all its current content will be deleted. As opposed to open(), this method also allows + /// writing several metadata attributes that will be stored in the header of the file + /// @param[in] os A string describing the operating system that was used to capture the packets. If this string + /// is empty or null it will be ignored + /// @param[in] hardware A string describing the hardware that was used to capture the packets. If this string is + /// empty or null it will be ignored + /// @param[in] captureApp A string describing the application that was used to capture the packets. If this + /// string is empty or null it will be ignored + /// @param[in] fileComment A string containing a user-defined comment that will be part of the metadata of the + /// file. If this string is empty or null it will be ignored + /// @return True if file was opened/created successfully or if file is already opened. False if opening the file + /// failed for some reason (an error will be printed to log) bool open(const std::string& os, const std::string& hardware, const std::string& captureApp, const std::string& fileComment); - /** - * The pcap-ng format allows adding a user-defined comment for each stored packet. This method writes a - * RawPacket to the file and adds a comment to it. Before using this method please verify the file is opened - * using open(). This method won't change the written packet or the input comment - * @param[in] packet A reference for an existing RawPcket to write to the file - * @param[in] comment The comment to be written for the packet. If this string is empty or null it will be - * ignored - * @return True if a packet was written successfully. False will be returned if the file isn't opened (an error - * will be printed to log) - */ + /// The pcap-ng format allows adding a user-defined comment for each stored packet. This method writes a + /// RawPacket to the file and adds a comment to it. Before using this method please verify the file is opened + /// using open(). This method won't change the written packet or the input comment + /// @param[in] packet A reference for an existing RawPcket to write to the file + /// @param[in] comment The comment to be written for the packet. If this string is empty or null it will be + /// ignored + /// @return True if a packet was written successfully. False will be returned if the file isn't opened (an error + /// will be printed to log) bool writePacket(RawPacket const& packet, const std::string& comment); // overridden methods - /** - * Write a RawPacket to the file. Before using this method please verify the file is opened using open(). This - * method won't change the written packet - * @param[in] packet A reference for an existing RawPcket to write to the file - * @return True if a packet was written successfully. False will be returned if the file isn't opened (an error - * will be printed to log) - */ + /// Write a RawPacket to the file. Before using this method please verify the file is opened using open(). This + /// method won't change the written packet + /// @param[in] packet A reference for an existing RawPcket to write to the file + /// @return True if a packet was written successfully. False will be returned if the file isn't opened (an error + /// will be printed to log) bool writePacket(RawPacket const& packet); - /** - * Write multiple RawPacket to the file. Before using this method please verify the file is opened using open(). - * This method won't change the written packets or the RawPacketVector instance - * @param[in] packets A reference for an existing RawPcketVector, all of its packets will be written to the file - * @return True if all packets were written successfully to the file. False will be returned if the file isn't - * opened (also, an error log will be printed) or if at least one of the packets wasn't written successfully to - * the file - */ + /// Write multiple RawPacket to the file. Before using this method please verify the file is opened using + /// open(). This method won't change the written packets or the RawPacketVector instance + /// @param[in] packets A reference for an existing RawPcketVector, all of its packets will be written to the + /// file + /// @return True if all packets were written successfully to the file. False will be returned if the file isn't + /// opened (also, an error log will be printed) or if at least one of the packets wasn't written successfully to + /// the file bool writePackets(const RawPacketVector& packets); - /** - * Open the file in a write mode. If file doesn't exist, it will be created. If it does exist it will be - * overwritten, meaning all its current content will be deleted - * @return True if file was opened/created successfully or if file is already opened. False if opening the file - * failed for some reason (an error will be printed to log) - */ + /// Open the file in a write mode. If file doesn't exist, it will be created. If it does exist it will be + /// overwritten, meaning all its current content will be deleted + /// @return True if file was opened/created successfully or if file is already opened. False if opening the file + /// failed for some reason (an error will be printed to log) bool open(); - /** - * Same as open(), but enables to open the file in append mode in which packets will be appended to the file - * instead of overwrite its current content. In append mode file must exist, otherwise opening will fail - * @param[in] appendMode A boolean indicating whether to open the file in append mode or not. If set to false - * this method will act exactly like open(). If set to true, file will be opened in append mode - * @return True of managed to open the file successfully. In case appendMode is set to true, false will be - * returned if file wasn't found or couldn't be read, if file type is not pcap-ng. In case appendMode is set to - * false, please refer to open() for return values - */ + /// Same as open(), but enables to open the file in append mode in which packets will be appended to the file + /// instead of overwrite its current content. In append mode file must exist, otherwise opening will fail + /// @param[in] appendMode A boolean indicating whether to open the file in append mode or not. If set to false + /// this method will act exactly like open(). If set to true, file will be opened in append mode + /// @return True of managed to open the file successfully. In case appendMode is set to true, false will be + /// returned if file wasn't found or couldn't be read, if file type is not pcap-ng. In case appendMode is set to + /// false, please refer to open() for return values bool open(bool appendMode); - /** - * Flush packets to the pcap-ng file - */ + /// Flush packets to the pcap-ng file void flush(); - /** - * Flush and close the pcap-ng file - */ + /// Flush and close the pcap-ng file void close(); - /** - * Get statistics of packets written so far. - * @param[out] stats The stats struct where stats are returned - */ + /// Get statistics of packets written so far. + /// @param[out] stats The stats struct where stats are returned void getStatistics(PcapStats& stats) const; - /** - * 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 - */ + /// 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); }; diff --git a/Pcap++/header/PcapFilter.h b/Pcap++/header/PcapFilter.h index 9e72ed8b7b..3f77392650 100644 --- a/Pcap++/header/PcapFilter.h +++ b/Pcap++/header/PcapFilter.h @@ -11,83 +11,71 @@ // Forward Declaration - used in GeneralFilter struct bpf_program; -/** - * @file - * Most packet capture engines contain packet filtering capabilities. In order to set the filters there should be a - * known syntax user can use. The most popular syntax is Berkeley Packet Filter (BPF) - see more in here: - * http://en.wikipedia.org/wiki/Berkeley_Packet_Filter. Detailed explanation of the syntax can be found here: - * http://www.tcpdump.org/manpages/pcap-filter.7.html. - * - * The problem with BPF is that, for my opinion, the syntax is too complicated and too poorly documented. In addition - * the BPF filter compilers may output syntax errors that are hard to understand. My experience with BPF was not good, - * so I decided to make the filters mechanism more structured, easier to understand and less error-prone by creating - * classes that represent filters. Each possible filter phrase is represented by a class. The filter, at the end, is - * that class. - * For example: the filter "src net 1.1.1.1" will be represented by IPFilter instance; "dst port 80" - * will be represented by PortFilter, and so on. - * So what about complex filters that involve "and", "or"? There are - * also 2 classes: AndFilter and OrFilter that can store more filters (in a composite idea) and connect them by "and" or - * "or". For example: "src host 1.1.1.1 and dst port 80" will be represented by an AndFilter that holds IPFilter and - * PortFilter inside it - */ - -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @file +/// Most packet capture engines contain packet filtering capabilities. In order to set the filters there should be a +/// known syntax user can use. The most popular syntax is Berkeley Packet Filter (BPF) - see more in here: +/// http://en.wikipedia.org/wiki/Berkeley_Packet_Filter. Detailed explanation of the syntax can be found here: +/// http://www.tcpdump.org/manpages/pcap-filter.7.html. +/// +/// The problem with BPF is that, for my opinion, the syntax is too complicated and too poorly documented. In addition +/// the BPF filter compilers may output syntax errors that are hard to understand. My experience with BPF was not good, +/// so I decided to make the filters mechanism more structured, easier to understand and less error-prone by creating +/// classes that represent filters. Each possible filter phrase is represented by a class. The filter, at the end, is +/// that class. +/// For example: the filter "src net 1.1.1.1" will be represented by IPFilter instance; "dst port 80" +/// will be represented by PortFilter, and so on. +/// So what about complex filters that involve "and", "or"? There are +/// also 2 classes: AndFilter and OrFilter that can store more filters (in a composite idea) and connect them by "and" +/// or "or". For example: "src host 1.1.1.1 and dst port 80" will be represented by an AndFilter that holds IPFilter and +/// PortFilter inside it + +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { // Forward Declaration - used in GeneralFilter class RawPacket; - /** - * An enum that contains direction (source or destination) - */ + /// An enum that contains direction (source or destination) typedef enum { - /** Source */ + /// Source SRC, - /** Destination */ + /// Destination DST, - /** Source or destination */ + /// Source or destination SRC_OR_DST } Direction; - /** - * Supported operators enum - */ + /// Supported operators enum typedef enum { - /** Equals */ + /// Equals EQUALS, - /** Not equals */ + /// Not equals NOT_EQUALS, - /** Greater than */ + /// Greater than GREATER_THAN, - /** Greater or equal */ + /// Greater or equal GREATER_OR_EQUAL, - /** Less than */ + /// Less than LESS_THAN, - /** Less or equal */ + /// Less or equal LESS_OR_EQUAL } FilterOperator; namespace internal { - /** - * @class BpfProgramDeleter - * A deleter that cleans up a bpf_program object. - */ + /// @class BpfProgramDeleter + /// A deleter that cleans up a bpf_program object. struct BpfProgramDeleter { void operator()(bpf_program* ptr) const; }; } // namespace internal - /** - * @class BpfFilterWrapper - * A wrapper class for BPF filtering. Enables setting a BPF filter and matching it against a packet - */ + /// @class BpfFilterWrapper + /// A wrapper class for BPF filtering. Enables setting a BPF filter and matching it against a packet class BpfFilterWrapper { private: @@ -98,98 +86,75 @@ namespace pcpp void freeProgram(); public: - /** - * A c'tor for this class - */ + /// A c'tor for this class BpfFilterWrapper(); - /** - * A copy constructor for this class. - * @param[in] other The instance to copy from - */ + /// 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 - */ + /// A copy assignment operator for this class. + /// @param[in] other An instance of IPNetwork to assign + /// @return A reference to the assignee BpfFilterWrapper& operator=(const BpfFilterWrapper& other); - /** - * 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 - */ + /// 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 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". - * If the link type of the raw packet is different than the one set in setFilter(), the filter will be - * re-compiled and stored in the object. - * @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 - */ + /// 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 + /// re-compiled and stored in the object. + /// @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); - /** - * 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 - * and stored in the object. - * @param[in] packetData A byte stream containing the packet data - * @param[in] packetDataLength The length in [bytes] of the byte stream - * @param[in] packetTimestamp The packet timestamp - * @param[in] linkType The packet link type - * @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 - */ + /// 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 + /// and stored in the object. + /// @param[in] packetData A byte stream containing the packet data + /// @param[in] packetDataLength The length in [bytes] of the byte stream + /// @param[in] packetTimestamp The packet timestamp + /// @param[in] linkType The packet link type + /// @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); }; - /** - * @class GeneralFilter - * The base class for all filter classes. This class is virtual and abstract, hence cannot be instantiated. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class GeneralFilter + /// The base class for all filter classes. This class is virtual and abstract, hence cannot be instantiated. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class GeneralFilter { protected: BpfFilterWrapper m_BpfWrapper; public: - /** - * 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 - */ + /// 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; - /** - * 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 - */ + /// 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); GeneralFilter() {} - /** - * Virtual destructor, frees the bpf program - */ - virtual ~GeneralFilter() - {} + /// Virtual destructor, frees the bpf program + virtual ~GeneralFilter() = default; }; - /** - * @class BPFStringFilter - * This class can be loaded with a BPF filter string and then can be used to verify the string is valid. - */ + /// @class BPFStringFilter + /// This class can be loaded with a BPF filter string and then can be used to verify the string is valid. class BPFStringFilter : public GeneralFilter { private: @@ -202,27 +167,21 @@ namespace pcpp virtual ~BPFStringFilter() {} - /** - * 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 - */ + /// 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; - /** - * Verify the filter is valid - * @return True if the filter is valid or false otherwise - */ + /// Verify the filter is valid + /// @return True if the filter is valid or false otherwise bool verifyFilter(); }; - /** - * @class IFilterWithDirection - * An abstract class that is the base class for all filters which contain a direction (source or destination). This - * class cannot be instantiated - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class IFilterWithDirection + /// An abstract class that is the base class for all filters which contain a direction (source or destination). This + /// class cannot be instantiated + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class IFilterWithDirection : public GeneralFilter { private: @@ -240,23 +199,19 @@ namespace pcpp } public: - /** - * Set the direction for the filter (source or destination) - * @param[in] dir The direction - */ + /// Set the direction for the filter (source or destination) + /// @param[in] dir The direction void setDirection(Direction dir) { m_Dir = dir; } }; - /** - * @class IFilterWithOperator - * An abstract class that is the base class for all filters which contain an operator (e.g X equals Y; A is greater - * than B; Z1 not equals Z2, etc.). This class cannot be instantiated - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class IFilterWithOperator + /// An abstract class that is the base class for all filters which contain an operator (e.g X equals Y; A is greater + /// than B; Z1 not equals Z2, etc.). This class cannot be instantiated + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class IFilterWithOperator : public GeneralFilter { private: @@ -274,22 +229,18 @@ namespace pcpp } public: - /** - * Set the operator for the filter - * @param[in] op The operator to set - */ + /// Set the operator for the filter + /// @param[in] op The operator to set void setOperator(FilterOperator op) { m_Operator = op; } }; - /** - * @class IPFilter - * A class for representing IPv4 or IPv6 address filter, equivalent to "net src x.x.x.x" or "net dst x.x.x.x" - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class IPFilter + /// A class for representing IPv4 or IPv6 address filter, equivalent to "net src x.x.x.x" or "net dst x.x.x.x" + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class IPFilter : public IFilterWithDirection { private: @@ -297,124 +248,105 @@ namespace pcpp IPNetwork m_Network; public: - /** - * The basic constructor that creates the filter from an IP address string and direction (source or destination) - * @param[in] ipAddress The IP address to build the filter with. - * @param[in] dir The address direction to filter (source or destination) - * @throws std::invalid_argument The provided address is not a valid IPv4 or IPv6 address. - */ + /// The basic constructor that creates the filter from an IP address string and direction (source or + /// destination) + /// @param[in] ipAddress The IP address to build the filter with. + /// @param[in] dir The address direction to filter (source or destination) + /// @throws std::invalid_argument The provided address is not a valid IPv4 or IPv6 address. IPFilter(const std::string& ipAddress, Direction dir) : IPFilter(IPAddress(ipAddress), dir) {} - /** - * The basic constructor that creates the filter from an IP address and direction (source or destination) - * @param[in] ipAddress The IP address to build the filter with. - * @param[in] dir The address direction to filter (source or destination) - */ + /// The basic constructor that creates the filter from an IP address and direction (source or destination) + /// @param[in] ipAddress The IP address to build the filter with. + /// @param[in] dir The address direction to filter (source or destination) IPFilter(const IPAddress& ipAddress, Direction dir) : IFilterWithDirection(dir), m_Address(ipAddress), m_Network(ipAddress) {} - /** - * A constructor that enable to filter only part of the address by using a mask (aka subnet). For example: - * "filter only IP addresses that matches the subnet 10.0.0.x" - * @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be matched. - * For example: if the address is "1.2.3.4" and the mask is "255.255.255.0" than the part of the address that - * will be matched is "1.2.3.X". - * @param[in] dir The address direction to filter (source or destination) - * @param[in] netmask The mask to use. The mask should be a valid IP address in either IPv4 dotted-decimal - * format (e.g., 255.255.255.0) or IPv6 colon-separated hexadecimal format (e.g., FFFF:FFFF:FFFF:FFFF::). - * @throws std::invalid_argument The provided address is not a valid IP address or the provided netmask string - * is invalid.. - */ + /// A constructor that enable to filter only part of the address by using a mask (aka subnet). For example: + /// "filter only IP addresses that matches the subnet 10.0.0.x" + /// @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be matched. + /// For example: if the address is "1.2.3.4" and the mask is "255.255.255.0" than the part of the address that + /// will be matched is "1.2.3.X". + /// @param[in] dir The address direction to filter (source or destination) + /// @param[in] netmask The mask to use. The mask should be a valid IP address in either IPv4 dotted-decimal + /// format (e.g., 255.255.255.0) or IPv6 colon-separated hexadecimal format (e.g., FFFF:FFFF:FFFF:FFFF::). + /// @throws std::invalid_argument The provided address is not a valid IP address or the provided netmask string + /// is invalid.. IPFilter(const std::string& ipAddress, Direction dir, const std::string& netmask) : IPFilter(IPv4Address(ipAddress), dir, netmask) {} - /** - * A constructor that enable to filter only part of the address by using a mask (aka subnet). For example: - * "filter only IP addresses that matches the subnet 10.0.0.x" - * @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be - * matched. For example: if the address is "1.2.3.4" and the mask is "255.255.255.0" than the part of the - * address that will be matched is "1.2.3.X". - * @param[in] dir The address direction to filter (source or destination) - * @param[in] netmask The mask to use. The mask should be a valid IP address in either IPv4 dotted-decimal - * format (e.g., 255.255.255.0) or IPv6 colon-separated hexadecimal format (e.g., FFFF:FFFF:FFFF:FFFF::). - * @throws std::invalid_argument The provided netmask string is invalid. - */ + /// A constructor that enable to filter only part of the address by using a mask (aka subnet). For example: + /// "filter only IP addresses that matches the subnet 10.0.0.x" + /// @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be + /// matched. For example: if the address is "1.2.3.4" and the mask is "255.255.255.0" than the part of the + /// address that will be matched is "1.2.3.X". + /// @param[in] dir The address direction to filter (source or destination) + /// @param[in] netmask The mask to use. The mask should be a valid IP address in either IPv4 dotted-decimal + /// format (e.g., 255.255.255.0) or IPv6 colon-separated hexadecimal format (e.g., FFFF:FFFF:FFFF:FFFF::). + /// @throws std::invalid_argument The provided netmask string is invalid. IPFilter(const IPAddress& ipAddress, Direction dir, const std::string& netmask) : IFilterWithDirection(dir), m_Address(ipAddress), m_Network(ipAddress, netmask) {} - /** - * A constructor that enables to filter by a subnet. For example: "filter only IP addresses that matches the - * subnet 10.0.0.3/24" which means the part of the address that will be matched is "10.0.0.X" - * @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be matched. - * For example: if the address is "1.2.3.4" and the subnet is "/24" than the part of the address that will be - * matched is "1.2.3.X". - * @param[in] dir The address direction to filter (source or destination) - * @param[in] len The subnet to use (e.g "/24"). Acceptable subnet values are [0, 32] for IPv4 and [0, 128] for - * IPv6. - * @throws std::invalid_argument The provided address is not a valid IPv4 or IPv6 address or the provided length - * is out of acceptable range. - */ + /// A constructor that enables to filter by a subnet. For example: "filter only IP addresses that matches the + /// subnet 10.0.0.3/24" which means the part of the address that will be matched is "10.0.0.X" + /// @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be matched. + /// For example: if the address is "1.2.3.4" and the subnet is "/24" than the part of the address that will be + /// matched is "1.2.3.X". + /// @param[in] dir The address direction to filter (source or destination) + /// @param[in] len The subnet to use (e.g "/24"). Acceptable subnet values are [0, 32] for IPv4 and [0, 128] for + /// IPv6. + /// @throws std::invalid_argument The provided address is not a valid IPv4 or IPv6 address or the provided + /// length is out of acceptable range. IPFilter(const std::string& ipAddress, Direction dir, int len) : IPFilter(IPAddress(ipAddress), dir, len) {} - /** - * A constructor that enables to filter by a subnet. For example: "filter only IP addresses that matches the - * subnet 10.0.0.3/24" which means the part of the address that will be matched is "10.0.0.X" - * @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be matched. - * For example: if the address is "1.2.3.4" and the subnet is "/24" than the part of the address that will be - * matched is "1.2.3.X". - * @param[in] dir The address direction to filter (source or destination) - * @param[in] len The subnet to use (e.g "/24"). Acceptable subnet values are [0, 32] for IPv4 and [0, 128] for - * IPv6. - * @throws std::invalid_argument The provided length is out of acceptable range. - */ + /// A constructor that enables to filter by a subnet. For example: "filter only IP addresses that matches the + /// subnet 10.0.0.3/24" which means the part of the address that will be matched is "10.0.0.X" + /// @param[in] ipAddress The IP address to use. Only the part of the address that is not masked will be matched. + /// For example: if the address is "1.2.3.4" and the subnet is "/24" than the part of the address that will be + /// matched is "1.2.3.X". + /// @param[in] dir The address direction to filter (source or destination) + /// @param[in] len The subnet to use (e.g "/24"). Acceptable subnet values are [0, 32] for IPv4 and [0, 128] for + /// IPv6. + /// @throws std::invalid_argument The provided length is out of acceptable range. IPFilter(const IPAddress& ipAddress, Direction dir, int len) : IFilterWithDirection(dir), m_Address(ipAddress), m_Network(ipAddress, len) {} - /** - * A constructor that enables to filter by a predefined network object. - * @param[in] network The network to use when filtering. IP address and subnet mask are taken from the network - * object. - * @param[in] dir The address direction to filter (source or destination) - */ + /// A constructor that enables to filter by a predefined network object. + /// @param[in] network The network to use when filtering. IP address and subnet mask are taken from the network + /// object. + /// @param[in] dir The address direction to filter (source or destination) IPFilter(const IPNetwork& network, Direction dir) : IFilterWithDirection(dir), m_Address(network.getNetworkPrefix()), m_Network(network) {} void parseToString(std::string& result) override; - /** - * Set the network to build the filter with. - * @param[in] network The IP Network object to be used when building the filter. - */ + /// Set the network to build the filter with. + /// @param[in] network The IP Network object to be used when building the filter. void setNetwork(const IPNetwork& network) { m_Network = network; m_Address = m_Network.getNetworkPrefix(); } - /** - * Set the IP address - * @param[in] ipAddress The IP address to build the filter with. - * @throws std::invalid_argument The provided string does not represent a valid IP address. - */ + /// Set the IP address + /// @param[in] ipAddress The IP address to build the filter with. + /// @throws std::invalid_argument The provided string does not represent a valid IP address. void setAddr(const std::string& ipAddress) { this->setAddr(IPAddress(ipAddress)); } - /** - * Set the IP address - * @param[in] ipAddress The IP address to build the filter with. - * @remarks Alternating between IPv4 and IPv6 can have unintended consequences on the subnet mask. - * Setting an IPv4 address when the prefix length is over 32 make the new prefix length 32. - * Setting an IPv6 address will keep the current IPv4 prefix mask length. - */ + /// Set the IP address + /// @param[in] ipAddress The IP address to build the filter with. + /// @remarks Alternating between IPv4 and IPv6 can have unintended consequences on the subnet mask. + /// Setting an IPv4 address when the prefix length is over 32 make the new prefix length 32. + /// Setting an IPv6 address will keep the current IPv4 prefix mask length. void setAddr(const IPAddress& ipAddress) { m_Address = ipAddress; @@ -427,122 +359,100 @@ namespace pcpp m_Network = IPNetwork(m_Address, newPrefixLen); } - /** - * Set the subnet mask - * @param[in] netmask The mask to use. The mask should match the IP version and be in a valid format. - * Valid formats: - * IPv4 - (X.X.X.X) - 'X' - a number in the range of 0 and 255 (inclusive)): - * IPv6 - (YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY) - 'Y' - a hexadecimal digit [0 - 9, A - F]. Short form - * IPv6 formats are allowed. - * @throws std::invalid_argument The provided netmask is invalid or does not correspond to the current IP - * address version. - */ + /// Set the subnet mask + /// @param[in] netmask The mask to use. The mask should match the IP version and be in a valid format. + /// Valid formats: + /// IPv4 - (X.X.X.X) - 'X' - a number in the range of 0 and 255 (inclusive)): + /// IPv6 - (YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY) - 'Y' - a hexadecimal digit [0 - 9, A - F]. Short form + /// IPv6 formats are allowed. + /// @throws std::invalid_argument The provided netmask is invalid or does not correspond to the current IP + /// address version. void setMask(const std::string& netmask) { m_Network = IPNetwork(m_Address, netmask); } - /** - * Clears the subnet mask. - */ + /// Clears the subnet mask. void clearMask() { this->clearLen(); } - /** - * Set the subnet (IPv4) or prefix length (IPv6). - * Acceptable subnet values are [0, 32] for IPv4 and [0, 128] for IPv6. - * @param[in] len The subnet to use (e.g "/24") - * @throws std::invalid_argument The provided length is out of acceptable range. - */ + /// Set the subnet (IPv4) or prefix length (IPv6). + /// Acceptable subnet values are [0, 32] for IPv4 and [0, 128] for IPv6. + /// @param[in] len The subnet to use (e.g "/24") + /// @throws std::invalid_argument The provided length is out of acceptable range. void setLen(const int len) { m_Network = IPNetwork(m_Address, len); } - /** - * Clears the subnet mask length. - */ + /// Clears the subnet mask length. void clearLen() { m_Network = IPNetwork(m_Address); } }; - /** - * @class IPv4IDFilter - * A class for filtering IPv4 traffic by IP ID field of the IPv4 protocol, for example: - * "filter only IPv4 traffic which IP ID is greater than 1234" - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class IPv4IDFilter + /// A class for filtering IPv4 traffic by IP ID field of the IPv4 protocol, for example: + /// "filter only IPv4 traffic which IP ID is greater than 1234" + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class IPv4IDFilter : public IFilterWithOperator { private: uint16_t m_IpID; public: - /** - * A constructor that gets the IP ID to filter and the operator and creates the filter out of them - * @param[in] ipID The IP ID to filter - * @param[in] op The operator to use (e.g "equal", "greater than", etc.) - */ + /// A constructor that gets the IP ID to filter and the operator and creates the filter out of them + /// @param[in] ipID The IP ID to filter + /// @param[in] op The operator to use (e.g "equal", "greater than", etc.) IPv4IDFilter(uint16_t ipID, FilterOperator op) : IFilterWithOperator(op), m_IpID(ipID) {} void parseToString(std::string& result) override; - /** - * Set the IP ID to filter - * @param[in] ipID The IP ID to filter - */ + /// Set the IP ID to filter + /// @param[in] ipID The IP ID to filter void setIpID(uint16_t ipID) { m_IpID = ipID; } }; - /** - * @class IPv4TotalLengthFilter - * A class for filtering IPv4 traffic by "total length" field of the IPv4 protocol, for example: - * "filter only IPv4 traffic which "total length" value is less than 60B" - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class IPv4TotalLengthFilter + /// A class for filtering IPv4 traffic by "total length" field of the IPv4 protocol, for example: + /// "filter only IPv4 traffic which "total length" value is less than 60B" + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class IPv4TotalLengthFilter : public IFilterWithOperator { private: uint16_t m_TotalLength; public: - /** - * A constructor that gets the total length to filter and the operator and creates the filter out of them - * @param[in] totalLength The total length value to filter - * @param[in] op The operator to use (e.g "equal", "greater than", etc.) - */ + /// A constructor that gets the total length to filter and the operator and creates the filter out of them + /// @param[in] totalLength The total length value to filter + /// @param[in] op The operator to use (e.g "equal", "greater than", etc.) IPv4TotalLengthFilter(uint16_t totalLength, FilterOperator op) : IFilterWithOperator(op), m_TotalLength(totalLength) {} void parseToString(std::string& result) override; - /** - * Set the total length value - * @param[in] totalLength The total length value to filter - */ + /// Set the total length value + /// @param[in] totalLength The total length value to filter void setTotalLength(uint16_t totalLength) { m_TotalLength = totalLength; } }; - /** - * @class PortFilter - * A class for filtering TCP or UDP traffic by port, for example: "dst port 80" or "src port 12345". - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class PortFilter + /// A class for filtering TCP or UDP traffic by port, for example: "dst port 80" or "src port 12345". + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class PortFilter : public IFilterWithDirection { private: @@ -550,33 +460,27 @@ namespace pcpp void portToString(uint16_t portAsInt); public: - /** - * A constructor that gets the port and the direction and creates the filter - * @param[in] port The port to create the filter with - * @param[in] dir The port direction to filter (source or destination) - */ + /// A constructor that gets the port and the direction and creates the filter + /// @param[in] port The port to create the filter with + /// @param[in] dir The port direction to filter (source or destination) PortFilter(uint16_t port, Direction dir); void parseToString(std::string& result) override; - /** - * Set the port - * @param[in] port The port to create the filter with - */ + /// Set the port + /// @param[in] port The port to create the filter with void setPort(uint16_t port) { portToString(port); } }; - /** - * @class PortRangeFilter - * A class for filtering TCP or UDP port ranges, meaning match only packets which port is within this range, for - * example: "src portrange 1000-2000" will match only TCP or UDP traffic which source port is in the range of 1000 - - * 2000 - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class PortRangeFilter + /// A class for filtering TCP or UDP port ranges, meaning match only packets which port is within this range, for + /// example: "src portrange 1000-2000" will match only TCP or UDP traffic which source port is in the range of 1000 + /// - 2000 + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class PortRangeFilter : public IFilterWithDirection { private: @@ -584,175 +488,140 @@ namespace pcpp uint16_t m_ToPort; public: - /** - * A constructor that gets the port range the the direction and creates the filter with them - * @param[in] fromPort The lower end of the port range - * @param[in] toPort The higher end of the port range - * @param[in] dir The port range direction to filter (source or destination) - */ + /// A constructor that gets the port range the the direction and creates the filter with them + /// @param[in] fromPort The lower end of the port range + /// @param[in] toPort The higher end of the port range + /// @param[in] dir The port range direction to filter (source or destination) PortRangeFilter(uint16_t fromPort, uint16_t toPort, Direction dir) : IFilterWithDirection(dir), m_FromPort(fromPort), m_ToPort(toPort) {} void parseToString(std::string& result) override; - /** - * Set the lower end of the port range - * @param[in] fromPort The lower end of the port range - */ + /// 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; } - /** - * Set the higher end of the port range - * @param[in] toPort The higher end of the port range - */ + /// Set the higher end of the port range + /// @param[in] toPort The higher end of the port range void setToPort(uint16_t toPort) { m_ToPort = toPort; } }; - /** - * @class MacAddressFilter - * A class for filtering Ethernet traffic by MAC addresses, for example: "ether src 12:34:56:78:90:12" or "ether dst - * 10:29:38:47:56:10:29" - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class MacAddressFilter + /// A class for filtering Ethernet traffic by MAC addresses, for example: "ether src 12:34:56:78:90:12" or "ether + /// dst 10:29:38:47:56:10:29" + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class MacAddressFilter : public IFilterWithDirection { private: MacAddress m_MacAddress; public: - /** - * A constructor that gets the MAC address and the direction and creates the filter with them - * @param[in] address The MAC address to use for filtering - * @param[in] dir The MAC address direction to filter (source or destination) - */ + /// A constructor that gets the MAC address and the direction and creates the filter with them + /// @param[in] address The MAC address to use for filtering + /// @param[in] dir The MAC address direction to filter (source or destination) MacAddressFilter(MacAddress address, Direction dir) : IFilterWithDirection(dir), m_MacAddress(address) {} void parseToString(std::string& result) override; - /** - * Set the MAC address - * @param[in] address The MAC address to use for filtering - */ + /// Set the MAC address + /// @param[in] address The MAC address to use for filtering void setMacAddress(MacAddress address) { m_MacAddress = address; } }; - /** - * @class EtherTypeFilter - * A class for filtering by EtherType field of the Ethernet protocol. This enables to filter packets from certain - * protocols, such as ARP, IPv4, IPv6, VLAN tags, etc. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class EtherTypeFilter + /// A class for filtering by EtherType field of the Ethernet protocol. This enables to filter packets from certain + /// protocols, such as ARP, IPv4, IPv6, VLAN tags, etc. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class EtherTypeFilter : public GeneralFilter { private: uint16_t m_EtherType; public: - /** - * A constructor that gets the EtherType and creates the filter with it - * @param[in] etherType The EtherType value to create the filter with - */ + /// A constructor that gets the EtherType and creates the filter with it + /// @param[in] etherType The EtherType value to create the filter with explicit EtherTypeFilter(uint16_t etherType) : m_EtherType(etherType) {} void parseToString(std::string& result) override; - /** - * Set the EtherType value - * @param[in] etherType The EtherType value to create the filter with - */ + /// Set the EtherType value + /// @param[in] etherType The EtherType value to create the filter with void setEtherType(uint16_t etherType) { m_EtherType = etherType; } }; - /** - * @class CompositeFilter - * The base class for all filter classes composed of several other filters. This class is virtual and abstract, - * hence cannot be instantiated. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class CompositeFilter + /// The base class for all filter classes composed of several other filters. This class is virtual and abstract, + /// hence cannot be instantiated. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class CompositeFilter : public GeneralFilter { protected: std::vector m_FilterList; public: - /** - * An empty constructor for this class. Use addFilter() to add filters to the composite filter. - */ + /// An empty constructor for this class. Use addFilter() to add filters to the composite filter. CompositeFilter() = default; - /** - * A constructor that gets a list of pointers to filters and creates one filter from all filters - * @param[in] filters The list of pointers to filters - */ + /// A constructor that gets a list of pointers to filters and creates one filter from all filters + /// @param[in] filters The list of pointers to filters explicit CompositeFilter(const std::vector& filters); - /** - * Add filter to the composite filter - * @param[in] filter The filter to add - */ + /// Add filter to the composite filter + /// @param[in] filter The filter to add void addFilter(GeneralFilter* filter) { m_FilterList.push_back(filter); } - /** - * Removes the first matching filter from the composite filter - * @param[in] filter The filter to remove - */ + /// Removes the first matching filter from the composite filter + /// @param[in] filter The filter to remove void removeFilter(GeneralFilter* filter); - /** - * Remove the current filters and set new ones - * @param[in] filters The new filters to set. The previous ones will be removed - */ + /// Remove the current filters and set new ones + /// @param[in] filters The new filters to set. The previous ones will be removed void setFilters(const std::vector& filters); - /** - * Remove all filters from the composite filter. - */ + /// Remove all filters from the composite filter. void clearAllFilters() { m_FilterList.clear(); } }; - /** - * Supported composite logic filter operators enum - */ + /// Supported composite logic filter operators enum enum class CompositeLogicFilterOp { - /** Logical AND operation */ + /// Logical AND operation AND, - /** Logical OR operation */ + /// Logical OR operation OR, }; namespace internal { - /* Could potentially be moved into CompositeLogicFilter as a private member function, with if constexpr when - * C++17 is the minimum supported standard.*/ - /** - * Returns the delimiter for joining filter strings for the composite logic filter operation. - * @return A string literal to place between the different filter strings to produce a composite expression. - */ + // Could potentially be moved into CompositeLogicFilter as a private member function, with if constexpr when + // C++17 is the minimum supported standard. + + /// Returns the delimiter for joining filter strings for the composite logic filter operation. + /// @return A string literal to place between the different filter strings to produce a composite expression. template constexpr const char* getCompositeLogicOpDelimiter() = delete; template <> constexpr const char* getCompositeLogicOpDelimiter() { @@ -764,12 +633,10 @@ namespace pcpp }; } // namespace internal - /** - * @class CompositeLogicFilter - * A class for connecting several filters into one filter with logical operation between them. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class CompositeLogicFilter + /// A class for connecting several filters into one filter with logical operation between them. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h template class CompositeLogicFilter : public CompositeFilter { public: @@ -791,44 +658,36 @@ namespace pcpp } }; - /** - * A class for connecting several filters into one filter with logical "and" between them. For example: if the 2 - * filters are: "IPv4 address = x.x.x.x" + "TCP port dst = 80", then the new filter will be: "IPv4 address = x.x.x.x - * _AND_ TCP port dst = 80" - * - * This class follows the composite design pattern. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// A class for connecting several filters into one filter with logical "and" between them. For example: if the 2 + /// filters are: "IPv4 address = x.x.x.x" + "TCP port dst = 80", then the new filter will be: "IPv4 address = + /// x.x.x.x _AND_ TCP port dst = 80" + /// + /// This class follows the composite design pattern. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h using AndFilter = CompositeLogicFilter; - /** - * A class for connecting several filters into one filter with logical "or" between them. For example: if the 2 - * filters are: "IPv4 address = x.x.x.x" + "TCP port dst = 80", then the new filter will be: "IPv4 address = x.x.x.x - * _OR_ TCP port dst = 80" - * - * This class follows the composite design pattern. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// A class for connecting several filters into one filter with logical "or" between them. For example: if the 2 + /// filters are: "IPv4 address = x.x.x.x" + "TCP port dst = 80", then the new filter will be: "IPv4 address = + /// x.x.x.x _OR_ TCP port dst = 80" + /// + /// This class follows the composite design pattern. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h using OrFilter = CompositeLogicFilter; - /** - * @class NotFilter - * A class for creating a filter which is inverse to another filter - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class NotFilter + /// A class for creating a filter which is inverse to another filter + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class NotFilter : public GeneralFilter { private: GeneralFilter* m_FilterToInverse; public: - /** - * A constructor that gets a pointer to a filter and create the inverse version of it - * @param[in] filterToInverse A pointer to filter which the created filter be the inverse of - */ + /// A constructor that gets a pointer to a filter and create the inverse version of it + /// @param[in] filterToInverse A pointer to filter which the created filter be the inverse of explicit NotFilter(GeneralFilter* filterToInverse) { m_FilterToInverse = filterToInverse; @@ -836,174 +695,144 @@ namespace pcpp void parseToString(std::string& result) 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 - */ + /// 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; } }; - /** - * @class ProtoFilter - * A class for filtering traffic by protocol. Notice not all protocols are supported, only the following protocol - * are supported: - * ::TCP, ::UDP, ::ICMP, ::VLAN, ::IPv4, ::IPv6, ::ARP, ::Ethernet. - * In addition, the following protocol families are supported: ::GRE (distinguish between ::GREv0 and ::GREv1 is not - * supported), - * ::IGMP (distinguish between ::IGMPv1, ::IGMPv2 and ::IGMPv3 is not supported). - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class ProtoFilter + /// A class for filtering traffic by protocol. Notice not all protocols are supported, only the following protocol + /// are supported: + /// ::TCP, ::UDP, ::ICMP, ::VLAN, ::IPv4, ::IPv6, ::ARP, ::Ethernet. + /// In addition, the following protocol families are supported: ::GRE (distinguish between ::GREv0 and ::GREv1 is + /// not supported), + /// ::IGMP (distinguish between ::IGMPv1, ::IGMPv2 and ::IGMPv3 is not supported). + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class ProtoFilter : public GeneralFilter { private: ProtocolTypeFamily m_ProtoFamily; public: - /** - * A constructor that gets a protocol and creates the filter - * @param[in] proto The protocol to filter, only packets matching this protocol will be received. Please note - * not all protocols are supported. List of supported protocols is found in the class description - */ + /// A constructor that gets a protocol and creates the filter + /// @param[in] proto The protocol to filter, only packets matching this protocol will be received. Please note + /// not all protocols are supported. List of supported protocols is found in the class description explicit ProtoFilter(ProtocolType proto) : m_ProtoFamily(proto) {} - /** - * A constructor that gets a protocol family and creates the filter - * @param[in] protoFamily The protocol family to filter, only packets matching this protocol will be received. - * Please note not all protocols are supported. List of supported protocols is found in the class description - */ + /// A constructor that gets a protocol family and creates the filter + /// @param[in] protoFamily The protocol family to filter, only packets matching this protocol will be received. + /// Please note not all protocols are supported. List of supported protocols is found in the class description explicit ProtoFilter(ProtocolTypeFamily protoFamily) : m_ProtoFamily(protoFamily) {} void parseToString(std::string& result) override; - /** - * Set the protocol to filter with - * @param[in] proto The protocol to filter, only packets matching this protocol will be received. Please note - * not all protocol families are supported. List of supported protocols is found in the class description - */ + /// Set the protocol to filter with + /// @param[in] proto The protocol to filter, only packets matching this protocol will be received. Please note + /// not all protocol families are supported. List of supported protocols is found in the class description void setProto(ProtocolType proto) { m_ProtoFamily = proto; } - /** - * Set the protocol family to filter with - * @param[in] protoFamily The protocol family to filter, only packets matching this protocol will be received. - * Please note not all protocol families are supported. List of supported protocols is found in the class - * description - */ + /// Set the protocol family to filter with + /// @param[in] protoFamily The protocol family to filter, only packets matching this protocol will be received. + /// Please note not all protocol families are supported. List of supported protocols is found in the class + /// description void setProto(ProtocolTypeFamily protoFamily) { m_ProtoFamily = protoFamily; } }; - /** - * @class ArpFilter - * A class for filtering ARP packets according the ARP opcode. When using this filter only ARP packets with the - * relevant opcode will be received - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class ArpFilter + /// A class for filtering ARP packets according the ARP opcode. When using this filter only ARP packets with the + /// relevant opcode will be received + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class ArpFilter : public GeneralFilter { private: ArpOpcode m_OpCode; public: - /** - * A constructor that get the ARP opcode and creates the filter - * @param[in] opCode The ARP opcode: ::ARP_REQUEST or ::ARP_REPLY - */ + /// A constructor that get the ARP opcode and creates the filter + /// @param[in] opCode The ARP opcode: ::ARP_REQUEST or ::ARP_REPLY explicit ArpFilter(ArpOpcode opCode) : m_OpCode(opCode) {} void parseToString(std::string& result) override; - /** - * Set the ARP opcode - * @param[in] opCode The ARP opcode: ::ARP_REQUEST or ::ARP_REPLY - */ + /// Set the ARP opcode + /// @param[in] opCode The ARP opcode: ::ARP_REQUEST or ::ARP_REPLY void setOpCode(ArpOpcode opCode) { m_OpCode = opCode; } }; - /** - * @class VlanFilter - * A class for filtering VLAN tagged packets by VLAN ID. When using this filter only packets tagged with VLAN which - * has the specific VLAN ID will be received - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class VlanFilter + /// A class for filtering VLAN tagged packets by VLAN ID. When using this filter only packets tagged with VLAN which + /// has the specific VLAN ID will be received + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class VlanFilter : public GeneralFilter { private: uint16_t m_VlanID; public: - /** - * A constructor the gets the VLAN ID and creates the filter - * @param[in] vlanId The VLAN ID to use for the filter - */ + /// A constructor the gets the VLAN ID and creates the filter + /// @param[in] vlanId The VLAN ID to use for the filter explicit VlanFilter(uint16_t vlanId) : m_VlanID(vlanId) {} void parseToString(std::string& result) override; - /** - * Set the VLAN ID of the filter - * @param[in] vlanId The VLAN ID to use for the filter - */ + /// 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; } }; - /** - * @class TcpFlagsFilter - * A class for filtering only TCP packets which certain TCP flags are set in them - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class TcpFlagsFilter + /// A class for filtering only TCP packets which certain TCP flags are set in them + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class TcpFlagsFilter : public GeneralFilter { public: - /** - * An enum of all TCP flags that can be use in the filter - */ + /// An enum of all TCP flags that can be use in the filter enum TcpFlags { - /** TCP FIN flag */ + /// TCP FIN flag tcpFin = 1, - /** TCP SYN flag */ + /// TCP SYN flag tcpSyn = 2, - /** TCP RST flag */ + /// TCP RST flag tcpRst = 4, - /** TCP PSH flag */ + /// TCP PSH flag tcpPush = 8, - /** TCP ACK flag */ + /// TCP ACK flag tcpAck = 16, - /** TCP URG flag */ + /// TCP URG flag tcpUrg = 32 }; - /** - * An enum for representing 2 type of matches: match only packets that contain all flags defined in the filter - * or match packets that contain at least one of the flags defined in the filter - */ + /// An enum for representing 2 type of matches: match only packets that contain all flags defined in the filter + /// or match packets that contain at least one of the flags defined in the filter enum MatchOptions { - /** Match only packets that contain all flags defined in the filter */ + /// Match only packets that contain all flags defined in the filter MatchAll, - /** Match packets that contain at least one of the flags defined in the filter */ + /// Match packets that contain at least one of the flags defined in the filter MatchOneAtLeast }; @@ -1012,25 +841,21 @@ namespace pcpp MatchOptions m_MatchOption; public: - /** - * A constructor that gets a 1-byte bitmask containing all TCP flags participating in the filter and the match - * option, and creates the filter - * @param[in] tcpFlagBitMask A 1-byte bitmask containing all TCP flags participating in the filter. This - * parameter can contain the following value for example: TcpFlagsFilter::tcpSyn | TcpFlagsFilter::tcpAck | - * TcpFlagsFilter::tcpUrg - * @param[in] matchOption The match option: TcpFlagsFilter::MatchAll or TcpFlagsFilter::MatchOneAtLeast - */ + /// A constructor that gets a 1-byte bitmask containing all TCP flags participating in the filter and the match + /// option, and creates the filter + /// @param[in] tcpFlagBitMask A 1-byte bitmask containing all TCP flags participating in the filter. This + /// parameter can contain the following value for example: TcpFlagsFilter::tcpSyn | TcpFlagsFilter::tcpAck | + /// TcpFlagsFilter::tcpUrg + /// @param[in] matchOption The match option: TcpFlagsFilter::MatchAll or TcpFlagsFilter::MatchOneAtLeast TcpFlagsFilter(uint8_t tcpFlagBitMask, MatchOptions matchOption) : m_TcpFlagsBitMask(tcpFlagBitMask), m_MatchOption(matchOption) {} - /** - * Set the TCP flags and the match option - * @param[in] tcpFlagBitMask A 1-byte bitmask containing all TCP flags participating in the filter. This - * parameter can contain the following value for example: TcpFlagsFilter::tcpSyn | TcpFlagsFilter::tcpAck | - * TcpFlagsFilter::tcpUrg - * @param[in] matchOption The match option: TcpFlagsFilter::MatchAll or TcpFlagsFilter::MatchOneAtLeast - */ + /// Set the TCP flags and the match option + /// @param[in] tcpFlagBitMask A 1-byte bitmask containing all TCP flags participating in the filter. This + /// parameter can contain the following value for example: TcpFlagsFilter::tcpSyn | TcpFlagsFilter::tcpAck | + /// TcpFlagsFilter::tcpUrg + /// @param[in] matchOption The match option: TcpFlagsFilter::MatchAll or TcpFlagsFilter::MatchOneAtLeast void setTcpFlagsBitMask(uint8_t tcpFlagBitMask, MatchOptions matchOption) { m_TcpFlagsBitMask = tcpFlagBitMask; @@ -1040,70 +865,57 @@ namespace pcpp void parseToString(std::string& result) override; }; - /** - * @class TcpWindowSizeFilter - * A class for filtering TCP packets that matches TCP window-size criteria. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class TcpWindowSizeFilter + /// A class for filtering TCP packets that matches TCP window-size criteria. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class TcpWindowSizeFilter : public IFilterWithOperator { private: uint16_t m_WindowSize; public: - /** - * A constructor that get the window-size and operator and creates the filter. For example: "filter all TCP - * packets with window-size less than 1000" - * @param[in] windowSize The window-size value that will be used in the filter - * @param[in] op The operator to use (e.g "equal", "greater than", etc.) - */ + /// A constructor that get the window-size and operator and creates the filter. For example: "filter all TCP + /// packets with window-size less than 1000" + /// @param[in] windowSize The window-size value that will be used in the filter + /// @param[in] op The operator to use (e.g "equal", "greater than", etc.) TcpWindowSizeFilter(uint16_t windowSize, FilterOperator op) : IFilterWithOperator(op), m_WindowSize(windowSize) {} void parseToString(std::string& result) override; - /** - * Set window-size value - * @param[in] windowSize The window-size value that will be used in the filter - */ + /// 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; } }; - /** - * @class UdpLengthFilter - * A class for filtering UDP packets that matches UDP length criteria. - * - * For deeper understanding of the filter concept please refer to PcapFilter.h - */ + /// @class UdpLengthFilter + /// A class for filtering UDP packets that matches UDP length criteria. + /// + /// For deeper understanding of the filter concept please refer to PcapFilter.h class UdpLengthFilter : public IFilterWithOperator { private: uint16_t m_Length; public: - /** - * A constructor that get the UDP length and operator and creates the filter. For example: "filter all UDP - * packets with length greater or equal to 500" - * @param[in] length The length value that will be used in the filter - * @param[in] op The operator to use (e.g "equal", "greater than", etc.) - */ + /// A constructor that get the UDP length and operator and creates the filter. For example: "filter all UDP + /// packets with length greater or equal to 500" + /// @param[in] length The length value that will be used in the filter + /// @param[in] op The operator to use (e.g "equal", "greater than", etc.) UdpLengthFilter(uint16_t length, FilterOperator op) : IFilterWithOperator(op), m_Length(length) {} void parseToString(std::string& result) override; - /** - * Set length value - * @param[in] length The length value that will be used in the filter - */ + /// Set length value + /// @param[in] length The length value that will be used in the filter void setLength(uint16_t length) { m_Length = length; } }; - } // namespace pcpp diff --git a/Pcap++/header/PcapLiveDevice.h b/Pcap++/header/PcapLiveDevice.h index e37e27d7cd..8af8ee067c 100644 --- a/Pcap++/header/PcapLiveDevice.h +++ b/Pcap++/header/PcapLiveDevice.h @@ -18,63 +18,52 @@ typedef struct pcap_addr pcap_addr_t; /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - class PcapLiveDevice; - /** - * A callback that is called when a packet is captured by PcapLiveDevice - * @param[in] packet A pointer to the raw packet - * @param[in] device A pointer to the PcapLiveDevice instance - * @param[in] userCookie A pointer to the object put by the user when packet capturing stared - */ + /// A callback that is called when a packet is captured by PcapLiveDevice + /// @param[in] packet A pointer to the raw packet + /// @param[in] device A pointer to the PcapLiveDevice instance + /// @param[in] userCookie A pointer to the object put by the user when packet capturing stared using OnPacketArrivesCallback = std::function; - /** - * A callback that is called when a packet is captured by PcapLiveDevice - * @param[in] packet A pointer to the raw packet - * @param[in] device A pointer to the PcapLiveDevice instance - * @param[in] userCookie A pointer to the object put by the user when packet capturing stared - * @return True when main thread should stop blocking or false otherwise - */ + /// A callback that is called when a packet is captured by PcapLiveDevice + /// @param[in] packet A pointer to the raw packet + /// @param[in] device A pointer to the PcapLiveDevice instance + /// @param[in] userCookie A pointer to the object put by the user when packet capturing stared + /// @return True when main thread should stop blocking or false otherwise using OnPacketArrivesStopBlocking = std::function; - /** - * A callback that is called periodically for stats collection if user asked to start packet capturing with periodic - * stats collection - * @param[in] stats A reference to the most updated stats - * @param[in] userCookie A pointer to the object put by the user when packet capturing stared - */ + /// A callback that is called periodically for stats collection if user asked to start packet capturing with + /// periodic stats collection + /// @param[in] stats A reference to the most updated stats + /// @param[in] userCookie A pointer to the object put by the user when packet capturing stared using OnStatsUpdateCallback = std::function; - /** - * @class PcapLiveDevice - * A class that wraps a network interface (each of the interfaces listed in ifconfig/ipconfig). - * This class wraps the libpcap capabilities of capturing packets from the network, filtering packets and sending - * packets back to the network. This class is relevant for Linux applications only. On Windows the WinPcapLiveDevice - * (which inherits this class) is used. Both classes are almost similar in capabilities, the main difference between - * them is adapting some capabilities to the specific OS. This class cannot be instantiated by the user (it has a - * private constructor), as network interfaces aren't dynamic. Instances of this class (one instance per network - * interface) are created by PcapLiveDeviceList singleton on application startup and the user can get access to them - * by using PcapLiveDeviceList public methods such as PcapLiveDeviceList#getPcapLiveDeviceByIp()
Main - * capabilities of this class: - * - Get all available information for this network interfaces such as name, IP addresses, MAC address, MTU, etc. - * This information is taken from both libpcap and the OS - * - Capture packets from the network. Capturing is always conducted on a different thread. PcapPlusPlus creates - * this thread when capturing starts and kills it when capturing ends. This prevents the application from being - * stuck while waiting for packets or processing them. Currently only one capturing thread is allowed, so when the - * interface is in capture mode, no further capturing is allowed. In addition to capturing the user can get stats - * on packets that were received by the application, dropped by the NIC (due to full NIC buffers), etc. Stats - * collection can be initiated by the user by calling getStatistics() or be pushed to the user periodically by - * supplying a callback and a timeout to startCapture() - * - Send packets back to the network. Sending the packets is done on the caller thread. No additional threads are - * created for this task - */ + /// @class PcapLiveDevice + /// A class that wraps a network interface (each of the interfaces listed in ifconfig/ipconfig). + /// This class wraps the libpcap capabilities of capturing packets from the network, filtering packets and sending + /// packets back to the network. This class is relevant for Linux applications only. On Windows the + /// WinPcapLiveDevice (which inherits this class) is used. Both classes are almost similar in capabilities, the main + /// difference between them is adapting some capabilities to the specific OS. This class cannot be instantiated by + /// the user (it has a private constructor), as network interfaces aren't dynamic. Instances of this class (one + /// instance per network interface) are created by PcapLiveDeviceList singleton on application startup and the user + /// can get access to them by using PcapLiveDeviceList public methods such as + /// PcapLiveDeviceList#getPcapLiveDeviceByIp()
Main capabilities of this class: + /// - Get all available information for this network interfaces such as name, IP addresses, MAC address, MTU, etc. + /// This information is taken from both libpcap and the OS + /// - Capture packets from the network. Capturing is always conducted on a different thread. PcapPlusPlus creates + /// this thread when capturing starts and kills it when capturing ends. This prevents the application from being + /// stuck while waiting for packets or processing them. Currently only one capturing thread is allowed, so when + /// the interface is in capture mode, no further capturing is allowed. In addition to capturing the user can get + /// stats on packets that were received by the application, dropped by the NIC (due to full NIC buffers), etc. + /// Stats collection can be initiated by the user by calling getStatistics() or be pushed to the user periodically + /// by supplying a callback and a timeout to startCapture() + /// - Send packets back to the network. Sending the packets is done on the caller thread. No additional threads are + /// created for this task class PcapLiveDevice : public IPcapDevice { friend class PcapLiveDeviceList; @@ -148,111 +137,93 @@ namespace pcpp static void onPacketArrivesBlockingMode(uint8_t* user, const struct pcap_pkthdr* pkthdr, const uint8_t* packet); public: - /** - * The type of the live device - */ + /// The type of the live device enum LiveDeviceType { - /** libPcap live device */ + /// libPcap live device LibPcapDevice, - /** WinPcap/Npcap live device */ + /// WinPcap/Npcap live device WinPcapDevice, - /** WinPcap/Npcap Remote Capture device */ + /// WinPcap/Npcap Remote Capture device RemoteDevice }; - /** - * Device capturing mode - */ + /// Device capturing mode enum DeviceMode { - /** Only packets that their destination is this NIC are captured */ + /// Only packets that their destination is this NIC are captured Normal = 0, - /** All packets that arrive to the NIC are captured, even packets that their destination isn't this NIC */ + /// All packets that arrive to the NIC are captured, even packets that their destination isn't this NIC Promiscuous = 1 }; - /** - * Set direction for capturing packets (you can read more here: - * ) - */ + /// Set direction for capturing packets (you can read more here: + /// ) enum PcapDirection { - /** Capture traffics both incoming and outgoing */ + /// Capture traffics both incoming and outgoing PCPP_INOUT = 0, - /** Only capture incoming traffics */ + /// Only capture incoming traffics PCPP_IN, - /** Only capture outgoing traffics */ + /// Only capture outgoing traffics PCPP_OUT }; - /** - * @struct DeviceConfiguration - * A struct that contains user configurable parameters for opening a device. All parameters have default values - * so the user isn't expected to set all parameters or understand exactly how they work - */ + /// @struct DeviceConfiguration + /// A struct that contains user configurable parameters for opening a device. All parameters have default values + /// so the user isn't expected to set all parameters or understand exactly how they work struct DeviceConfiguration { - /** Indicates whether to open the device in promiscuous or normal mode */ + /// Indicates whether to open the device in promiscuous or normal mode DeviceMode mode; - /** Set the packet buffer timeout in milliseconds. You can read more here: - * https://www.tcpdump.org/manpages/pcap.3pcap.html . - * Any value above 0 is considered legal, otherwise a value of 1 or -1 is used (depends on the platform) - */ + /// Set the packet buffer timeout in milliseconds. You can read more here: + /// https://www.tcpdump.org/manpages/pcap.3pcap.html . + /// Any value above 0 is considered legal, otherwise a value of 1 or -1 is used (depends on the platform) int packetBufferTimeoutMs; - /** - * Set the packet buffer size. You can read more about the packet buffer here: - * https://www.tcpdump.org/manpages/pcap.3pcap.html . - * Any value of 100 or above is considered valid, otherwise the default value is used (which varies between - * different OS's). However, please notice that setting values which are too low or two high may result in - * failure to open the device. These too low or too high thresholds may vary between OS's, as an example - * please refer to this thread: https://stackoverflow.com/questions/11397367/issue-in-pcap-set-buffer-size - */ + /// Set the packet buffer size. You can read more about the packet buffer here: + /// https://www.tcpdump.org/manpages/pcap.3pcap.html . + /// Any value of 100 or above is considered valid, otherwise the default value is used (which varies between + /// different OS's). However, please notice that setting values which are too low or two high may result in + /// failure to open the device. These too low or too high thresholds may vary between OS's, as an example + /// please refer to this thread: https://stackoverflow.com/questions/11397367/issue-in-pcap-set-buffer-size int packetBufferSize; - /** - * Set the direction for capturing packets. You can read more here: - * . - */ + /// Set the direction for capturing packets. You can read more here: + /// . PcapDirection direction; - /** - * Set the snapshot length. Snapshot length is the amount of data for each frame that is actually captured. - * Note that taking larger snapshots both increases the amount of time it takes to process packets and, - * effectively, decreases the amount of packet buffering. This may cause packets to be lost. Note also that - * taking smaller snapshots will discard data from protocols above the transport layer, which loses - * information that may be important. You can read more here: https://wiki.wireshark.org/SnapLen - */ + /// Set the snapshot length. Snapshot length is the amount of data for each frame that is actually captured. + /// Note that taking larger snapshots both increases the amount of time it takes to process packets and, + /// effectively, decreases the amount of packet buffering. This may cause packets to be lost. Note also that + /// taking smaller snapshots will discard data from protocols above the transport layer, which loses + /// information that may be important. You can read more here: https://wiki.wireshark.org/SnapLen int snapshotLength; - /** - * Set NFLOG group. Which NFLOG group to be listened to when connecting to NFLOG device. If device is not of - * type NFLOG this attribute is ignored. - */ + /// Set NFLOG group. Which NFLOG group to be listened to when connecting to NFLOG device. If device is not + /// of type NFLOG this attribute is ignored. unsigned int nflogGroup; /// In Unix-like system, use poll() for blocking mode. bool usePoll; - /** - * A c'tor for this struct - * @param[in] mode The mode to open the device: promiscuous or non-promiscuous. Default value is promiscuous - * @param[in] packetBufferTimeoutMs Buffer timeout in millisecond. Default value is 0 which means set - * timeout of 1 or -1 (depends on the platform) - * @param[in] packetBufferSize The packet buffer size. Default value is 0 which means use the default value - * (varies between different OS's) - * @param[in] direction Direction for capturing packets. Default value is INOUT which means capture both - * incoming and outgoing packets (not all platforms support this) - * @param[in] snapshotLength Snapshot length for capturing packets. Default value is 0 which means use the - * default value. A snapshot length of 262144 should be big enough for maximum-size Linux loopback packets - * (65549) and some USB packets captured with USBPcap (> 131072, < 262144). A snapshot length of 65535 - * should be sufficient, on most if not all networks, to capture all the data available from the packet. - * @param[in] nflogGroup NFLOG group for NFLOG devices. Default value is 0. - * @param[in] usePoll use `poll()` when capturing packets in blocking more (`startCaptureBlockingMode()`) on - * Unix-like system. Default value is false. - */ + /// A c'tor for this struct + /// @param[in] mode The mode to open the device: promiscuous or non-promiscuous. Default value is + /// promiscuous + /// @param[in] packetBufferTimeoutMs Buffer timeout in millisecond. Default value is 0 which means set + /// timeout of 1 or -1 (depends on the platform) + /// @param[in] packetBufferSize The packet buffer size. Default value is 0 which means use the default value + /// (varies between different OS's) + /// @param[in] direction Direction for capturing packets. Default value is INOUT which means capture both + /// incoming and outgoing packets (not all platforms support this) + /// @param[in] snapshotLength Snapshot length for capturing packets. Default value is 0 which means use the + /// default value. A snapshot length of 262144 should be big enough for maximum-size Linux loopback packets + /// (65549) and some USB packets captured with USBPcap (> 131072, < 262144). A snapshot length of 65535 + /// should be sufficient, on most if not all networks, to capture all the data available from the packet. + /// @param[in] nflogGroup NFLOG group for NFLOG devices. Default value is 0. + /// @param[in] usePoll use `poll()` when capturing packets in blocking more (`startCaptureBlockingMode()`) + /// on Unix-like system. Default value is false. explicit DeviceConfiguration(DeviceMode mode = Promiscuous, int packetBufferTimeoutMs = 0, int packetBufferSize = 0, PcapDirection direction = PCPP_INOUT, int snapshotLength = 0, unsigned int nflogGroup = 0, bool usePoll = false) @@ -269,380 +240,319 @@ namespace pcpp PcapLiveDevice(const PcapLiveDevice& other) = delete; PcapLiveDevice& operator=(const PcapLiveDevice& other) = delete; - /** - * A destructor for this class - */ + /// A destructor for this class ~PcapLiveDevice() override; - /** - * @return The type of the device (libPcap, WinPcap/Npcap or a remote device) - */ + /// @return The type of the device (libPcap, WinPcap/Npcap or a remote device) virtual LiveDeviceType getDeviceType() const { return LibPcapDevice; } - /** - * @return The name of the device (e.g eth0), taken from pcap_if_t->name - */ + /// @return The name of the device (e.g eth0), taken from pcap_if_t->name std::string getName() const { return m_InterfaceDetails.name; } - /** - * @return A human-readable description of the device, taken from pcap_if_t->description. May be empty string in - * some interfaces - */ + /// @return A human-readable description of the device, taken from pcap_if_t->description. May be empty string + /// in some interfaces std::string getDesc() const { return m_InterfaceDetails.description; } - /** - * @return True if this interface is a loopback interface, false otherwise - */ + /// @return True if this interface is a loopback interface, false otherwise bool getLoopback() const { return m_InterfaceDetails.isLoopback; } - /** - * @return The device's maximum transmission unit (MTU) in bytes - */ + /// @return The device's maximum transmission unit (MTU) in bytes virtual uint32_t getMtu() const { return m_DeviceMtu; } - /** - * @return The device's link layer type - */ + /// @return The device's link layer type virtual LinkLayerType getLinkType() const { return m_LinkType; } - /** - * @return A vector containing all IP addresses defined for this interface. - */ + /// @return A vector containing all IP addresses defined for this interface. std::vector getIPAddresses() const { return m_InterfaceDetails.addresses; } - /** - * @return The MAC address for this interface - */ + /// @return The MAC address for this interface virtual MacAddress getMacAddress() const { return m_MacAddress; } - /** - * @return The IPv4 address for this interface. If multiple IPv4 addresses are defined for this interface, the - * first will be picked. If no IPv4 addresses are defined, a zeroed IPv4 address (IPv4Address#Zero) will be - * returned - */ + /// @return The IPv4 address for this interface. If multiple IPv4 addresses are defined for this interface, the + /// first will be picked. If no IPv4 addresses are defined, a zeroed IPv4 address (IPv4Address#Zero) will be + /// returned IPv4Address getIPv4Address() const; - /** - * @return The IPv6 address for this interface. If multiple IPv6 addresses are defined for this interface, the - * first will be picked. If no IPv6 addresses are defined, a zeroed IPv6 address (IPv6Address#Zero) will be - * returned - */ + /// @return The IPv6 address for this interface. If multiple IPv6 addresses are defined for this interface, the + /// first will be picked. If no IPv6 addresses are defined, a zeroed IPv6 address (IPv6Address#Zero) will be + /// returned IPv6Address getIPv6Address() const; - /** - * @return The default gateway defined for this interface. If no default gateway is defined, if it's not IPv4 or - * if couldn't extract default gateway IPv4Address#Zero will be returned. If multiple gateways were defined the - * first one will be returned - */ + /// @return The default gateway defined for this interface. If no default gateway is defined, if it's not IPv4 + /// or if couldn't extract default gateway IPv4Address#Zero will be returned. If multiple gateways were defined + /// the first one will be returned IPv4Address getDefaultGateway() const; - /** - * @return A list of all DNS servers defined for this machine. If this list is empty it means no DNS servers - * were defined or they couldn't be extracted from some reason. This list is created in PcapLiveDeviceList class - * and can be also retrieved from there. This method exists for convenience - so it'll be possible to get this - * list from PcapLiveDevice as well - */ + /// @return A list of all DNS servers defined for this machine. If this list is empty it means no DNS servers + /// were defined or they couldn't be extracted from some reason. This list is created in PcapLiveDeviceList + /// class and can be also retrieved from there. This method exists for convenience - so it'll be possible to get + /// this list from PcapLiveDevice as well const std::vector& getDnsServers() const; - /** - * Start capturing packets on this network interface (device). Each time a packet is captured the - * onPacketArrives callback is called. The capture is done on a new thread created by this method, meaning all - * callback calls are done in a thread other than the caller thread. Capture process will stop and this capture - * thread will be terminated when calling stopCapture(). This method must be called after the device is opened - * (i.e the open() method was called), otherwise an error will be returned. - * @param[in] onPacketArrives A callback that is called each time a packet is captured - * @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to - * the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that - * give context to the capture callback, for example: objects that counts packets, manages flow state or manages - * the application state according to the packet that was captured - * @return True if capture started successfully, false if (relevant log error is printed in any case): - * - Capture is already running - * - Device is not opened - * - Capture thread could not be created - */ + /// Start capturing packets on this network interface (device). Each time a packet is captured the + /// onPacketArrives callback is called. The capture is done on a new thread created by this method, meaning all + /// callback calls are done in a thread other than the caller thread. Capture process will stop and this capture + /// thread will be terminated when calling stopCapture(). This method must be called after the device is opened + /// (i.e the open() method was called), otherwise an error will be returned. + /// @param[in] onPacketArrives A callback that is called each time a packet is captured + /// @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to + /// the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects + /// that give context to the capture callback, for example: objects that counts packets, manages flow state or + /// manages the application state according to the packet that was captured + /// @return True if capture started successfully, false if (relevant log error is printed in any case): + /// - Capture is already running + /// - Device is not opened + /// - Capture thread could not be created virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie); - /** - * Start capturing packets on this network interface (device) with periodic stats collection. Each time a packet - * is captured the onPacketArrives callback is called. In addition, each intervalInSecondsToUpdateStats seconds - * stats are collected from the device and the onStatsUpdate callback is called. Both the capture and periodic - * stats collection are done on new threads created by this method, each on a different thread, meaning all - * callback calls are done in threads other than the caller thread. Capture process and stats collection will - * stop and threads will be terminated when calling stopCapture(). This method must be called after the device - * is opened (i.e the open() method was called), otherwise an error will be returned. - * @param[in] onPacketArrives A callback that is called each time a packet is captured - * @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to - * the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that - * give context to the capture callback, for example: objects that counts packets, manages flow state or manages - * the application state according to the packet that was captured - * @param[in] intervalInSecondsToUpdateStats The interval in seconds to activate periodic stats collection - * @param[in] onStatsUpdate A callback that will be called each time intervalInSecondsToUpdateStats expires and - * stats are collected. This callback will contain the collected stats - * @param[in] onStatsUpdateUserCookie A pointer to a user provided object. This object will be transferred to - * the onStatsUpdate callback each time it is called - * @return True if capture started successfully, false if (relevant log error is printed in any case): - * - Capture is already running - * - Device is not opened - * - Capture thread could not be created - * - Stats collection thread could not be created - */ + /// Start capturing packets on this network interface (device) with periodic stats collection. Each time a + /// packet is captured the onPacketArrives callback is called. In addition, each intervalInSecondsToUpdateStats + /// seconds stats are collected from the device and the onStatsUpdate callback is called. Both the capture and + /// periodic stats collection are done on new threads created by this method, each on a different thread, + /// meaning all callback calls are done in threads other than the caller thread. Capture process and stats + /// collection will stop and threads will be terminated when calling stopCapture(). This method must be called + /// after the device is opened (i.e the open() method was called), otherwise an error will be returned. + /// @param[in] onPacketArrives A callback that is called each time a packet is captured + /// @param[in] onPacketArrivesUserCookie A pointer to a user provided object. This object will be transferred to + /// the onPacketArrives callback each time it is called. This cookie is very useful for transferring objects + /// that give context to the capture callback, for example: objects that counts packets, manages flow state or + /// manages the application state according to the packet that was captured + /// @param[in] intervalInSecondsToUpdateStats The interval in seconds to activate periodic stats collection + /// @param[in] onStatsUpdate A callback that will be called each time intervalInSecondsToUpdateStats expires and + /// stats are collected. This callback will contain the collected stats + /// @param[in] onStatsUpdateUserCookie A pointer to a user provided object. This object will be transferred to + /// the onStatsUpdate callback each time it is called + /// @return True if capture started successfully, false if (relevant log error is printed in any case): + /// - Capture is already running + /// - Device is not opened + /// - Capture thread could not be created + /// - Stats collection thread could not be created virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie, int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate, void* onStatsUpdateUserCookie); - /** - * Start capturing packets on this network interface (device) with periodic stats collection only. This means - * that packets arriving to the network interface aren't delivered to the user but only counted. Each - * intervalInSecondsToUpdateStats seconds stats are collected from the device and the onStatsUpdate callback is - * called with the updated counters. The periodic stats collection is done on a new thread created by this - * method, meaning all callback calls are done in threads other than the caller thread. Stats collection will - * stop and threads will be terminated when calling stopCapture(). This method must be called after the device - * is opened (i.e the open() method was called), otherwise an error will be returned. - * @param[in] intervalInSecondsToUpdateStats The interval in seconds to activate periodic stats collection - * @param[in] onStatsUpdate A callback that will be called each time intervalInSecondsToUpdateStats expires and - * stats are collected. This callback will contain the collected stats - * @param[in] onStatsUpdateUserCookie A pointer to a user provided object. This object will be transferred to - * the onStatsUpdate callback each time it is called - * @return True if capture started successfully, false if (relevant log error is printed in any case): - * - Capture is already running - * - Device is not opened - * - Stats collection thread could not be created - */ + /// Start capturing packets on this network interface (device) with periodic stats collection only. This means + /// that packets arriving to the network interface aren't delivered to the user but only counted. Each + /// intervalInSecondsToUpdateStats seconds stats are collected from the device and the onStatsUpdate callback is + /// called with the updated counters. The periodic stats collection is done on a new thread created by this + /// method, meaning all callback calls are done in threads other than the caller thread. Stats collection will + /// stop and threads will be terminated when calling stopCapture(). This method must be called after the device + /// is opened (i.e the open() method was called), otherwise an error will be returned. + /// @param[in] intervalInSecondsToUpdateStats The interval in seconds to activate periodic stats collection + /// @param[in] onStatsUpdate A callback that will be called each time intervalInSecondsToUpdateStats expires and + /// stats are collected. This callback will contain the collected stats + /// @param[in] onStatsUpdateUserCookie A pointer to a user provided object. This object will be transferred to + /// the onStatsUpdate callback each time it is called + /// @return True if capture started successfully, false if (relevant log error is printed in any case): + /// - Capture is already running + /// - Device is not opened + /// - Stats collection thread could not be created virtual bool startCapture(int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate, void* onStatsUpdateUserCookie); - /** - * Start capturing packets on this network interface (device). All captured packets are added to - * capturedPacketsVector, so at the end of the capture (when calling stopCapture()) this vector contains - * pointers to all captured packets in the form of RawPacket. The capture is done on a new thread created by - * this method, meaning capturedPacketsVector is updated from another thread other than the caller thread (so - * user should avoid changing or iterating this vector while capture is on). Capture process will stop and this - * capture thread will be terminated when calling stopCapture(). This method must be called after the device is - * opened (i.e the open() method was called), otherwise an error will be returned. - * @param[in] capturedPacketsVector A reference to a RawPacketVector, meaning a vector of pointer to RawPacket - * objects - * @return True if capture started successfully, false if (relevant log error is printed in any case): - * - Capture is already running - * - Device is not opened - * - Capture thread could not be created - */ + /// Start capturing packets on this network interface (device). All captured packets are added to + /// capturedPacketsVector, so at the end of the capture (when calling stopCapture()) this vector contains + /// pointers to all captured packets in the form of RawPacket. The capture is done on a new thread created by + /// this method, meaning capturedPacketsVector is updated from another thread other than the caller thread (so + /// user should avoid changing or iterating this vector while capture is on). Capture process will stop and this + /// capture thread will be terminated when calling stopCapture(). This method must be called after the device is + /// opened (i.e the open() method was called), otherwise an error will be returned. + /// @param[in] capturedPacketsVector A reference to a RawPacketVector, meaning a vector of pointer to RawPacket + /// objects + /// @return True if capture started successfully, false if (relevant log error is printed in any case): + /// - Capture is already running + /// - Device is not opened + /// - Capture thread could not be created virtual bool startCapture(RawPacketVector& capturedPacketsVector); - /** - * Start capturing packets on this network interface (device) in blocking mode, meaning this method blocks and - * won't return until the user frees the blocking (via onPacketArrives callback) or until a user defined timeout - * expires. Whenever a packets is captured the onPacketArrives callback is called and lets the user handle the - * packet. In each callback call the user should return true if he wants to release the block or false if it - * wants it to keep blocking. Regardless of this callback a timeout is defined when start capturing. When this - * timeout expires the method will return.
Please notice that stopCapture() isn't needed here because when - * the method returns (after timeout or per user decision) capturing on the device is stopped - * @param[in] onPacketArrives A callback given by the user for handling incoming packets. After handling each - * packet the user needs to return a boolean value. True value indicates stop capturing and stop blocking and - * false value indicates continue capturing and blocking - * @param[in] userCookie A pointer to a user provided object. This object will be transferred to the - * onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that - * give context to the capture callback, for example: objects that counts packets, manages flow state or manages - * the application state according to the packet that was captured - * @param[in] timeout A timeout in seconds for the blocking to stop even if the user didn't return "true" in the - * onPacketArrives callback. The precision of `timeout` is millisecond, e.g. 2.345 seconds means 2345 - * milliseconds. If this timeout is set to 0 or less the timeout will be ignored, meaning the method will keep - * handling packets until the `onPacketArrives` callback returns `true`. - * @return -1 if timeout expired, 1 if blocking was stopped via onPacketArrives callback or 0 if an error - * occurred (such as device not open etc.). When returning 0 an appropriate error message is printed to log - * @note On Unix-like systems, enabling the `usePoll` option in `DeviceConfiguration` prevents the method from - * blocking indefinitely when no packets are available, even if a timeout is set. - */ + /// Start capturing packets on this network interface (device) in blocking mode, meaning this method blocks and + /// won't return until the user frees the blocking (via onPacketArrives callback) or until a user defined + /// timeout expires. Whenever a packets is captured the onPacketArrives callback is called and lets the user + /// handle the packet. In each callback call the user should return true if he wants to release the block or + /// false if it wants it to keep blocking. Regardless of this callback a timeout is defined when start + /// capturing. When this timeout expires the method will return.
Please notice that stopCapture() isn't + /// needed here because when the method returns (after timeout or per user decision) capturing on the device is + /// stopped + /// @param[in] onPacketArrives A callback given by the user for handling incoming packets. After handling each + /// packet the user needs to return a boolean value. True value indicates stop capturing and stop blocking and + /// false value indicates continue capturing and blocking + /// @param[in] userCookie A pointer to a user provided object. This object will be transferred to the + /// onPacketArrives callback each time it is called. This cookie is very useful for transferring objects that + /// give context to the capture callback, for example: objects that counts packets, manages flow state or + /// manages the application state according to the packet that was captured + /// @param[in] timeout A timeout in seconds for the blocking to stop even if the user didn't return "true" in + /// the onPacketArrives callback. The precision of `timeout` is millisecond, e.g. 2.345 seconds means 2345 + /// milliseconds. If this timeout is set to 0 or less the timeout will be ignored, meaning the method will keep + /// handling packets until the `onPacketArrives` callback returns `true`. + /// @return -1 if timeout expired, 1 if blocking was stopped via onPacketArrives callback or 0 if an error + /// occurred (such as device not open etc.). When returning 0 an appropriate error message is printed to log + /// @note On Unix-like systems, enabling the `usePoll` option in `DeviceConfiguration` prevents the method from + /// blocking indefinitely when no packets are available, even if a timeout is set. virtual int startCaptureBlockingMode(OnPacketArrivesStopBlocking onPacketArrives, void* userCookie, const double timeout); - /** - * Stop a currently running packet capture. This method terminates gracefully both packet capture thread and - * periodic stats collection thread (both if exist) - */ + /// Stop a currently running packet capture. This method terminates gracefully both packet capture thread and + /// periodic stats collection thread (both if exist) void stopCapture(); - /** - * Check if a capture thread is running - * @return True if a capture thread is currently running - */ + /// Check if a capture thread is running + /// @return True if a capture thread is currently running bool captureActive(); - /** - * Checks whether the packetPayloadLength is larger than the device MTU. Logs an error if check fails - * @param[in] packetPayloadLength The length of the IP layer of the packet - * @return True if the packetPayloadLength is less than or equal to the device MTU - */ + /// Checks whether the packetPayloadLength is larger than the device MTU. Logs an error if check fails + /// @param[in] packetPayloadLength The length of the IP layer of the packet + /// @return True if the packetPayloadLength is less than or equal to the device MTU bool doMtuCheck(int packetPayloadLength) const; - /** - * Send a RawPacket to the network - * @param[in] rawPacket A reference to the raw packet to send. This method treats the raw packet as read-only, - * it doesn't change anything in it - * @param[in] checkMtu Whether the length of the packet's payload should be checked against the MTU. If enabled - * this comes with a small performance penalty. Default value is false to avoid performance overhead. Set to - * true if you don't know whether packets fit the live device's MTU and you can afford the overhead. - * @return True if packet was sent successfully. False will be returned in the following cases (relevant log - * error is printed in any case): - * - Device is not opened - * - Packet length is 0 - * - Packet length is larger than device MTU - * - Packet could not be sent due to some error in libpcap/WinPcap/Npcap - */ + /// Send a RawPacket to the network + /// @param[in] rawPacket A reference to the raw packet to send. This method treats the raw packet as read-only, + /// it doesn't change anything in it + /// @param[in] checkMtu Whether the length of the packet's payload should be checked against the MTU. If enabled + /// this comes with a small performance penalty. Default value is false to avoid performance overhead. Set to + /// true if you don't know whether packets fit the live device's MTU and you can afford the overhead. + /// @return True if packet was sent successfully. False will be returned in the following cases (relevant log + /// error is printed in any case): + /// - Device is not opened + /// - Packet length is 0 + /// - Packet length is larger than device MTU + /// - Packet could not be sent due to some error in libpcap/WinPcap/Npcap bool sendPacket(RawPacket const& rawPacket, bool checkMtu = false); - /** - * Send a buffer containing packet raw data (including all layers) to the network. - * This particular version of the sendPacket method should only be used if you already have access to the size - * of the network layer of the packet, since it allows you to check the payload size (see packetPayloadLength - * parameter) MTU of the live device without incurring a parsing overhead. If the packetPayloadLength is - * unknown, please use a different implementation of the sendPacket method. - * @param[in] packetData The buffer containing the packet raw data - * @param[in] packetDataLength The length of the buffer (this is the entire packet, including link layer) - * @param[in] packetPayloadLength The length of the payload for the data link layer. This includes all data - * apart from the header for the data link layer. - * @return True if the packet was sent successfully. False will be returned in the following cases (relevant log - * error is printed in any case): - * - Device is not opened - * - Packet data length is 0 - * - Packet payload length is larger than device MTU - * - Packet could not be sent due to some error in libpcap/WinPcap/Npcap - */ + /// Send a buffer containing packet raw data (including all layers) to the network. + /// This particular version of the sendPacket method should only be used if you already have access to the size + /// of the network layer of the packet, since it allows you to check the payload size (see packetPayloadLength + /// parameter) MTU of the live device without incurring a parsing overhead. If the packetPayloadLength is + /// unknown, please use a different implementation of the sendPacket method. + /// @param[in] packetData The buffer containing the packet raw data + /// @param[in] packetDataLength The length of the buffer (this is the entire packet, including link layer) + /// @param[in] packetPayloadLength The length of the payload for the data link layer. This includes all data + /// apart from the header for the data link layer. + /// @return True if the packet was sent successfully. False will be returned in the following cases (relevant + /// log error is printed in any case): + /// - Device is not opened + /// - Packet data length is 0 + /// - Packet payload length is larger than device MTU + /// - Packet could not be sent due to some error in libpcap/WinPcap/Npcap bool sendPacket(const uint8_t* packetData, int packetDataLength, int packetPayloadLength); - /** - * Send a buffer containing packet raw data (including all layers) to the network - * @param[in] packetData The buffer containing the packet raw data - * @param[in] packetDataLength The length of the buffer - * @param[in] checkMtu Whether the length of the packet's payload should be checked against the MTU. If enabled - * this comes with a small performance penalty. Default value is false to avoid performance overhead. Set to - * true if you don't know whether packets fit the live device's MTU and you can afford the overhead. - * @param[in] linkType Only used if checkMtu is true. Defines the layer type for parsing the first layer of the - * packet. Used for parsing the packet to perform the MTU check. Default value is pcpp::LINKTYPE_ETHERNET. - * Ensure this parameter matches the linktype of the packet if checkMtu is true. - * @return True if packet was sent successfully. False will be returned in the following cases (relevant log - * error is printed in any case): - * - Device is not opened - * - Packet length is 0 - * - Packet length is larger than device MTU and checkMtu is true - * - Packet could not be sent due to some error in libpcap/WinPcap/Npcap - */ + /// Send a buffer containing packet raw data (including all layers) to the network + /// @param[in] packetData The buffer containing the packet raw data + /// @param[in] packetDataLength The length of the buffer + /// @param[in] checkMtu Whether the length of the packet's payload should be checked against the MTU. If enabled + /// this comes with a small performance penalty. Default value is false to avoid performance overhead. Set to + /// true if you don't know whether packets fit the live device's MTU and you can afford the overhead. + /// @param[in] linkType Only used if checkMtu is true. Defines the layer type for parsing the first layer of the + /// packet. Used for parsing the packet to perform the MTU check. Default value is pcpp::LINKTYPE_ETHERNET. + /// Ensure this parameter matches the linktype of the packet if checkMtu is true. + /// @return True if packet was sent successfully. False will be returned in the following cases (relevant log + /// error is printed in any case): + /// - Device is not opened + /// - Packet length is 0 + /// - Packet length is larger than device MTU and checkMtu is true + /// - Packet could not be sent due to some error in libpcap/WinPcap/Npcap bool sendPacket(const uint8_t* packetData, int packetDataLength, bool checkMtu = false, pcpp::LinkLayerType linkType = pcpp::LINKTYPE_ETHERNET); - /** - * Send a parsed Packet to the network - * @param[in] packet A pointer to the packet to send. This method treats the packet as read-only, it doesn't - * change anything in it - * @param[in] checkMtu Whether the length of the packet's payload should be checked against the MTU. Default - * value is true, since the packet being passed in has already been parsed, so checking the MTU does not incur - * significant processing overhead. - * @return True if packet was sent successfully. False will be returned in the following cases (relevant log - * error is printed in any case): - * - Device is not opened - * - Packet length is 0 - * - Packet length is larger than device MTU and checkMtu is true - * - Packet could not be sent due to some error in libpcap/WinPcap/Npcap - */ + /// Send a parsed Packet to the network + /// @param[in] packet A pointer to the packet to send. This method treats the packet as read-only, it doesn't + /// change anything in it + /// @param[in] checkMtu Whether the length of the packet's payload should be checked against the MTU. Default + /// value is true, since the packet being passed in has already been parsed, so checking the MTU does not incur + /// significant processing overhead. + /// @return True if packet was sent successfully. False will be returned in the following cases (relevant log + /// error is printed in any case): + /// - Device is not opened + /// - Packet length is 0 + /// - Packet length is larger than device MTU and checkMtu is true + /// - Packet could not be sent due to some error in libpcap/WinPcap/Npcap bool sendPacket(Packet* packet, bool checkMtu = true); - /** - * Send an array of RawPacket objects to the network - * @param[in] rawPacketsArr The array of RawPacket objects to send. This method treats all packets as read-only, - * it doesn't change anything in them - * @param[in] arrLength The length of the array - * @param[in] checkMtu Whether to check the size of the packet payload against MTU size. Incurs a parsing - * overhead. Default value is false to avoid performance overhead. Set to true if you don't know whether packets - * fit the live device's MTU and you can afford the overhead. - * @return The number of packets sent successfully. Sending a packet can fail if: - * - Device is not opened. In this case no packets will be sent, return value will be 0 - * - Packet length is 0 - * - Packet length is larger than device MTU and checkMtu is true - * - Packet could not be sent due to some error in libpcap/WinPcap/Npcap - */ + /// Send an array of RawPacket objects to the network + /// @param[in] rawPacketsArr The array of RawPacket objects to send. This method treats all packets as + /// read-only, it doesn't change anything in them + /// @param[in] arrLength The length of the array + /// @param[in] checkMtu Whether to check the size of the packet payload against MTU size. Incurs a parsing + /// overhead. Default value is false to avoid performance overhead. Set to true if you don't know whether + /// packets fit the live device's MTU and you can afford the overhead. + /// @return The number of packets sent successfully. Sending a packet can fail if: + /// - Device is not opened. In this case no packets will be sent, return value will be 0 + /// - Packet length is 0 + /// - Packet length is larger than device MTU and checkMtu is true + /// - Packet could not be sent due to some error in libpcap/WinPcap/Npcap virtual int sendPackets(RawPacket* rawPacketsArr, int arrLength, bool checkMtu = false); - /** - * Send an array of pointers to Packet objects to the network - * @param[in] packetsArr The array of pointers to Packet objects to send. This method treats all packets as - * read-only, it doesn't change anything in them - * @param[in] arrLength The length of the array - * @param[in] checkMtu Whether to check the size of the packet payload against MTU size. Default value is true, - * since the packets being passed in has already been parsed, so checking the MTU does not incur significant - * processing overhead. - * @return The number of packets sent successfully. Sending a packet can fail if: - * - Device is not opened. In this case no packets will be sent, return value will be 0 - * - Packet length is 0 - * - Packet length is larger than device MTU and checkMtu is true - * - Packet could not be sent due to some error in libpcap/WinPcap/Npcap - */ + /// Send an array of pointers to Packet objects to the network + /// @param[in] packetsArr The array of pointers to Packet objects to send. This method treats all packets as + /// read-only, it doesn't change anything in them + /// @param[in] arrLength The length of the array + /// @param[in] checkMtu Whether to check the size of the packet payload against MTU size. Default value is true, + /// since the packets being passed in has already been parsed, so checking the MTU does not incur significant + /// processing overhead. + /// @return The number of packets sent successfully. Sending a packet can fail if: + /// - Device is not opened. In this case no packets will be sent, return value will be 0 + /// - Packet length is 0 + /// - Packet length is larger than device MTU and checkMtu is true + /// - Packet could not be sent due to some error in libpcap/WinPcap/Npcap virtual int sendPackets(Packet** packetsArr, int arrLength, bool checkMtu = true); - /** - * Send a vector of pointers to RawPacket objects to the network - * @param[in] rawPackets The array of pointers to RawPacket objects to send. This method treats all packets as - * read-only, it doesn't change anything in them - * @param[in] checkMtu Whether to check the size of the packet payload against MTU size. Incurs a parsing - * overhead. Default value is false to avoid performance overhead. Set to true if you don't know whether packets - * fit the live device's MTU and you can afford the overhead. - * @return The number of packets sent successfully. Sending a packet can fail if: - * - Device is not opened. In this case no packets will be sent, return value will be 0 - * - Packet length is 0 - * - Packet length is larger than device MTU and checkMtu is true - * - Packet could not be sent due to some error in libpcap/WinPcap/Npcap - */ + /// Send a vector of pointers to RawPacket objects to the network + /// @param[in] rawPackets The array of pointers to RawPacket objects to send. This method treats all packets as + /// read-only, it doesn't change anything in them + /// @param[in] checkMtu Whether to check the size of the packet payload against MTU size. Incurs a parsing + /// overhead. Default value is false to avoid performance overhead. Set to true if you don't know whether + /// packets fit the live device's MTU and you can afford the overhead. + /// @return The number of packets sent successfully. Sending a packet can fail if: + /// - Device is not opened. In this case no packets will be sent, return value will be 0 + /// - Packet length is 0 + /// - Packet length is larger than device MTU and checkMtu is true + /// - Packet could not be sent due to some error in libpcap/WinPcap/Npcap virtual int sendPackets(const RawPacketVector& rawPackets, bool checkMtu = false); // implement abstract methods - /** - * Open the device using libpcap pcap_open_live. Opening the device only makes the device ready for use, it - * doesn't start packet capturing. For packet capturing the user should call startCapture(). This implies that - * calling this method is a must before calling startCapture() (otherwise startCapture() will fail with a - * "device not open" error). The device is opened in promiscuous mode - * @return True if the device was opened successfully, false otherwise. When opening the device fails an error - * will be printed to log as well - */ + /// Open the device using libpcap pcap_open_live. Opening the device only makes the device ready for use, it + /// doesn't start packet capturing. For packet capturing the user should call startCapture(). This implies that + /// calling this method is a must before calling startCapture() (otherwise startCapture() will fail with a + /// "device not open" error). The device is opened in promiscuous mode + /// @return True if the device was opened successfully, false otherwise. When opening the device fails an error + /// will be printed to log as well bool open() override; - /** - * Enables to open a device in a non-default configuration. Configuration has parameters like packet buffer - * timeout & size, open in promiscuous/non-promiscuous mode, etc. Please check DeviceConfiguration for more - * details - * @param[in] config The requested configuration - * @return Same as open() - */ + /// Enables to open a device in a non-default configuration. Configuration has parameters like packet buffer + /// timeout & size, open in promiscuous/non-promiscuous mode, etc. Please check DeviceConfiguration for more + /// details + /// @param[in] config The requested configuration + /// @return Same as open() bool open(const DeviceConfiguration& config); void close() override; - /** - * Clones the current device class - * @return Pointer to the copied class - */ + /// Clones the current device class + /// @return Pointer to the copied class virtual PcapLiveDevice* clone() const; void getStatistics(IPcapDevice::PcapStats& stats) const override; @@ -650,5 +560,4 @@ namespace pcpp protected: pcap_t* doOpen(const DeviceConfiguration& config); }; - } // namespace pcpp diff --git a/Pcap++/header/PcapLiveDeviceList.h b/Pcap++/header/PcapLiveDeviceList.h index 84f33b4ab6..bb4a842d6d 100644 --- a/Pcap++/header/PcapLiveDeviceList.h +++ b/Pcap++/header/PcapLiveDeviceList.h @@ -7,20 +7,15 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class PcapLiveDeviceList - * A singleton class that creates, stores and provides access to all PcapLiveDevice (on Linux) or WinPcapLiveDevice - * (on Windows) instances. All live devices are initialized on startup and wrap the network interfaces installed on - * the machine. This class enables access to them through their IP addresses or get a vector of all of them so the - * user can search them in some other way - */ + /// @class PcapLiveDeviceList + /// A singleton class that creates, stores and provides access to all PcapLiveDevice (on Linux) or WinPcapLiveDevice + /// (on Windows) instances. All live devices are initialized on startup and wrap the network interfaces installed on + /// the machine. This class enables access to them through their IP addresses or get a vector of all of them so the + /// user can search them in some other way class PcapLiveDeviceList { private: @@ -42,85 +37,63 @@ namespace pcpp PcapLiveDeviceList& operator=(const PcapLiveDeviceList&) = delete; PcapLiveDeviceList& operator=(PcapLiveDeviceList&&) noexcept = delete; - /** - * The access method to the singleton - * @return The singleton instance of this class - */ + /// The access method to the singleton + /// @return The singleton instance of this class static PcapLiveDeviceList& getInstance() { static PcapLiveDeviceList instance; return instance; } - /** - * @return A vector containing pointers to all live devices currently installed on the machine - */ + /// @return A vector containing pointers to all live devices currently installed on the machine const std::vector& getPcapLiveDevicesList() const { return m_LiveDeviceListView; }; - /** - * Get a pointer to the live device by its IP address. IP address can be both IPv4 or IPv6 - * @param[in] ipAddr The IP address defined for the device - * @return A pointer to the live device if this IP address exists. nullptr otherwise - */ + /// Get a pointer to the live device by its IP address. IP address can be both IPv4 or IPv6 + /// @param[in] ipAddr The IP address defined for the device + /// @return A pointer to the live device if this IP address exists. nullptr otherwise PcapLiveDevice* getPcapLiveDeviceByIp(const IPAddress& ipAddr) const; - /** - * Get a pointer to the live device by its IPv4 address - * @param[in] ipAddr The IPv4 address defined for the device - * @return A pointer to the live device if this IPv4 address exists. nullptr otherwise - */ + /// Get a pointer to the live device by its IPv4 address + /// @param[in] ipAddr The IPv4 address defined for the device + /// @return A pointer to the live device if this IPv4 address exists. nullptr otherwise PcapLiveDevice* getPcapLiveDeviceByIp(const IPv4Address& ipAddr) const; - /** - * Get a pointer to the live device by its IPv6 address - * @param[in] ip6Addr The IPv6 address defined for the device - * @return A pointer to the live device if this IPv6 address exists. nullptr otherwise - */ + /// Get a pointer to the live device by its IPv6 address + /// @param[in] ip6Addr The IPv6 address defined for the device + /// @return A pointer to the live device if this IPv6 address exists. nullptr otherwise PcapLiveDevice* getPcapLiveDeviceByIp(const IPv6Address& ip6Addr) const; - /** - * Get a pointer to the live device by its IP address represented as string. IP address can be both IPv4 or IPv6 - * @param[in] ipAddrAsString The IP address defined for the device as string - * @return A pointer to the live device if this IP address is valid and exists. nullptr otherwise - */ + /// Get a pointer to the live device by its IP address represented as string. IP address can be both IPv4 or + /// IPv6 + /// @param[in] ipAddrAsString The IP address defined for the device as string + /// @return A pointer to the live device if this IP address is valid and exists. nullptr otherwise PcapLiveDevice* getPcapLiveDeviceByIp(const std::string& ipAddrAsString) const; - /** - * Get a pointer to the live device by its name - * @param[in] name The name of the interface (e.g eth0) - * @return A pointer to the live device if this name exists. nullptr otherwise - */ + /// Get a pointer to the live device by its name + /// @param[in] name The name of the interface (e.g eth0) + /// @return A pointer to the live device if this name exists. nullptr otherwise PcapLiveDevice* getPcapLiveDeviceByName(const std::string& name) const; - /** - * Get a pointer to the live device by its IP address or name - * @param[in] ipOrName An IP address or name of the interface - * @return A pointer to the live device if exists, nullptr otherwise - */ + /// Get a pointer to the live device by its IP address or name + /// @param[in] ipOrName An IP address or name of the interface + /// @return A pointer to the live device if exists, nullptr otherwise PcapLiveDevice* getPcapLiveDeviceByIpOrName(const std::string& ipOrName) const; - /** - * @return A list of all DNS servers defined for this machine. If this list is empty it means no DNS servers - * were defined or they couldn't be extracted from some reason - */ + /// @return A list of all DNS servers defined for this machine. If this list is empty it means no DNS servers + /// were defined or they couldn't be extracted from some reason const std::vector& getDnsServers() const { return m_DnsServers; } - /** - * Copies the current live device list - * @return A pointer to the cloned device list - */ + /// Copies the current live device list + /// @return A pointer to the cloned device list PcapLiveDeviceList* clone(); - /** - * Reset the live device list and DNS server list, meaning clear and refetch them - */ + /// Reset the live device list and DNS server list, meaning clear and refetch them void reset(); }; - } // namespace pcpp diff --git a/Pcap++/header/PcapRemoteDevice.h b/Pcap++/header/PcapRemoteDevice.h index 8158be244c..f3bcb50505 100644 --- a/Pcap++/header/PcapRemoteDevice.h +++ b/Pcap++/header/PcapRemoteDevice.h @@ -8,79 +8,62 @@ struct pcap_rmtauth; -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @struct PcapRemoteAuthentication - * The remote daemon (rpcapd) can be configured to require authentication before allowing a client to connect. This - * is done for security reasons of course. This struct wraps the WinPcap/Npcap authentication object (pcap_rmtauth) - * and can (but not must) be given to PcapRemoteDeviceList when initiating a connection to the remote daemon - */ + /// @struct PcapRemoteAuthentication + /// The remote daemon (rpcapd) can be configured to require authentication before allowing a client to connect. This + /// is done for security reasons of course. This struct wraps the WinPcap/Npcap authentication object (pcap_rmtauth) + /// and can (but not must) be given to PcapRemoteDeviceList when initiating a connection to the remote daemon struct PcapRemoteAuthentication { public: - /** - * A constructor that sets username and password - * @param[in] username The username for authentication with the remote daemon - * @param[in] password The password for authentication with the remote daemon - */ + /// A constructor that sets username and password + /// @param[in] username The username for authentication with the remote daemon + /// @param[in] password The password for authentication with the remote daemon PcapRemoteAuthentication(const std::string& username, const std::string& password) : userName(username) { this->password = password; } - /** - * A copy c'tor for this object - * @param[in] other The object to copy from - */ + /// A copy c'tor for this object + /// @param[in] other The object to copy from PcapRemoteAuthentication(const PcapRemoteAuthentication& other) : userName(other.userName), password(other.password) {} - /** - * The username for authentication - */ + /// The username for authentication std::string userName; - /** - * The password for authentication - */ + /// The password for authentication std::string password; - /** - * A conversion method from PcapRemoteAuthentication to pcap_rmtauth. Note: the char* pointers of the returned - * pcap_rmtauth points to the same places in memory as PcapRemoteAuthentication::userName and - * PcapRemoteAuthentication::password so the user should avoid freeing this memory - * @return A pcap_rmtauth that is converted from this class - */ + /// A conversion method from PcapRemoteAuthentication to pcap_rmtauth. Note: the char* pointers of the returned + /// pcap_rmtauth points to the same places in memory as PcapRemoteAuthentication::userName and + /// PcapRemoteAuthentication::password so the user should avoid freeing this memory + /// @return A pcap_rmtauth that is converted from this class pcap_rmtauth getPcapRmAuth() const; }; - /** - * @class PcapRemoteDevice - * A class that provides a C++ wrapper for WinPcap/Npcap Remote Capture feature. This feature allows to interact to - * a remote machine and capture packets that are being transmitted on the remote network interfaces. This requires a - * remote daemon (called rpcapd) which performs the capture and sends data back and the local client (represented by - * PcapRemoteDevice) that sends the appropriate commands and receives the captured data. You can read more about - * this feature in WinPcap Remote Capture manual: https://www.winpcap.org/docs/docs_412/html/group__remote.html
- * Since this feature is supported in WinPcap and Npcap only and not in libpcap, PcapRemoteDevice can only be used - * in Windows only.
This class provides a wrapper for the local client, meaning it assumes the daemon (rpcapd) - * is already running on the remote machine and it tries to connect to it and start receiving/sending packets - * from/to it. This class assumes rpcapd is in passive mode, meaning PcapRemoteDevice connects to the remote daemon, - * sends the appropriate commands to it, and starts capturing packets, rather than letting the daemon connect to the - * client by itself. Using PcapRemoteDevice is very similar to using the other live devices (PcapLiveDevice or - * WinPcapLiveDevice), meaning the API's are the same and the same logic is used (for example: capturing is done on - * a different thread, sending packets are done on the same thread, etc.). For the full API and explanations, please - * refer to PcapLiveDevice. The reason for the similar API is that WinPcap/Npcap's API is very similar between - * Remote Capture and local network interface capture. The things that are different are some are some - * implementation details, mainly in making the connection to the remote daemon, and the way the user can get the - * instance of PcapRemoteDevice. For more details on that please refer to PcapRemoteDeviceList - */ + /// @class PcapRemoteDevice + /// A class that provides a C++ wrapper for WinPcap/Npcap Remote Capture feature. This feature allows to interact to + /// a remote machine and capture packets that are being transmitted on the remote network interfaces. This requires + /// a remote daemon (called rpcapd) which performs the capture and sends data back and the local client (represented + /// by PcapRemoteDevice) that sends the appropriate commands and receives the captured data. You can read more about + /// this feature in WinPcap Remote Capture manual: https://www.winpcap.org/docs/docs_412/html/group__remote.html
+ /// Since this feature is supported in WinPcap and Npcap only and not in libpcap, PcapRemoteDevice can only be used + /// in Windows only.
This class provides a wrapper for the local client, meaning it assumes the daemon (rpcapd) + /// is already running on the remote machine and it tries to connect to it and start receiving/sending packets + /// from/to it. This class assumes rpcapd is in passive mode, meaning PcapRemoteDevice connects to the remote + /// daemon, sends the appropriate commands to it, and starts capturing packets, rather than letting the daemon + /// connect to the client by itself. Using PcapRemoteDevice is very similar to using the other live devices + /// (PcapLiveDevice or WinPcapLiveDevice), meaning the API's are the same and the same logic is used (for example: + /// capturing is done on a different thread, sending packets are done on the same thread, etc.). For the full API + /// and explanations, please refer to PcapLiveDevice. The reason for the similar API is that WinPcap/Npcap's API is + /// very similar between Remote Capture and local network interface capture. The things that are different are some + /// are some implementation details, mainly in making the connection to the remote daemon, and the way the user can + /// get the instance of PcapRemoteDevice. For more details on that please refer to PcapRemoteDeviceList class PcapRemoteDevice : public PcapLiveDevice { friend class PcapRemoteDeviceList; @@ -107,62 +90,48 @@ namespace pcpp PcapRemoteDevice& operator=(const PcapRemoteDevice&) = delete; PcapRemoteDevice& operator=(PcapRemoteDevice&&) noexcept = delete; - ~PcapRemoteDevice() override - {} + ~PcapRemoteDevice() override = default; - /** - * @return The IP address of the remote machine where packets are transmitted from the remote machine to the - * client machine - */ + /// @return The IP address of the remote machine where packets are transmitted from the remote machine to the + /// client machine IPAddress getRemoteMachineIpAddress() const { return m_RemoteMachineIpAddress; } - /** - * @return The port of the remote machine where packets are transmitted from the remote machine to the client - * machine - */ + /// @return The port of the remote machine where packets are transmitted from the remote machine to the client + /// machine uint16_t getRemoteMachinePort() const { return m_RemoteMachinePort; } - /** - * @return The type of the device (libPcap, WinPcap/Npcap or a remote device) - */ + /// @return The type of the device (libPcap, WinPcap/Npcap or a remote device) LiveDeviceType getDeviceType() const override { return RemoteDevice; } - /** - * MTU isn't supported for remote devices - * @return 0 - */ + /// MTU isn't supported for remote devices + /// @return 0 uint32_t getMtu() const override; - /** - * MAC address isn't supported for remote devices - * @return MacAddress#Zero - */ + /// MAC address isn't supported for remote devices + /// @return MacAddress#Zero MacAddress getMacAddress() const override; - /** - * Open the device using pcap_open. Opening the device makes the connection to the remote daemon (including - * authentication if needed and provided). If this methods succeeds it means the connection to the remote daemon - * succeeded and the device is ready for use. As in PcapLiveDevice, packet capturing won't start yet. For packet - * capturing the user should call startCapture(). This implies that calling this method is a must before calling - * startCapture() (otherwise startCapture() will fail with a "device not open" error). The remote daemon is - * asked to capture packets in promiscuous mode - * @return True if the device was opened successfully, false otherwise. When opening the device fails an error - * will be printed to log as well, including the WinPcap/Npcap error if exists - */ + /// Open the device using pcap_open. Opening the device makes the connection to the remote daemon (including + /// authentication if needed and provided). If this methods succeeds it means the connection to the remote + /// daemon succeeded and the device is ready for use. As in PcapLiveDevice, packet capturing won't start yet. + /// For packet capturing the user should call startCapture(). This implies that calling this method is a must + /// before calling startCapture() (otherwise startCapture() will fail with a "device not open" error). The + /// remote daemon is asked to capture packets in promiscuous mode + /// @return True if the device was opened successfully, false otherwise. When opening the device fails an error + /// will be printed to log as well, including the WinPcap/Npcap error if exists bool open() override; void getStatistics(IPcapDevice::PcapStats& stats) const override; PcapRemoteDevice* clone() const override; }; - } // namespace pcpp diff --git a/Pcap++/header/PcapRemoteDeviceList.h b/Pcap++/header/PcapRemoteDeviceList.h index 9d1d1fac6c..b8a07bbf50 100644 --- a/Pcap++/header/PcapRemoteDeviceList.h +++ b/Pcap++/header/PcapRemoteDeviceList.h @@ -7,25 +7,20 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class PcapRemoteDeviceList - * A class that creates, stores and provides access to all instances of PcapRemoteDevice for a certain remote - * machine. To get an instance of this class use one of the static methods of getRemoteDeviceList(). These methods - * creates a PcapRemoteDeviceList instance for the certain remote machine which holds a list of PcapRemoteDevice - * instances, one for each remote network interface. Note there is not a public constructor for this class, so the - * only way to get an instance of it is through getRemoteDeviceList(). After getting this object, this class - * provides ways to access the PcapRemoteDevice instances: either through IP address of the remote network interface - * or by iterating the PcapRemoteDevice instances (through the PcapRemoteDeviceList#RemoteDeviceListIterator - * iterator)
Since Remote Capture is supported in WinPcap and Npcap only, this class is available in Windows - * only - */ + /// @class PcapRemoteDeviceList + /// A class that creates, stores and provides access to all instances of PcapRemoteDevice for a certain remote + /// machine. To get an instance of this class use one of the static methods of getRemoteDeviceList(). These methods + /// creates a PcapRemoteDeviceList instance for the certain remote machine which holds a list of PcapRemoteDevice + /// instances, one for each remote network interface. Note there is not a public constructor for this class, so the + /// only way to get an instance of it is through getRemoteDeviceList(). After getting this object, this class + /// provides ways to access the PcapRemoteDevice instances: either through IP address of the remote network + /// interface or by iterating the PcapRemoteDevice instances (through the + /// PcapRemoteDeviceList#RemoteDeviceListIterator iterator)
Since Remote Capture is supported in WinPcap and + /// Npcap only, this class is available in Windows only class PcapRemoteDeviceList { private: @@ -40,14 +35,10 @@ namespace pcpp std::vector deviceList); public: - /** - * Iterator object that can be used for iterating all PcapRemoteDevice in list - */ + /// Iterator object that can be used for iterating all PcapRemoteDevice in list using RemoteDeviceListIterator = typename std::vector::iterator; - /** - * Const iterator object that can be used for iterating all PcapRemoteDevice in a constant list - */ + /// Const iterator object that can be used for iterating all PcapRemoteDevice in a constant list using ConstRemoteDeviceListIterator = typename std::vector::const_iterator; PcapRemoteDeviceList(const PcapRemoteDeviceList&) = delete; @@ -57,166 +48,137 @@ namespace pcpp ~PcapRemoteDeviceList(); - /** - * A static method for creating a PcapRemoteDeviceList instance for a certain remote machine. This methods - * creates the instance, and also creates a list of PcapRemoteDevice instances stored in it, one for each remote - * network interface. Notice this method allocates the PcapRemoteDeviceList instance and returns a pointer to - * it. It's the user responsibility to free it when done using it
This method overload is for remote daemons - * which don't require authentication for accessing them. For daemons which do require authentication use the - * other method overload - * @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd - * daemon - * @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon - * @return A pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will be - * printed to log in each case): - * - IP address provided is nullptr or not valid - * - WinPcap/Npcap encountered an error in creating the remote connection string - * - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving - * devices on the remote machine - * @deprecated This factory function has been deprecated in favor of 'createRemoteDeviceList' factory for better - * memory safety. - */ + /// A static method for creating a PcapRemoteDeviceList instance for a certain remote machine. This methods + /// creates the instance, and also creates a list of PcapRemoteDevice instances stored in it, one for each + /// remote network interface. Notice this method allocates the PcapRemoteDeviceList instance and returns a + /// pointer to it. It's the user responsibility to free it when done using it
This method overload is for + /// remote daemons which don't require authentication for accessing them. For daemons which do require + /// authentication use the other method overload + /// @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd + /// daemon + /// @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon + /// @return A pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will be + /// printed to log in each case): + /// - IP address provided is nullptr or not valid + /// - WinPcap/Npcap encountered an error in creating the remote connection string + /// - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving + /// devices on the remote machine + /// @deprecated This factory function has been deprecated in favor of 'createRemoteDeviceList' factory for + /// better memory safety. PCPP_DEPRECATED("Please use 'createRemoteDeviceList' factory method instead.") static PcapRemoteDeviceList* getRemoteDeviceList(const IPAddress& ipAddress, uint16_t port); - /** - * A static method for creating a PcapRemoteDeviceList instance for a specific remote machine. - * This methods creates the instance and populates it with PcapRemoteDevice instances. - * Each PcapRemoteDevice instance corresponds to a network interface on the remote machine. - * - * This method overload is for remote daemons which don't require authentication for accessing them. - * For daemons which do require authentication use the other method overload. - * - * @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd - * daemon - * @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon - * @return A smart pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will - * be printed to log in each case): - * - WinPcap/Npcap encountered an error in creating the remote connection string - * - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving - * devices on the remote machine - */ + /// A static method for creating a PcapRemoteDeviceList instance for a specific remote machine. + /// This methods creates the instance and populates it with PcapRemoteDevice instances. + /// Each PcapRemoteDevice instance corresponds to a network interface on the remote machine. + /// + /// This method overload is for remote daemons which don't require authentication for accessing them. + /// For daemons which do require authentication use the other method overload. + /// + /// @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd + /// daemon + /// @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon + /// @return A smart pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will + /// be printed to log in each case): + /// - WinPcap/Npcap encountered an error in creating the remote connection string + /// - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving + /// devices on the remote machine static std::unique_ptr createRemoteDeviceList(const IPAddress& ipAddress, uint16_t port); - /** - * An overload of the previous getRemoteDeviceList() method but with authentication support. This method is - * suitable for connecting to remote daemons which require authentication for accessing them - * @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd - * daemon - * @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon - * @param[in] remoteAuth A pointer to the authentication object which contains the username and password for - * connecting to the remote daemon - * @return A pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will be - * printed to log in each case): - * - IP address provided is nullptr or not valid - * - WinPcap/Npcap encountered an error in creating the remote connection string - * - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving - * devices on the remote machine - * @deprecated This factory function has been deprecated in favor of 'createRemoteDeviceList' factory for better - * memory safety. - */ + /// An overload of the previous getRemoteDeviceList() method but with authentication support. This method is + /// suitable for connecting to remote daemons which require authentication for accessing them + /// @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd + /// daemon + /// @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon + /// @param[in] remoteAuth A pointer to the authentication object which contains the username and password for + /// connecting to the remote daemon + /// @return A pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will be + /// printed to log in each case): + /// - IP address provided is nullptr or not valid + /// - WinPcap/Npcap encountered an error in creating the remote connection string + /// - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving + /// devices on the remote machine + /// @deprecated This factory function has been deprecated in favor of 'createRemoteDeviceList' factory for + /// better memory safety. PCPP_DEPRECATED("Please use 'createRemoteDeviceList' factory method instead.") static PcapRemoteDeviceList* getRemoteDeviceList(const IPAddress& ipAddress, uint16_t port, PcapRemoteAuthentication* remoteAuth); - /** - * A static method for creating a PcapRemoteDeviceList instance for a specific remote machine. - * This methods creates the instance and populates it with PcapRemoteDevice instances. - * Each PcapRemoteDevice instance corresponds to a network interface on the remote machine. - * - * This method overload is for remote daemons which require authentication for accessing them. - * If no authentication is required, use the other method overload. - * - * @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd - * daemon - * @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon - * @param[in] remoteAuth A pointer to the authentication object which contains the username and password for - * connecting to the remote daemon - * @return A smart pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will - * be printed to log in each case): - * - WinPcap/Npcap encountered an error in creating the remote connection string - * - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving - * devices on the remote machine - */ + /// A static method for creating a PcapRemoteDeviceList instance for a specific remote machine. + /// This methods creates the instance and populates it with PcapRemoteDevice instances. + /// Each PcapRemoteDevice instance corresponds to a network interface on the remote machine. + /// + /// This method overload is for remote daemons which require authentication for accessing them. + /// If no authentication is required, use the other method overload. + /// + /// @param[in] ipAddress The IP address of the remote machine through which clients can connect to the rpcapd + /// daemon + /// @param[in] port The port of the remote machine through which clients can connect to the rpcapd daemon + /// @param[in] remoteAuth A pointer to the authentication object which contains the username and password for + /// connecting to the remote daemon + /// @return A smart pointer to the newly created PcapRemoteDeviceList, or nullptr if (an appropriate error will + /// be printed to log in each case): + /// - WinPcap/Npcap encountered an error in creating the remote connection string + /// - WinPcap/Npcap encountered an error connecting to the rpcapd daemon on the remote machine or retrieving + /// devices on the remote machine static std::unique_ptr createRemoteDeviceList(const IPAddress& ipAddress, uint16_t port, PcapRemoteAuthentication const* remoteAuth); - /** - * @return The IP address of the remote machine - */ + /// @return The IP address of the remote machine IPAddress getRemoteMachineIpAddress() const { return m_RemoteMachineIpAddress; } - /** - * @return The port of the remote machine where packets are transmitted from the remote machine to the client - * machine - */ + /// @return The port of the remote machine where packets are transmitted from the remote machine to the client + /// machine uint16_t getRemoteMachinePort() const { return m_RemoteMachinePort; } - /** - * Search a PcapRemoteDevice in the list by its IPv4 address - * @param[in] ip4Addr The IPv4 address - * @return The PcapRemoteDevice if found, nullptr otherwise - */ + /// Search a PcapRemoteDevice in the list by its IPv4 address + /// @param[in] ip4Addr The IPv4 address + /// @return The PcapRemoteDevice if found, nullptr otherwise PcapRemoteDevice* getRemoteDeviceByIP(const IPv4Address& ip4Addr) const; - /** - * Search a PcapRemoteDevice in the list by its IPv6 address - * @param[in] ip6Addr The IPv6 address - * @return The PcapRemoteDevice if found, nullptr otherwise - */ + /// Search a PcapRemoteDevice in the list by its IPv6 address + /// @param[in] ip6Addr The IPv6 address + /// @return The PcapRemoteDevice if found, nullptr otherwise PcapRemoteDevice* getRemoteDeviceByIP(const IPv6Address& ip6Addr) const; - /** - * Search a PcapRemoteDevice in the list by its IP address (IPv4 or IPv6) - * @param[in] ipAddr The IP address - * @return The PcapRemoteDevice if found, nullptr otherwise - */ + /// Search a PcapRemoteDevice in the list by its IP address (IPv4 or IPv6) + /// @param[in] ipAddr The IP address + /// @return The PcapRemoteDevice if found, nullptr otherwise PcapRemoteDevice* getRemoteDeviceByIP(const IPAddress& ipAddr) const; - /** - * Search a PcapRemoteDevice in the list by its IP address - * @param[in] ipAddrAsString The IP address in string format - * @return The PcapRemoteDevice if found, nullptr otherwise - */ + /// Search a PcapRemoteDevice in the list by its IP address + /// @param[in] ipAddrAsString The IP address in string format + /// @return The PcapRemoteDevice if found, nullptr otherwise PcapRemoteDevice* getRemoteDeviceByIP(const std::string& ipAddrAsString) const; - /** - * @return An iterator object pointing to the first PcapRemoteDevice in list - */ + /// @return An iterator object pointing to the first PcapRemoteDevice in list RemoteDeviceListIterator begin() { return m_RemoteDeviceList.begin(); } - /** - * @return A const iterator object pointing to the first PcapRemoteDevice in list - */ + /// @return A const iterator object pointing to the first PcapRemoteDevice in list ConstRemoteDeviceListIterator begin() const { return m_RemoteDeviceList.begin(); } - /** - * @return An iterator object pointing to the last PcapRemoteDevice in list - */ + /// @return An iterator object pointing to the last PcapRemoteDevice in list RemoteDeviceListIterator end() { return m_RemoteDeviceList.end(); } - /** - * @return A const iterator object pointing to the last PcapRemoteDevice in list - */ + /// @return A const iterator object pointing to the last PcapRemoteDevice in list ConstRemoteDeviceListIterator end() const { return m_RemoteDeviceList.end(); } }; - } // namespace pcpp diff --git a/Pcap++/header/PcapUtils.h b/Pcap++/header/PcapUtils.h index 5942ad2c5d..7fefa0abed 100644 --- a/Pcap++/header/PcapUtils.h +++ b/Pcap++/header/PcapUtils.h @@ -6,25 +6,23 @@ typedef pcap pcap_t; struct pcap_if; typedef pcap_if pcap_if_t; +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { /// @cond PCPP_INTERNAL namespace internal { - /** - * @class PcapCloseDeleter - * A deleter that cleans up a pcap_t structure by calling pcap_close. - */ + /// @class PcapCloseDeleter + /// A deleter that cleans up a pcap_t structure by calling pcap_close. struct PcapCloseDeleter { void operator()(pcap_t* ptr) const; }; - /** - * @class PcapFreeAllDevsDeleter - * A deleter that frees an interface list of pcap_if_t ptr by calling 'pcap_freealldevs' function on it. - */ + /// @class PcapFreeAllDevsDeleter + /// A deleter that frees an interface list of pcap_if_t ptr by calling 'pcap_freealldevs' function on it. struct PcapFreeAllDevsDeleter { void operator()(pcap_if_t* ptr) const; diff --git a/Pcap++/header/PfRingDevice.h b/Pcap++/header/PfRingDevice.h index 18227f0a26..552d2d8a96 100644 --- a/Pcap++/header/PfRingDevice.h +++ b/Pcap++/header/PfRingDevice.h @@ -16,10 +16,8 @@ struct __pfring; typedef struct __pfring pfring; -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { @@ -28,10 +26,8 @@ namespace pcpp typedef void (*OnPfRingPacketsArriveCallback)(RawPacket* packets, uint32_t numOfPackets, uint8_t threadId, PfRingDevice* device, void* userCookie); - /** - * @class PfRingDevice - * A class representing a PF_RING port - */ + /// @class PfRingDevice + /// A class representing a PF_RING port class PfRingDevice : public IDevice, public IFilterableDevice { friend class PfRingDeviceList; @@ -84,293 +80,226 @@ namespace pcpp bool sendData(const uint8_t* packetData, int packetDataLength, bool flushTxQueues); public: - /** - * An enum representing the type of packet distribution between different RX channels - */ + /// An enum representing the type of packet distribution between different RX channels enum ChannelDistribution { - /** - * Packets are distributed between channels in a round-robin manner - */ + /// Packets are distributed between channels in a round-robin manner RoundRobin, - /** - * Packets are distributed between channels per flow (each flow goes for different channel) - */ + /// Packets are distributed between channels per flow (each flow goes for different channel) PerFlow }; - /** - * @struct PfRingStats - * A container for PfRingDevice statistics - */ + /// @struct PfRingStats + /// A container for PfRingDevice statistics struct PfRingStats { - /** Number of packets received */ + /// Number of packets received uint64_t recv; - /** Number of packets dropped */ + /// Number of packets dropped uint64_t drop; }; - /** - * A destructor for PfRingDevice class - */ + /// A destructor for PfRingDevice class ~PfRingDevice(); - /** - * Get the MAC address of the current device - * @return The MAC address of the current device - */ + /// Get the MAC address of the current device + /// @return The MAC address of the current device MacAddress getMacAddress() { setPfRingDeviceAttributes(); return m_MacAddress; } - /** - * Get PF_RING interface index of the current device - * @return PF_RING interface index of the current device - */ + /// Get PF_RING interface index of the current device + /// @return PF_RING interface index of the current device int getInterfaceIndex() { setPfRingDeviceAttributes(); return m_InterfaceIndex; } - /** - * Get MTU of the current device - * @return Upon success return the device MTU, 0 otherwise - */ + /// Get MTU of the current device + /// @return Upon success return the device MTU, 0 otherwise int getMtu() { setPfRingDeviceAttributes(); return m_DeviceMTU; } - /** - * Return true if device supports hardware timestamping. If it does, this feature will be automatically set - * for this device. You can read more about this in PF_RING documentation - * @return True if device supports hardware timestamping, false otherwise - */ + /// Return true if device supports hardware timestamping. If it does, this feature will be automatically set + /// for this device. You can read more about this in PF_RING documentation + /// @return True if device supports hardware timestamping, false otherwise bool isHwClockEnabledForDevice() { setPfRingDeviceAttributes(); return m_HwClockEnabled; } - /** - * Gets the interface name (e.g eth0, eth1, etc.) - * @return The interface name - */ + /// Gets the interface name (e.g eth0, eth1, etc.) + /// @return The interface name std::string getDeviceName() const { return m_DeviceName; } - /** - * Start single-threaded capturing with callback. Works with open() or openSingleRxChannel(). - * @param[in] onPacketsArrive A callback to call whenever a packet arrives - * @param[in] onPacketsArriveUserCookie A cookie that will be delivered to onPacketsArrive callback on every - * packet - * @return True if this action succeeds, false otherwise - */ + /// Start single-threaded capturing with callback. Works with open() or openSingleRxChannel(). + /// @param[in] onPacketsArrive A callback to call whenever a packet arrives + /// @param[in] onPacketsArriveUserCookie A cookie that will be delivered to onPacketsArrive callback on every + /// packet + /// @return True if this action succeeds, false otherwise bool startCaptureSingleThread(OnPfRingPacketsArriveCallback onPacketsArrive, void* onPacketsArriveUserCookie); - /** - * Start multi-threaded (multi-core) capturing with callback. Works with openMultiRxChannels(). - * This method will return an error if the number of opened channels is different than the number of - * threads/cores requested - * @param[in] onPacketsArrive A callback to call whenever a packet arrives - * @param[in] onPacketsArriveUserCookie A cookie that will be delivered to onPacketsArrive callback on every - * packet - * @param[in] coreMask The cores to be used as mask. For example: - * @return True if this action succeeds, false otherwise - */ + /// Start multi-threaded (multi-core) capturing with callback. Works with openMultiRxChannels(). + /// This method will return an error if the number of opened channels is different than the number of + /// threads/cores requested + /// @param[in] onPacketsArrive A callback to call whenever a packet arrives + /// @param[in] onPacketsArriveUserCookie A cookie that will be delivered to onPacketsArrive callback on every + /// packet + /// @param[in] coreMask The cores to be used as mask. For example: + /// @return True if this action succeeds, false otherwise bool startCaptureMultiThread(OnPfRingPacketsArriveCallback onPacketsArrive, void* onPacketsArriveUserCookie, CoreMask coreMask); - /** - * Stops capturing packets (works will all type of startCapture*) - */ + /// Stops capturing packets (works will all type of startCapture*) void stopCapture(); - /** - * Opens a single RX channel (=RX queue) on this interface. All packets will be received on a single thread - * without core affinity. If the channel ID requested doesn't exist on this interface, the method will fail - * (return false) - * @param[in] channelId The requested channel ID - * @return True if this action succeeds, false otherwise - */ + /// Opens a single RX channel (=RX queue) on this interface. All packets will be received on a single thread + /// without core affinity. If the channel ID requested doesn't exist on this interface, the method will fail + /// (return false) + /// @param[in] channelId The requested channel ID + /// @return True if this action succeeds, false otherwise bool openSingleRxChannel(uint8_t channelId); - /** - * Opens a set of RX channels (=RX queues) on this interface, identified by their IDs. All packets will be - * received on a single thread without core affinity. If one of the channel IDs requested doesn't exist on this - * interface, the method will fail (return false) - * @param[in] channelIds An array of channel IDs - * @param[in] numOfChannelIds The channel ID array size - * @return True if this action succeeds, false otherwise - */ + /// Opens a set of RX channels (=RX queues) on this interface, identified by their IDs. All packets will be + /// received on a single thread without core affinity. If one of the channel IDs requested doesn't exist on this + /// interface, the method will fail (return false) + /// @param[in] channelIds An array of channel IDs + /// @param[in] numOfChannelIds The channel ID array size + /// @return True if this action succeeds, false otherwise bool openMultiRxChannels(const uint8_t* channelIds, int numOfChannelIds); - /** - * Opens numOfRxChannelsToOpen RX channels. If numOfRxChannelsToOpen is larger than available RX queues for this - * interface than a number of RX channels will be opened on each RX queue. For example: if the user asks for 10 - * RX channels but the interface has only 4 RX queues, then 3 RX channels will be opened for RX-queue0 and - * RX-queue2, and 2 RX channels will be opened for RX-queue2 and RX-queue3. Packets will be distributed between - * different RX queues on per-flow manner, but within multiple RX channels in the same RX queue packet will be - * distributed according to distribution requested by "dist" - * @param[in] numOfRxChannelsToOpen Number of RX channels to open - * @param[in] dist Distribution method - * @return True if this action succeeds, false otherwise - */ + /// Opens numOfRxChannelsToOpen RX channels. If numOfRxChannelsToOpen is larger than available RX queues for + /// this interface than a number of RX channels will be opened on each RX queue. For example: if the user asks + /// for 10 RX channels but the interface has only 4 RX queues, then 3 RX channels will be opened for RX-queue0 + /// and RX-queue2, and 2 RX channels will be opened for RX-queue2 and RX-queue3. Packets will be distributed + /// between different RX queues on per-flow manner, but within multiple RX channels in the same RX queue packet + /// will be distributed according to distribution requested by "dist" + /// @param[in] numOfRxChannelsToOpen Number of RX channels to open + /// @param[in] dist Distribution method + /// @return True if this action succeeds, false otherwise bool openMultiRxChannels(uint8_t numOfRxChannelsToOpen, ChannelDistribution dist); - /** - * Gets the number of RX channels currently open. RX channels aren't necessary interface's RX queues - * because in some cases the user asks to open several channels on the same queue. For example: if the user uses - * openMultiRxChannels() and asks to open 8 channels but interface has only 4 RX queues, 2 channels will be - * opened for each RX queue - * @return Number of opened RX channels - */ + /// Gets the number of RX channels currently open. RX channels aren't necessary interface's RX queues + /// because in some cases the user asks to open several channels on the same queue. For example: if the user + /// uses openMultiRxChannels() and asks to open 8 channels but interface has only 4 RX queues, 2 channels will + /// be opened for each RX queue + /// @return Number of opened RX channels uint8_t getNumOfOpenedRxChannels() const { return m_NumOfOpenedRxChannels; } - /** - * Gets the total number of RX channels (RX queues) this interface has - * @return The number of RX channels (queues) for this interface - */ + /// Gets the total number of RX channels (RX queues) this interface has + /// @return The number of RX channels (queues) for this interface uint8_t getTotalNumOfRxChannels() const; - /** - * Gets the core used in the current thread context - * @return The system core used in the current thread context - */ + /// Gets the core used in the current thread context + /// @return The system core used in the current thread context static SystemCore getCurrentCoreId(); - /** - * Get the statistics of a specific thread/core (=RX channel) - * @param[in] core The requested core - * @param[out] stats A reference for the stats object where the stats are written. Current values will be - * overridden - */ + /// Get the statistics of a specific thread/core (=RX channel) + /// @param[in] core The requested core + /// @param[out] stats A reference for the stats object where the stats are written. Current values will be + /// overridden void getThreadStatistics(SystemCore core, PfRingStats& stats) const; - /** - * Get the statistics of the current thread/core (=RX channel) - * @param[out] stats A reference for the stats object where the stats are written. Current values will be - * overridden - */ + /// Get the statistics of the current thread/core (=RX channel) + /// @param[out] stats A reference for the stats object where the stats are written. Current values will be + /// overridden void getCurrentThreadStatistics(PfRingStats& stats) const; - /** - * Get the statistics for the entire device. If more than 1 RX channel is opened, this method aggregates the - * stats of all channels - * @param[out] stats A reference for the stats object where the stats are written. Current values will be - * overridden - */ + /// Get the statistics for the entire device. If more than 1 RX channel is opened, this method aggregates the + /// stats of all channels + /// @param[out] stats A reference for the stats object where the stats are written. Current values will be + /// overridden void getStatistics(PfRingStats& stats) const; - /** - * Return true if filter is currently set - * @return True if filter is currently set, false otherwise - */ + /// Return true if filter is currently set + /// @return True if filter is currently set, false otherwise bool isFilterCurrentlySet() const; - /** - * Send a raw packet. This packet must be fully specified (the MAC address up) - * and it will be transmitted as-is without any further manipulation. - * This method doesn't change or manipulate the data in any way (hence the "const" declaration). - * Note this method flushes the TX queues after the data is sent. So if you want to send several packets - * In the burst please use sendPackets() - * @param[in] rawPacket The raw packet to send - * @return True if raw packet was sent completely, false otherwise - */ + /// Send a raw packet. This packet must be fully specified (the MAC address up) + /// and it will be transmitted as-is without any further manipulation. + /// This method doesn't change or manipulate the data in any way (hence the "const" declaration). + /// Note this method flushes the TX queues after the data is sent. So if you want to send several packets + /// In the burst please use sendPackets() + /// @param[in] rawPacket The raw packet to send + /// @return True if raw packet was sent completely, false otherwise bool sendPacket(const RawPacket& rawPacket); - /** - * Send raw data. This data must be a valid and fully specified packet (the MAC address up); - * it will be transmitted as-is without any further manipulation. - * This method doesn't change or manipulate the data in any way (hence the "const" declaration). - * Note this method flushes the TX queues after the data is sent. So if you want to send several packets - * in the burst please use sendPackets() - * @param[in] packetData The raw data to send - * @param[in] packetDataLength the length of packetData - * @return True if raw packet was sent completely, false otherwise - * - */ + /// Send raw data. This data must be a valid and fully specified packet (the MAC address up); + /// it will be transmitted as-is without any further manipulation. + /// This method doesn't change or manipulate the data in any way (hence the "const" declaration). + /// Note this method flushes the TX queues after the data is sent. So if you want to send several packets + /// in the burst please use sendPackets() + /// @param[in] packetData The raw data to send + /// @param[in] packetDataLength the length of packetData + /// @return True if raw packet was sent completely, false otherwise bool sendPacket(const uint8_t* packetData, int packetDataLength); - /** - * Send a packet. This packet must be fully specified (the MAC address up) - * and it will be transmitted as-is without any further manipulation. - * This method doesn't change or manipulate the data in any way (hence the "const" declaration). - * Note this method flushes the TX queues after the data is sent. So if you want to send several packets - * In the burst please use sendPackets() - * @param[in] packet The packet to send - * @return True if raw packet was sent completely, false otherwise - */ + /// Send a packet. This packet must be fully specified (the MAC address up) + /// and it will be transmitted as-is without any further manipulation. + /// This method doesn't change or manipulate the data in any way (hence the "const" declaration). + /// Note this method flushes the TX queues after the data is sent. So if you want to send several packets + /// In the burst please use sendPackets() + /// @param[in] packet The packet to send + /// @return True if raw packet was sent completely, false otherwise bool sendPacket(const Packet& packet); - /** - * Send raw packets. All raw packets must be fully specified (the MAC address up) - * and it will be transmitted as-is without any further manipulation. - * This method doesn't change or manipulate the raw packets data in any way (hence the "const" declaration). - * This method flushes the TX queues only when the last packet is sent - * @param[in] rawPacketsArr The RawPacket array - * @param[in] arrLength RawPacket array length - * @return Number of packets that were sent completely - */ + /// Send raw packets. All raw packets must be fully specified (the MAC address up) + /// and it will be transmitted as-is without any further manipulation. + /// This method doesn't change or manipulate the raw packets data in any way (hence the "const" declaration). + /// This method flushes the TX queues only when the last packet is sent + /// @param[in] rawPacketsArr The RawPacket array + /// @param[in] arrLength RawPacket array length + /// @return Number of packets that were sent completely int sendPackets(const RawPacket* rawPacketsArr, int arrLength); - /** - * Send packets. All packets must be fully specified (the MAC address up) - * and it will be transmitted as-is without any further manipulation. - * This method doesn't change or manipulate the packets data in any way (hence the "const" declaration). - * This method flushes the TX queues only when the last packet is sent - * @param[in] packetsArr An array of pointers to Packet objects - * @param[in] arrLength Packet pointers array length - * @return Number of packets that were sent completely - */ + /// Send packets. All packets must be fully specified (the MAC address up) + /// and it will be transmitted as-is without any further manipulation. + /// This method doesn't change or manipulate the packets data in any way (hence the "const" declaration). + /// This method flushes the TX queues only when the last packet is sent + /// @param[in] packetsArr An array of pointers to Packet objects + /// @param[in] arrLength Packet pointers array length + /// @return Number of packets that were sent completely int sendPackets(const Packet** packetsArr, int arrLength); - /** - * Send all raw packets pointed by the RawPacketVector. All packets must be fully specified (the MAC address up) - * and it will be transmitted as-is without any further manipulation. - * This method doesn't change or manipulate the packets data in any way (hence the "const" declaration). - * This method flushes the TX queues only when the last packet is sent - * @param[in] rawPackets The raw packet vector - * @return Number of raw packets that were sent completely - */ + /// Send all raw packets pointed by the RawPacketVector. All packets must be fully specified (the MAC address + /// up) and it will be transmitted as-is without any further manipulation. This method doesn't change or + /// manipulate the packets data in any way (hence the "const" declaration). This method flushes the TX queues + /// only when the last packet is sent + /// @param[in] rawPackets The raw packet vector + /// @return Number of raw packets that were sent completely int sendPackets(const RawPacketVector& rawPackets); // implement abstract methods - /** - * Opens the entire device (including all RX channels/queues on this interface). All packets will be received - * on a single thread without core affinity - * @return True if this action succeeds, false otherwise - */ + /// Opens the entire device (including all RX channels/queues on this interface). All packets will be received + /// on a single thread without core affinity + /// @return True if this action succeeds, false otherwise bool open(); - /** - * Closes all RX channels currently opened in device - */ + /// Closes all RX channels currently opened in device void close(); using IFilterableDevice::setFilter; - /** - * Sets a BPF filter to the device - * @param[in] filterAsString The BPF filter in string format - */ + /// 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 - */ + /// Remove a filter if currently set + /// @return True if filter was removed successfully or if no filter was set, false otherwise bool clearFilter(); }; diff --git a/Pcap++/header/PfRingDeviceList.h b/Pcap++/header/PfRingDeviceList.h index f38928ad1a..6e364c59e6 100644 --- a/Pcap++/header/PfRingDeviceList.h +++ b/Pcap++/header/PfRingDeviceList.h @@ -6,18 +6,13 @@ /// @file -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class PfRingDeviceList - * A singleton class that holds all available PF_RING devices. Through this class the user can iterate all PF_RING - * devices or find a specific device by name - */ + /// @class PfRingDeviceList + /// A singleton class that holds all available PF_RING devices. Through this class the user can iterate all PF_RING + /// devices or find a specific device by name class PfRingDeviceList { private: @@ -33,36 +28,28 @@ namespace pcpp PfRingDeviceList& operator=(const PfRingDeviceList&) = delete; PfRingDeviceList& operator=(PfRingDeviceList&&) noexcept = delete; - /** - * A static method that returns the singleton object for PfRingDeviceList - * @return PfRingDeviceList singleton - */ + /// A static method that returns the singleton object for PfRingDeviceList + /// @return PfRingDeviceList singleton static PfRingDeviceList& getInstance() { static PfRingDeviceList instance; return instance; } - /** - * Return a list of all available PF_RING devices - * @return a list of all available PF_RING devices - */ + /// Return a list of all available PF_RING devices + /// @return a list of all available PF_RING devices const std::vector& getPfRingDevicesList() const { return m_PfRingDeviceListView; } - /** - * Get a PF_RING device by name. The name is the Linux interface name which appears in ifconfig - * (e.g eth0, eth1, etc.) - * @return A pointer to the PF_RING device - */ + /// Get a PF_RING device by name. The name is the Linux interface name which appears in ifconfig + /// (e.g eth0, eth1, etc.) + /// @return A pointer to the PF_RING device PfRingDevice* getPfRingDeviceByName(const std::string& devName) const; - /** - * Get installed PF_RING version - * @return A string representing PF_RING version - */ + /// Get installed PF_RING version + /// @return A string representing PF_RING version std::string getPfRingVersion() const { return m_PfRingVersion; diff --git a/Pcap++/header/RawSocketDevice.h b/Pcap++/header/RawSocketDevice.h index 254af4e186..8b69c84d87 100644 --- a/Pcap++/header/RawSocketDevice.h +++ b/Pcap++/header/RawSocketDevice.h @@ -5,144 +5,123 @@ #include "IpAddress.h" #include "Device.h" -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - /** - * @class RawSocketDevice - * A class that wraps the raw socket functionality. A raw socket is a network socket that allows direct sending and - * receiving of IP packets without any protocol-specific transport layer formatting (taken from Wikipedia: - * https://en.wikipedia.org/wiki/Network_socket#Raw_socket). This wrapper class enables creation of a raw socket, - * binding it to a network interface, and then receiving and sending packets on it. Current implementation supports - * only Windows and Linux because other platforms provide poor support for raw sockets making them practically - * unusable. There are also major differences between Linux and Windows in raw socket implementation, let's mention - * some of the: - * - On Windows administrative privileges are required for raw sockets creation, meaning the process running the - * code has to have these privileges. In Linux 'sudo' is required - * - On Windows raw sockets are implemented in L3, meaning the L2 (Ethernet) layer is omitted by the socket and - * only L3 and up are visible to the user. On Linux raw sockets are implemented on L2, meaning all layers - * (including the Ethernet data) are visible to the user. - * - On Windows sending packets is not supported, a raw socket can only receive packets. On Linux both send and - * receive are supported - * - Linux doesn't require binding to a specific network interface for receiving packets, but it does require - * binding for sending packets. Windows requires binding for receiving packets. For the sake of keeping a unified - * and simple cross-platform interface this class requires binding for both Linux and Windows, on both send and - * receive - * - * More details about opening the raw socket, receiving and sending packets are explained in the corresponding class - * methods. Raw sockets are supported for both IPv4 and IPv6, so you can create and bind raw sockets to each of the - * two. Also, there is no limit on the number of sockets opened for a specific IP address or network interface, so - * you can create multiple instances of this class and bind all of them to the same interface and IP address. - */ + /// @class RawSocketDevice + /// A class that wraps the raw socket functionality. A raw socket is a network socket that allows direct sending and + /// receiving of IP packets without any protocol-specific transport layer formatting (taken from Wikipedia: + /// https://en.wikipedia.org/wiki/Network_socket#Raw_socket). This wrapper class enables creation of a raw socket, + /// binding it to a network interface, and then receiving and sending packets on it. Current implementation supports + /// only Windows and Linux because other platforms provide poor support for raw sockets making them practically + /// unusable. There are also major differences between Linux and Windows in raw socket implementation, let's mention + /// some of the: + /// - On Windows administrative privileges are required for raw sockets creation, meaning the process running the + /// code has to have these privileges. In Linux 'sudo' is required + /// - On Windows raw sockets are implemented in L3, meaning the L2 (Ethernet) layer is omitted by the socket and + /// only L3 and up are visible to the user. On Linux raw sockets are implemented on L2, meaning all layers + /// (including the Ethernet data) are visible to the user. + /// - On Windows sending packets is not supported, a raw socket can only receive packets. On Linux both send and + /// receive are supported + /// - Linux doesn't require binding to a specific network interface for receiving packets, but it does require + /// binding for sending packets. Windows requires binding for receiving packets. For the sake of keeping a + /// unified and simple cross-platform interface this class requires binding for both Linux and Windows, on both + /// send and receive + /// + /// More details about opening the raw socket, receiving and sending packets are explained in the corresponding + /// class methods. Raw sockets are supported for both IPv4 and IPv6, so you can create and bind raw sockets to each + /// of the two. Also, there is no limit on the number of sockets opened for a specific IP address or network + /// interface, so you can create multiple instances of this class and bind all of them to the same interface and IP + /// address. class RawSocketDevice : public IDevice { public: - /** - * An enum for reporting packet receive results - */ + /// An enum for reporting packet receive results enum RecvPacketResult { - /** Receive success */ + /// Receive success RecvSuccess = 0, - /** Receive timeout - timeout expired without any packets being captured */ + /// Receive timeout - timeout expired without any packets being captured RecvTimeout = 1, - /** Receive would block - in non-blocking mode if there are no packets in the rx queue the receive method - * will return immediately with this return value */ + /// Receive would block - in non-blocking mode if there are no packets in the rx queue the receive method + /// will return immediately with this return value RecvWouldBlock = 2, - /** Receive error, usually will be followed by an error log */ + /// Receive error, usually will be followed by an error log RecvError = 3 }; - /* - * A c'tor for this class. This c'tor doesn't create the raw socket, but rather initializes internal structures. - * The actual raw socket creation is done in the open() method. Each raw socket is bound to a network interface - * which means packets will be received and sent from only from this network interface only - * @param[in] interfaceIP The network interface IP to bind the raw socket to. It can be either an IPv4 or IPv6 - * address (both are supported in raw sockets) - */ + /// A c'tor for this class. This c'tor doesn't create the raw socket, but rather initializes internal + /// structures. The actual raw socket creation is done in the open() method. Each raw socket is bound to a + /// network interface which means packets will be received and sent from only from this network interface only + /// @param[in] interfaceIP The network interface IP to bind the raw socket to. It can be either an IPv4 or IPv6 + /// address (both are supported in raw sockets) explicit RawSocketDevice(const IPAddress& interfaceIP); - /** - * A d'tor for this class. It closes the raw socket if not previously closed by calling close() - */ + /// A d'tor for this class. It closes the raw socket if not previously closed by calling close() ~RawSocketDevice(); - /** - * Receive a packet on the raw socket. This method has several modes of operation: - * - Blocking/non-blocking - in blocking mode the method will not return until a packet is received on the - * socket or until the timeout expires. In non-blocking mode it will return immediately and in case no - * packets are on the receive queue RawSocketDevice#RecvWouldBlock will be returned. Unless specified - * otherwise, the default value is blocking mode - * - Receive timeout - in blocking mode, the user can set a timeout to wait until a packet is received. If the - * timeout expires and no packets were received, the method will return RawSocketDevice#RecvTimeout. The - * default value is a negative value which means no timeout - * - * There is a slight difference on this method's behavior between Windows and Linux around how packets are - * received. On Linux the received packet contains all layers starting from the L2 (Ethernet). However on - * Windows raw socket are integrated in L3 level so the received packet contains only L3 (IP) layer and up. - * @param[out] rawPacket An empty packet instance where the received packet data will be written to - * @param[in] blocking Indicates whether to run in blocking or non-blocking mode. Default value is blocking - * @param[in] timeout When in blocking mode, specifies the timeout [in seconds] to wait for a packet. If timeout - * expired and no packets were captured the method will return RawSocketDevice#RecvTimeout. Zero or negative - * values mean no timeout. The default value is no timeout. The timeout precision is in milliseconds, for - * example a timeout of 0.123 means 123 milliseconds. - * @return The method returns one on the following values: - * - RawSocketDevice#RecvSuccess is returned if a packet was received successfully - * - RawSocketDevice#RecvTimeout is returned if in blocking mode and timeout expired - * - RawSocketDevice#RecvWouldBlock is returned if in non-blocking mode and no packets were captured - * - RawSocketDevice#RecvError is returned if an error occurred such as device is not opened or the recv - * operation returned some error. A log message will be followed specifying the error and error code - */ + /// Receive a packet on the raw socket. This method has several modes of operation: + /// - Blocking/non-blocking - in blocking mode the method will not return until a packet is received on the + /// socket or until the timeout expires. In non-blocking mode it will return immediately and in case no + /// packets are on the receive queue RawSocketDevice#RecvWouldBlock will be returned. Unless specified + /// otherwise, the default value is blocking mode + /// - Receive timeout - in blocking mode, the user can set a timeout to wait until a packet is received. If the + /// timeout expires and no packets were received, the method will return RawSocketDevice#RecvTimeout. The + /// default value is a negative value which means no timeout + /// + /// There is a slight difference on this method's behavior between Windows and Linux around how packets are + /// received. On Linux the received packet contains all layers starting from the L2 (Ethernet). However on + /// Windows raw socket are integrated in L3 level so the received packet contains only L3 (IP) layer and up. + /// @param[out] rawPacket An empty packet instance where the received packet data will be written to + /// @param[in] blocking Indicates whether to run in blocking or non-blocking mode. Default value is blocking + /// @param[in] timeout When in blocking mode, specifies the timeout [in seconds] to wait for a packet. If + /// timeout expired and no packets were captured the method will return RawSocketDevice#RecvTimeout. Zero or + /// negative values mean no timeout. The default value is no timeout. The timeout precision is in milliseconds, + /// for example a timeout of 0.123 means 123 milliseconds. + /// @return The method returns one on the following values: + /// - RawSocketDevice#RecvSuccess is returned if a packet was received successfully + /// - RawSocketDevice#RecvTimeout is returned if in blocking mode and timeout expired + /// - RawSocketDevice#RecvWouldBlock is returned if in non-blocking mode and no packets were captured + /// - RawSocketDevice#RecvError is returned if an error occurred such as device is not opened or the recv + /// operation returned some error. A log message will be followed specifying the error and error code RecvPacketResult receivePacket(RawPacket& rawPacket, bool blocking = true, double timeout = -1); - /** - * Receive packets into a packet vector for a certain amount of time. This method starts a timer and invokes the - * receivePacket() method in blocking mode repeatedly until the timeout expires. All packets received - * successfully are put into a packet vector - * @param[out] packetVec The packet vector to add the received packet to - * @param[in] timeout Timeout in seconds to receive packets on the raw socket. The timeout precision is in - * milliseconds, for example a timeout of 0.123 means 123 milliseconds. - * @param[out] failedRecv Number of receive attempts that failed - * @return The number of packets received successfully - */ + /// Receive packets into a packet vector for a certain amount of time. This method starts a timer and invokes + /// the receivePacket() method in blocking mode repeatedly until the timeout expires. All packets received + /// successfully are put into a packet vector + /// @param[out] packetVec The packet vector to add the received packet to + /// @param[in] timeout Timeout in seconds to receive packets on the raw socket. The timeout precision is in + /// milliseconds, for example a timeout of 0.123 means 123 milliseconds. + /// @param[out] failedRecv Number of receive attempts that failed + /// @return The number of packets received successfully int receivePackets(RawPacketVector& packetVec, double timeout, int& failedRecv); - /** - * Send an Ethernet packet to the network. L2 protocols other than Ethernet are not supported in raw sockets. - * The entire packet is sent as is, including the original Ethernet and IP data. - * This method is only supported in Linux as Windows doesn't allow sending packets from raw sockets. Using - * it from other platforms will also return "false" with a corresponding error log message - * @param[in] rawPacket The packet to send - * @return True if packet was sent successfully or false if the socket is not open, if the packet is not - * Ethernet or if there was a failure sending the packet - */ + /// Send an Ethernet packet to the network. L2 protocols other than Ethernet are not supported in raw sockets. + /// The entire packet is sent as is, including the original Ethernet and IP data. + /// This method is only supported in Linux as Windows doesn't allow sending packets from raw sockets. Using + /// it from other platforms will also return "false" with a corresponding error log message + /// @param[in] rawPacket The packet to send + /// @return True if packet was sent successfully or false if the socket is not open, if the packet is not + /// Ethernet or if there was a failure sending the packet bool sendPacket(const RawPacket* rawPacket); - /** - * Send a set of Ethernet packets to the network. L2 protocols other than Ethernet are not supported by raw - * sockets. The entire packet is sent as is, including the original Ethernet and IP data. This method is only - * supported in Linux as Windows doesn't allow sending packets from raw sockets. Using it from other platforms - * will return "false" with an appropriate error log message - * @param[in] packetVec The set of packets to send - * @return The number of packets sent successfully. For packets that weren't sent successfully there will be a - * corresponding error message printed to log - */ + /// Send a set of Ethernet packets to the network. L2 protocols other than Ethernet are not supported by raw + /// sockets. The entire packet is sent as is, including the original Ethernet and IP data. This method is only + /// supported in Linux as Windows doesn't allow sending packets from raw sockets. Using it from other platforms + /// will return "false" with an appropriate error log message + /// @param[in] packetVec The set of packets to send + /// @return The number of packets sent successfully. For packets that weren't sent successfully there will be a + /// corresponding error message printed to log int sendPackets(const RawPacketVector& packetVec); // overridden methods - /** - * Open the device by creating a raw socket and binding it to the network interface specified in the c'tor - * @return True if device was opened successfully, false otherwise with a corresponding error log message - */ + /// Open the device by creating a raw socket and binding it to the network interface specified in the c'tor + /// @return True if device was opened successfully, false otherwise with a corresponding error log message bool open() override; - /** - * Close the raw socket - */ + /// Close the raw socket void close() override; private: diff --git a/Pcap++/header/WinPcapLiveDevice.h b/Pcap++/header/WinPcapLiveDevice.h index c199428e32..7b91c9b877 100644 --- a/Pcap++/header/WinPcapLiveDevice.h +++ b/Pcap++/header/WinPcapLiveDevice.h @@ -4,20 +4,15 @@ #include "PcapLiveDevice.h" -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @brief The main namespace for the PcapPlusPlus lib namespace pcpp { - - /** - * @class WinPcapLiveDevice - * A class that wraps a Windows network interface (each of the interfaces listed in ipconfig). - * This class is almost similar in its capabilities to PcapLiveDevice (its parent class) with some small changes - * that mainly result from differences between libpcap and WinPcap/Npcap. Please see the reference for - * PcapLiveDevice for more details - */ + /// @class WinPcapLiveDevice + /// A class that wraps a Windows network interface (each of the interfaces listed in ipconfig). + /// This class is almost similar in its capabilities to PcapLiveDevice (its parent class) with some small changes + /// that mainly result from differences between libpcap and WinPcap/Npcap. Please see the reference for + /// PcapLiveDevice for more details class WinPcapLiveDevice : public PcapLiveDevice { friend class PcapLiveDeviceList; @@ -55,20 +50,16 @@ namespace pcpp using PcapLiveDevice::sendPackets; virtual int sendPackets(RawPacket* rawPacketsArr, int arrLength); - /** - * WinPcap/Npcap have a feature (that doesn't exist in libpcap) to change the minimum amount of data in the - * kernel buffer that causes a read from the application to return (unless the timeout expires). Please see - * documentation for pcap_setmintocopy for more info. This method enables the user to change this size. Note the - * device must be open for this method to work - * @param[in] size The size to set in bytes - * @return True if set succeeded, false if the device is closed or if pcap_setmintocopy failed - */ + /// WinPcap/Npcap have a feature (that doesn't exist in libpcap) to change the minimum amount of data in the + /// kernel buffer that causes a read from the application to return (unless the timeout expires). Please see + /// documentation for pcap_setmintocopy for more info. This method enables the user to change this size. Note + /// the device must be open for this method to work + /// @param[in] size The size to set in bytes + /// @return True if set succeeded, false if the device is closed or if pcap_setmintocopy failed bool setMinAmountOfDataToCopyFromKernelToApplication(int size); - /** - * @return The current amount of data in the kernel buffer that causes a read from the application to return - * (see also setMinAmountOfDataToCopyFromKernelToApplication()) - */ + /// @return The current amount of data in the kernel buffer that causes a read from the application to return + /// (see also setMinAmountOfDataToCopyFromKernelToApplication()) int getMinAmountOfDataToCopyFromKernelToApplication() const { return m_MinAmountOfDataToCopyFromKernelToApplication; @@ -76,5 +67,4 @@ namespace pcpp WinPcapLiveDevice* clone() const override; }; - } // namespace pcpp diff --git a/Pcap++/header/XdpDevice.h b/Pcap++/header/XdpDevice.h index 7e573e2304..e60498d505 100644 --- a/Pcap++/header/XdpDevice.h +++ b/Pcap++/header/XdpDevice.h @@ -6,112 +6,86 @@ #include #include -/** - * \namespace pcpp - * \brief The main namespace for the PcapPlusPlus lib - */ +/// @namespace pcpp +/// @ namespace pcpp { - /** - * @class XdpDevice - * A class wrapping the main functionality of using AF_XDP (XSK) sockets - * which are optimized for high performance packet processing. - * - * It provides methods for configuring and initializing an AF_XDP socket, and then send and receive packets through - * it. It also provides a method for gathering statistics from the socket. - */ + /// @class XdpDevice + /// A class wrapping the main functionality of using AF_XDP (XSK) sockets + /// which are optimized for high performance packet processing. + /// + /// It provides methods for configuring and initializing an AF_XDP socket, and then send and receive packets through + /// it. It also provides a method for gathering statistics from the socket. class XdpDevice : public IDevice { public: - /** - * @typedef OnPacketsArrive - * The callback that is called whenever packets are received on the socket - * @param[in] packets An array of the raw packets received - * @param[in] packetCount The number of packets received - * @param[in] device The XdpDevice packets are received from (represents the AF_XDP socket) - * @param[in] userCookie A pointer to an object set by the user when receivePackets() started - */ + /// @typedef OnPacketsArrive + /// The callback that is called whenever packets are received on the socket + /// @param[in] packets An array of the raw packets received + /// @param[in] packetCount The number of packets received + /// @param[in] device The XdpDevice packets are received from (represents the AF_XDP socket) + /// @param[in] userCookie A pointer to an object set by the user when receivePackets() started typedef void (*OnPacketsArrive)(RawPacket packets[], uint32_t packetCount, XdpDevice* device, void* userCookie); - /** - * @struct XdpDeviceConfiguration - * A struct containing the configuration parameters available for opening an XDP device - */ + /// @struct XdpDeviceConfiguration + /// A struct containing the configuration parameters available for opening an XDP device struct XdpDeviceConfiguration { - /** - * @enum AttachMode - * AF_XDP operation mode - */ + /// @enum AttachMode + /// AF_XDP operation mode enum AttachMode { - /** A fallback mode that works for any network device. Use it if the network driver doesn't have support - * for XDP */ + /// A fallback mode that works for any network device. Use it if the network driver doesn't have support + /// for XDP SkbMode = 1, - /** Use this mode if the network driver has support for XDP */ + /// Use this mode if the network driver has support for XDP DriverMode = 2, - /** Automatically detect whether driver mode is supported, otherwise fallback to SKB mode */ + /// Automatically detect whether driver mode is supported, otherwise fallback to SKB mode AutoMode = 3 }; - /** AF_XDP operation mode */ + /// AF_XDP operation mode AttachMode attachMode; - /** - * UMEM is a region of virtual contiguous memory, divided into equal-sized frames. - * This parameter determines the number of frames that will be allocated as pert of the UMEM. - **/ + /// UMEM is a region of virtual contiguous memory, divided into equal-sized frames. + /// This parameter determines the number of frames that will be allocated as pert of the UMEM. uint16_t umemNumFrames; - /** - * UMEM is a region of virtual contiguous memory, divided into equal-sized frames. - * This parameter determines the frame size that will be allocated. - * NOTE: the frame size should be equal to the memory page size (use getpagesize() to determine this size) - **/ + /// UMEM is a region of virtual contiguous memory, divided into equal-sized frames. + /// This parameter determines the frame size that will be allocated. + /// NOTE: the frame size should be equal to the memory page size (use getpagesize() to determine this size) uint16_t umemFrameSize; - /** - * The size of the fill ring used by the AF_XDP socket. This size should be a power of two - * and less or equal to the total number of UMEM frames - */ + /// The size of the fill ring used by the AF_XDP socket. This size should be a power of two + /// and less or equal to the total number of UMEM frames uint32_t fillRingSize; - /** - * The size of the completion ring used by the AF_XDP socket. This size should be a power of two - * and less or equal to the total number of UMEM frames - */ + /// The size of the completion ring used by the AF_XDP socket. This size should be a power of two + /// and less or equal to the total number of UMEM frames uint32_t completionRingSize; - /** - * The size of the RX ring used by the AF_XDP socket. This size should be a power of two - * and less or equal to the total number of UMEM frames - */ + /// The size of the RX ring used by the AF_XDP socket. This size should be a power of two + /// and less or equal to the total number of UMEM frames uint32_t rxSize; - /** - * The size of the TX ring used by the AF_XDP socket. This size should be a power of two - * and less or equal to the total number of UMEM frames - */ + /// The size of the TX ring used by the AF_XDP socket. This size should be a power of two + /// and less or equal to the total number of UMEM frames uint32_t txSize; - /** - * The max number of packets to be received or sent in one batch - */ + /// The max number of packets to be received or sent in one batch uint16_t rxTxBatchSize; - /** - * A c'tor for this struct. Each parameter has a default value described below. - * @param[in] attachMode AF_XDP operation mode. The default value is auto mode - * @param[in] umemNumFrames Number of UMEM frames to allocate. The default value is 4096 - * @param[in] umemFrameSize The size of each UMEM frame. The default value is equal to getpagesize() - * @param[in] fillRingSize The size of the fill ring used by the AF_XDP socket. The default value is 4096 - * @param[in] completionRingSize The size of the completion ring used by the AF_XDP socket. The default - * value is 2048 - * @param[in] rxSize The size of the RX ring used by the AF_XDP socket. The default value is 2048 - * @param[in] txSize The size of the TX ring used by the AF_XDP socket. The default value is 2048 - * @param[in] rxTxBatchSize The max number of packets to be received or sent in one batch. The default value - * is 64 - */ + /// A c'tor for this struct. Each parameter has a default value described below. + /// @param[in] attachMode AF_XDP operation mode. The default value is auto mode + /// @param[in] umemNumFrames Number of UMEM frames to allocate. The default value is 4096 + /// @param[in] umemFrameSize The size of each UMEM frame. The default value is equal to getpagesize() + /// @param[in] fillRingSize The size of the fill ring used by the AF_XDP socket. The default value is 4096 + /// @param[in] completionRingSize The size of the completion ring used by the AF_XDP socket. The default + /// value is 2048 + /// @param[in] rxSize The size of the RX ring used by the AF_XDP socket. The default value is 2048 + /// @param[in] txSize The size of the TX ring used by the AF_XDP socket. The default value is 2048 + /// @param[in] rxTxBatchSize The max number of packets to be received or sent in one batch. The default + /// value is 64 explicit XdpDeviceConfiguration(AttachMode attachMode = AutoMode, uint16_t umemNumFrames = 0, uint16_t umemFrameSize = 0, uint32_t fillRingSize = 0, uint32_t completionRingSize = 0, uint32_t rxSize = 0, uint32_t txSize = 0, @@ -128,156 +102,133 @@ namespace pcpp } }; - /** - * @struct XdpDeviceStats - * A container for XDP device statistics - */ + /// @struct XdpDeviceStats + /// A container for XDP device statistics struct XdpDeviceStats { - /** The timestamp when the stats were collected */ + /// The timestamp when the stats were collected timespec timestamp; - /** Number of packets received */ + /// Number of packets received uint64_t rxPackets; - /** Packets received per second. Measured from to the previous time stats were collected */ + /// Packets received per second. Measured from to the previous time stats were collected uint64_t rxPacketsPerSec; - /** Number of bytes received */ + /// Number of bytes received uint64_t rxBytes; - /** Bytes per second received. Measured from to the previous time stats were collected */ + /// Bytes per second received. Measured from to the previous time stats were collected uint64_t rxBytesPerSec; - /** Total number of dropped RX packets */ + /// Total number of dropped RX packets uint64_t rxDroppedTotalPackets; - /** RX packets dropped due to invalid descriptor */ + /// RX packets dropped due to invalid descriptor uint64_t rxDroppedInvalidPackets; - /** RX packets dropped due to RX ring being full */ + /// RX packets dropped due to RX ring being full uint64_t rxDroppedRxRingFullPackets; - /** Failed RX packets to retrieve item from fill ring */ + /// Failed RX packets to retrieve item from fill ring uint64_t rxDroppedFillRingPackets; - /** Number of poll() timeouts */ + /// Number of poll() timeouts uint64_t rxPollTimeout; - /** Number of packets sent from the application */ + /// Number of packets sent from the application uint64_t txSentPackets; - /** Packets sent from the app per second. Measured from to the previous time stats were collected */ + /// Packets sent from the app per second. Measured from to the previous time stats were collected uint64_t txSentPacketsPerSec; - /** Number of bytes sent from the application */ + /// Number of bytes sent from the application uint64_t txSentBytes; - /** Bytes per second sent from the app. Measured from to the previous time stats were collected */ + /// Bytes per second sent from the app. Measured from to the previous time stats were collected uint64_t txSentBytesPerSec; - /** Number of completed sent packets, meaning packets that were confirmed as sent by the kernel */ + /// Number of completed sent packets, meaning packets that were confirmed as sent by the kernel uint64_t txCompletedPackets; - /** Completed sent packets per second. Measured from to the previous time stats were collected */ + /// Completed sent packets per second. Measured from to the previous time stats were collected uint64_t txCompletedPacketsPerSec; - /** TX packets dropped due to invalid descriptor */ + /// TX packets dropped due to invalid descriptor uint64_t txDroppedInvalidPackets; - /** Current RX ring ID */ + /// Current RX ring ID uint64_t rxRingId; - /** Current TX ring ID */ + /// Current TX ring ID uint64_t txRingId; - /** Current fill ring ID */ + /// Current fill ring ID uint64_t fqRingId; - /** Current completion ring ID */ + /// Current completion ring ID uint64_t cqRingId; - /** Number of UMEM frames that are currently in-use (allocated) */ + /// Number of UMEM frames that are currently in-use (allocated) uint64_t umemAllocatedFrames; - /** Number of UMEM frames that are currently free (not allocated) */ + /// Number of UMEM frames that are currently free (not allocated) uint64_t umemFreeFrames; }; - /** - * A c'tor for this class. Please note that calling this c'tor doesn't initialize the AF_XDP socket. In order to - * set up the socket call open(). - * @param[in] interfaceName The interface name to open the AF_XDP socket on - */ + /// A c'tor for this class. Please note that calling this c'tor doesn't initialize the AF_XDP socket. In order + /// to set up the socket call open(). + /// @param[in] interfaceName The interface name to open the AF_XDP socket on explicit XdpDevice(std::string interfaceName); - /** - * A d'tor for this class. It closes the device if it's open. - */ + /// A d'tor for this class. It closes the device if it's open. ~XdpDevice() override; - /** - * Open the device with default configuration. Call getConfig() after opening the device to get the - * current configuration. - * This method initializes the UMEM, and then creates and configures the AF_XDP socket. If it succeeds the - * socket is ready to receive and send packets. - * @return True if device was opened successfully, false otherwise - */ + /// Open the device with default configuration. Call getConfig() after opening the device to get the + /// current configuration. + /// This method initializes the UMEM, and then creates and configures the AF_XDP socket. If it succeeds the + /// socket is ready to receive and send packets. + /// @return True if device was opened successfully, false otherwise bool open() override; - /** - * Open the device with custom configuration set by the user. - * This method initializes the UMEM, and then creates and configures the AF_XDP socket. If it succeeds the - * socket is ready to receive and send packets. - * @param[in] config The configuration to use for opening the device - * @return True if device was opened successfully, false otherwise - */ + /// Open the device with custom configuration set by the user. + /// This method initializes the UMEM, and then creates and configures the AF_XDP socket. If it succeeds the + /// socket is ready to receive and send packets. + /// @param[in] config The configuration to use for opening the device + /// @return True if device was opened successfully, false otherwise bool open(const XdpDeviceConfiguration& config); - /** - * Close the device. This method closes the AF_XDP socket and frees the UMEM that was allocated for it. - */ + /// Close the device. This method closes the AF_XDP socket and frees the UMEM that was allocated for it. void close() override; - /** - * Start receiving packets. In order to use this method the device should be open. Note that this method is - * blocking and will return if: - * - stopReceivePackets() was called from within the user callback - * - timeoutMS passed without receiving any packets - * - Some error occurred (an error log will be printed) - * @param[in] onPacketsArrive A callback to be called when packets are received - * @param[in] onPacketsArriveUserCookie The callback is invoked with this cookie as a parameter. It can be used - * to pass information from the user application to the callback - * @param[in] timeoutMS Timeout in milliseconds to stop if no packets are received. The default value is 5000 ms - * @return True if stopped receiving packets because stopReceivePackets() was called or because timeoutMS - * passed, or false if an error occurred. - */ + /// Start receiving packets. In order to use this method the device should be open. Note that this method is + /// blocking and will return if: + /// - stopReceivePackets() was called from within the user callback + /// - timeoutMS passed without receiving any packets + /// - Some error occurred (an error log will be printed) + /// @param[in] onPacketsArrive A callback to be called when packets are received + /// @param[in] onPacketsArriveUserCookie The callback is invoked with this cookie as a parameter. It can be used + /// to pass information from the user application to the callback + /// @param[in] timeoutMS Timeout in milliseconds to stop if no packets are received. The default value is 5000 + /// ms + /// @return True if stopped receiving packets because stopReceivePackets() was called or because timeoutMS + /// passed, or false if an error occurred. bool receivePackets(OnPacketsArrive onPacketsArrive, void* onPacketsArriveUserCookie, int timeoutMS = 5000); - /** - * Stop receiving packets. Call this method from within the callback passed to receivePackets() whenever you - * want to stop receiving packets. - */ + /// Stop receiving packets. Call this method from within the callback passed to receivePackets() whenever you + /// want to stop receiving packets. void stopReceivePackets(); - /** - * Send a vector of packet pointers. - * @param[in] packets A vector of packet pointers to send - * @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true - * this method will wait until the number of packets in the completion ring is equal or greater to the number - * of packets that were sent. The default value is false - * @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with - * this timeout. The default value is 5000 ms - * @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. - * Returns false if an error occurred or if poll timed out. - */ + /// Send a vector of packet pointers. + /// @param[in] packets A vector of packet pointers to send + /// @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true + /// this method will wait until the number of packets in the completion ring is equal or greater to the number + /// of packets that were sent. The default value is false + /// @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with + /// this timeout. The default value is 5000 ms + /// @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. + /// Returns false if an error occurred or if poll timed out. bool sendPackets(const RawPacketVector& packets, bool waitForTxCompletion = false, int waitForTxCompletionTimeoutMS = 5000); - /** - * Send an array of packets. - * @param[in] packets An array of raw packets to send - * @param[in] packetCount The length of the packet array - * @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true - * this method will wait until the number of packets in the completion ring is equal or greater to the number - * of packets sent. The default value is false - * @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with - * this timeout. The default value is 5000 ms - * @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. - * Returns false if an error occurred or if poll timed out. - */ + /// Send an array of packets. + /// @param[in] packets An array of raw packets to send + /// @param[in] packetCount The length of the packet array + /// @param[in] waitForTxCompletion Wait for confirmation from the kernel that packets were sent. If set to true + /// this method will wait until the number of packets in the completion ring is equal or greater to the number + /// of packets sent. The default value is false + /// @param[in] waitForTxCompletionTimeoutMS If waitForTxCompletion is set to true, poll the completion ring with + /// this timeout. The default value is 5000 ms + /// @return True if all packets were sent, or if waitForTxCompletion is true - all sent packets were confirmed. + /// Returns false if an error occurred or if poll timed out. bool sendPackets(RawPacket packets[], size_t packetCount, bool waitForTxCompletion = false, int waitForTxCompletionTimeoutMS = 5000); - /** - * @return A pointer to the current device configuration. If the device is not open this method returns nullptr - */ + /// @return A pointer to the current device configuration. If the device is not open this method returns nullptr XdpDeviceConfiguration* getConfig() const { return m_Config; } - /** - * @return Current device statistics - */ + /// @return Current device statistics XdpDeviceStats getStatistics(); private: diff --git a/Pcap++/src/DpdkDevice.cpp b/Pcap++/src/DpdkDevice.cpp index 7aa7b7e171..fadf38de76 100644 --- a/Pcap++/src/DpdkDevice.cpp +++ b/Pcap++/src/DpdkDevice.cpp @@ -34,18 +34,16 @@ namespace pcpp { - /** - * ================ - * Class DpdkDevice - * ================ - */ + /// ================ + /// Class DpdkDevice + /// ================ -#define DPDK_CONFIG_HEADER_SPLIT 0 /**< Header Split disabled */ +#define DPDK_CONFIG_HEADER_SPLIT 0 ///< Header Split disabled #define DPDK_CONFIG_SPLIT_HEADER_SIZE 0 -#define DPDK_CONFIG_HW_IP_CHECKSUM 0 /**< IP checksum offload disabled */ -#define DPDK_CONFIG_HW_VLAN_FILTER 0 /**< VLAN filtering disabled */ -#define DPDK_CONFIG_JUMBO_FRAME 0 /**< Jumbo Frame Support disabled */ -#define DPDK_CONFIG_HW_STRIP_CRC 0 /**< CRC stripped by hardware disabled */ +#define DPDK_CONFIG_HW_IP_CHECKSUM 0 ///< IP checksum offload disabled +#define DPDK_CONFIG_HW_VLAN_FILTER 0 ///< VLAN filtering disabled +#define DPDK_CONFIG_JUMBO_FRAME 0 ///< Jumbo Frame Support disabled +#define DPDK_CONFIG_HW_STRIP_CRC 0 ///< CRC stripped by hardware disabled #if (RTE_VER_YEAR < 21) || (RTE_VER_YEAR == 21 && RTE_VER_MONTH < 11) # define DPDK_CONFIG_ETH_LINK_FULL_DUPLEX ETH_LINK_FULL_DUPLEX # define DPDK_CONFIG_MQ_RSS ETH_RSS diff --git a/Pcap++/src/KniDevice.cpp b/Pcap++/src/KniDevice.cpp index 832bda282c..0adc8a73eb 100644 --- a/Pcap++/src/KniDevice.cpp +++ b/Pcap++/src/KniDevice.cpp @@ -41,11 +41,9 @@ namespace pcpp { - /** - * ========================== - * Class KniDevice::KniThread - * ========================== - */ + /// ========================== + /// Class KniDevice::KniThread + /// ========================== struct KniDevice::KniThread { @@ -90,11 +88,9 @@ namespace pcpp m_StopThread = true; } - /** - * =============== - * Class KniDevice - * =============== - */ + /// =============== + /// Class KniDevice + /// =============== namespace { @@ -960,9 +956,9 @@ namespace pcpp case LINK_ERROR: return m_DeviceOpened = false; case LINK_NOT_SUPPORTED: - /* fall through */ + // fall through case LINK_DOWN: - /* fall through */ + // fall through case LINK_UP: return m_DeviceOpened = true; } diff --git a/Pcap++/src/KniDeviceList.cpp b/Pcap++/src/KniDeviceList.cpp index 36a0856639..1b639c14f9 100644 --- a/Pcap++/src/KniDeviceList.cpp +++ b/Pcap++/src/KniDeviceList.cpp @@ -21,11 +21,9 @@ namespace pcpp { - /** - * =================== - * Class KniDeviceList - * =================== - */ + /// =================== + /// Class KniDeviceList + /// =================== static inline bool checkKniDriver() { @@ -153,11 +151,11 @@ namespace pcpp switch (cbType) { case KniDeviceList::CALLBACK_MTU: - /* fall through */ + // fall through case KniDeviceList::CALLBACK_LINK: return true; case KniDeviceList::CALLBACK_MAC: - /* fall through */ + // fall through case KniDeviceList::CALLBACK_PROMISC: #if RTE_VERSION >= RTE_VERSION_NUM(18, 2, 0, 0) return true; diff --git a/Pcap++/src/MBufRawPacket.cpp b/Pcap++/src/MBufRawPacket.cpp index fc271f0d64..9389a209f7 100644 --- a/Pcap++/src/MBufRawPacket.cpp +++ b/Pcap++/src/MBufRawPacket.cpp @@ -23,11 +23,9 @@ namespace pcpp { - /** - * =================== - * Class MBufRawPacket - * =================== - */ + /// =================== + /// Class MBufRawPacket + /// =================== MBufRawPacket::~MBufRawPacket() { diff --git a/Pcap++/src/NetworkUtils.cpp b/Pcap++/src/NetworkUtils.cpp index 6e595adfc8..61269bc26c 100644 --- a/Pcap++/src/NetworkUtils.cpp +++ b/Pcap++/src/NetworkUtils.cpp @@ -57,7 +57,7 @@ namespace pcpp return; // verify it's the right ARP response - if (arpReplyLayer->getArpHeader()->hardwareType != htobe16(1) /* Ethernet */ + if (arpReplyLayer->getArpHeader()->hardwareType != htobe16(1) // Ethernet || arpReplyLayer->getArpHeader()->protocolType != htobe16(PCPP_ETHERTYPE_IP)) return; @@ -215,7 +215,7 @@ namespace pcpp return; // verify it's the right DNS response - if (dnsResponseLayer->getDnsHeader()->queryOrResponse != 1 /* DNS response */ + if (dnsResponseLayer->getDnsHeader()->queryOrResponse != 1 // DNS response || dnsResponseLayer->getDnsHeader()->numberOfAnswers < htobe16(1) || dnsResponseLayer->getDnsHeader()->transactionID != htobe16(data->transactionID)) { diff --git a/Pcap++/src/PcapDevice.cpp b/Pcap++/src/PcapDevice.cpp index f546be634c..c72585dd3a 100644 --- a/Pcap++/src/PcapDevice.cpp +++ b/Pcap++/src/PcapDevice.cpp @@ -82,10 +82,8 @@ namespace pcpp PCPP_LOG_DEBUG("Compiling the filter '" << filterAsString << "'"); if (pcap_compile(m_PcapDescriptor.get(), &prog, filterAsString.c_str(), 1, 0) < 0) { - /* - * Print out appropriate text, followed by the error message - * generated by the packet capture library. - */ + // Print out appropriate text, followed by the error message + // generated by the packet capture library. PCPP_LOG_ERROR("Error compiling filter. Error message is: " << m_PcapDescriptor.getLastError()); return false; } @@ -93,11 +91,9 @@ namespace pcpp PCPP_LOG_DEBUG("Setting the compiled filter"); if (pcap_setfilter(m_PcapDescriptor.get(), &prog) < 0) { - /* - * Print out error. The format will be the prefix string, - * created above, followed by the error message that the packet - * capture library generates. - */ + // Print out error. The format will be the prefix string, + // created above, followed by the error message that the packet + // capture library generates. PCPP_LOG_ERROR("Error setting a compiled filter. Error message is: " << m_PcapDescriptor.getLastError()); pcap_freecode(&prog); return false; diff --git a/Pcap++/src/PcapFileDevice.cpp b/Pcap++/src/PcapFileDevice.cpp index d37997e5ca..079d2ab2cc 100644 --- a/Pcap++/src/PcapFileDevice.cpp +++ b/Pcap++/src/PcapFileDevice.cpp @@ -166,15 +166,15 @@ namespace pcpp // From https://datatracker.ietf.org/doc/html/rfc1761 static const pcpp::LinkLayerType snoop_encap[] = { - LINKTYPE_ETHERNET, /* IEEE 802.3 */ - LINKTYPE_NULL, /* IEEE 802.4 Token Bus */ - LINKTYPE_IEEE802_5, /* IEEE 802.5 */ - LINKTYPE_NULL, /* IEEE 802.6 Metro Net */ - LINKTYPE_ETHERNET, /* Ethernet */ - LINKTYPE_C_HDLC, /* HDLC */ - LINKTYPE_NULL, /* Character Synchronous, e.g. bisync */ - LINKTYPE_NULL, /* IBM Channel-to-Channel */ - LINKTYPE_FDDI /* FDDI */ + LINKTYPE_ETHERNET, /// IEEE 802.3 + LINKTYPE_NULL, /// IEEE 802.4 Token Bus + LINKTYPE_IEEE802_5, /// IEEE 802.5 + LINKTYPE_NULL, /// IEEE 802.6 Metro Net + LINKTYPE_ETHERNET, /// Ethernet + LINKTYPE_C_HDLC, /// HDLC + LINKTYPE_NULL, /// Character Synchronous, e.g. bisync + LINKTYPE_NULL, /// IBM Channel-to-Channel + LINKTYPE_FDDI /// FDDI }; uint32_t datalink_type = be32toh(snoop_file_header.datalink_type); if (datalink_type > ARRAY_SIZE(snoop_encap) - 1) diff --git a/Pcap++/src/PcapLiveDevice.cpp b/Pcap++/src/PcapLiveDevice.cpp index 831db83502..c5d33c4048 100644 --- a/Pcap++/src/PcapLiveDevice.cpp +++ b/Pcap++/src/PcapLiveDevice.cpp @@ -854,7 +854,7 @@ namespace pcpp { if (oidData->Length <= sizeof(uint32_t)) { - /* copy value from driver */ + // copy value from driver memcpy(&mtuValue, oidData->Data, oidData->Length); // Sometimes the query gives a wrong number that includes the link header size // A very common value is 1514 - if identify this value just reduce to 1500. @@ -867,7 +867,7 @@ namespace pcpp } else { - /* the driver returned a value that is longer than expected (and longer than the given buffer) */ + // the driver returned a value that is longer than expected (and longer than the given buffer) PCPP_LOG_ERROR( "Error in retrieving MTU: Size of Oid larger than uint32_t, OidLen: " << oidData->Length); return; @@ -931,7 +931,7 @@ namespace pcpp { # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Warray-bounds" - /* copy value from driver */ + // copy value from driver m_MacAddress = MacAddress(oidData->Data[0], oidData->Data[1], oidData->Data[2], oidData->Data[3], oidData->Data[4], oidData->Data[5]); # pragma GCC diagnostic pop @@ -939,7 +939,7 @@ namespace pcpp } else { - /* the driver returned a value that is longer than expected (and longer than the given buffer) */ + // the driver returned a value that is longer than expected (and longer than the given buffer) PCPP_LOG_DEBUG( "Error in retrieving MAC address: Size of Oid larger than 6, OidLen: " << oidData->Length); return; diff --git a/Pcap++/src/PcapRemoteDeviceList.cpp b/Pcap++/src/PcapRemoteDeviceList.cpp index b725f3b817..01791d6dde 100644 --- a/Pcap++/src/PcapRemoteDeviceList.cpp +++ b/Pcap++/src/PcapRemoteDeviceList.cpp @@ -14,15 +14,13 @@ namespace pcpp namespace { - /** - * Fetches a list of all network devices on a remote machine that WinPcap/NPcap can find. - * @param[in] ipAddress IP address of the remote machine. - * @param[in] port Port to use when connecting to the remote machine. - * @param[in] pRmAuth Pointer to an authentication structure to use when connecting to the remote machine. - * Nullptr if no authentication is required. - * @return A smart pointer to an interface list structure. - * @throws std::runtime_error The system encountered an error fetching the devices. - */ + /// Fetches a list of all network devices on a remote machine that WinPcap/NPcap can find. + /// @param[in] ipAddress IP address of the remote machine. + /// @param[in] port Port to use when connecting to the remote machine. + /// @param[in] pRmAuth Pointer to an authentication structure to use when connecting to the remote machine. + /// Nullptr if no authentication is required. + /// @return A smart pointer to an interface list structure. + /// @throws std::runtime_error The system encountered an error fetching the devices. std::unique_ptr getAllRemotePcapDevices( const IPAddress& ipAddress, uint16_t port, pcap_rmtauth* pRmAuth = nullptr) { diff --git a/Pcap++/src/PfRingDeviceList.cpp b/Pcap++/src/PfRingDeviceList.cpp index be41d07be8..bd1be57d75 100644 --- a/Pcap++/src/PfRingDeviceList.cpp +++ b/Pcap++/src/PfRingDeviceList.cpp @@ -17,10 +17,8 @@ namespace pcpp namespace { - /** - * @class PfRingCloseDeleter - * A deleter that cleans up a pfring structure by calling pfring_close. - */ + /// @class PfRingCloseDeleter + /// A deleter that cleans up a pfring structure by calling pfring_close. struct PfRingCloseDeleter { void operator()(pfring* ptr) const @@ -29,11 +27,9 @@ namespace pcpp } }; - /** - * Reads the ring version of a PF_RING handle. - * @param[in] ring A PF_RING handle. - * @return A string representation of the ring version or empty string if the read fails. - */ + /// Reads the ring version of a PF_RING handle. + /// @param[in] ring A PF_RING handle. + /// @return A string representation of the ring version or empty string if the read fails. std::string readPfRingVersion(pfring* ring) { uint32_t version; @@ -130,7 +126,6 @@ namespace pcpp return devIter->get(); } - } // namespace pcpp // GCOVR_EXCL_STOP diff --git a/Pcap++/src/RawSocketDevice.cpp b/Pcap++/src/RawSocketDevice.cpp index 40da2331e7..956d3460e9 100644 --- a/Pcap++/src/RawSocketDevice.cpp +++ b/Pcap++/src/RawSocketDevice.cpp @@ -24,8 +24,8 @@ namespace pcpp #if defined(_WIN32) # ifndef SIO_RCVALL -/* SIO_RCVALL defined on w2k and later. Not defined in Mingw32 */ -/* 0x98000001 = _WSAIOW(IOC_VENDOR,1) */ +// SIO_RCVALL defined on w2k and later. Not defined in Mingw32 +// 0x98000001 = _WSAIOW(IOC_VENDOR,1) # define SIO_RCVALL 0x98000001 # endif // SIO_RCVALL diff --git a/ci/check-clang-format-version.py b/ci/check-clang-format-version.py index 7379a828a5..c2f97822d3 100644 --- a/ci/check-clang-format-version.py +++ b/ci/check-clang-format-version.py @@ -1,6 +1,6 @@ import subprocess -EXPECTED_CLANG_VERSION = "18.1.6" +EXPECTED_CLANG_VERSION = "19.1.6" def main():