23 #include "ns3/assert.h"
24 #include "ns3/packet.h"
25 #include "ns3/fatal-error.h"
26 #include "ns3/fatal-impl.h"
27 #include "ns3/header.h"
28 #include "ns3/buffer.h"
29 #include "pcap-file.h"
40 const uint32_t
MAGIC = 0xa1b2c3d4;
58 PcapFile::~PcapFile ()
67 PcapFile::Fail (
void)
const
70 return m_file.fail ();
73 PcapFile::Eof (
void)
const
79 PcapFile::Clear (
void)
87 PcapFile::Close (
void)
94 PcapFile::GetMagic (
void)
97 return m_fileHeader.m_magicNumber;
101 PcapFile::GetVersionMajor (
void)
104 return m_fileHeader.m_versionMajor;
108 PcapFile::GetVersionMinor (
void)
111 return m_fileHeader.m_versionMinor;
115 PcapFile::GetTimeZoneOffset (
void)
118 return m_fileHeader.m_zone;
122 PcapFile::GetSigFigs (
void)
125 return m_fileHeader.m_sigFigs;
129 PcapFile::GetSnapLen (
void)
132 return m_fileHeader.m_snapLen;
136 PcapFile::GetDataLinkType (
void)
139 return m_fileHeader.m_type;
143 PcapFile::GetSwapMode (
void)
150 PcapFile::Swap (uint8_t val)
157 PcapFile::Swap (uint16_t val)
160 return ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00);
164 PcapFile::Swap (uint32_t val)
167 return ((val >> 24) & 0x000000ff) | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) | ((val << 24) & 0xff000000);
171 PcapFile::Swap (PcapFileHeader *from, PcapFileHeader *to)
174 to->m_magicNumber = Swap (from->m_magicNumber);
175 to->m_versionMajor = Swap (from->m_versionMajor);
176 to->m_versionMinor = Swap (from->m_versionMinor);
177 to->m_zone = Swap (uint32_t (from->m_zone));
178 to->m_sigFigs = Swap (from->m_sigFigs);
179 to->m_snapLen = Swap (from->m_snapLen);
180 to->m_type = Swap (from->m_type);
184 PcapFile::Swap (PcapRecordHeader *from, PcapRecordHeader *to)
187 to->m_tsSec = Swap (from->m_tsSec);
188 to->m_tsUsec = Swap (from->m_tsUsec);
189 to->m_inclLen = Swap (from->m_inclLen);
190 to->m_origLen = Swap (from->m_origLen);
194 PcapFile::WriteFileHeader (
void)
201 m_file.seekp (0, std::ios::beg);
207 PcapFileHeader header;
213 PcapFileHeader *headerOut = 0;
215 if (m_swapMode ==
false)
217 headerOut = &m_fileHeader;
221 Swap (&m_fileHeader, &header);
229 m_file.write ((
const char *)&headerOut->m_magicNumber,
sizeof(headerOut->m_magicNumber));
230 m_file.write ((
const char *)&headerOut->m_versionMajor,
sizeof(headerOut->m_versionMajor));
231 m_file.write ((
const char *)&headerOut->m_versionMinor,
sizeof(headerOut->m_versionMinor));
232 m_file.write ((
const char *)&headerOut->m_zone,
sizeof(headerOut->m_zone));
233 m_file.write ((
const char *)&headerOut->m_sigFigs,
sizeof(headerOut->m_sigFigs));
234 m_file.write ((
const char *)&headerOut->m_snapLen,
sizeof(headerOut->m_snapLen));
235 m_file.write ((
const char *)&headerOut->m_type,
sizeof(headerOut->m_type));
239 PcapFile::ReadAndVerifyFileHeader (
void)
245 m_file.seekg (0, std::ios::beg);
251 m_file.read ((
char *)&m_fileHeader.m_magicNumber,
sizeof(m_fileHeader.m_magicNumber));
252 m_file.read ((
char *)&m_fileHeader.m_versionMajor,
sizeof(m_fileHeader.m_versionMajor));
253 m_file.read ((
char *)&m_fileHeader.m_versionMinor,
sizeof(m_fileHeader.m_versionMinor));
254 m_file.read ((
char *)&m_fileHeader.m_zone,
sizeof(m_fileHeader.m_zone));
255 m_file.read ((
char *)&m_fileHeader.m_sigFigs,
sizeof(m_fileHeader.m_sigFigs));
256 m_file.read ((
char *)&m_fileHeader.m_snapLen,
sizeof(m_fileHeader.m_snapLen));
257 m_file.read ((
char *)&m_fileHeader.m_type,
sizeof(m_fileHeader.m_type));
269 if (m_fileHeader.m_magicNumber != MAGIC && m_fileHeader.m_magicNumber != SWAPPED_MAGIC &&
270 m_fileHeader.m_magicNumber != NS_MAGIC && m_fileHeader.m_magicNumber != NS_SWAPPED_MAGIC)
272 m_file.setstate (std::ios::failbit);
284 Swap (&m_fileHeader, &m_fileHeader);
290 if (m_fileHeader.m_versionMajor != VERSION_MAJOR || m_fileHeader.m_versionMinor != VERSION_MINOR)
292 m_file.setstate (std::ios::failbit);
299 if (m_fileHeader.m_zone < -12 || m_fileHeader.m_zone > 12)
301 m_file.setstate (std::ios::failbit);
311 PcapFile::Open (std::string
const &filename, std::ios::openmode mode)
319 mode |= std::ios::binary;
321 m_file.open (filename.c_str (), mode);
322 if (mode & std::ios::in)
325 ReadAndVerifyFileHeader ();
330 PcapFile::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t timeZoneCorrection,
bool swapMode)
332 NS_LOG_FUNCTION (
this << dataLinkType << snapLen << timeZoneCorrection << swapMode);
336 m_fileHeader.m_magicNumber =
MAGIC;
339 m_fileHeader.m_zone = timeZoneCorrection;
340 m_fileHeader.m_sigFigs = 0;
341 m_fileHeader.m_snapLen = snapLen;
342 m_fileHeader.m_type = dataLinkType;
364 bool bigEndian = u.b[3];
369 m_swapMode = swapMode | bigEndian;
375 PcapFile::WritePacketHeader (uint32_t tsSec, uint32_t tsUsec, uint32_t totalLen)
380 uint32_t inclLen = totalLen > m_fileHeader.m_snapLen ? m_fileHeader.m_snapLen : totalLen;
382 PcapRecordHeader header;
383 header.m_tsSec = tsSec;
384 header.m_tsUsec = tsUsec;
385 header.m_inclLen = inclLen;
386 header.m_origLen = totalLen;
390 Swap (&header, &header);
397 m_file.write ((
const char *)&header.m_tsSec,
sizeof(header.m_tsSec));
398 m_file.write ((
const char *)&header.m_tsUsec,
sizeof(header.m_tsUsec));
399 m_file.write ((
const char *)&header.m_inclLen,
sizeof(header.m_inclLen));
400 m_file.write ((
const char *)&header.m_origLen,
sizeof(header.m_origLen));
405 PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, uint8_t
const *
const data, uint32_t totalLen)
408 uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, totalLen);
409 m_file.write ((
const char *)data, inclLen);
416 uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, p->
GetSize ());
425 uint32_t totalSize = headerSize + p->
GetSize ();
426 uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, totalSize);
431 uint32_t toCopy = std::min (headerSize, inclLen);
432 headerBuffer.
CopyData (&m_file, toCopy);
439 uint8_t *
const data,
447 NS_LOG_FUNCTION (
this << &data <<maxBytes << tsSec << tsUsec << inclLen << origLen << readLen);
456 m_file.read ((
char *)&header.m_tsSec,
sizeof(header.m_tsSec));
457 m_file.read ((
char *)&header.m_tsUsec,
sizeof(header.m_tsUsec));
458 m_file.read ((
char *)&header.m_inclLen,
sizeof(header.m_inclLen));
459 m_file.read ((
char *)&header.m_origLen,
sizeof(header.m_origLen));
468 Swap (&header, &header);
471 tsSec = header.m_tsSec;
472 tsUsec = header.m_tsUsec;
473 inclLen = header.m_inclLen;
474 origLen = header.m_origLen;
483 readLen = maxBytes < header.m_inclLen ? maxBytes : header.m_inclLen;
484 m_file.read ((
char *)data, readLen);
490 if (readLen < header.m_inclLen)
492 m_file.seekg (header.m_inclLen - readLen, std::ios::cur);
497 PcapFile::Diff (std::string
const & f1, std::string
const & f2,
498 uint32_t & sec, uint32_t & usec,
503 pcap1.
Open (f1, std::ios::in);
504 pcap2.
Open (f2, std::ios::in);
505 bool bad = pcap1.
Fail () || pcap2.
Fail ();
511 uint8_t *data1 =
new uint8_t [snapLen] ();
512 uint8_t *data2 =
new uint8_t [snapLen] ();
515 uint32_t tsUsec1 = 0;
516 uint32_t tsUsec2 = 0;
517 uint32_t inclLen1 = 0;
518 uint32_t inclLen2 = 0;
519 uint32_t origLen1 = 0;
520 uint32_t origLen2 = 0;
521 uint32_t readLen1 = 0;
522 uint32_t readLen2 = 0;
525 while (!pcap1.
Eof () && !pcap2.
Eof ())
527 pcap1.
Read (data1, snapLen, tsSec1, tsUsec1, inclLen1, origLen1, readLen1);
528 pcap2.
Read (data2, snapLen, tsSec2, tsUsec2, inclLen2, origLen2, readLen2);
530 bool same = pcap1.
Fail () == pcap2.
Fail ();
541 if (tsSec1 != tsSec2 || tsUsec1 != tsUsec2)
547 if (readLen1 != readLen2)
553 if (std::memcmp (data1, data2, readLen1) != 0)
562 bad = pcap1.
Fail () || pcap2.
Fail ();
563 bool eof = pcap1.
Eof () && pcap2.
Eof ();
#define NS_LOG_FUNCTION(parameters)
automatically resized byte buffer
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSize(void) const
const uint16_t VERSION_MAJOR
const uint32_t SWAPPED_MAGIC
void Read(uint8_t *const data, uint32_t maxBytes, uint32_t &tsSec, uint32_t &tsUsec, uint32_t &inclLen, uint32_t &origLen, uint32_t &readLen)
Read next packet from file.
void RegisterStream(std::ostream *stream)
Register a stream to be flushed on abnormal exit.
void CopyData(std::ostream *os, uint32_t size) const
Buffer::Iterator Begin(void) const
const uint32_t NS_SWAPPED_MAGIC
void Open(std::string const &filename, std::ios::openmode mode)
const uint16_t VERSION_MINOR
void UnregisterStream(std::ostream *stream)
Unregister a stream for flushing on abnormal exit.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
bool AddAtStart(uint32_t start)
const int32_t SIGFIGS_DEFAULT