@@ -152,77 +152,84 @@ namespace pcpp
152152 // / packet-by-packet
153153 class PcapFileReaderDevice : public IFileReaderDevice
154154 {
155- private:
156- FileTimestampPrecision m_Precision;
157- LinkLayerType m_PcapLinkLayerType;
158-
159- // private copy c'tor
160- PcapFileReaderDevice (const PcapFileReaderDevice& other);
161- PcapFileReaderDevice& operator =(const PcapFileReaderDevice& other);
162-
163155 public:
164156 // / A constructor for this class that gets the pcap full path file name to open. Notice that after calling this
165157 // / constructor the file isn't opened yet, so reading packets will fail. For opening the file call open()
166158 // / @param[in] fileName The full path of the file to read
167- PcapFileReaderDevice (const std::string& fileName)
168- : IFileReaderDevice(fileName), m_Precision(FileTimestampPrecision::Unknown),
169- m_PcapLinkLayerType (LINKTYPE_ETHERNET)
159+ explicit PcapFileReaderDevice (const std::string& fileName) : IFileReaderDevice(fileName)
170160 {}
171161
172162 // / A destructor for this class
173- virtual ~PcapFileReaderDevice () = default ;
163+ ~PcapFileReaderDevice () override = default ;
164+
165+ PcapFileReaderDevice (const PcapFileReaderDevice& other) = delete ;
166+ PcapFileReaderDevice& operator =(const PcapFileReaderDevice& other) = delete ;
174167
175168 // / @return The link layer type of this file
176169 LinkLayerType getLinkLayerType () const
177170 {
178171 return m_PcapLinkLayerType;
179172 }
180173
181- // / @return The precision of the timestamps in the file. If the platform supports nanosecond precision, this
182- // / method will return nanoseconds even if the file has microseconds since libpcap scales timestamps before
183- // / supply. Otherwise, it will return microseconds.
174+ // / @return The precision of the timestamps in the file
184175 FileTimestampPrecision getTimestampPrecision () const
185176 {
186177 return m_Precision;
187178 }
188179
180+ // / @return The file's snapshot length (snaplen)
181+ uint32_t getSnapshotLength () const
182+ {
183+ return m_SnapshotLength;
184+ }
185+
189186 // / A static method that checks if nano-second precision is supported in the current platform and environment
190187 // / @return True if nano-second precision is supported, false otherwise
191- static bool isNanoSecondPrecisionSupported ();
188+ // / @deprecated Nanosecond precision is now natively supported by the internal parser and always returns true
189+ PCPP_DEPRECATED (" Nanosecond precision is now natively supported by the internal parser and always returns true" )
190+ static bool isNanoSecondPrecisionSupported ()
191+ {
192+ return true ;
193+ }
192194
193195 // overridden methods
194196
195197 // / Read the next packet from the file. Before using this method please verify the file is opened using open()
196198 // / @param[out] rawPacket A reference for an empty RawPacket where the packet will be written
197199 // / @return True if a packet was read successfully. False will be returned if the file isn't opened (also, an
198200 // / error log will be printed) or if reached end-of-file
199- bool getNextPacket (RawPacket& rawPacket);
201+ bool getNextPacket (RawPacket& rawPacket) override ;
200202
201203 // / Open the file name which path was specified in the constructor in a read-only mode
202204 // / @return True if file was opened successfully or if file is already opened. False if opening the file failed
203205 // / for some reason (for example: file path does not exist)
204- bool open ();
206+ bool open () override ;
207+
208+ // / Close the pacp file
209+ void close () override ;
210+
211+ protected:
212+ bool doUpdateFilter (std::string const * filterAsString) override ;
213+
214+ private:
215+ FileTimestampPrecision m_Precision = FileTimestampPrecision::Unknown;
216+ LinkLayerType m_PcapLinkLayerType = LINKTYPE_ETHERNET;
217+ std::ifstream m_PcapFile;
218+ bool m_NeedsSwap = false ;
219+ uint32_t m_SnapshotLength = 0 ;
220+ BpfFilterWrapper m_BpfWrapper;
221+
222+ bool readNextPacket (timespec& packetTimestamp, uint8_t * packetData, uint32_t packetDataLen,
223+ uint32_t & capturedLength, uint32_t & frameLength);
205224 };
206225
207226 // / @class PcapFileWriterDevice
208- // / A class for opening a pcap file for writing or create a new pcap file and write packets to it. This class adds
209- // / a unique capability that isn't supported in WinPcap and in older libpcap versions which is to open a pcap file
210- // / in append mode where packets are written at the end of the pcap file instead of running it over
227+ // / A class for opening a pcap file for writing or creating a new pcap file and writing packets to it.
228+ // / It supports opening a pcap file in append mode where packets are written at the end of the file
229+ // / instead of overwriting it. This implementation writes the pcap stream directly using C++ I/O
230+ // / facilities (std::fstream) and does not require libpcap/WinPcap at runtime.
211231 class PcapFileWriterDevice : public IFileWriterDevice
212232 {
213- private:
214- pcap_dumper_t * m_PcapDumpHandler;
215- LinkLayerType m_PcapLinkLayerType;
216- bool m_AppendMode;
217- FileTimestampPrecision m_Precision;
218- FILE* m_File;
219-
220- // private copy c'tor
221- PcapFileWriterDevice (const PcapFileWriterDevice& other);
222- PcapFileWriterDevice& operator =(const PcapFileWriterDevice& other);
223-
224- void closeFile ();
225-
226233 public:
227234 // / A constructor for this class that gets the pcap full path file name to open for writing or create. Notice
228235 // / that after calling this constructor the file isn't opened yet, so writing packets will fail. For opening the
@@ -237,11 +244,8 @@ namespace pcpp
237244 PcapFileWriterDevice (const std::string& fileName, LinkLayerType linkLayerType = LINKTYPE_ETHERNET,
238245 bool nanosecondsPrecision = false );
239246
240- // / A destructor for this class
241- ~PcapFileWriterDevice ()
242- {
243- PcapFileWriterDevice::close ();
244- }
247+ PcapFileWriterDevice (const PcapFileWriterDevice& other) = delete ;
248+ PcapFileWriterDevice& operator =(const PcapFileWriterDevice& other) = delete ;
245249
246250 // / Write a RawPacket to the file. Before using this method please verify the file is opened using open(). This
247251 // / method won't change the written packet
@@ -268,9 +272,17 @@ namespace pcpp
268272
269273 // / A static method that checks if nano-second precision is supported in the current platform and environment
270274 // / @return True if nano-second precision is supported, false otherwise
271- static bool isNanoSecondPrecisionSupported ();
275+ // / @deprecated Nanosecond precision is now natively supported by the internal parser and always returns true
276+ PCPP_DEPRECATED (" Nanosecond precision is now natively supported by the internal parser and always returns true" )
277+ static bool isNanoSecondPrecisionSupported ()
278+ {
279+ return true ;
280+ }
272281
273- // override methods
282+ LinkLayerType getLinkLayerType () const
283+ {
284+ return m_PcapLinkLayerType;
285+ }
274286
275287 // / Open the file in a write mode. If file doesn't exist, it will be created. If it does exist it will be
276288 // / overwritten, meaning all its current content will be deleted
@@ -294,9 +306,49 @@ namespace pcpp
294306 // / Flush packets to disk.
295307 void flush ();
296308
309+ protected:
310+ bool doUpdateFilter (std::string const * filterAsString) override ;
311+
297312 private:
298- bool openWrite ();
299- bool openAppend ();
313+ LinkLayerType m_PcapLinkLayerType = LINKTYPE_ETHERNET;
314+ bool m_NeedsSwap = false ;
315+ FileTimestampPrecision m_Precision = FileTimestampPrecision::Unknown;
316+ std::fstream m_PcapFile;
317+ BpfFilterWrapper m_BpfWrapper;
318+
319+ struct CheckHeaderResult
320+ {
321+ enum class Result
322+ {
323+ HeaderOk,
324+ HeaderError,
325+ HeaderNeeded
326+ };
327+
328+ Result result;
329+ std::string error;
330+ bool needsSwap = false ;
331+
332+ static CheckHeaderResult fromOk (bool needsSwap)
333+ {
334+ return { Result::HeaderOk, " " , needsSwap };
335+ }
336+
337+ static CheckHeaderResult fromError (const std::string& error)
338+ {
339+ return { Result::HeaderError, error };
340+ }
341+
342+ static CheckHeaderResult fromHeaderNeeded ()
343+ {
344+ return { Result::HeaderNeeded };
345+ }
346+ };
347+
348+ static bool writeHeader (std::fstream& pcapFile, FileTimestampPrecision precision, uint32_t snaplen,
349+ LinkLayerType linkType);
350+ static CheckHeaderResult checkHeader (std::fstream& pcapFile, FileTimestampPrecision requestedPrecision,
351+ LinkLayerType requestedLinkType);
300352 };
301353
302354 // / @class PcapNgFileReaderDevice
0 commit comments