Skip to content

Commit b6b3075

Browse files
authored
Remove IPcapDevice and move relevant logic to PcapLiveDevice (#2056)
1 parent ca14a3c commit b6b3075

14 files changed

Lines changed: 319 additions & 348 deletions

File tree

Examples/Tutorials/Tutorial-PcapFiles/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ int main(int argc, char* argv[])
6767
}
6868

6969
// Use lambda to simplify statistics output
70-
auto printStats = [](const std::string& writerName, const pcpp::IPcapDevice::PcapStats& stats) {
70+
auto printStats = [](const std::string& writerName, const pcpp::PcapStats& stats) {
7171
std::cout << "Written " << stats.packetsRecv << " packets successfully to " << writerName << " and "
7272
<< stats.packetsDrop << " packets could not be written" << std::endl;
7373
};
7474

7575
// create the stats object
76-
pcpp::IPcapDevice::PcapStats stats;
76+
pcpp::PcapStats stats;
7777

7878
// read stats from reader and print them
7979
reader->getStatistics(stats);

Examples/XdpExample-FilterTraffic/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ int main(int argc, char* argv[])
573573
std::vector<std::string> additionalStats;
574574
if (pcapWriter)
575575
{
576-
pcpp::IPcapDevice::PcapStats stats;
576+
pcpp::PcapStats stats;
577577
pcapWriter->getStatistics(stats);
578578
additionalStats.push_back("Wrote " + std::to_string(stats.packetsRecv) + " packets to '" +
579579
pcapWriter->getFileName() + "'");

Pcap++/header/PcapDevice.h

Lines changed: 11 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,31 @@
11
#pragma once
22

3-
#include "Device.h"
4-
#include "DeprecationUtils.h"
5-
6-
// forward declaration for the pcap descriptor defined in pcap.h
7-
struct pcap;
8-
typedef pcap pcap_t;
9-
struct pcap_pkthdr;
3+
#include <cstdint>
104

115
/// @file
126

137
/// @namespace pcpp
148
/// @brief The main namespace for the PcapPlusPlus lib
159
namespace pcpp
1610
{
17-
// Forward Declaration - required for IPcapDevice::matchPacketWithFilter
18-
class GeneralFilter;
19-
20-
namespace internal
11+
/// @struct PcapStats
12+
/// A container for pcap device statistics
13+
struct PcapStats
2114
{
22-
/// @struct PcapStats
23-
/// A container for pcap device statistics
24-
struct PcapStats
25-
{
26-
/// Number of packets received
27-
uint64_t packetsRecv;
28-
/// Number of packets dropped
29-
uint64_t packetsDrop;
30-
/// number of packets dropped by interface (not supported on all platforms)
31-
uint64_t packetsDropByInterface;
32-
};
33-
34-
/// @class PcapHandle
35-
/// @brief A wrapper class for pcap_t* which is the libpcap packet capture descriptor.
36-
/// This class is used to manage the lifecycle of the pcap_t* object
37-
class PcapHandle
38-
{
39-
public:
40-
/// @brief Creates an empty handle.
41-
constexpr PcapHandle() noexcept = default;
42-
/// @brief Creates a handle from the provided pcap descriptor.
43-
/// @param pcapDescriptor The pcap descriptor to wrap.
44-
explicit PcapHandle(pcap_t* pcapDescriptor) noexcept;
45-
46-
PcapHandle(const PcapHandle&) = delete;
47-
PcapHandle(PcapHandle&& other) noexcept;
48-
49-
PcapHandle& operator=(const PcapHandle&) = delete;
50-
PcapHandle& operator=(PcapHandle&& other) noexcept;
51-
PcapHandle& operator=(std::nullptr_t) noexcept;
52-
53-
~PcapHandle();
54-
55-
/// @return True if the handle is not null, false otherwise.
56-
bool isValid() const noexcept
57-
{
58-
return m_PcapDescriptor != nullptr;
59-
}
60-
61-
/// @return The underlying pcap descriptor.
62-
pcap_t* get() const noexcept
63-
{
64-
return m_PcapDescriptor;
65-
}
66-
67-
/// @brief Releases ownership of the handle and returns the pcap descriptor.
68-
/// @return The pcap descriptor or nullptr if no handle is owned.
69-
pcap_t* release() noexcept;
70-
71-
/// @brief Replaces the managed handle with the provided one.
72-
/// @param pcapDescriptor A new pcap descriptor to manage.
73-
/// @remarks If the handle contains a non-null descriptor it will be closed.
74-
void reset(pcap_t* pcapDescriptor = nullptr) noexcept;
75-
76-
/// @brief Helper function to retrieve a view of the last error string for this handle.
77-
/// @return A null-terminated view of the last error string.
78-
/// @remarks The returned view is only valid until the next call to a pcap function.
79-
char const* getLastError() const noexcept;
80-
81-
/// @brief Sets a filter on the handle. Only packets that match the filter will be captured by the handle.
82-
///
83-
/// The filter uses Berkeley Packet Filter (BPF) syntax (http://biot.com/capstats/bpf.html).
84-
///
85-
/// @param[in] filter The filter to set in Berkeley Packet Filter (BPF) syntax.
86-
/// @return True if the filter was set successfully, false otherwise.
87-
bool setFilter(std::string const& filter);
88-
89-
/// @brief Clears the filter currently set on the handle.
90-
/// @return True if the filter was removed successfully or if no filter was set, false otherwise.
91-
bool clearFilter();
92-
93-
/// @brief Retrieves statistics from the pcap handle.
94-
///
95-
/// The function internally calls pcap_stats() to retrieve the statistics and only works on live devices.
96-
///
97-
/// @param stats Structure to store the statistics.
98-
/// @return True if the statistics were retrieved successfully, false otherwise.
99-
bool getStatistics(PcapStats& stats) const;
100-
101-
/// @return True if the handle is not null, false otherwise.
102-
explicit operator bool() const noexcept
103-
{
104-
return isValid();
105-
}
106-
107-
bool operator==(std::nullptr_t) const noexcept
108-
{
109-
return !isValid();
110-
}
111-
bool operator!=(std::nullptr_t) const noexcept
112-
{
113-
return isValid();
114-
}
115-
116-
private:
117-
pcap_t* m_PcapDescriptor = nullptr;
118-
};
119-
} // namespace internal
15+
/// Number of packets received
16+
uint64_t packetsRecv;
17+
/// Number of packets dropped
18+
uint64_t packetsDrop;
19+
/// number of packets dropped by interface (not supported on all platforms)
20+
uint64_t packetsDropByInterface;
21+
};
12022

12123
/// @brief An interface for providing Pcap-based device statistics
12224
class IPcapStatisticsProvider
12325
{
12426
public:
12527
virtual ~IPcapStatisticsProvider() = default;
12628

127-
using PcapStats = internal::PcapStats;
128-
12929
/// @brief Get statistics from the device
13030
/// @return An object containing the stats
13131
PcapStats getStatistics() const;
@@ -134,36 +34,4 @@ namespace pcpp
13434
/// @param[out] stats An object containing the stats
13535
virtual void getStatistics(PcapStats& stats) const = 0;
13636
};
137-
138-
/// @class IPcapDevice
139-
/// An abstract class representing all libpcap-based packet capturing devices: files, libPcap, WinPcap/Npcap and
140-
/// RemoteCapture. This class is abstract and cannot be instantiated
141-
class IPcapDevice : public IFilterableDevice, public IPcapStatisticsProvider
142-
{
143-
protected:
144-
internal::PcapHandle m_PcapDescriptor;
145-
146-
// c'tor should not be public
147-
IPcapDevice() = default;
148-
149-
public:
150-
virtual ~IPcapDevice() = default;
151-
152-
/// A static method for retrieving pcap lib (libpcap/WinPcap/etc.) version information. This method is actually
153-
/// a wrapper for [pcap_lib_version()](https://www.tcpdump.org/manpages/pcap_lib_version.3pcap.html)
154-
/// @return A string containing the pcap lib version information
155-
static std::string getPcapLibVersionInfo();
156-
157-
/// Match a raw packet with a given BPF filter. Notice this method is static which means you don't need any
158-
/// device instance in order to perform this match
159-
/// @param[in] filter A filter class to test against
160-
/// @param[in] rawPacket A pointer to the raw packet to match the filter with
161-
/// @return True if raw packet matches the filter or false otherwise
162-
/// @deprecated This method is deprecated, use GeneralFilter::matches(...) method directly.
163-
PCPP_DEPRECATED("Prefer GeneralFilter::matches(...) method directly.")
164-
static bool matchPacketWithFilter(GeneralFilter& filter, RawPacket* rawPacket);
165-
166-
protected:
167-
bool doUpdateFilter(std::string const* filterAsString) override;
168-
};
16937
} // namespace pcpp

Pcap++/header/PcapFileDevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "Device.h"
34
#include "PcapDevice.h"
45
#include "RawPacket.h"
56
#include <fstream>

Pcap++/header/PcapLiveDevice.h

Lines changed: 113 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,111 @@
66
#include <functional>
77

88
#include "IpAddress.h"
9+
#include "Device.h"
910
#include "PcapDevice.h"
1011

1112
// forward declarations for structs and typedefs that are defined in pcap.h
1213
struct pcap_if;
1314
typedef pcap_if pcap_if_t;
14-
struct pcap_addr;
15-
typedef struct pcap_addr pcap_addr_t;
15+
struct pcap;
16+
typedef pcap pcap_t;
17+
struct pcap_pkthdr;
1618

1719
/// @file
1820

1921
/// @namespace pcpp
2022
/// @brief The main namespace for the PcapPlusPlus lib
2123
namespace pcpp
2224
{
25+
namespace internal
26+
{
27+
/// @class PcapHandle
28+
/// @brief A wrapper class for pcap_t* which is the libpcap packet capture descriptor.
29+
/// This class is used to manage the lifecycle of the pcap_t* object
30+
class PcapHandle
31+
{
32+
public:
33+
/// @brief Creates an empty handle.
34+
constexpr PcapHandle() noexcept = default;
35+
/// @brief Creates a handle from the provided pcap descriptor.
36+
/// @param pcapDescriptor The pcap descriptor to wrap.
37+
explicit PcapHandle(pcap_t* pcapDescriptor) noexcept;
38+
39+
PcapHandle(const PcapHandle&) = delete;
40+
PcapHandle(PcapHandle&& other) noexcept;
41+
42+
PcapHandle& operator=(const PcapHandle&) = delete;
43+
PcapHandle& operator=(PcapHandle&& other) noexcept;
44+
PcapHandle& operator=(std::nullptr_t) noexcept;
45+
46+
~PcapHandle();
47+
48+
/// @return True if the handle is not null, false otherwise.
49+
bool isValid() const noexcept
50+
{
51+
return m_PcapDescriptor != nullptr;
52+
}
53+
54+
/// @return The underlying pcap descriptor.
55+
pcap_t* get() const noexcept
56+
{
57+
return m_PcapDescriptor;
58+
}
59+
60+
/// @brief Releases ownership of the handle and returns the pcap descriptor.
61+
/// @return The pcap descriptor or nullptr if no handle is owned.
62+
pcap_t* release() noexcept;
63+
64+
/// @brief Replaces the managed handle with the provided one.
65+
/// @param pcapDescriptor A new pcap descriptor to manage.
66+
/// @remarks If the handle contains a non-null descriptor it will be closed.
67+
void reset(pcap_t* pcapDescriptor = nullptr) noexcept;
68+
69+
/// @brief Helper function to retrieve a view of the last error string for this handle.
70+
/// @return A null-terminated view of the last error string.
71+
/// @remarks The returned view is only valid until the next call to a pcap function.
72+
char const* getLastError() const noexcept;
73+
74+
/// @brief Sets a filter on the handle. Only packets that match the filter will be captured by the handle.
75+
///
76+
/// The filter uses Berkeley Packet Filter (BPF) syntax (http://biot.com/capstats/bpf.html).
77+
///
78+
/// @param[in] filter The filter to set in Berkeley Packet Filter (BPF) syntax.
79+
/// @return True if the filter was set successfully, false otherwise.
80+
bool setFilter(std::string const& filter);
81+
82+
/// @brief Clears the filter currently set on the handle.
83+
/// @return True if the filter was removed successfully or if no filter was set, false otherwise.
84+
bool clearFilter();
85+
86+
/// @brief Retrieves statistics from the pcap handle.
87+
///
88+
/// The function internally calls pcap_stats() to retrieve the statistics and only works on live devices.
89+
///
90+
/// @param stats Structure to store the statistics.
91+
/// @return True if the statistics were retrieved successfully, false otherwise.
92+
bool getStatistics(PcapStats& stats) const;
93+
94+
/// @return True if the handle is not null, false otherwise.
95+
explicit operator bool() const noexcept
96+
{
97+
return isValid();
98+
}
99+
100+
bool operator==(std::nullptr_t) const noexcept
101+
{
102+
return !isValid();
103+
}
104+
bool operator!=(std::nullptr_t) const noexcept
105+
{
106+
return isValid();
107+
}
108+
109+
private:
110+
pcap_t* m_PcapDescriptor = nullptr;
111+
};
112+
} // namespace internal
113+
23114
class PcapLiveDevice;
24115

25116
/// A callback that is called when a packet is captured by PcapLiveDevice
@@ -39,7 +130,7 @@ namespace pcpp
39130
/// periodic stats collection
40131
/// @param[in] stats A reference to the most updated stats
41132
/// @param[in] userCookie A pointer to the object put by the user when packet capturing stared
42-
using OnStatsUpdateCallback = std::function<void(IPcapDevice::PcapStats&, void*)>;
133+
using OnStatsUpdateCallback = std::function<void(PcapStats&, void*)>;
43134

44135
/// @class PcapLiveDevice
45136
/// A class that wraps a network interface (each of the interfaces listed in ifconfig/ipconfig).
@@ -62,7 +153,7 @@ namespace pcpp
62153
/// by supplying a callback and a timeout to startCapture()
63154
/// - Send packets back to the network. Sending the packets is done on the caller thread. No additional threads are
64155
/// created for this task
65-
class PcapLiveDevice : public IPcapDevice
156+
class PcapLiveDevice : public IFilterableDevice, public IPcapStatisticsProvider
66157
{
67158
friend class PcapLiveDeviceList;
68159

@@ -83,6 +174,7 @@ namespace pcpp
83174
};
84175

85176
bool m_DeviceOpened = false;
177+
internal::PcapHandle m_PcapDescriptor;
86178

87179
// This is a second descriptor for the same device. It is needed because of a bug
88180
// that occurs in libpcap on Linux (on Windows using WinPcap/Npcap it works well):
@@ -339,6 +431,11 @@ namespace pcpp
339431
/// this list from PcapLiveDevice as well
340432
const std::vector<IPv4Address>& getDnsServers() const;
341433

434+
/// A static method for retrieving pcap lib (libpcap/WinPcap/etc.) version information. This method is actually
435+
/// a wrapper for [pcap_lib_version()](https://www.tcpdump.org/manpages/pcap_lib_version.3pcap.html)
436+
/// @return A string containing the pcap lib version information
437+
static std::string getPcapLibVersionInfo();
438+
342439
/// Start capturing packets on this network interface (device). Each time a packet is captured the
343440
/// onPacketArrives callback is called. The capture is done on a new thread created by this method, meaning all
344441
/// callback calls are done in a thread other than the caller thread. Capture process will stop and this capture
@@ -611,7 +708,16 @@ namespace pcpp
611708
/// @return Pointer to the copied class
612709
virtual PcapLiveDevice* clone() const;
613710

614-
void getStatistics(IPcapDevice::PcapStats& stats) const override;
711+
void getStatistics(PcapStats& stats) const override;
712+
713+
/// Match a raw packet with a given BPF filter. Notice this method is static which means you don't need any
714+
/// device instance in order to perform this match
715+
/// @param[in] filter A filter class to test against
716+
/// @param[in] rawPacket A pointer to the raw packet to match the filter with
717+
/// @return True if raw packet matches the filter or false otherwise
718+
/// @deprecated This method is deprecated, use GeneralFilter::matches(...) method directly.
719+
PCPP_DEPRECATED("Prefer GeneralFilter::matches(...) method directly.")
720+
static bool matchPacketWithFilter(GeneralFilter& filter, RawPacket* rawPacket);
615721

616722
protected:
617723
/// @brief Called before starting a capture to prepare the device for capturing packets.
@@ -688,5 +794,7 @@ namespace pcpp
688794

689795
private:
690796
bool isNflogDevice() const;
797+
798+
bool doUpdateFilter(std::string const* filterAsString) override;
691799
};
692800
} // namespace pcpp

Pcap++/header/PcapRemoteDevice.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ namespace pcpp
130130
/// will be printed to log as well, including the WinPcap/Npcap error if exists
131131
bool open() override;
132132

133-
void getStatistics(IPcapDevice::PcapStats& stats) const override;
133+
void getStatistics(PcapStats& stats) const override;
134134

135135
PcapRemoteDevice* clone() const override;
136136
};

0 commit comments

Comments
 (0)