Skip to content

Commit

Permalink
Change PcapLiveDevice to store IP information as IPAddresses. (#1497)
Browse files Browse the repository at this point in the history
* Null to nullptr.

* Encapsulated data directly fetched from pcap_if_t into a separate struct DeviceInterfaceDetails to allow direct construction of the device without re-fetching from the Pcap layer.

* Updated WinPcapLiveDevice with the changes from PcapLiveDevice.

* Updated PcapRemoteDevice with changes from PcapLiveDevice.

* Explicitly deleted copy ctor and copy assignment.

* Updated PcapLiveDeviceList with changes from PcapLiveDevice.

* Updated PcapRemoteDeviceList with changes from PcapLiveDevice.

* Updated PcapLiveDevice::clone to operate without the need to query the Pcap layer.

* Added override 'cloneInternal' method to PcapRemoteDevice.

* Renamed 'cloneInternal' to 'doClone',

* Added unit test to validate that remote device->clone produces object of the correct type.

* Lint

* Changed device addresses to be held by IPAddress class instead of pcap_addr.

* Fixed getIPAddresses using the old implementation.

* Lint

* Removed doClone as there is no need for it anymore and made clone virtual.

* Lint

* Add comment note.

* Revert removed comment line.
  • Loading branch information
Dimi1010 authored Oct 12, 2024
1 parent 40ba4c5 commit 662f027
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 318 deletions.
60 changes: 32 additions & 28 deletions Pcap++/header/PcapLiveDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,30 @@ namespace pcpp
friend class PcapLiveDeviceList;

protected:
/// @struct DeviceInterfaceDetails
/// @brief A struct that contains all details of a network interface.
struct DeviceInterfaceDetails
{
explicit DeviceInterfaceDetails(pcap_if_t* pInterface);
/// @brief Name of the device.
std::string name;
/// @brief Description of the device.
std::string description;
/// @brief IP addresses associated with the device.
std::vector<IPAddress> addresses;
/// @brief Flag to indicate if the device is a loopback device.
bool isLoopback;
};

// This is a second descriptor for the same device. It is needed because of a bug
// that occurs in libpcap on Linux (on Windows using WinPcap/Npcap it works well):
// It's impossible to capture packets sent by the same descriptor
pcap_t* m_PcapSendDescriptor;
int m_PcapSelectableFd;
std::string m_Name;
std::string m_Description;
bool m_IsLoopback;
DeviceInterfaceDetails m_InterfaceDetails;
// NOTE@Dimi: Possibly pull mtu, mac address and default gateway in the interface details.
// They only appear to be set in the constructor and not modified afterwards.
uint32_t m_DeviceMtu;
std::vector<pcap_addr_t> m_Addresses;
MacAddress m_MacAddress;
IPv4Address m_DefaultGateway;
std::thread m_CaptureThread;
Expand All @@ -114,11 +128,12 @@ namespace pcpp
bool m_UsePoll;

// c'tor is not public, there should be only one for every interface (created by PcapLiveDeviceList)
PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress,
PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway)
: PcapLiveDevice(DeviceInterfaceDetails(pInterface), calculateMTU, calculateMacAddress,
calculateDefaultGateway)
{}
PcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress,
bool calculateDefaultGateway);
// copy c'tor is not public
PcapLiveDevice(const PcapLiveDevice& other);
PcapLiveDevice& operator=(const PcapLiveDevice& other);

void setDeviceMtu();
void setDeviceMacAddress();
Expand Down Expand Up @@ -252,6 +267,8 @@ namespace pcpp
}
};

PcapLiveDevice(const PcapLiveDevice& other) = delete;
PcapLiveDevice& operator=(const PcapLiveDevice& other) = delete;
/**
* A destructor for this class
*/
Expand All @@ -270,7 +287,7 @@ namespace pcpp
*/
std::string getName() const
{
return m_Name;
return m_InterfaceDetails.name;
}

/**
Expand All @@ -279,15 +296,15 @@ namespace pcpp
*/
std::string getDesc() const
{
return m_Description;
return m_InterfaceDetails.description;
}

/**
* @return True if this interface is a loopback interface, false otherwise
*/
bool getLoopback() const
{
return m_IsLoopback;
return m_InterfaceDetails.isLoopback;
}

/**
Expand All @@ -307,24 +324,13 @@ namespace pcpp
}

/**
* @return A vector containing all addresses defined for this interface, each in pcap_addr_t struct
* @deprecated This method is deprecated and will be removed in future versions. Please use getIPAddresses()
* instead.
* @return A vector containing all IP addresses defined for this interface.
*/
// clang-format off
// Breaking the macro into multiple lines causes doxygen to cause a fit.
PCPP_DEPRECATED("This method is deprecated and will be removed in future versions. Please use getIPAddresses() instead.")
// clang-format on
const std::vector<pcap_addr_t>& getAddresses() const
std::vector<IPAddress> getIPAddresses() const
{
return m_Addresses;
return m_InterfaceDetails.addresses;
}

/**
* @return A vector containing all IP addresses defined for this interface.
*/
std::vector<IPAddress> getIPAddresses() const;

/**
* @return The MAC address for this interface
*/
Expand Down Expand Up @@ -637,14 +643,12 @@ namespace pcpp
* Clones the current device class
* @return Pointer to the copied class
*/
PcapLiveDevice* clone() const;
virtual PcapLiveDevice* clone() const;

void getStatistics(IPcapDevice::PcapStats& stats) const override;

protected:
pcap_t* doOpen(const DeviceConfiguration& config);

virtual PcapLiveDevice* cloneInternal(pcap_if_t& devInterface) const;
};

} // namespace pcpp
8 changes: 8 additions & 0 deletions Pcap++/header/PcapRemoteDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ namespace pcpp
// c'tor is private, as only PcapRemoteDeviceList should create instances of it, and it'll create only one for
// every remote interface
PcapRemoteDevice(pcap_if_t* iface, std::shared_ptr<PcapRemoteAuthentication> remoteAuthentication,
const IPAddress& remoteMachineIP, uint16_t remoteMachinePort)
: PcapRemoteDevice(DeviceInterfaceDetails(iface), std::move(remoteAuthentication), remoteMachineIP,
remoteMachinePort)
{}
PcapRemoteDevice(DeviceInterfaceDetails deviceInterface,
std::shared_ptr<PcapRemoteAuthentication> remoteAuthentication,
const IPAddress& remoteMachineIP, uint16_t remoteMachinePort);

public:
Expand Down Expand Up @@ -155,6 +161,8 @@ namespace pcpp
bool open() override;

void getStatistics(IPcapDevice::PcapStats& stats) const override;

PcapRemoteDevice* clone() const override;
};

} // namespace pcpp
16 changes: 10 additions & 6 deletions Pcap++/header/WinPcapLiveDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ namespace pcpp
int m_MinAmountOfDataToCopyFromKernelToApplication;

// c'tor is not public, there should be only one for every interface (created by PcapLiveDeviceList)
WinPcapLiveDevice(pcap_if_t* iface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway);
// copy c'tor is not public
WinPcapLiveDevice(const WinPcapLiveDevice& other);
WinPcapLiveDevice& operator=(const WinPcapLiveDevice& other);
WinPcapLiveDevice(pcap_if_t* iface, bool calculateMTU, bool calculateMacAddress, bool calculateDefaultGateway)
: WinPcapLiveDevice(DeviceInterfaceDetails(iface), calculateMTU, calculateMacAddress,
calculateDefaultGateway)
{}
WinPcapLiveDevice(DeviceInterfaceDetails interfaceDetails, bool calculateMTU, bool calculateMacAddress,
bool calculateDefaultGateway);

public:
WinPcapLiveDevice(const WinPcapLiveDevice& other) = delete;
WinPcapLiveDevice& operator=(const WinPcapLiveDevice& other) = delete;

LiveDeviceType getDeviceType() const override
{
return WinPcapDevice;
Expand Down Expand Up @@ -69,8 +74,7 @@ namespace pcpp
return m_MinAmountOfDataToCopyFromKernelToApplication;
}

protected:
WinPcapLiveDevice* cloneInternal(pcap_if_t& devInterface) const override;
WinPcapLiveDevice* clone() const override;
};

} // namespace pcpp
Loading

0 comments on commit 662f027

Please sign in to comment.