use I2n::tmpfstream to write pcap dump files
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 21 May 2015 09:33:44 +0000 (11:33 +0200)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 21 May 2015 09:33:44 +0000 (11:33 +0200)
src/icmp/icmppacketfactory.cpp
src/icmp/icmppacketfactory.h
src/tools/pcap.cpp
src/tools/pcap.h

index 762ce2e..2eed296 100644 (file)
@@ -33,6 +33,7 @@
 #include <boost/scoped_array.hpp>
 
 #include <logfunc.hpp>
+#include <tmpfstream.hpp>
 
 #include "boost_assert_handler.h"
 #include "icmp/icmpdata.h"
@@ -194,75 +195,52 @@ IcmpPacketItem IcmpPacketFactory::create_icmp_packet_echo_request(
 }
 
 
-/**
- * @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;
+    std::stringstream temp_name;
+    temp_name << DumpFilePrefix << capture_time << ".pcap.XXXXXX";
 
-    // create file pointer for file descriptor
-    FILE *fp = fdopen(fd, "w");
+    // open file
+    I2n::tmpfstream temp_stream;
+    if ( !temp_stream.open(temp_name.str()) )
+    {
+        GlobalLogger.warning() << "Failed to create temp file "
+            << temp_name.str() << ": " << strerror(errno) << "!" << endl;
+        return;
+    }
 
-    // dump data
-    write_pcap_packet_data(data, fp, capture_time);
+    // write
+    write_pcap_packet_data(data, temp_stream, capture_time);
 
-    // clean up
-    fclose(fp);
-    close(fd);
+    // close
+    GlobalLogger.debug() << "Dumped a copy of the ICMP data into "
+                         << temp_stream.get_tmp_filename() << endl;
+    temp_stream.close();
 }
 
 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");
+    std::stringstream temp_name;
+    temp_name << DumpFilePrefix << capture_time << ".pcap.XXXXXX";
 
-    // create string with packet contents
-    std::stringstream data;
-    packet.dump(data);
+    // open file
+    I2n::tmpfstream temp_stream;
+    if ( !temp_stream.open(temp_name.str()) )
+    {
+        GlobalLogger.warning() << "Failed to create temp file "
+            << temp_name.str() << ": " << strerror(errno) << "!" << endl;
+        return;
+    }
 
     // dump data
-    write_pcap_packet_data(data.str(), fp, capture_time);
+    packet.dump(temp_stream);
 
-    // clean up
-    fclose(fp);
-    close(fd);
+    // close
+    GlobalLogger.debug() << "Dumped a copy of the packet into "
+                         << temp_stream.get_tmp_filename() << endl;
+    temp_stream.close();
 }
index ddad6a5..1028d99 100644 (file)
@@ -71,9 +71,6 @@ 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 b2d48a6..4c9cc58 100644 (file)
 #pragma pack(push, 1) // exact fit -- no padding of data in structs
 
 void write_pcap_packet_data(const std::string &data,
-                            FILE *fp,
+                            std::ostream &os,
                             const time_t &capture_time)
 {
     std::size_t data_size = data.size();
 
     // create a pcap header
-    pcapfile_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 = data_size;
-    pcap_hdr.network = 101;   // LINKTYPE_RAW, according to
+    pcapfile_hdr_t pcapfile_hdr;
+    pcapfile_hdr.magic_number = 0xa1b2c3d4;
+    pcapfile_hdr.version_major = 2;
+    pcapfile_hdr.version_minor = 4;
+    pcapfile_hdr.thiszone = 0;
+    pcapfile_hdr.sigfigs = 0;
+    pcapfile_hdr.snaplen = data_size;
+    pcapfile_hdr.network = 101;   // LINKTYPE_RAW, according to
                               // http://www.tcpdump.org/linktypes.html
 
     // create a record (packet) header
@@ -53,9 +53,9 @@ void write_pcap_packet_data(const std::string &data,
     pcaprec_hdr.orig_len = data_size;
 
     // write data
-    fwrite(&pcap_hdr, sizeof(pcapfile_hdr_t), 1, fp);
-    fwrite(&pcaprec_hdr, sizeof(pcaprec_hdr_t), 1, fp);
-    fwrite(data.c_str(), sizeof(char), data_size, fp);
+    os.write( (char *)&pcapfile_hdr, sizeof(pcapfile_hdr_t) );
+    os.write( (char *)&pcaprec_hdr,  sizeof( pcaprec_hdr_t) );
+    os << data;
 }
 
 //const uint32_t pcap_magic_number = 0xa1b2c3d4;
index 33de76a..dd91752 100644 (file)
@@ -24,7 +24,7 @@
 #define PCAP_H
 
 #include <stdint.h>
-#include <istream>
+#include <iostream>
 #include <ctime>
 
 #pragma pack(push, 1) // exact fit -- no padding of data in structs
@@ -67,7 +67,7 @@ const std::streamsize pcap_packet_header_size = sizeof(pcaprec_hdr_t);
 const std::streamsize pcap_ethernet_header_size = sizeof(pcapeth_hdr_t);
 
 void write_pcap_packet_data(const std::string &data,
-                            FILE *fp,
+                            std::ostream &os,
                             const time_t &capture_time);
 
 bool check_for_pcap_header(std::istream &input_stream);