Skip to content

Commit 3c37937

Browse files
authored
Unified file device statistics tracking. (#1958)
* Defaulted empty destructor. * Consolidated file device statistics tracking under `IFileDevice`. * Lint * Fixed merge issues.
1 parent d5094c8 commit 3c37937

File tree

2 files changed

+63
-98
lines changed

2 files changed

+63
-98
lines changed

Pcap++/header/PcapFileDevice.h

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,38 @@ namespace pcpp
5252

5353
/// Close the file
5454
void close() override;
55+
56+
/// @brief Get the statistics for this device.
57+
///
58+
/// The PcapStats structure will hold the following:
59+
/// - packetsRecv: Number of packets processed (read or written, depending on the device type)
60+
/// - packetsDrop: Number of packets dropped (not read or not written, depending on the device type)
61+
/// - packetsDropByInterface: Not supported for file devices, will always be 0
62+
///
63+
/// @param[out] stats The stats object to fill in.
64+
void getStatistics(PcapStats& stats) const override;
65+
66+
protected:
67+
/// @brief Report that packets were processed (read or written, depending on the device type).
68+
/// @param numPackets The number of packets processed. Default is 1.
69+
void reportPacketProcessed(uint64_t numPackets = 1)
70+
{
71+
m_NumOfPacketsProcessed += numPackets;
72+
}
73+
74+
/// @brief Report that packets were dropped (not read or not written, depending on the device type).
75+
/// @param numPackets The number of packets dropped. Default is 1.
76+
void reportPacketDropped(uint64_t numPackets = 1)
77+
{
78+
m_NumOfPacketsDropped += numPackets;
79+
}
80+
81+
/// @brief Reset the internal statistic counters to zero.
82+
void resetStatisticCounters();
83+
84+
private:
85+
uint64_t m_NumOfPacketsProcessed = 0;
86+
uint64_t m_NumOfPacketsDropped = 0;
5587
};
5688

5789
/// @class IFileReaderDevice
@@ -60,9 +92,6 @@ namespace pcpp
6092
class IFileReaderDevice : public IFileDevice
6193
{
6294
protected:
63-
uint32_t m_NumOfPacketsRead;
64-
uint32_t m_NumOfPacketsNotParsed;
65-
6695
/// A constructor for this class that gets the pcap full path file name to open. Notice that after calling this
6796
/// constructor the file isn't opened yet, so reading packets will fail. For opening the file call open()
6897
/// @param[in] fileName The full path of the file to read
@@ -98,15 +127,11 @@ namespace pcpp
98127
class IFileWriterDevice : public IFileDevice
99128
{
100129
protected:
101-
uint32_t m_NumOfPacketsWritten;
102-
uint32_t m_NumOfPacketsNotWritten;
103-
104130
IFileWriterDevice(const std::string& fileName);
105131

106132
public:
107133
/// A destructor for this class
108-
virtual ~IFileWriterDevice()
109-
{}
134+
virtual ~IFileWriterDevice() = default;
110135

111136
virtual bool writePacket(RawPacket const& packet) = 0;
112137

@@ -171,11 +196,6 @@ namespace pcpp
171196
/// @return True if file was opened successfully or if file is already opened. False if opening the file failed
172197
/// for some reason (for example: file path does not exist)
173198
bool open();
174-
175-
/// Get statistics of packets read so far. In the PcapStats struct, only the packetsRecv member is relevant. The
176-
/// rest of the members will contain 0
177-
/// @param[out] stats The stats struct where stats are returned
178-
void getStatistics(PcapStats& stats) const;
179199
};
180200

181201
/// @class PcapFileWriterDevice
@@ -266,10 +286,6 @@ namespace pcpp
266286
/// Flush packets to disk.
267287
void flush();
268288

269-
/// Get statistics of packets written so far.
270-
/// @param[out] stats The stats struct where stats are returned
271-
void getStatistics(PcapStats& stats) const override;
272-
273289
private:
274290
bool openWrite();
275291
bool openAppend();
@@ -346,10 +362,6 @@ namespace pcpp
346362
/// for some reason (for example: file path does not exist)
347363
bool open();
348364

349-
/// Get statistics of packets read so far.
350-
/// @param[out] stats The stats struct where stats are returned
351-
void getStatistics(PcapStats& stats) const;
352-
353365
/// Set a filter for PcapNG reader device. Only packets that match the filter will be received
354366
/// @param[in] filterAsString The filter to be set in Berkeley Packet Filter (BPF) syntax
355367
/// (http://biot.com/capstats/bpf.html)
@@ -456,10 +468,6 @@ namespace pcpp
456468
/// Flush and close the pcap-ng file
457469
void close() override;
458470

459-
/// Get statistics of packets written so far.
460-
/// @param[out] stats The stats struct where stats are returned
461-
void getStatistics(PcapStats& stats) const override;
462-
463471
/// Set a filter for PcapNG writer device. Only packets that match the filter will be persisted
464472
/// @param[in] filterAsString The filter to be set in Berkeley Packet Filter (BPF) syntax
465473
/// (http://biot.com/capstats/bpf.html)
@@ -550,11 +558,6 @@ namespace pcpp
550558
/// for some reason (for example: file path does not exist)
551559
bool open();
552560

553-
/// Get statistics of packets read so far. In the PcapStats struct, only the packetsRecv member is relevant. The
554-
/// rest of the members will contain 0
555-
/// @param[out] stats The stats struct where stats are returned
556-
void getStatistics(PcapStats& stats) const;
557-
558561
/// Close the snoop file
559562
void close();
560563
};

Pcap++/src/PcapFileDevice.cpp

Lines changed: 30 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,26 @@ namespace pcpp
9696
m_DeviceOpened = false;
9797
}
9898

99+
void IFileDevice::getStatistics(PcapStats& stats) const
100+
{
101+
PCPP_LOG_DEBUG("Statistics requested for file device for filename '" << m_FileName << "'");
102+
stats.packetsRecv = m_NumOfPacketsProcessed;
103+
stats.packetsDrop = m_NumOfPacketsDropped;
104+
stats.packetsDropByInterface = 0;
105+
}
106+
107+
void IFileDevice::resetStatisticCounters()
108+
{
109+
m_NumOfPacketsProcessed = 0;
110+
m_NumOfPacketsDropped = 0;
111+
}
112+
99113
// ~~~~~~~~~~~~~~~~~~~~~~~~~
100114
// IFileReaderDevice members
101115
// ~~~~~~~~~~~~~~~~~~~~~~~~~
102116

103117
IFileReaderDevice::IFileReaderDevice(const std::string& fileName) : IFileDevice(fileName)
104-
{
105-
m_NumOfPacketsNotParsed = 0;
106-
m_NumOfPacketsRead = 0;
107-
}
118+
{}
108119

109120
IFileReaderDevice* IFileReaderDevice::getReader(const std::string& fileName)
110121
{
@@ -152,19 +163,15 @@ namespace pcpp
152163
// ~~~~~~~~~~~~~~~~~~~~~~~~~
153164

154165
IFileWriterDevice::IFileWriterDevice(const std::string& fileName) : IFileDevice(fileName)
155-
{
156-
m_NumOfPacketsNotWritten = 0;
157-
m_NumOfPacketsWritten = 0;
158-
}
166+
{}
159167

160168
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161169
// PcapFileReaderDevice members
162170
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163171

164172
bool PcapFileReaderDevice::open()
165173
{
166-
m_NumOfPacketsRead = 0;
167-
m_NumOfPacketsNotParsed = 0;
174+
resetStatisticCounters();
168175

169176
if (m_PcapDescriptor != nullptr)
170177
{
@@ -217,14 +224,6 @@ namespace pcpp
217224
return checkNanoSupport();
218225
}
219226

220-
void PcapFileReaderDevice::getStatistics(PcapStats& stats) const
221-
{
222-
stats.packetsRecv = m_NumOfPacketsRead;
223-
stats.packetsDrop = m_NumOfPacketsNotParsed;
224-
stats.packetsDropByInterface = 0;
225-
PCPP_LOG_DEBUG("Statistics received for reader device for filename '" << m_FileName << "'");
226-
}
227-
228227
bool PcapFileReaderDevice::getNextPacket(RawPacket& rawPacket)
229228
{
230229
rawPacket.clear();
@@ -255,7 +254,7 @@ namespace pcpp
255254
PCPP_LOG_ERROR("Couldn't set data to raw packet");
256255
return false;
257256
}
258-
m_NumOfPacketsRead++;
257+
reportPacketProcessed();
259258
return true;
260259
}
261260

@@ -298,14 +297,14 @@ namespace pcpp
298297
if ((!m_AppendMode && m_PcapDescriptor == nullptr) || (m_PcapDumpHandler == nullptr))
299298
{
300299
PCPP_LOG_ERROR("Device not opened");
301-
m_NumOfPacketsNotWritten++;
300+
reportPacketDropped();
302301
return false;
303302
}
304303

305304
if (packet.getLinkLayerType() != m_PcapLinkLayerType)
306305
{
307306
PCPP_LOG_ERROR("Cannot write a packet with a different link layer type");
308-
m_NumOfPacketsNotWritten++;
307+
reportPacketDropped();
309308
return false;
310309
}
311310

@@ -348,7 +347,7 @@ namespace pcpp
348347
fwrite(packet.getRawData(), pktHdrTemp.caplen, 1, m_File);
349348
}
350349
PCPP_LOG_DEBUG("Packet written successfully to '" << m_FileName << "'");
351-
m_NumOfPacketsWritten++;
350+
reportPacketProcessed();
352351
return true;
353352
}
354353

@@ -408,8 +407,7 @@ namespace pcpp
408407
break;
409408
}
410409

411-
m_NumOfPacketsNotWritten = 0;
412-
m_NumOfPacketsWritten = 0;
410+
resetStatisticCounters();
413411

414412
#if defined(PCAP_TSTAMP_PRECISION_NANO)
415413
auto pcapDescriptor = internal::PcapHandle(pcap_open_dead_with_tstamp_precision(
@@ -534,14 +532,6 @@ namespace pcpp
534532
PCPP_LOG_DEBUG("File writer closed for file '" << m_FileName << "'");
535533
}
536534

537-
void PcapFileWriterDevice::getStatistics(PcapStats& stats) const
538-
{
539-
stats.packetsRecv = m_NumOfPacketsWritten;
540-
stats.packetsDrop = m_NumOfPacketsNotWritten;
541-
stats.packetsDropByInterface = 0;
542-
PCPP_LOG_DEBUG("Statistics received for writer device for filename '" << m_FileName << "'");
543-
}
544-
545535
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
546536
// PcapNgFileReaderDevice members
547537
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -553,8 +543,7 @@ namespace pcpp
553543

554544
bool PcapNgFileReaderDevice::open()
555545
{
556-
m_NumOfPacketsRead = 0;
557-
m_NumOfPacketsNotParsed = 0;
546+
resetStatisticCounters();
558547

559548
if (m_LightPcapNg != nullptr)
560549
{
@@ -623,7 +612,7 @@ namespace pcpp
623612
if (pktHeader.comment != nullptr && pktHeader.comment_length > 0)
624613
packetComment = std::string(pktHeader.comment, pktHeader.comment_length);
625614

626-
m_NumOfPacketsRead++;
615+
reportPacketProcessed();
627616
return true;
628617
}
629618

@@ -633,14 +622,6 @@ namespace pcpp
633622
return getNextPacket(rawPacket, temp);
634623
}
635624

636-
void PcapNgFileReaderDevice::getStatistics(PcapStats& stats) const
637-
{
638-
stats.packetsRecv = m_NumOfPacketsRead;
639-
stats.packetsDrop = m_NumOfPacketsNotParsed;
640-
stats.packetsDropByInterface = 0;
641-
PCPP_LOG_DEBUG("Statistics received for pcapng reader device for filename '" << m_FileName << "'");
642-
}
643-
644625
bool PcapNgFileReaderDevice::setFilter(std::string filterAsString)
645626
{
646627
return m_BpfWrapper.setFilter(filterAsString);
@@ -734,7 +715,7 @@ namespace pcpp
734715
if (m_LightPcapNg == nullptr)
735716
{
736717
PCPP_LOG_ERROR("Device not opened");
737-
m_NumOfPacketsNotWritten++;
718+
reportPacketDropped();
738719
return false;
739720
}
740721

@@ -763,7 +744,7 @@ namespace pcpp
763744
const uint8_t* pktData = packet.getRawData();
764745

765746
light_write_packet(toLightPcapNgT(m_LightPcapNg), &pktHeader, pktData);
766-
m_NumOfPacketsWritten++;
747+
reportPacketProcessed();
767748
return true;
768749
}
769750

@@ -815,8 +796,7 @@ namespace pcpp
815796
return true;
816797
}
817798

818-
m_NumOfPacketsNotWritten = 0;
819-
m_NumOfPacketsWritten = 0;
799+
resetStatisticCounters();
820800

821801
light_pcapng_file_info* info;
822802
if (metadata == nullptr)
@@ -857,8 +837,7 @@ namespace pcpp
857837
return true;
858838
}
859839

860-
m_NumOfPacketsNotWritten = 0;
861-
m_NumOfPacketsWritten = 0;
840+
resetStatisticCounters();
862841

863842
m_LightPcapNg = toLightPcapNgHandle(light_pcapng_open_append(m_FileName.c_str()));
864843
if (m_LightPcapNg == nullptr)
@@ -895,14 +874,6 @@ namespace pcpp
895874
PCPP_LOG_DEBUG("File writer closed for file '" << m_FileName << "'");
896875
}
897876

898-
void PcapNgFileWriterDevice::getStatistics(PcapStats& stats) const
899-
{
900-
stats.packetsRecv = m_NumOfPacketsWritten;
901-
stats.packetsDrop = m_NumOfPacketsNotWritten;
902-
stats.packetsDropByInterface = 0;
903-
PCPP_LOG_DEBUG("Statistics received for pcap-ng writer device for filename '" << m_FileName << "'");
904-
}
905-
906877
bool PcapNgFileWriterDevice::setFilter(std::string filterAsString)
907878
{
908879
return m_BpfWrapper.setFilter(filterAsString);
@@ -919,8 +890,7 @@ namespace pcpp
919890

920891
bool SnoopFileReaderDevice::open()
921892
{
922-
m_NumOfPacketsRead = 0;
923-
m_NumOfPacketsNotParsed = 0;
893+
resetStatisticCounters();
924894

925895
m_snoopFile.open(m_FileName.c_str(), std::ifstream::binary);
926896
if (!m_snoopFile.is_open())
@@ -970,14 +940,6 @@ namespace pcpp
970940
return true;
971941
}
972942

973-
void SnoopFileReaderDevice::getStatistics(PcapStats& stats) const
974-
{
975-
stats.packetsRecv = m_NumOfPacketsRead;
976-
stats.packetsDrop = m_NumOfPacketsNotParsed;
977-
stats.packetsDropByInterface = 0;
978-
PCPP_LOG_DEBUG("Statistics received for reader device for filename '" << m_FileName << "'");
979-
}
980-
981943
bool SnoopFileReaderDevice::getNextPacket(RawPacket& rawPacket)
982944
{
983945
rawPacket.clear();
@@ -1019,7 +981,7 @@ namespace pcpp
1019981
return false;
1020982
}
1021983

1022-
m_NumOfPacketsRead++;
984+
reportPacketProcessed();
1023985
return true;
1024986
}
1025987

0 commit comments

Comments
 (0)