Skip to content

Commit 8e3e9cf

Browse files
authored
Refactored overrides of WinPcapLiveDevice::startCapture. (#1832)
* Added an extension point `prepareCapture` allowing derived classes of `PcapLiveDevice` to run logic prior to initializing capture. - Replaced WinPcapLiveDevice overrides of `startCapture` with a `prepareCapture` method. * Added `final` qualifier to `startCapture` as a transitional step before converting the virtual methods to static. * Removed final qualifier. Added a remarks section in startCapture comments. * Changed usage to pcapDesciptor.getLastError()
1 parent dfeb47b commit 8e3e9cf

File tree

4 files changed

+59
-50
lines changed

4 files changed

+59
-50
lines changed

Pcap++/header/PcapLiveDevice.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ namespace pcpp
404404
/// - Capture is already running
405405
/// - Device is not opened
406406
/// - Capture thread could not be created
407+
/// @remarks This method is planned for conversion to non-virtual in the future, so it should not be overridden.
407408
virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie);
408409

409410
/// Start capturing packets on this network interface (device) with periodic stats collection. Each time a
@@ -428,6 +429,7 @@ namespace pcpp
428429
/// - Device is not opened
429430
/// - Capture thread could not be created
430431
/// - Stats collection thread could not be created
432+
/// @remarks This method is planned for conversion to non-virtual in the future, so it should not be overridden.
431433
virtual bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie,
432434
int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
433435
void* onStatsUpdateUserCookie);
@@ -448,6 +450,7 @@ namespace pcpp
448450
/// - Capture is already running
449451
/// - Device is not opened
450452
/// - Stats collection thread could not be created
453+
/// @remarks This method is planned for conversion to non-virtual in the future, so it should not be overridden.
451454
virtual bool startCapture(int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
452455
void* onStatsUpdateUserCookie);
453456

@@ -464,6 +467,7 @@ namespace pcpp
464467
/// - Capture is already running
465468
/// - Device is not opened
466469
/// - Capture thread could not be created
470+
/// @remarks This method is planned for conversion to non-virtual in the future, so it should not be overridden.
467471
virtual bool startCapture(RawPacketVector& capturedPacketsVector);
468472

469473
/// Start capturing packets on this network interface (device) in blocking mode, meaning this method blocks and
@@ -489,6 +493,7 @@ namespace pcpp
489493
/// occurred (such as device not open etc.). When returning 0 an appropriate error message is printed to log
490494
/// @note On Unix-like systems, enabling the `usePoll` option in `DeviceConfiguration` prevents the method from
491495
/// blocking indefinitely when no packets are available, even if a timeout is set.
496+
/// @remarks This method is planned for conversion to non-virtual in the future, so it should not be overridden.
492497
virtual int startCaptureBlockingMode(OnPacketArrivesStopBlocking onPacketArrives, void* userCookie,
493498
const double timeout);
494499

@@ -654,6 +659,16 @@ namespace pcpp
654659
void getStatistics(IPcapDevice::PcapStats& stats) const override;
655660

656661
protected:
662+
/// @brief Called before starting a capture to prepare the device for capturing packets.
663+
///
664+
/// This method can be overridden by derived classes to perform additional preparations before starting
665+
/// the packet capture.
666+
///
667+
/// @param asyncCapture True if the capture is asynchronous (i.e. packets are captured in a separate thread),
668+
/// @param captureStats True if statistics should be captured during the capture process.
669+
virtual void prepareCapture(bool asyncCapture, bool captureStats)
670+
{}
671+
657672
internal::PcapHandle doOpen(const DeviceConfiguration& config);
658673

659674
// Sends a packet directly to the network.

Pcap++/header/WinPcapLiveDevice.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,6 @@ namespace pcpp
3737
return WinPcapDevice;
3838
}
3939

40-
bool startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie,
41-
int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
42-
void* onStatsUpdateUserCookie) override;
43-
bool startCapture(int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
44-
void* onStatsUpdateUserCookie) override;
45-
bool startCapture(RawPacketVector& capturedPacketsVector) override
46-
{
47-
return PcapLiveDevice::startCapture(capturedPacketsVector);
48-
}
49-
5040
using PcapLiveDevice::sendPackets;
5141
virtual int sendPackets(RawPacket* rawPacketsArr, int arrLength);
5242

@@ -66,5 +56,8 @@ namespace pcpp
6656
}
6757

6858
WinPcapLiveDevice* clone() const override;
59+
60+
protected:
61+
void prepareCapture(bool asyncCapture, bool captureStats) override;
6962
};
7063
} // namespace pcpp

Pcap++/src/PcapLiveDevice.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,16 @@ namespace pcpp
658658
return false;
659659
}
660660

661+
try
662+
{
663+
prepareCapture(true, onStatsUpdate != nullptr);
664+
}
665+
catch (std::exception const& ex)
666+
{
667+
PCPP_LOG_ERROR("Failed to prepare capture: " << ex.what());
668+
return false;
669+
}
670+
661671
m_CaptureCallbackMode = true;
662672
m_cbOnPacketArrives = std::move(onPacketArrives);
663673
m_cbOnPacketArrivesUserCookie = onPacketArrivesUserCookie;
@@ -700,6 +710,16 @@ namespace pcpp
700710
return false;
701711
}
702712

713+
try
714+
{
715+
prepareCapture(true, false);
716+
}
717+
catch (const std::exception& ex)
718+
{
719+
PCPP_LOG_ERROR("Failed to prepare capture: " << ex.what());
720+
return false;
721+
}
722+
703723
m_CapturedPackets = &capturedPacketsVector;
704724
m_CapturedPackets->clear();
705725

@@ -733,6 +753,15 @@ namespace pcpp
733753
return 0;
734754
}
735755

756+
try
757+
{
758+
prepareCapture(false, false);
759+
}
760+
catch (const std::exception& ex)
761+
{
762+
PCPP_LOG_ERROR("Failed to prepare capture: " << ex.what());
763+
return 0;
764+
}
736765
m_cbOnPacketArrives = nullptr;
737766
m_cbOnPacketArrivesUserCookie = nullptr;
738767

Pcap++/src/WinPcapLiveDevice.cpp

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,46 +18,6 @@ namespace pcpp
1818
m_MinAmountOfDataToCopyFromKernelToApplication = 16000;
1919
}
2020

21-
bool WinPcapLiveDevice::startCapture(OnPacketArrivesCallback onPacketArrives, void* onPacketArrivesUserCookie,
22-
int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
23-
void* onStatsUpdateUserCookie)
24-
{
25-
if (!m_DeviceOpened || m_PcapDescriptor == nullptr)
26-
{
27-
PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened");
28-
return false;
29-
}
30-
31-
// Put the interface in capture mode
32-
if (pcap_setmode(m_PcapDescriptor.get(), MODE_CAPT) < 0)
33-
{
34-
PCPP_LOG_ERROR("Error setting the capture mode for device '" << m_InterfaceDetails.name << "'");
35-
return false;
36-
}
37-
38-
return PcapLiveDevice::startCapture(onPacketArrives, onPacketArrivesUserCookie, intervalInSecondsToUpdateStats,
39-
onStatsUpdate, onStatsUpdateUserCookie);
40-
}
41-
42-
bool WinPcapLiveDevice::startCapture(int intervalInSecondsToUpdateStats, OnStatsUpdateCallback onStatsUpdate,
43-
void* onStatsUpdateUserCookie)
44-
{
45-
if (!m_DeviceOpened || m_PcapDescriptor == nullptr)
46-
{
47-
PCPP_LOG_ERROR("Device '" << m_InterfaceDetails.name << "' not opened");
48-
return false;
49-
}
50-
51-
// Put the interface in statistics mode
52-
if (pcap_setmode(m_PcapDescriptor.get(), MODE_STAT) < 0)
53-
{
54-
PCPP_LOG_ERROR("Error setting the statistics mode for device '" << m_InterfaceDetails.name << "'");
55-
return false;
56-
}
57-
58-
return PcapLiveDevice::startCapture(intervalInSecondsToUpdateStats, onStatsUpdate, onStatsUpdateUserCookie);
59-
}
60-
6121
int WinPcapLiveDevice::sendPackets(RawPacket* rawPacketsArr, int arrLength)
6222
{
6323
if (!m_DeviceOpened || m_PcapDescriptor == nullptr)
@@ -145,4 +105,16 @@ namespace pcpp
145105
return new WinPcapLiveDevice(m_InterfaceDetails, true, true, true);
146106
}
147107

108+
void WinPcapLiveDevice::prepareCapture(bool asyncCapture, bool captureStats)
109+
{
110+
111+
int mode = captureStats ? MODE_STAT : MODE_CAPT;
112+
int res = pcap_setmode(m_PcapDescriptor.get(), mode);
113+
if (res < 0)
114+
{
115+
throw std::runtime_error("Error setting the mode for device '" + m_InterfaceDetails.name +
116+
"': " + m_PcapDescriptor.getLastError());
117+
}
118+
}
119+
148120
} // namespace pcpp

0 commit comments

Comments
 (0)