Skip to content

Commit

Permalink
Fixed live device clone method returning wrong device type on win32 m…
Browse files Browse the repository at this point in the history
…achines. (#1406)

* Added unit test to ensure windows systems get WinPcapLiveDevice after clone.

* Marked clone as a virtual method. Added clone override for WinPcapLiveDevice.

* Lint

* Deduplicated shared code between clones of PcapLiveDevice and WinPcapLiveDevice.

* Changed clone internal signature on derived class.
  • Loading branch information
Dimi1010 authored May 30, 2024
1 parent cc2507e commit e4f8328
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 6 deletions.
4 changes: 3 additions & 1 deletion Pcap++/header/PcapLiveDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,12 +570,14 @@ namespace pcpp
* Clones the current device class
* @return Pointer to the copied class
*/
PcapLiveDevice* clone();
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
3 changes: 3 additions & 0 deletions Pcap++/header/WinPcapLiveDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ namespace pcpp
* setMinAmountOfDataToCopyFromKernelToApplication())
*/
int getMinAmountOfDataToCopyFromKernelToApplication() const { return m_MinAmountOfDataToCopyFromKernelToApplication; }

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

} // namespace pcpp
Expand Down
13 changes: 9 additions & 4 deletions Pcap++/src/PcapLiveDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,11 @@ void PcapLiveDevice::close()
PCPP_LOG_DEBUG("Device '" << m_Name << "' closed");
}

PcapLiveDevice* PcapLiveDevice::clone()
PcapLiveDevice* PcapLiveDevice::clone() const
{
PcapLiveDevice *retval = nullptr;
PcapLiveDevice* retval = nullptr;

pcap_if_t *interfaceList;
pcap_if_t* interfaceList;
char errbuf[PCAP_ERRBUF_SIZE];
int err = pcap_findalldevs(&interfaceList, errbuf);
if (err < 0)
Expand All @@ -424,14 +424,19 @@ PcapLiveDevice* PcapLiveDevice::clone()
}

if(currInterface)
retval = new PcapLiveDevice(currInterface, true, true, true);
retval = cloneInternal(*currInterface);
else
PCPP_LOG_ERROR("Can't find interface " << getName().c_str());

pcap_freealldevs(interfaceList);
return retval;
}

PcapLiveDevice* PcapLiveDevice::cloneInternal(pcap_if_t& devInterface) const
{
return new PcapLiveDevice(&devInterface, true, true, true);
}

bool PcapLiveDevice::startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie)
{
return startCapture(std::move(onPacketArrives), onPacketArrivesUserCookie, 0, nullptr, nullptr);
Expand Down
5 changes: 5 additions & 0 deletions Pcap++/src/WinPcapLiveDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ bool WinPcapLiveDevice::setMinAmountOfDataToCopyFromKernelToApplication(int size
return true;
}

WinPcapLiveDevice* WinPcapLiveDevice::cloneInternal(pcap_if_t& devInterface) const
{
return new WinPcapLiveDevice(&devInterface, true, true, true);
}

} // namespace pcpp

#endif // _WIN32
20 changes: 19 additions & 1 deletion Tests/Pcap++Test/Tests/LiveDeviceTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,26 @@ PTF_TEST_CASE(TestPcapLiveDeviceClone)
// Test of clone device should be same with original
pcpp::PcapLiveDevice* liveDev = nullptr;
pcpp::IPv4Address ipToSearch(PcapTestGlobalArgs.ipToSendReceivePackets.c_str());
liveDev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(ipToSearch)->clone();

{
pcpp::PcapLiveDevice* originalDev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(ipToSearch);
PTF_ASSERT_NOT_NULL(originalDev);

#ifdef _WIN32
// Tests if device pointer points to a Windows Live Device on a Windows machine.
PTF_ASSERT_NOT_NULL(dynamic_cast<pcpp::WinPcapLiveDevice*>(originalDev));
#endif // _WIN32

liveDev = originalDev->clone();
}

PTF_ASSERT_NOT_NULL(liveDev);

#ifdef _WIN32
// Tests if the clone is correctly returns a Windows Live Device on Windows systems.
PTF_ASSERT_NOT_NULL(dynamic_cast<pcpp::WinPcapLiveDevice*>(liveDev));
#endif // _WIN32

PTF_ASSERT_GREATER_THAN(liveDev->getMtu(), 0);
PTF_ASSERT_TRUE(liveDev->open());
DeviceTeardown devTeardown(liveDev, true);
Expand Down

0 comments on commit e4f8328

Please sign in to comment.