From 9765a83d8ee55d3b1823b675e5ea1eed95052b97 Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Wed, 25 Feb 2015 15:34:16 +0100 Subject: [PATCH] dumping now into a .pcap file with nicer filename, so can analyze with wireshark --- src/icmp/icmppacketfactory.cpp | 104 ++++++++++++++++++++++++++++++++------- 1 files changed, 85 insertions(+), 19 deletions(-) diff --git a/src/icmp/icmppacketfactory.cpp b/src/icmp/icmppacketfactory.cpp index 9ebd2cf..fe422bb 100644 --- a/src/icmp/icmppacketfactory.cpp +++ b/src/icmp/icmppacketfactory.cpp @@ -20,7 +20,9 @@ #include "icmp/icmppacketfactory.h" +// for dumping packets #include +#include #include #include @@ -40,6 +42,84 @@ using boost::asio::ip::icmp; using I2n::Logger::GlobalLogger; //----------------------------------------------------------------------------- +// Dump of data packets to pcap files +//----------------------------------------------------------------------------- +#pragma pack(push, 1) // exact fit -- no padding of data in structs + +// pcap header for dumping of packet data +// (http://wiki.wireshark.org/Development/LibpcapFileFormat) +typedef struct pcap_hdr_s { + uint32_t magic_number; /* magic number */ + uint16_t version_major; /* major version number */ + uint16_t version_minor; /* minor version number */ + int32_t thiszone; /* GMT to local correction */ + uint32_t sigfigs; /* accuracy of timestamps */ + uint32_t snaplen; /* max length of captured packets, in octets */ + uint32_t network; /* data link type */ +} pcap_hdr_t; + +typedef struct pcaprec_hdr_s { + uint32_t ts_sec; /* timestamp seconds */ + uint32_t ts_usec; /* timestamp microseconds */ + uint32_t incl_len; /* number of octets of packet saved in file */ + uint32_t orig_len; /* actual length of packet */ +} pcaprec_hdr_t; + + +void dump_packet(const std::string &data) +{ + std::size_t data_size = data.size(); + + // create unique file name + std::stringstream temp_name; + temp_name << "/datastore/pingcheck.broken/icmp_"; + time_t capture_time = time(0); + temp_name << capture_time; + temp_name << "_XXXXXX.pcap"; + std::string temp_str = temp_name.str(); + char *secure_filename = strdup(temp_str.c_str()); + int fd = mkstemps(secure_filename, 5); // 5 = ".pcap".length + if (fd == -1) + { + GlobalLogger.warning() << "Failed to create temp file!" << endl; + return; + } + + // create a pcap header + pcap_hdr_t pcap_hdr; + pcap_hdr.magic_number = 0xa1b2c3d4; + pcap_hdr.version_major = 2; + pcap_hdr.version_minor = 4; + pcap_hdr.thiszone = 0; + pcap_hdr.sigfigs = 0; + pcap_hdr.snaplen = 40; + pcap_hdr.network = 101; // LINKTYPE_RAW, according to + // http://www.tcpdump.org/linktypes.html + + // create a record (packet) header + pcaprec_hdr_t pcaprec_hdr; + pcaprec_hdr.ts_sec = static_cast(capture_time); + pcaprec_hdr.ts_usec = 0; // do not care about that precision + pcaprec_hdr.incl_len = data_size; + pcaprec_hdr.orig_len = data_size; + + // create file pointer for file descriptor + FILE *fp = fdopen(fd, "w"); + + // write data + fwrite(&pcap_hdr, sizeof(pcap_hdr_t), 1, fp); + fwrite(&pcaprec_hdr, sizeof(pcaprec_hdr_t), 1, fp); + fwrite(data.c_str(), sizeof(char), data_size, fp); + + // done -- clean up + fclose(fp); + close(fd); + GlobalLogger.debug() << "Dumped a copy of the data into " + << secure_filename << endl; +} +#pragma pack(pop) // restore old value + +//----------------------------------------------------------------------------- // IcmpPacketFactory //----------------------------------------------------------------------------- @@ -80,7 +160,6 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet( // create buffer for saving data in it stringbuf data_backup; - size_t data_size; // read packet from stream, possibly copying data first if (dump_broken_packets) @@ -88,9 +167,9 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet( // read all data into backup ostream backup_filler(&data_backup); backup_filler << is.rdbuf(); - data_size = data_backup.str().size(); - GlobalLogger.debug() << "Copied ICMP raw data (" << data_size - << " bytes) for dumping in case of broken packet" << endl; + //GlobalLogger.debug() << "Copied ICMP raw data (" + // << data_backup.str().size(); + // << " bytes) for dumping in case of broken packet" << endl; // create a new stream from backup buffer // and use that in read @@ -114,22 +193,9 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet( icmp_packet.reset(); // --> (!icmp_packet) is true } + // dump data if had trouble with packet if (dump_broken_packets && !icmp_packet) - { - char secure_filename[] = "/datastore/pingcheck.broken/icmp_XXXXXX"; - int fd = mkstemp(secure_filename); - if (fd == -1) - GlobalLogger.warning() << "Failed to create temp file!" << endl; - else - { - // write data - write(fd, data_backup.str().c_str(), data_size); - // to check od -t u1 - close(fd); - GlobalLogger.debug() << "Dumped a copy of the data into " - << secure_filename << endl; - } - } + dump_packet(data_backup.str()); return icmp_packet; } -- 1.7.1