From 1d110d20332dc3eaca24e5f3c5efe66014eeedfd Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Fri, 27 Feb 2015 18:06:37 +0100 Subject: [PATCH] started creating a utility program in new folder tools that feeds packet data directly into ICMP/TCP factories --- src/tools/feed_packet_data.cpp | 170 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 170 insertions(+), 0 deletions(-) create mode 100644 src/tools/feed_packet_data.cpp diff --git a/src/tools/feed_packet_data.cpp b/src/tools/feed_packet_data.cpp new file mode 100644 index 0000000..e8d4d1d --- /dev/null +++ b/src/tools/feed_packet_data.cpp @@ -0,0 +1,170 @@ +/* +The software in this package is distributed under the GNU General +Public License version 2 (with a special exception described below). + +A copy of GNU General Public License (GPL) is included in this distribution, +in the file COPYING.GPL. + +As a special exception, if other files instantiate templates or use macros +or inline functions from this file, or you compile this file and link it +with other works to produce a work based on this file, this file +does not by itself cause the resulting work to be covered +by the GNU General Public License. + +However the source code for this file must still be made available +in accordance with section (3) of the GNU General Public License. + +This exception does not invalidate any other reasons why a work based +on this file might be covered by the GNU General Public License. +*/ + +#include +#include + +#include "icmp/icmppacketfactory.h" +#include "tcp/tcpsegmentfactory.h" + +using I2n::Logger::GlobalLogger; +namespace po = boost::program_options; + +//const uint32_t pcap_magic_number = 0xa1b2c3d4; +const char pcap_magic_bytes[] = {0xa1, 0xb2, 0xc3, 0xd4}; +const bool default_is_icmp = true; +const bool default_is_v4 = true; + +void init_logger() +{ + // set default: log at level NOTICE to syslog and stderr + // to ensure that in case of faulty config, the error is noticed + I2n::Logger::enable_syslog( I2n::Logger::Facility::User ); + I2n::Logger::enable_stderr_log( true ); + I2n::Logger::set_log_level( I2n::Logger::LogLevel::Notice ); +} + +void increase_verbosity() +{ + I2n::Logger::set_log_level( I2n::Logger::LogLevel::Info ); +} + +// determine whether is raw data or pcap by peeking at first 4 bytes +bool check_for_pcap_header(std::istream &input_stream) +{ + int peek_idx; + bool is_pcap = true; + for (peek_idx=0; peek_idx<4; ++peek_idx) + { + if (file_reader.get() != pcap_magic_bytes[peek_idx]) + { + is_pcap = false; + break; + } + } + for (int back_idx=peek_idx; back_idx > 0; --back_idx) + file_reader.unget(); + if (is_pcap) + GlobalLogger.info() << "File is pcap"; + else + GlobalLogger.info() << "File is not pcap"; + return is_pcap; +} + +int main(int argc, char *argv[]) +{ + // init logging + init_logger(); + GlobalLogger.debug() << "logger initiated with default config"; + + bool is_icmp = default_is_icmp; + bool is_v4 = default_is_v4; + std::istream input_stream; + bool is_pcap; + bool have_stream = false; + + IcmpPacketItem packet; + TcpSegmentItem segment; + + // convert arguments + std::vector args(argv, argv + argc); + + // loop over arguments + BOOST_FOREACH (const std::string &arg, args) + { + // check if is some specification of data format + if (arg == "-i" || arg == "-icmp" || arg == "i" || arg == "icmp") + is_icmp = true; + else if (arg == "-t" || arg == "-tcp" || arg == "t" || arg == "tcp") + is_icmp = false; + else if (arg == "-4" || arg == "-v4" || arg == "4" || arg == "v4") + is_v4 = false; + else if (arg == "-6" || arg == "-v6" || arg == "6" || arg == "v6") + is_v6 = false; + else if (arg == "--") // read input from stdin + { + if (have_stream) + input_stream.close(); + GlobalLogger.info() << "Trying to read from stdin" << std::endl; + input_stream = std::cin; + } + else // assume is file name + { + if (have_stream) + input_stream.close(); + GlobalLogger.info() << "Trying to read from " << file_name + << std::endl; + input_stream = file_reader(file_name, ios::in | ios::binary); + } + + // no stream yet --> check next arg + if (!have_stream) + continue; + + // read from stream until it is empty + while (input_stream) + { + is_pcap = check_for_pcap_header(input_stream); + // TODO consume that header: file header and/or packet header + // (maybe assume for now that there is only one data set per file) + + // feed data to right factory + if (is_icmp) + { + if (is_v4) + { + GlobalLogger.info() << "Creating ICMP v4 packet" + << std::endl; + packet = IcmpPacketFactory.create_icmp_packet( + boost::asio::ip::icmp::v4, input_stream); + } + else // v6 + { + GlobalLogger.info() << "Creating ICMP v6 packet" + << std::endl; + packet = IcmpPacketFactory.create_icmp_packet( + boost::asio::ip::icmp::v6, input_stream); + } + } + else // is tcp + { + if (is_v4) + { + GlobalLogger.info() << "Creating TCP v4 packet" + << std::endl; + segment = TcpSegmentFactory::create_tcp_segment( + boost::asio::ip::tcp_raw_protocol::v4, + input_stream); + } + else // v6 + { + GlobalLogger.info() << "Creating TCP v6 packet" + << std::endl; + segment = TcpSegmentFactory::create_tcp_segment( + boost::asio::ip::tcp_raw_protocol::v6, + input_stream); + } + } + } //eo: while (input_stream) + + input_stream.close(); + have_stream = false; + } //eo: loop over input-files +} // eo: function main -- 1.7.1