#include "icmp/icmppacketfactory.h"
+// for dumping packets
#include <stdlib.h>
+#include <ctime>
#include <iostream>
#include <sstream>
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<uint32_t>(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
//-----------------------------------------------------------------------------
// 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)
// 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
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;
}