extended ICMP packet dumping to parts after packet creation
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Wed, 20 May 2015 10:38:16 +0000 (12:38 +0200)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Wed, 20 May 2015 10:38:16 +0000 (12:38 +0200)
in detail:
* in IcmpPinger::handle_receive_icmp_packet, may get exceptions from boost assertions
  in to_string and print and match_xy functions --> put into a try-catch
* created a dump_packet(packet) and moved dump_packet functions into IcmpPacketFactory
* to dump an IcmpPacket, need to also dump its IP header --> created IpHeader::write
* for this moved the Payload variable from Ipv4/6Header to IpHeader super class
* during testing in feed_packet_data, add skipped byte size to log output

17 files changed:
src/icmp/icmpdata_pingfailreply.cpp
src/icmp/icmpechodata.cpp
src/icmp/icmpechodata.h
src/icmp/icmppacket.cpp
src/icmp/icmppacket.h
src/icmp/icmppacketfactory.cpp
src/icmp/icmppacketfactory.h
src/icmp/icmppinger.cpp
src/ip/ipheader.cpp
src/ip/ipheader.h
src/ip/ipv4header.cpp
src/ip/ipv4header.h
src/ip/ipv6header.cpp
src/ip/ipv6header.h
src/tools/feed_packet_data.cpp
src/tools/pcap.cpp
src/tools/pcap.h

index b7f07cf..91abf10 100644 (file)
@@ -66,7 +66,7 @@ uint16_t IcmpData_PingFailReply::get_icmp_request_data(
                                                 const int icmp_start_byte) const
 {
     // payload should be the original query, which is an IP packet.
-    // first check wheter that IP packet contains an ICMP message at all
+    // first check whether that IP packet contains an ICMP message at all
     int offset = get_icmp_data_offset();
 
     if (offset == -1)
@@ -85,6 +85,8 @@ uint16_t IcmpData_PingFailReply::get_icmp_request_data(
  *
  * Unfortunately, the value in packet is not the original one, but the one
  *   change en route to destination, so in case of TimeExceeded, it is always 1
+ *
+ * @throws boost assertion if data does not seem to start with an IP v4/6 header
  */
 uint8_t IcmpData_PingFailReply::get_ip_ttl() const
 {
@@ -107,9 +109,8 @@ uint8_t IcmpData_PingFailReply::get_ip_ttl() const
 
 /** @brief get byte index of start of ICMP request data after IP header
  *
- * @returns -1 if this data is not a
- * @throws boost assertion if data does not start with an IP header of version
- *   4 or 6
+ * @returns -1 if this data does not contain a ICMP request packet
+ * @throws boost assertion if data does not seem to start with an IP v4/6 header
  */
 int IcmpData_PingFailReply::get_icmp_data_offset() const
 {
@@ -130,9 +131,10 @@ int IcmpData_PingFailReply::get_icmp_data_offset() const
     }
     else
     {
-        GlobalLogger.error() << "Request IP header is neither IPv4 nor v6!"
-                             << std::endl;
-        BOOST_ASSERT( !"Source IP header is neither IPv4 nor v6!" );
+        GlobalLogger.error()
+            << "Icmp data does not seem to start with IPv4/6 header!"
+            << std::endl;
+        BOOST_ASSERT( !"Icmp data does not seem to start with IPv4/6 header!" );
     }
 
     if (is_icmp)
index c2e327d..c213ed5 100644 (file)
@@ -57,7 +57,8 @@ bool IcmpEchoData::match_destination_unreachable(
 
 bool IcmpEchoData::match_time_exceeded(
                                     const uint16_t identifier,
-                                    const uint16_t sequence_number) const
+                                    const uint16_t sequence_number,
+                                    const address &destination_address) const
 { return false; }
 
 
index b5a9fed..946121c 100644 (file)
@@ -54,7 +54,8 @@ public:
                           const uint16_t sequence_number) const;
 
     bool match_time_exceeded(const uint16_t identifier,
-                             const uint16_t sequence_number) const;
+                             const uint16_t sequence_number,
+                             const address &destination_address) const;
 
     uint16_t get_identifier() const;
 
index 873c1b7..5adcaec 100644 (file)
@@ -36,6 +36,7 @@
 #include "icmp/icmpechodata.h"
 #include "icmp/icmpdestinationunreachabledata.h"
 #include "icmp/icmptimeexceededdata.h"
+#include "icmp/icmppacketfactory.h"
 
 
 using I2n::Logger::GlobalLogger;
@@ -267,7 +268,7 @@ IcmpPacket::ReadReturnCode IcmpPacket::read( std::istream &is )
         else
         {   // unspecified icmp data type, will consume right amount of data
             //   from stream but return false for match_echo_request and
-            //   match_destination_unreachable 
+            //   match_destination_unreachable
             icmp_data_ptr.reset( new IcmpData(
                                        static_cast<std::size_t>(data_length)) );
         }
@@ -323,6 +324,21 @@ bool IcmpPacket::write( std::ostream &os ) const
     return !os.fail();
 }
 
+/** @brief like write but also writes the IP header
+ *
+ * this is required in packet dumping for debugging
+ */
+bool IcmpPacket::dump( std::ostream &os ) const
+{
+    os.clear();
+
+    ip_head_ptr->write(os);
+    icmp_header.write(os);
+    icmp_data_ptr->write(os);
+
+    return !os.fail();
+}
+
 /**
  * @brief create packet from data in @a is;  calls IcmpPacket::read
  *
@@ -353,6 +369,12 @@ std::ostream& operator<<(
 }
 
 
+/**
+ * @brief returns a short string representation of this packet
+ *
+ * @throws some kind of exception, possibly a runtime_error cause by a failed
+ *   BOOST_ASSERT
+ */
 std::string IcmpPacket::to_string() const
 {
     std::stringstream buf;
index 2f8a702..152462d 100644 (file)
@@ -106,6 +106,7 @@ public:
     ReadReturnCode read(std::istream &is);
 
     bool write(std::ostream &os) const;
+    bool dump( std::ostream &os) const;
 
     std::string to_string() const;
 
index 0f01c67..762ce2e 100644 (file)
@@ -45,40 +45,6 @@ using namespace std;
 using boost::asio::ip::icmp;
 using I2n::Logger::GlobalLogger;
 
-void dump_packet(const std::string &data)
-{
-    // create unique file name
-    std::stringstream temp_name;
-    temp_name << IcmpPacketFactory::DumpFilePrefix;
-    time_t capture_time = time(0);
-    temp_name << capture_time;
-    temp_name << "_XXXXXX.pcap";
-    std::string temp_str = temp_name.str();
-    std::size_t temp_size = temp_str.size();
-    boost::scoped_array<char> secure_filename( new char[temp_size + 1] );
-    std::copy(temp_str.begin(), temp_str.end(), secure_filename.get());
-    secure_filename[temp_size] = '\0';
-    int fd = mkstemps(secure_filename.get(), 5);   // 5 = ".pcap".length
-    if (fd == -1)
-    {
-        GlobalLogger.warning() << "Failed to create temp file "
-            << secure_filename.get() << ": " << strerror(errno) << "!" << endl;
-        // maybe create containing directory if errno == ENOENT?
-        return;
-    }
-
-    // create file pointer for file descriptor
-    FILE *fp = fdopen(fd, "w");
-
-    // dump data
-    write_pcap_packet_data(data, fp, capture_time);
-
-    // clean up
-    fclose(fp);
-    close(fd);
-    GlobalLogger.debug() << "Dumped a copy of the data into "
-                         << secure_filename.get() << endl;
-}
 //-----------------------------------------------------------------------------
 // IcmpPacketFactory
 //-----------------------------------------------------------------------------
@@ -136,6 +102,29 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet(
         }
         else
             return_code = icmp_packet->read( is );
+
+        if ( return_code != IcmpPacket::ReadReturnCode_OK )
+        {
+            GlobalLogger.warning() << "ICMP packet creation failed: "
+                << IcmpPacket::return_code_to_string(return_code) << endl;
+            icmp_packet.reset();    // --> (!icmp_packet) is true
+               // --> icmp_pinger will not try to continue working with this packet
+        }
+        else if ( !is.good() )
+        {
+            GlobalLogger.warning() << "ICMP packet creation failed: "
+                << "Stream not good at end of creation!" << endl;
+            icmp_packet.reset();    // --> (!icmp_packet) is true
+        }
+
+        // print end result within try-catch because to_string might also
+        // throw exception
+        if (icmp_packet)
+            GlobalLogger.debug() << "Read packet " << icmp_packet->to_string()
+                                 << endl;
+        else
+            GlobalLogger.debug() << "Read packet failed" << endl;
+
     }
     catch ( const std::exception &ex )
     {
@@ -149,20 +138,6 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet(
         icmp_packet.reset();
     }
 
-    if ( return_code != IcmpPacket::ReadReturnCode_OK )
-    {
-        GlobalLogger.warning() << "ICMP packet creation failed: "
-            << IcmpPacket::return_code_to_string(return_code) << endl;
-        icmp_packet.reset();    // --> (!icmp_packet) is true
-           // --> icmp_pinger will not try to continue working with this packet
-    }
-    else if ( !is.good() )
-    {
-        GlobalLogger.warning() << "ICMP packet creation failed: "
-            << "Stream not good at end of creation!" << endl;
-        icmp_packet.reset();    // --> (!icmp_packet) is true
-    }
-
     // dump data if had trouble with packet or dumping is set to always
     if ( PacketDumpMode == DUMP_ALWAYS ||
        ( PacketDumpMode == DUMP_IF_ERROR && !icmp_packet ) )
@@ -174,12 +149,6 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet(
                 << "trouble occured before backup was created!";
     }
 
-    if (icmp_packet)
-        GlobalLogger.debug() << "Read packet " << icmp_packet->to_string()
-                             << endl;
-    else
-        GlobalLogger.debug() << "Read packet failed" << endl;
-
     return icmp_packet;
 }
 
@@ -224,3 +193,76 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet_echo_request(
     return icmp_packet;
 }
 
+
+/**
+ * @brief helper function for dump_packet methods, do not use elsewhere!
+ *
+ * creates a file descriptor and expects calling function dump_packet to deal
+ *   with it (i.e. test and close); also logs a dump_packet-related text
+ *   
+ * @returns file descriptor from mkstemps
+ */
+int IcmpPacketFactory::create_dump_file(const time_t &capture_time)
+{
+    std::stringstream temp_name;
+    temp_name << DumpFilePrefix;
+    temp_name << capture_time;
+    temp_name << "_XXXXXX.pcap";
+    std::string temp_str = temp_name.str();
+    std::size_t temp_size = temp_str.size();
+    boost::scoped_array<char> secure_filename( new char[temp_size + 1] );
+    std::copy(temp_str.begin(), temp_str.end(), secure_filename.get());
+    secure_filename[temp_size] = '\0';
+    int fd = mkstemps(secure_filename.get(), 5);   // 5 = ".pcap".length
+    if (fd == -1)
+        GlobalLogger.warning() << "Failed to create temp file "
+            << secure_filename.get() << ": " << strerror(errno) << "!" << endl;
+        // maybe create containing directory if errno == ENOENT?
+    else
+        GlobalLogger.debug() << "Dumping a copy of the data into "
+                             << secure_filename.get() << endl;
+    return fd;
+}
+
+
+void IcmpPacketFactory::dump_packet(const std::string &data)
+{
+    // create unique file name
+    time_t capture_time = time(0);
+    int fd = create_dump_file(capture_time);
+    if (fd == -1)
+        return;
+
+    // create file pointer for file descriptor
+    FILE *fp = fdopen(fd, "w");
+
+    // dump data
+    write_pcap_packet_data(data, fp, capture_time);
+
+    // clean up
+    fclose(fp);
+    close(fd);
+}
+
+void IcmpPacketFactory::dump_packet(const IcmpPacket &packet)
+{
+    // create unique file name
+    time_t capture_time = time(0);
+    int fd = create_dump_file(capture_time);
+    if (fd == -1)
+        return;
+
+    // create file pointer for file descriptor
+    FILE *fp = fdopen(fd, "w");
+
+    // create string with packet contents
+    std::stringstream data;
+    packet.dump(data);
+
+    // dump data
+    write_pcap_packet_data(data.str(), fp, capture_time);
+
+    // clean up
+    fclose(fp);
+    close(fd);
+}
index 384126b..ddad6a5 100644 (file)
@@ -34,8 +34,6 @@
 #include "icmp/icmppacket.h"
 
 
-void dump_packet(const std::string &data);
-
 enum DumpMode {
     DUMP_NEVER = 0,
     DUMP_IF_ERROR = 1,
@@ -61,6 +59,9 @@ public:
     static std::string DumpFilePrefix;
     static DumpMode PacketDumpMode;
 
+    static void dump_packet(const std::string &data);
+    static void dump_packet(const IcmpPacket &packet);
+
     static IcmpPacketItem create_icmp_packet(
             const boost::asio::ip::icmp::socket::protocol_type &protocol,
             std::istream &is
@@ -70,6 +71,9 @@ public:
             const uint16_t identifier,
             const uint16_t sequence_number
     );
+
+private:
+    static int create_dump_file(const time_t &capture_time);
 };
 
 #endif // ICMP_PACKET_FACTORY_H
index 8b85702..9b69521 100644 (file)
@@ -305,63 +305,88 @@ bool IcmpPinger::handle_receive_icmp_packet(const IcmpPacketItem icmp_packet,
     // expected sequence number, and destination host address (receive just
     // the ICMP packets from the host we had ping).
 
-    if ( icmp_packet->match_echo_reply(
-                            Identifier, SequenceNumber,
-                            DestinationEndpoint.address() ) )
+    try
     {
-        GlobalLogger.info()
-           << DestinationEndpoint.address().to_string()
-           << ": Received reply" << endl;
+        if ( icmp_packet->match_echo_reply(
+                                Identifier, SequenceNumber,
+                                DestinationEndpoint.address() ) )
+        {
+            GlobalLogger.info()
+               << DestinationEndpoint.address().to_string()
+               << ": Received reply" << endl;
 
-        ReplyReceived = true;
-        does_match = true;
+            ReplyReceived = true;
+            does_match = true;
 
-        icmp_packet->print( bytes_transferred, TimeSent );
+            icmp_packet->print( bytes_transferred, TimeSent );
 
-        set_ping_status( PingStatus_SuccessReply );
+            set_ping_status( PingStatus_SuccessReply );
 
-        IcmpPacketReceiveTimer.cancel();                            //lint !e534
-    }
-    else if ( icmp_packet->match_destination_unreachable(
-                                 Identifier, SequenceNumber,
-                                 DestinationEndpoint.address() ) )
-    {
-        GlobalLogger.info()
-           << DestinationEndpoint.address().to_string()
-           << ": Received destination unreachable" << endl;
+            IcmpPacketReceiveTimer.cancel();                            //lint !e534
+        }
+        else if ( icmp_packet->match_destination_unreachable(
+                                     Identifier, SequenceNumber,
+                                     DestinationEndpoint.address() ) )
+        {
+            GlobalLogger.info()
+               << DestinationEndpoint.address().to_string()
+               << ": Received destination unreachable" << endl;
 
-        ReplyReceived = true;
-        does_match = true;
+            ReplyReceived = true;
+            does_match = true;
 
-        icmp_packet->print( bytes_transferred, TimeSent );
+            icmp_packet->print( bytes_transferred, TimeSent );
 
-        set_ping_status( PingStatus_FailureDestinationUnreachable );
+            set_ping_status( PingStatus_FailureDestinationUnreachable );
 
-        IcmpPacketReceiveTimer.cancel();                            //lint !e534
-    }
-    else if ( icmp_packet->match_time_exceeded(
-                                 Identifier, SequenceNumber,
-                                 DestinationEndpoint.address() ) )
-    {
-        GlobalLogger.info()
-           << DestinationEndpoint.address().to_string()
-           << ": Received time exceeded" << endl;
+            IcmpPacketReceiveTimer.cancel();                            //lint !e534
+        }
+        else if ( icmp_packet->match_time_exceeded(
+                                     Identifier, SequenceNumber,
+                                     DestinationEndpoint.address() ) )
+        {
+            GlobalLogger.info()
+               << DestinationEndpoint.address().to_string()
+               << ": Received time exceeded" << endl;
 
-        ReplyReceived = true;
-        does_match = true;
+            ReplyReceived = true;
+            does_match = true;
 
-        icmp_packet->print( bytes_transferred, TimeSent );
+            icmp_packet->print( bytes_transferred, TimeSent );
 
-        set_ping_status( PingStatus_FailureDestinationUnreachable );
+            set_ping_status( PingStatus_FailureDestinationUnreachable );
 
-        IcmpPacketReceiveTimer.cancel();                            //lint !e534
+            IcmpPacketReceiveTimer.cancel();                            //lint !e534
+        }
+        else
+        {
+            GlobalLogger.debug()
+               << DestinationEndpoint.address().to_string()
+               << ": Received packet that does not match or has wrong seq.nr"
+               << endl;
+        }
     }
-    else
+    catch ( std::exception &exc)
     {
-        GlobalLogger.debug()
-           << DestinationEndpoint.address().to_string()
-           << ": Received packet that does not match or has wrong seq.nr"
-           << endl;
+        GlobalLogger.warning()
+            << DestinationEndpoint.address().to_string()
+            << ": Caught exception in packet interpretation: " << exc.what()
+            << std::endl;
+        if ( IcmpPacketFactory::PacketDumpMode == DUMP_ALWAYS ||
+             IcmpPacketFactory::PacketDumpMode == DUMP_IF_ERROR )
+            IcmpPacketFactory::dump_packet(*icmp_packet);
+        does_match = true;   // avoid the same procedure in all other pingers
+    }
+    catch ( ... )
+    {
+        GlobalLogger.warning()
+            << DestinationEndpoint.address().to_string()
+            << ": Caught unspecified exception in packet interpretation!"
+            << std::endl;
+        if ( IcmpPacketFactory::PacketDumpMode == DUMP_ALWAYS ||
+             IcmpPacketFactory::PacketDumpMode == DUMP_IF_ERROR )
+            IcmpPacketFactory::dump_packet(*icmp_packet);
+        does_match = true;   // avoid the same procedure in all other pingers
     }
 
     return does_match;
@@ -542,7 +567,7 @@ void IcmpPacketDistributor::handle_receive(
         }
         if (!packet_matches)
             GlobalLogger.info() << "Packet did not match any pinger"
-                                   << std::endl;
+                                << std::endl;
     }
 
     // re-register receive handler
index d6d38d5..1734ab8 100644 (file)
 #include "ip/ipheader.h"
 #include <sstream>
 
+IpHeader::IpHeader(const size_t payload_size)
+    : Payload(payload_size)
+{}
+
 std::string IpHeader::to_string() const
 {
     std::stringstream buf;
@@ -31,3 +35,7 @@ std::string IpHeader::to_string() const
     return buf.str();
 }
 
+std::ostream &IpHeader::write(std::ostream &os) const
+{
+    return Payload.write(os);
+}
index 66175d7..2911b53 100644 (file)
 #define IPHEADER_H
 
 #include <stdint.h>
+#include <ostream>
 #include <boost/shared_ptr.hpp>
 #include <boost/asio/ip/address.hpp>
+#include "host/messagepayload.h"
 
 /**
  * abstract base class of IPv4Header and IPv6Header
@@ -33,6 +35,7 @@
 class IpHeader
 {
 public:
+    IpHeader(const size_t payload_size);
     virtual boost::asio::ip::address get_source_address() const = 0;
     virtual boost::asio::ip::address get_destination_address() const = 0;
     virtual uint8_t get_version() const = 0;
@@ -43,6 +46,11 @@ public:
     virtual ~IpHeader() {}
 
     virtual std::string to_string() const;
+
+    virtual std::ostream& write(std::ostream &os) const;
+
+protected:
+    MessagePayload Payload;
 };
 
 typedef boost::shared_ptr<IpHeader> IpHeaderPtr;
index a4649ab..6fb6eb4 100644 (file)
@@ -26,7 +26,7 @@ static const size_t Ipv4HeaderSizeInBytes_withoutOptions = 20;
  * @brief Default constructor.
  */
 Ipv4Header::Ipv4Header() :
-    Payload( Ipv4HeaderSizeInBytes_withoutOptions )
+    IpHeader( Ipv4HeaderSizeInBytes_withoutOptions )
 {
     // encode a 4 into the first 4 bits
     Payload.encode1(0, 0, 0);
index 71f8290..12eb300 100644 (file)
@@ -12,7 +12,6 @@
 #include <boost/asio/ip/address_v4.hpp>
 
 #include "ip/ipheader.h"
-#include "host/messagepayload.h"
 
 //-----------------------------------------------------------------------------
 // Ipv4Header
@@ -82,9 +81,6 @@ public:
             Ipv4Header &header
     );
 
-private:
-    MessagePayload Payload;
-
 };
 
 #endif // IPV4_HEADER_H
index adc91ca..93c5baf 100644 (file)
@@ -26,7 +26,7 @@ static const size_t Ipv6HeaderSizeInBytes = 40;
  * @brief Default constructor.
  */
 Ipv6Header::Ipv6Header() :
-    Payload( Ipv6HeaderSizeInBytes )
+    IpHeader( Ipv6HeaderSizeInBytes )
 {
     // encode a 6 into the first 4 bits
     Payload.encode1(0, 0, 0);
index 31fd8ef..4e34cf9 100644 (file)
@@ -12,7 +12,6 @@
 #include <boost/asio/ip/address_v6.hpp>
 
 #include "ip/ipheader.h"
-#include "host/messagepayload.h"
 
 //-----------------------------------------------------------------------------
 // Ipv6Header
@@ -90,9 +89,6 @@ public:
             Ipv6Header &header
     );
 
-private:
-    MessagePayload Payload;
-
 };
 
 #endif // IPV6_HEADER_H
index 5a0733d..5f0af82 100644 (file)
@@ -42,7 +42,7 @@ const bool default_is_v4 = true;
 // function declarations
 void init_logger();
 void increase_verbosity();
-int read_packets(std::istream &input_stream, const bool, const bool, const int);
+int read_packets(std::istream &input_stream, const bool, const bool);
 
 //------------------------------------------------------------------------------
 // helper functions
@@ -51,7 +51,7 @@ void init_logger()
 {
     // set default: log at level NOTICE to stderr
     I2n::Logger::enable_stderr_log( true );
-    I2n::Logger::set_log_level( I2n::Logger::LogLevel::Info );
+    I2n::Logger::set_log_level( I2n::Logger::LogLevel::Debug );
     GlobalLogger.info() << "Logger initiated";
 }
 
@@ -72,7 +72,8 @@ int read_packets( std::istream &input_stream, const bool is_icmp,
     // peek at start of stream to see if there is a pcap header
     bool is_pcap = check_for_pcap_header(input_stream);
     if (is_pcap)
-        GlobalLogger.info() << "File is pcap";
+        GlobalLogger.info() << "File is pcap --> consume first "
+            << pcap_file_header_size << " bytes";
     else
         GlobalLogger.info() << "File is not pcap";
 
@@ -96,7 +97,8 @@ int read_packets( std::istream &input_stream, const bool is_icmp,
         if (is_pcap)
         {
             // assume that there is a packet header if stream had pcap header
-            GlobalLogger.debug() << "Consume packet header";
+            GlobalLogger.debug() << "Consume packet header ("
+                << pcap_packet_header_size << " bytes)";
             consume_pcap_packet_header(input_stream);
             if ( !input_stream )
             {
@@ -106,7 +108,8 @@ int read_packets( std::istream &input_stream, const bool is_icmp,
 
             if (packet_type == 1)
             {
-                GlobalLogger.debug() << "Consume ethernet header";
+                GlobalLogger.debug() << "Consume ethernet header ("
+                    << pcap_ethernet_header_size << " bytes)";
                 consume_pcap_ethernet_header(input_stream);
                 if ( !input_stream )
                 {
index 1ca7a69..b2d48a6 100644 (file)
@@ -61,15 +61,6 @@ void write_pcap_packet_data(const std::string &data,
 //const uint32_t pcap_magic_number = 0xa1b2c3d4;
 const uint8_t pcap_magic_bytes[] = {0xa1, 0xb2, 0xc3, 0xd4};
 
-// pcap file header is 5 x uint32 + 2 x uint16 --> 24 bytes
-const std::streamsize pcap_file_header_size = sizeof(pcapfile_hdr_t);
-
-// pcap file header is 4 x uint32 --> 16 bytes
-const std::streamsize pcap_packet_header_size = sizeof(pcaprec_hdr_t);
-
-// pcap ethernet header is 2 x 6 byte + 2 byte --> 14 bytes
-const std::streamsize pcap_ethernet_header_size = sizeof(pcapeth_hdr_t);
-
 // determine whether is raw data or pcap by peeking at first 4 bytes
 bool check_for_pcap_header(std::istream &input_stream)
 {
index 0db4807..33de76a 100644 (file)
@@ -57,6 +57,15 @@ typedef struct pcapeth_hdr_s {
         uint16_t ether_type;
 } pcapeth_hdr_t;
 
+// pcap file header is 5 x uint32 + 2 x uint16 --> 24 bytes
+const std::streamsize pcap_file_header_size = sizeof(pcapfile_hdr_t);
+
+// pcap file header is 4 x uint32 --> 16 bytes
+const std::streamsize pcap_packet_header_size = sizeof(pcaprec_hdr_t);
+
+// pcap ethernet header is 2 x 6 byte + 2 byte --> 14 bytes
+const std::streamsize pcap_ethernet_header_size = sizeof(pcapeth_hdr_t);
+
 void write_pcap_packet_data(const std::string &data,
                             FILE *fp,
                             const time_t &capture_time);