PcapPlusPlus  Next
PcapLiveDevice.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <atomic>
4 #include <vector>
5 #include <thread>
6 #include <functional>
7 
8 #include "IpAddress.h"
9 #include "PcapDevice.h"
10 
11 // forward declarations for structs and typedefs that are defined in pcap.h
12 struct pcap_if;
13 typedef pcap_if pcap_if_t;
14 struct pcap_addr;
15 typedef struct pcap_addr pcap_addr_t;
16 
18 
21 namespace pcpp
22 {
23  class PcapLiveDevice;
24 
29  using OnPacketArrivesCallback = std::function<void(RawPacket*, PcapLiveDevice*, void*)>;
30 
36  using OnPacketArrivesStopBlocking = std::function<bool(RawPacket*, PcapLiveDevice*, void*)>;
37 
42  using OnStatsUpdateCallback = std::function<void(IPcapDevice::PcapStats&, void*)>;
43 
65  class PcapLiveDevice : public IPcapDevice
66  {
67  friend class PcapLiveDeviceList;
68 
69  protected:
73  {
74  explicit DeviceInterfaceDetails(pcap_if_t* pInterface);
76  std::string name;
78  std::string description;
80  std::vector<IPAddress> addresses;
82  bool isLoopback;
83  };
84 
87  {
88  public:
95  StatisticsUpdateWorker(PcapLiveDevice const& pcapDevice, OnStatsUpdateCallback onStatsUpdateCallback,
96  void* onStatsUpdateUserCookie = nullptr, unsigned int updateIntervalMs = 1000);
97 
99  void stopWorker();
100 
101  private:
102  struct ThreadData
103  {
104  PcapLiveDevice const* pcapDevice = nullptr;
105  OnStatsUpdateCallback cbOnStatsUpdate;
106  void* cbOnStatsUpdateUserCookie = nullptr;
107  unsigned int updateIntervalMs = 1000; // Default update interval is 1 second
108  };
109 
110  struct SharedThreadData
111  {
112  std::atomic_bool stopRequested{ false };
113  };
114 
117  static void workerMain(std::shared_ptr<SharedThreadData> sharedThreadData, ThreadData threadData);
118 
119  std::shared_ptr<SharedThreadData> m_SharedThreadData;
120  std::thread m_WorkerThread;
121  };
122 
123  // This is a second descriptor for the same device. It is needed because of a bug
124  // that occurs in libpcap on Linux (on Windows using WinPcap/Npcap it works well):
125  // It's impossible to capture packets sent by the same descriptor
126  pcap_t* m_PcapSendDescriptor;
127  int m_PcapSelectableFd;
128  DeviceInterfaceDetails m_InterfaceDetails;
129  // NOTE@Dimi: Possibly pull mtu, mac address and default gateway in the interface details.
130  // They only appear to be set in the constructor and not modified afterwards.
131  uint32_t m_DeviceMtu;
132  MacAddress m_MacAddress;
133  IPv4Address m_DefaultGateway;
134  std::thread m_CaptureThread;
135 
136  // TODO: Cpp17 Using std::optional might be better here
137  std::unique_ptr<StatisticsUpdateWorker> m_StatisticsUpdateWorker;
138 
139  // Should be set to true by the Caller for the Callee
140  std::atomic<bool> m_StopThread;
141  // Should be set to true by the Callee for the Caller
142  std::atomic<bool> m_CaptureThreadStarted;
143 
144  OnPacketArrivesCallback m_cbOnPacketArrives;
145  void* m_cbOnPacketArrivesUserCookie;
146  OnPacketArrivesStopBlocking m_cbOnPacketArrivesBlockingMode;
147  void* m_cbOnPacketArrivesBlockingModeUserCookie;
148  RawPacketVector* m_CapturedPackets;
149  bool m_CaptureCallbackMode;
150  LinkLayerType m_LinkType;
151  bool m_UsePoll;
152 
153  // c'tor is not public, there should be only one for every interface (created by PcapLiveDeviceList)
154  PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway)
155  : PcapLiveDevice(DeviceInterfaceDetails(pInterface), calculateMTU, calculateMacAddress,
156  calculateDefaultGateway)
157  {}
158  PcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress,
159  bool calculateDefaultGateway);
160 
161  void setDeviceMtu();
162  void setDeviceMacAddress();
163  void setDefaultGateway();
164 
165  // threads
166  void captureThreadMain();
167 
168  static void onPacketArrives(uint8_t* user, const struct pcap_pkthdr* pkthdr, const uint8_t* packet);
169  static void onPacketArrivesNoCallback(uint8_t* user, const struct pcap_pkthdr* pkthdr, const uint8_t* packet);
170  static void onPacketArrivesBlockingMode(uint8_t* user, const struct pcap_pkthdr* pkthdr, const uint8_t* packet);
171 
172  public:
175  {
182  };
183 
186  {
188  Normal = 0,
190  Promiscuous = 1
191  };
192 
196  {
202  PCPP_OUT
203  };
204 
207  enum class TimestampProvider
208  {
210  Host = 0,
216  Adapter,
221  };
222 
226  {
228  Microseconds = 0,
230  Nanoseconds,
231  };
232 
237  {
240 
245 
253 
257 
264 
267  unsigned int nflogGroup;
268 
270  bool usePoll;
271 
275 
279 
302  int snapshotLength = 0, unsigned int nflogGroup = 0, bool usePoll = false,
305  {
306  this->mode = mode;
307  this->packetBufferTimeoutMs = packetBufferTimeoutMs;
308  this->packetBufferSize = packetBufferSize;
309  this->direction = direction;
310  this->snapshotLength = snapshotLength;
311  this->nflogGroup = nflogGroup;
312  this->usePoll = usePoll;
313  this->timestampProvider = timestampProvider;
314  this->timestampPrecision = timestampPrecision;
315  }
316  };
317 
318  PcapLiveDevice(const PcapLiveDevice& other) = delete;
319  PcapLiveDevice& operator=(const PcapLiveDevice& other) = delete;
321  ~PcapLiveDevice() override;
322 
325  {
326  return LibPcapDevice;
327  }
328 
330  std::string getName() const
331  {
332  return m_InterfaceDetails.name;
333  }
334 
337  std::string getDesc() const
338  {
339  return m_InterfaceDetails.description;
340  }
341 
343  bool getLoopback() const
344  {
345  return m_InterfaceDetails.isLoopback;
346  }
347 
349  virtual uint32_t getMtu() const
350  {
351  return m_DeviceMtu;
352  }
353 
355  virtual LinkLayerType getLinkType() const
356  {
357  return m_LinkType;
358  }
359 
361  std::vector<IPAddress> getIPAddresses() const
362  {
363  return m_InterfaceDetails.addresses;
364  }
365 
367  virtual MacAddress getMacAddress() const
368  {
369  return m_MacAddress;
370  }
371 
376 
381 
386 
391  const std::vector<IPv4Address>& getDnsServers() const;
392 
408  virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie);
409 
433  virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie,
434  int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
435  void* onStatsUpdateUserCookie);
436 
454  virtual bool startCapture(int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
455  void* onStatsUpdateUserCookie);
456 
471  virtual bool startCapture(RawPacketVector& capturedPacketsVector);
472 
497  virtual int startCaptureBlockingMode(OnPacketArrivesStopBlocking onPacketArrives, void* userCookie,
498  const double timeout);
499 
502  void stopCapture();
503 
507 
511  bool doMtuCheck(int packetPayloadLength) const;
512 
526  PCPP_DEPRECATED("This method is deprecated. Use sendPacket(Packet const& packet, bool checkMtu) instead")
527  bool sendPacket(Packet* packet, bool checkMtu = true)
528  {
529  return sendPacket(*packet, checkMtu);
530  }
531 
544  bool sendPacket(Packet const& packet, bool checkMtu = true);
545 
558  bool sendPacket(RawPacket const& rawPacket, bool checkMtu = false);
559 
575  bool sendPacket(const uint8_t* packetData, int packetDataLength, int packetPayloadLength);
576 
592  bool sendPacket(const uint8_t* packetData, int packetDataLength, bool checkMtu = false,
594 
607  virtual int sendPackets(RawPacket* rawPacketsArr, int arrLength, bool checkMtu = false);
608 
621  virtual int sendPackets(Packet** packetsArr, int arrLength, bool checkMtu = true);
622 
634  virtual int sendPackets(const RawPacketVector& rawPackets, bool checkMtu = false);
635 
636  // implement abstract methods
637 
644  bool open() override;
645 
651  bool open(const DeviceConfiguration& config);
652 
653  void close() override;
654 
657  virtual PcapLiveDevice* clone() const;
658 
659  void getStatistics(IPcapDevice::PcapStats& stats) const override;
660 
661  protected:
669  virtual void prepareCapture(bool asyncCapture, bool captureStats)
670  {}
671 
672  internal::PcapHandle doOpen(const DeviceConfiguration& config);
673 
674  // Sends a packet directly to the network.
675  bool sendPacketDirect(uint8_t const* packetData, int packetDataLength);
676 
677  private:
678  bool isNflogDevice() const;
679  };
680 } // namespace pcpp
Definition: PcapDevice.h:141
Definition: IpAddress.h:28
Definition: IpAddress.h:156
Definition: MacAddress.h:21
Definition: Packet.h:22
A worker thread that periodically calls the provided callback with updated statistics.
Definition: PcapLiveDevice.h:87
StatisticsUpdateWorker(PcapLiveDevice const &pcapDevice, OnStatsUpdateCallback onStatsUpdateCallback, void *onStatsUpdateUserCookie=nullptr, unsigned int updateIntervalMs=1000)
Constructs and starts a worker thread that periodically calls the provided callback with updated stat...
void stopWorker()
Stops the worker thread.
Definition: PcapLiveDevice.h:66
PcapDirection
Definition: PcapLiveDevice.h:196
@ PCPP_IN
Only capture incoming traffics.
Definition: PcapLiveDevice.h:200
@ PCPP_OUT
Only capture outgoing traffics.
Definition: PcapLiveDevice.h:202
@ PCPP_INOUT
Capture traffics both incoming and outgoing.
Definition: PcapLiveDevice.h:198
void close() override
Close the device.
LiveDeviceType
The type of the live device.
Definition: PcapLiveDevice.h:175
@ WinPcapDevice
WinPcap/Npcap live device.
Definition: PcapLiveDevice.h:179
@ RemoteDevice
WinPcap/Npcap Remote Capture device.
Definition: PcapLiveDevice.h:181
@ LibPcapDevice
libPcap live device
Definition: PcapLiveDevice.h:177
virtual int startCaptureBlockingMode(OnPacketArrivesStopBlocking onPacketArrives, void *userCookie, const double timeout)
DeviceMode
Device capturing mode.
Definition: PcapLiveDevice.h:186
@ Normal
Only packets that their destination is this NIC are captured.
Definition: PcapLiveDevice.h:188
@ Promiscuous
All packets that arrive to the NIC are captured, even packets that their destination isn't this NIC.
Definition: PcapLiveDevice.h:190
virtual bool startCapture(int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate, void *onStatsUpdateUserCookie)
bool sendPacket(RawPacket const &rawPacket, bool checkMtu=false)
virtual uint32_t getMtu() const
Definition: PcapLiveDevice.h:349
virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void *onPacketArrivesUserCookie)
void getStatistics(IPcapDevice::PcapStats &stats) const override
bool open(const DeviceConfiguration &config)
bool doMtuCheck(int packetPayloadLength) const
virtual MacAddress getMacAddress() const
Definition: PcapLiveDevice.h:367
bool sendPacket(const uint8_t *packetData, int packetDataLength, int packetPayloadLength)
IPv4Address getDefaultGateway() const
std::string getDesc() const
Definition: PcapLiveDevice.h:337
bool sendPacket(const uint8_t *packetData, int packetDataLength, bool checkMtu=false, pcpp::LinkLayerType linkType=pcpp::LINKTYPE_ETHERNET)
const std::vector< IPv4Address > & getDnsServers() const
virtual int sendPackets(Packet **packetsArr, int arrLength, bool checkMtu=true)
virtual LiveDeviceType getDeviceType() const
Definition: PcapLiveDevice.h:324
virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void *onPacketArrivesUserCookie, int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate, void *onStatsUpdateUserCookie)
TimestampPrecision
Definition: PcapLiveDevice.h:226
@ Microseconds
use timestamps with microsecond precision, default
@ Nanoseconds
use timestamps with nanosecond precision
IPv6Address getIPv6Address() const
virtual bool startCapture(RawPacketVector &capturedPacketsVector)
~PcapLiveDevice() override
A destructor for this class.
bool sendPacket(Packet const &packet, bool checkMtu=true)
std::string getName() const
Definition: PcapLiveDevice.h:330
IPv4Address getIPv4Address() const
bool sendPacket(Packet *packet, bool checkMtu=true)
Definition: PcapLiveDevice.h:527
virtual int sendPackets(const RawPacketVector &rawPackets, bool checkMtu=false)
virtual int sendPackets(RawPacket *rawPacketsArr, int arrLength, bool checkMtu=false)
virtual LinkLayerType getLinkType() const
Definition: PcapLiveDevice.h:355
TimestampProvider
Definition: PcapLiveDevice.h:208
@ AdapterUnsynced
device-provided, not synced with the system clock
@ HostLowPrecision
host-provided, low precision, synced with the system clock
@ Adapter
device-provided, synced with the system clock
@ HostHighPrecision
host-provided, high precision, synced with the system clock
@ Host
host-provided, unknown characteristics, default
@ HostHighPrecisionUnsynced
host-provided, high precision, not synced with the system clock
bool getLoopback() const
Definition: PcapLiveDevice.h:343
virtual PcapLiveDevice * clone() const
bool open() override
std::vector< IPAddress > getIPAddresses() const
Definition: PcapLiveDevice.h:361
virtual void prepareCapture(bool asyncCapture, bool captureStats)
Called before starting a capture to prepare the device for capturing packets.
Definition: PcapLiveDevice.h:669
Definition: PcapLiveDeviceList.h:22
Definition: PointerVector.h:50
Definition: RawPacket.h:259
A wrapper class for pcap_t* which is the libpcap packet capture descriptor. This class is used to man...
Definition: PcapDevice.h:37
The main namespace for the PcapPlusPlus lib.
PointerVector< RawPacket > RawPacketVector
A vector of pointers to RawPacket.
Definition: Device.h:14
std::function< bool(RawPacket *, PcapLiveDevice *, void *)> OnPacketArrivesStopBlocking
Definition: PcapLiveDevice.h:36
std::function< void(RawPacket *, PcapLiveDevice *, void *)> OnPacketArrivesCallback
Definition: PcapLiveDevice.h:29
std::function< void(IPcapDevice::PcapStats &, void *)> OnStatsUpdateCallback
Definition: PcapLiveDevice.h:42
LinkLayerType
An enum describing all known link layer type. Taken from: http://www.tcpdump.org/linktypes....
Definition: RawPacket.h:20
@ LINKTYPE_ETHERNET
IEEE 802.3 Ethernet.
Definition: RawPacket.h:24
Definition: PcapLiveDevice.h:237
int packetBufferTimeoutMs
Definition: PcapLiveDevice.h:244
int snapshotLength
Definition: PcapLiveDevice.h:263
TimestampProvider timestampProvider
Definition: PcapLiveDevice.h:274
DeviceConfiguration(DeviceMode mode=Promiscuous, int packetBufferTimeoutMs=0, int packetBufferSize=0, PcapDirection direction=PCPP_INOUT, int snapshotLength=0, unsigned int nflogGroup=0, bool usePoll=false, TimestampProvider timestampProvider=TimestampProvider::Host, TimestampPrecision timestampPrecision=TimestampPrecision::Microseconds)
Definition: PcapLiveDevice.h:300
bool usePoll
In Unix-like system, use poll() for blocking mode.
Definition: PcapLiveDevice.h:270
int packetBufferSize
Definition: PcapLiveDevice.h:252
unsigned int nflogGroup
Definition: PcapLiveDevice.h:267
PcapDirection direction
Definition: PcapLiveDevice.h:256
TimestampPrecision timestampPrecision
Definition: PcapLiveDevice.h:278
DeviceMode mode
Indicates whether to open the device in promiscuous or normal mode.
Definition: PcapLiveDevice.h:239
A struct that contains all details of a network interface.
Definition: PcapLiveDevice.h:73
std::string description
Description of the device.
Definition: PcapLiveDevice.h:78
std::string name
Name of the device.
Definition: PcapLiveDevice.h:76
std::vector< IPAddress > addresses
IP addresses associated with the device.
Definition: PcapLiveDevice.h:80
bool isLoopback
Flag to indicate if the device is a loopback device.
Definition: PcapLiveDevice.h:82
Definition: PcapDevice.h:24