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 
85  bool m_DeviceOpened = false;
86 
87  // This is a second descriptor for the same device. It is needed because of a bug
88  // that occurs in libpcap on Linux (on Windows using WinPcap/Npcap it works well):
89  // It's impossible to capture packets sent by the same descriptor
90  pcap_t* m_PcapSendDescriptor;
91  int m_PcapSelectableFd;
92  DeviceInterfaceDetails m_InterfaceDetails;
93  // NOTE@Dimi: Possibly pull mtu, mac address and default gateway in the interface details.
94  // They only appear to be set in the constructor and not modified afterwards.
95  uint32_t m_DeviceMtu;
96  MacAddress m_MacAddress;
97  IPv4Address m_DefaultGateway;
98  std::thread m_CaptureThread;
99  std::thread m_StatsThread;
100 
101  // Should be set to true by the Caller for the Callee
102  std::atomic<bool> m_StopThread;
103  // Should be set to true by the Callee for the Caller
104  std::atomic<bool> m_CaptureThreadStarted;
105 
106  OnPacketArrivesCallback m_cbOnPacketArrives;
107  void* m_cbOnPacketArrivesUserCookie;
108  OnPacketArrivesStopBlocking m_cbOnPacketArrivesBlockingMode;
109  void* m_cbOnPacketArrivesBlockingModeUserCookie;
110  RawPacketVector* m_CapturedPackets;
111  bool m_CaptureCallbackMode;
112  LinkLayerType m_LinkType;
113  bool m_UsePoll;
114 
115  // c'tor is not public, there should be only one for every interface (created by PcapLiveDeviceList)
116  PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway)
117  : PcapLiveDevice(DeviceInterfaceDetails(pInterface), calculateMTU, calculateMacAddress,
118  calculateDefaultGateway)
119  {}
120  PcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress,
121  bool calculateDefaultGateway);
122 
123  void setDeviceMtu();
124  void setDeviceMacAddress();
125  void setDefaultGateway();
126 
127  // threads
128  void captureThreadMain();
129 
130  static void onPacketArrives(uint8_t* user, const struct pcap_pkthdr* pkthdr, const uint8_t* packet);
131  static void onPacketArrivesNoCallback(uint8_t* user, const struct pcap_pkthdr* pkthdr, const uint8_t* packet);
132  static void onPacketArrivesBlockingMode(uint8_t* user, const struct pcap_pkthdr* pkthdr, const uint8_t* packet);
133 
134  public:
137  {
144  };
145 
148  {
150  Normal = 0,
152  Promiscuous = 1
153  };
154 
158  {
164  PCPP_OUT
165  };
166 
169  enum class TimestampProvider
170  {
172  Host = 0,
178  Adapter,
183  };
184 
188  {
190  Microseconds = 0,
192  Nanoseconds,
193  };
194 
199  {
202 
207 
215 
219 
226 
229  unsigned int nflogGroup;
230 
232  bool usePoll;
233 
237 
241 
264  int snapshotLength = 0, unsigned int nflogGroup = 0, bool usePoll = false,
267  {
268  this->mode = mode;
269  this->packetBufferTimeoutMs = packetBufferTimeoutMs;
270  this->packetBufferSize = packetBufferSize;
271  this->direction = direction;
272  this->snapshotLength = snapshotLength;
273  this->nflogGroup = nflogGroup;
274  this->usePoll = usePoll;
275  this->timestampProvider = timestampProvider;
276  this->timestampPrecision = timestampPrecision;
277  }
278  };
279 
280  PcapLiveDevice(const PcapLiveDevice& other) = delete;
281  PcapLiveDevice& operator=(const PcapLiveDevice& other) = delete;
283  ~PcapLiveDevice() override;
284 
287  {
288  return LibPcapDevice;
289  }
290 
292  std::string getName() const
293  {
294  return m_InterfaceDetails.name;
295  }
296 
299  std::string getDesc() const
300  {
301  return m_InterfaceDetails.description;
302  }
303 
305  bool getLoopback() const
306  {
307  return m_InterfaceDetails.isLoopback;
308  }
309 
311  virtual uint32_t getMtu() const
312  {
313  return m_DeviceMtu;
314  }
315 
317  virtual LinkLayerType getLinkType() const
318  {
319  return m_LinkType;
320  }
321 
323  std::vector<IPAddress> getIPAddresses() const
324  {
325  return m_InterfaceDetails.addresses;
326  }
327 
329  virtual MacAddress getMacAddress() const
330  {
331  return m_MacAddress;
332  }
333 
338 
343 
348 
353  const std::vector<IPv4Address>& getDnsServers() const;
354 
370  virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie);
371 
395  virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie,
396  int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
397  void* onStatsUpdateUserCookie);
398 
416  virtual bool startCapture(int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
417  void* onStatsUpdateUserCookie);
418 
433  virtual bool startCapture(RawPacketVector& capturedPacketsVector);
434 
459  virtual int startCaptureBlockingMode(OnPacketArrivesStopBlocking onPacketArrives, void* userCookie,
460  const double timeout);
461 
465  void stopCapture();
466 
470 
474  bool doMtuCheck(int packetPayloadLength) const;
475 
489  PCPP_DEPRECATED("This method is deprecated. Use sendPacket(Packet const& packet, bool checkMtu) instead")
490  bool sendPacket(Packet* packet, bool checkMtu = true)
491  {
492  return sendPacket(*packet, checkMtu);
493  }
494 
507  bool sendPacket(Packet const& packet, bool checkMtu = true);
508 
521  bool sendPacket(RawPacket const& rawPacket, bool checkMtu = false);
522 
538  bool sendPacket(const uint8_t* packetData, int packetDataLength, int packetPayloadLength);
539 
555  bool sendPacket(const uint8_t* packetData, int packetDataLength, bool checkMtu = false,
557 
570  virtual int sendPackets(RawPacket* rawPacketsArr, int arrLength, bool checkMtu = false);
571 
584  virtual int sendPackets(Packet** packetsArr, int arrLength, bool checkMtu = true);
585 
597  virtual int sendPackets(const RawPacketVector& rawPackets, bool checkMtu = false);
598 
599  // implement abstract methods
600 
607  bool open() override;
608 
614  bool open(const DeviceConfiguration& config);
615 
616  void close() override;
617 
618  bool isOpened() const override
619  {
620  return m_DeviceOpened;
621  }
622 
625  virtual PcapLiveDevice* clone() const;
626 
627  void getStatistics(IPcapDevice::PcapStats& stats) const override;
628 
629  protected:
637  virtual void prepareCapture(bool asyncCapture, bool captureStats)
638  {}
639 
640  internal::PcapHandle doOpen(const DeviceConfiguration& config);
641 
645  bool isPayloadWithinMtu(size_t payloadLength) const;
646 
659  bool isPayloadWithinMtu(Packet const& packet, bool allowUnknownLength = false,
660  size_t* outPayloadLength = nullptr) const;
661 
674  bool isPayloadWithinMtu(RawPacket const& rawPacket, bool allowUnknownLength = false,
675  size_t* outPayloadLength = nullptr) const;
676 
691  bool isPayloadWithinMtu(uint8_t const* packetData, size_t packetLen,
692  LinkLayerType linkType = pcpp::LINKTYPE_ETHERNET, bool allowUnknownLength = false,
693  size_t* outPayloadLength = nullptr) const;
694 
695  // Sends a packet directly to the network.
696  bool sendPacketUnchecked(uint8_t const* packetData, int packetDataLength);
697  bool sendPacketUnchecked(RawPacket const& rawPacket)
698  {
699  return sendPacketUnchecked(rawPacket.getRawData(), rawPacket.getRawDataLen());
700  }
701 
702  private:
703  bool isNflogDevice() const;
704  };
705 } // namespace pcpp
Definition: PcapDevice.h:141
Definition: IpAddress.h:30
Definition: IpAddress.h:165
Definition: MacAddress.h:24
Definition: Packet.h:22
Definition: PcapLiveDevice.h:66
PcapDirection
Definition: PcapLiveDevice.h:158
@ PCPP_IN
Only capture incoming traffics.
Definition: PcapLiveDevice.h:162
@ PCPP_OUT
Only capture outgoing traffics.
Definition: PcapLiveDevice.h:164
@ PCPP_INOUT
Capture traffics both incoming and outgoing.
Definition: PcapLiveDevice.h:160
void close() override
Close the device.
LiveDeviceType
The type of the live device.
Definition: PcapLiveDevice.h:137
@ WinPcapDevice
WinPcap/Npcap live device.
Definition: PcapLiveDevice.h:141
@ RemoteDevice
WinPcap/Npcap Remote Capture device.
Definition: PcapLiveDevice.h:143
@ LibPcapDevice
libPcap live device
Definition: PcapLiveDevice.h:139
virtual int startCaptureBlockingMode(OnPacketArrivesStopBlocking onPacketArrives, void *userCookie, const double timeout)
DeviceMode
Device capturing mode.
Definition: PcapLiveDevice.h:148
@ Normal
Only packets that their destination is this NIC are captured.
Definition: PcapLiveDevice.h:150
@ Promiscuous
All packets that arrive to the NIC are captured, even packets that their destination isn't this NIC.
Definition: PcapLiveDevice.h:152
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:311
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:329
bool sendPacket(const uint8_t *packetData, int packetDataLength, int packetPayloadLength)
IPv4Address getDefaultGateway() const
std::string getDesc() const
Definition: PcapLiveDevice.h:299
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)
bool isPayloadWithinMtu(size_t payloadLength) const
Checks whether the packetPayloadLength is smaller or equal than the device MTU.
virtual LiveDeviceType getDeviceType() const
Definition: PcapLiveDevice.h:286
virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void *onPacketArrivesUserCookie, int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate, void *onStatsUpdateUserCookie)
TimestampPrecision
Definition: PcapLiveDevice.h:188
@ 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:292
bool isPayloadWithinMtu(uint8_t const *packetData, size_t packetLen, LinkLayerType linkType=pcpp::LINKTYPE_ETHERNET, bool allowUnknownLength=false, size_t *outPayloadLength=nullptr) const
Checks whether the payload length of a packet's raw data is smaller or equal than the device MTU.
IPv4Address getIPv4Address() const
bool sendPacket(Packet *packet, bool checkMtu=true)
Definition: PcapLiveDevice.h:490
virtual int sendPackets(const RawPacketVector &rawPackets, bool checkMtu=false)
virtual int sendPackets(RawPacket *rawPacketsArr, int arrLength, bool checkMtu=false)
bool isPayloadWithinMtu(Packet const &packet, bool allowUnknownLength=false, size_t *outPayloadLength=nullptr) const
Checks whether the packet's payload length is smaller or equal than the device MTU.
virtual LinkLayerType getLinkType() const
Definition: PcapLiveDevice.h:317
bool isOpened() const override
Definition: PcapLiveDevice.h:618
TimestampProvider
Definition: PcapLiveDevice.h:170
@ 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:305
virtual PcapLiveDevice * clone() const
bool isPayloadWithinMtu(RawPacket const &rawPacket, bool allowUnknownLength=false, size_t *outPayloadLength=nullptr) const
Checks whether the payload length of a RawPacket is smaller or equal than the device MTU.
bool open() override
std::vector< IPAddress > getIPAddresses() const
Definition: PcapLiveDevice.h:323
virtual void prepareCapture(bool asyncCapture, bool captureStats)
Called before starting a capture to prepare the device for capturing packets.
Definition: PcapLiveDevice.h:637
Definition: PcapLiveDeviceList.h:22
Definition: PointerVector.h:50
Definition: RawPacket.h:259
const uint8_t * getRawData() const
Definition: RawPacket.h:370
int getRawDataLen() const
Definition: RawPacket.h:389
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.
Definition: AssertionUtils.h:19
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:199
int packetBufferTimeoutMs
Definition: PcapLiveDevice.h:206
int snapshotLength
Definition: PcapLiveDevice.h:225
TimestampProvider timestampProvider
Definition: PcapLiveDevice.h:236
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:262
bool usePoll
In Unix-like system, use poll() for blocking mode.
Definition: PcapLiveDevice.h:232
int packetBufferSize
Definition: PcapLiveDevice.h:214
unsigned int nflogGroup
Definition: PcapLiveDevice.h:229
PcapDirection direction
Definition: PcapLiveDevice.h:218
TimestampPrecision timestampPrecision
Definition: PcapLiveDevice.h:240
DeviceMode mode
Indicates whether to open the device in promiscuous or normal mode.
Definition: PcapLiveDevice.h:201
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