X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=example%2Fdiameter%2FpcapDecoder%2Fmain.cpp;h=97474e8428a5cb9d2a32b241ddedb2c8220ee5d5;hb=5a6cba5fde2b2f538a7515f8293cc0a8d9589dfa;hp=7dd71c4216713c20a8877b2c8a1f5933644b591a;hpb=deae6754c23826dba6046e76ff37b43939bca3c1;p=anna.git diff --git a/example/diameter/pcapDecoder/main.cpp b/example/diameter/pcapDecoder/main.cpp index 7dd71c4..97474e8 100644 --- a/example/diameter/pcapDecoder/main.cpp +++ b/example/diameter/pcapDecoder/main.cpp @@ -1,40 +1,11 @@ -// ANNA - Anna is Not Nothingness Anymore -// -// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo -// -// http://redmine.teslayout.com/projects/anna-suite -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: eduardo.ramos.testillano@gmail.com -// cisco.tierra@gmail.com - - -// Standard +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // + + #include #include #include @@ -47,22 +18,13 @@ #include #include -#include #include #include #include #include -#include -#include -#include -#include - - using namespace anna; -using namespace anna::diameter; - // Payload and frame metadata ///////////////////////////////////////////////////////////////////////////// class Payload { @@ -75,64 +37,89 @@ class Payload { size_t _diameterLength; public: - Payload() { reset(); } + Payload() { + reset(); + } void setDiameterLength(size_t dl) { - if (_diameterLength == -1) { - _diameterLength=dl; - LOGDEBUG (Logger::debug(anna::functions::asString("Diameter message length: %d bytes", dl), ANNA_FILE_LOCATION)); - } + if(_diameterLength == -1) { + _diameterLength = dl; + LOGDEBUG( + Logger::debug(anna::functions::asString("Diameter message length: %d bytes", dl), ANNA_FILE_LOCATION)); + } } - void setSourceIP(const std::string &srcIP) throw() { _sourceIP = srcIP; } - void setDestinationIP(const std::string &dstIP) throw() { _destinationIP = dstIP; } - void setTimestamp(time_t ts) throw() { _timestamp = ts; } - void setTimestampU(int tsu) throw() { _timestampU = tsu; } + void setSourceIP(const std::string &srcIP) { + _sourceIP = srcIP; + } + void setDestinationIP(const std::string &dstIP) { + _destinationIP = dstIP; + } + void setTimestamp(time_t ts) { + _timestamp = ts; + } + void setTimestampU(int tsu) { + _timestampU = tsu; + } // Returns true if completed: - bool appendData(const char *data, size_t size) throw(RuntimeException) { - LOGDEBUG (Logger::debug(anna::functions::asString("Appending %d bytes", size), ANNA_FILE_LOCATION)); + bool appendData(const char *data, size_t size) noexcept(false) { + LOGDEBUG( + Logger::debug(anna::functions::asString("Appending %d bytes", size), ANNA_FILE_LOCATION)); _data.append(data, size); - if (_data.size() > _diameterLength) throw RuntimeException("Data overflow (unexpected offset exceed diameter message length)", ANNA_FILE_LOCATION); - if (_data.size() < _diameterLength) return false; - LOGDEBUG (anna::Logger::debug("Completed!", ANNA_FILE_LOCATION)); + + if(_data.size() > _diameterLength) + throw RuntimeException( + "Data overflow (unexpected offset exceed diameter message length)", + ANNA_FILE_LOCATION); + + if(_data.size() < _diameterLength) + return false; + + LOGDEBUG(anna::Logger::debug("Completed!", ANNA_FILE_LOCATION)); return true; } - void reset() throw() { - _sourceIP = ""; - _destinationIP = ""; - _timestamp = 0; - _timestampU = 0; - _data = ""; - _diameterLength = -1; // not calculated yet + void reset() { + _sourceIP = ""; + _destinationIP = ""; + _timestamp = 0; + _timestampU = 0; + _data = ""; + _diameterLength = -1; // not calculated yet } - const std::string &getSourceIP() const throw() { return _sourceIP; } - const std::string &getDestinationIP() const throw() { return _destinationIP; } - time_t getTimestamp() const throw() { return _timestamp; } - int getTimestampU() const throw() { return _timestampU; } - const std::string &getData() const throw() { return _data; } - std::string getDataAsHex() const throw() { return anna::functions::asHexString(anna::DataBlock(_data.c_str(), _data.size())); } + const std::string &getSourceIP() const { + return _sourceIP; + } + const std::string &getDestinationIP() const { + return _destinationIP; + } + time_t getTimestamp() const { + return _timestamp; + } + int getTimestampU() const { + return _timestampU; + } + const std::string &getData() const { + return _data; + } + std::string getDataAsHex() const { + return anna::functions::asHexString( + anna::DataBlock(_data.c_str(), _data.size())); + } }; - - // Data maps ////////////////////////////////////////////////////////////////////////////////////////////// -typedef std::map payloads_t; -typedef std::map ::const_iterator payloads_it; +typedef std::map < int /* frame */, Payload > payloads_t; +typedef std::map < int /* frame */, Payload >::const_iterator payloads_it; payloads_t G_payloads; -anna::diameter::codec::Message G_codecMsg; - - - - // Sniffing structures //////////////////////////////////////////////////////////////////////////////////// /* ethernet headers are always exactly 14 bytes */ #define SIZE_ETHERNET 14 /* Ethernet addresses are 6 bytes */ -#define ETHER_ADDR_LEN 6 +#define ETHER_ADDR_LEN 6 /* Ethernet header */ struct sniff_ethernet { @@ -143,36 +130,36 @@ struct sniff_ethernet { /* IP header */ struct sniff_ip { - u_char ip_vhl; /* version << 4 | header length >> 2 */ - u_char ip_tos; /* type of service */ - u_short ip_len; /* total length */ - u_short ip_id; /* identification */ - u_short ip_off; /* fragment offset field */ -#define IP_RF 0x8000 /* reserved fragment flag */ -#define IP_DF 0x4000 /* dont fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u_char ip_ttl; /* time to live */ - u_char ip_p; /* protocol */ - u_short ip_sum; /* checksum */ - struct in_addr ip_src,ip_dst; /* source and dest address */ + u_char ip_vhl; /* version << 4 | header length >> 2 */ + u_char ip_tos; /* type of service */ + u_short ip_len; /* total length */ + u_short ip_id; /* identification */ + u_short ip_off; /* fragment offset field */ +#define IP_RF 0x8000 /* reserved fragment flag */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src, ip_dst; /* source and dest address */ }; #define IP_OFF(ip) (((ip)->ip_off) & IP_OFFMASK) #define IP_DF_VAL(ip) ((((ip)->ip_off) & IP_DF) >> 14) #define IP_MF_VAL(ip) ((((ip)->ip_off) & IP_MF) >> 13) -#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) -#define IP_V(ip) (((ip)->ip_vhl) >> 4) +#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) +#define IP_V(ip) (((ip)->ip_vhl) >> 4) /* TCP header */ typedef u_int tcp_seq; struct sniff_tcp { - u_short th_sport; /* source port */ - u_short th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ - u_char th_offx2; /* data offset, rsvd */ -#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) + u_short th_sport; /* source port */ + u_short th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ + u_char th_offx2; /* data offset, rsvd */ +#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) u_char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 @@ -183,26 +170,25 @@ struct sniff_tcp { #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) - u_short th_win; /* window */ - u_short th_sum; /* checksum */ - u_short th_urp; /* urgent pointer */ + u_short th_win; /* window */ + u_short th_sum; /* checksum */ + u_short th_urp; /* urgent pointer */ }; // Payload extraction ///////////////////////////////////////////////////////////////////////////////////// -u_char *getPayload(const u_char* packet, int packetSize, int &payloadSize, std::string &srcIp, std::string &dstIp, int &fragmentId, bool &dfFlag, bool &mfFlag, int &fragmentOffset) { - - const struct sniff_ethernet *ethernet; /* The ethernet header */ +u_char *getPayload(const u_char* packet, int packetSize, int &payloadSize, + std::string &srcIp, std::string &dstIp, int &fragmentId, bool &dfFlag, + bool &mfFlag, int &fragmentOffset) { const struct sniff_ip *ip; /* The IP header */ const struct sniff_tcp *tcp; /* The TCP header */ - u_int size_ip; u_int size_tcp; - - ethernet = (struct sniff_ethernet*)(packet); ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); - size_ip = IP_HL(ip)*4; // 4 bytes per 32 bits word - if (size_ip < 20) { - LOGDEBUG (Logger::debug(anna::functions::asString("Invalid IP header length: %d bytes", size_ip), ANNA_FILE_LOCATION)); + size_ip = IP_HL(ip) * 4; // 4 bytes per 32 bits word + + if(size_ip < 20) { + LOGDEBUG( + Logger::debug(anna::functions::asString("Invalid IP header length: %d bytes", size_ip), ANNA_FILE_LOCATION)); return NULL; } @@ -211,229 +197,206 @@ u_char *getPayload(const u_char* packet, int packetSize, int &payloadSize, std:: srcIp = str; inet_ntop(AF_INET, &(ip->ip_dst), str, INET_ADDRSTRLEN); dstIp = str; - - LOGDEBUG (Logger::debug(anna::functions::asString("ip_id: %d | ip_off: %d", ip->ip_id, ip->ip_off), ANNA_FILE_LOCATION)); + LOGDEBUG( + Logger::debug(anna::functions::asString("ip_id: %d | ip_off: %d", ip->ip_id, ip->ip_off), ANNA_FILE_LOCATION)); fragmentId = ip->ip_id; dfFlag = IP_DF_VAL(ip); mfFlag = IP_MF_VAL(ip); fragmentOffset = IP_OFF(ip); - - tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); - size_tcp = TH_OFF(tcp)*4; - if (size_tcp < 20) { - LOGDEBUG (Logger::debug(anna::functions::asString("Invalid TCP header length: %d bytes", size_tcp), ANNA_FILE_LOCATION)); + size_tcp = TH_OFF(tcp) * 4; + + if(size_tcp < 20) { + LOGDEBUG( + Logger::debug(anna::functions::asString("Invalid TCP header length: %d bytes", size_tcp), ANNA_FILE_LOCATION)); return NULL; } int payloadOffset = SIZE_ETHERNET + size_ip + size_tcp; - LOGDEBUG (Logger::debug(anna::functions::asString("PayloadOffset=%d", payloadOffset), ANNA_FILE_LOCATION)); + LOGDEBUG( + Logger::debug(anna::functions::asString("PayloadOffset=%d", payloadOffset), ANNA_FILE_LOCATION)); payloadSize = packetSize - payloadOffset; return ((u_char *)(packet + payloadOffset)); } // Sniffing callback ////////////////////////////////////////////////////////////////////////////////////// -void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet) -{ - static int count = 1; - - static Payload auxPayload; - - int packetSize = pkthdr->len; - int payloadSize; - std::string srcIp, dstIp; - int fragmentId, fragmentOffset; - bool dfFlag, mfFlag; - const u_char* payload = getPayload(packet, packetSize, payloadSize, srcIp, dstIp, fragmentId, dfFlag, mfFlag, fragmentOffset); - if (payload && (payloadSize > 0)) { - LOGDEBUG ( - std::string msg; - msg += anna::functions::asString("\nFrame %d:", count); - msg += anna::functions::asHexString(anna::DataBlock((const char *)packet, pkthdr->len)); - time_t time = pkthdr->ts.tv_sec; - msg += "\n"; - msg += anna::functions::asString("\ntimestamp %d.%d", pkthdr->ts.tv_sec, pkthdr->ts.tv_usec); - msg += anna::functions::asString("\ndate %s", ctime(&time)); - msg += anna::functions::asString("\ncaplen %d", pkthdr->caplen); - msg += anna::functions::asString("\npacketSize %d", packetSize); - msg += anna::functions::asString("\npayloadSize %d", payloadSize); - msg += "\nPayload:"; - msg += anna::functions::asHexString(anna::DataBlock((const char *)payload, payloadSize)); - msg += "\n"; - msg += anna::functions::asString("\nsourceIP %s", srcIp.c_str()); - msg += anna::functions::asString("\ndestinationIP %s", dstIp.c_str()); - msg += "\n"; - msg += anna::functions::asString("\nfragmentId %d:", fragmentId); - msg += anna::functions::asString("\nDF %s:", (dfFlag ? "1":"0")); - msg += anna::functions::asString("\nMF %s:", (mfFlag ? "1":"0")); - msg += anna::functions::asString("\nfragmentOffset %d:", fragmentOffset); - - Logger::debug(msg, ANNA_FILE_LOCATION); - ); - - auxPayload.setDiameterLength((payload[1] << 16) + (payload[2] << 8) + payload[3]); - auxPayload.setSourceIP(srcIp); - auxPayload.setDestinationIP(dstIp); - auxPayload.setTimestamp(pkthdr->ts.tv_sec); - auxPayload.setTimestampU(pkthdr->ts.tv_usec); - bool completed = auxPayload.appendData((const char *)payload, payloadSize); - if (completed) { - G_payloads[count] = auxPayload; - auxPayload.reset(); - } +void my_callback(u_char *useless, const struct pcap_pkthdr* pkthdr, + const u_char* packet) { + static int count = 1; + static Payload auxPayload; + int packetSize = pkthdr->len; + int payloadSize; + std::string srcIp, dstIp; + int fragmentId, fragmentOffset; + bool dfFlag, mfFlag; + const u_char* payload = getPayload(packet, packetSize, payloadSize, srcIp, + dstIp, fragmentId, dfFlag, mfFlag, fragmentOffset); + + if(payload && (payloadSize > 0)) { + LOGDEBUG( + std::string msg; msg += anna::functions::asString("\nFrame %d:", count); msg += anna::functions::asHexString(anna::DataBlock((const char *)packet, pkthdr->len)); time_t time = pkthdr->ts.tv_sec; msg += "\n"; msg += anna::functions::asString("\ntimestamp %d.%d", pkthdr->ts.tv_sec, pkthdr->ts.tv_usec); msg += anna::functions::asString("\ndate %s", ctime(&time)); msg += anna::functions::asString("\ncaplen %d", pkthdr->caplen); msg += anna::functions::asString("\npacketSize %d", packetSize); msg += anna::functions::asString("\npayloadSize %d", payloadSize); msg += "\nPayload:"; msg += anna::functions::asHexString(anna::DataBlock((const char *)payload, payloadSize)); msg += "\n"; msg += anna::functions::asString("\nsourceIP %s", srcIp.c_str()); msg += anna::functions::asString("\ndestinationIP %s", dstIp.c_str()); msg += "\n"; msg += anna::functions::asString("\nfragmentId %d:", fragmentId); msg += anna::functions::asString("\nDF %s:", (dfFlag ? "1" : "0")); msg += anna::functions::asString("\nMF %s:", (mfFlag ? "1" : "0")); msg += anna::functions::asString("\nfragmentOffset %d:", fragmentOffset); + Logger::debug(msg, ANNA_FILE_LOCATION);); + auxPayload.setDiameterLength( + (payload[1] << 16) + (payload[2] << 8) + payload[3]); + auxPayload.setSourceIP(srcIp); + auxPayload.setDestinationIP(dstIp); + auxPayload.setTimestamp(pkthdr->ts.tv_sec); + auxPayload.setTimestampU(pkthdr->ts.tv_usec); + bool completed = auxPayload.appendData((const char *) payload, payloadSize); + + if(completed) { + G_payloads[count] = auxPayload; + auxPayload.reset(); + } } count++; } +bool getDataBlockFromHexFile(const std::string &pathfile, anna::DataBlock &db) { + // Get hex string + static char buffer[8192]; + std::ifstream infile(pathfile.c_str(), std::ifstream::in); + + if(infile.is_open()) { + infile >> buffer; + std::string hexString(buffer, strlen(buffer)); + // Allow colon separator in hex string: we have to remove them before processing with 'fromHexString': + hexString.erase(std::remove(hexString.begin(), hexString.end(), ':'), hexString.end()); + LOGDEBUG( + std::string msg = "Hex string (remove colons if exists): "; + msg += hexString; + anna::Logger::debug(msg, ANNA_FILE_LOCATION); + ); + anna::functions::fromHexString(hexString, db); + // Close file + infile.close(); + return true; + } + + return false; +} + + +void _exit(const std::string &message, int resultCode = 1) { + if(resultCode) + std::cerr << message << std::endl << std::endl; + else + std::cout << message << std::endl << std::endl; + + exit(resultCode); +} + + +//------------------------------------------------------------------- +int main(int argc, char **argv) { + std::string exec = argv[0]; + std::string execBN = exec.substr(exec.find_last_of("/") + 1); + std::string filetrace = execBN + ".trace"; + std::cout << std::endl; + + //check command line arguments + if(argc < 2) { + std::string msg = "Usage: "; msg += exec; + msg += " [--write-hex: to write hex files] [--debug: activates debug level traces (warning by default)]\n\n"; + _exit(msg); + } + + // Command-line parameters: + std::string inputFile = argv[1]; + //bool isHex = (inputFile.substr(inputFile.find_last_of(".") + 1) == "hex"); + std::string outputFile = inputFile; // extension will be added later + std::string optionals; + int indx = 2; + while(indx < argc) { optionals += " "; optionals += argv[indx]; indx++; } + + bool debug = (optionals.find("--debug") != std::string::npos); + bool writeHex = (optionals.find("--write-hex") != std::string::npos); + Logger::setLevel(debug ? Logger::Debug:Logger::Warning); + Logger::initialize(execBN.c_str(), new TraceWriter(filetrace.c_str(), 2048000)); + + anna::DataBlock db_aux(true); + + // SNIFFING //////////////////////////////////////////////////////////////////////////////////////////////7 + //temporary packet buffers + //struct pcap_pkthdr header; // The header that pcap gives us + //const u_char *packet; // The actual packet + //------------------ + //open the pcap file + pcap_t *handle; + char errbuf[PCAP_ERRBUF_SIZE]; //not sure what to do with this, oh well + handle = pcap_open_offline(inputFile.c_str(), errbuf); //call pcap library function + + if(handle == NULL) _exit(errbuf, 2); + + // TODO: add filtering. At the moment, pcap must be previously filtered for diameter protocol ('tcp port 3868' or any other filter allowed) + /* + // Filtering: + std::string filter = ?????; + struct bpf_program _fp; + struct bpf_program *fp = &_fp; + bpf_u_int32 netmask = 4294967295; // FFFFFFFF + + if (pcap_compile(handle, fp, (char*)(filter.c_str()), 1, netmask) == -1) { + std::cerr << "Couldn't compile the filter " << filter << std::endl; + return(2); + } + if (pcap_setfilter(handle, fp) == -1) { + std::cerr << "Couldn't set the filter " << filter << std::endl; + return(2); + } + */ + + //begin processing the packets in this particular file + int packets = -1; + + try { + while(packets != 0) + packets = pcap_dispatch(handle, -1, (pcap_handler) my_callback, NULL); + } catch(RuntimeException &ex) { + _exit(ex.asString()); + } + + pcap_close(handle); //close the pcap file + + // Print payloads ////////////////////////////////////////////////////////////////////////////////////////////// + // Open output file: + outputFile += ".report"; + std::ofstream out(outputFile.c_str(), std::ifstream::out); + + for(payloads_it it = G_payloads.begin(); it != G_payloads.end(); it++) { + LOGDEBUG( + Logger::debug(anna::functions::asString("Dumping frame %d", it->first), ANNA_FILE_LOCATION)); + time_t ts = (it->second).getTimestamp(); + int tsu = (it->second).getTimestampU(); + std::string ts_str = ctime(&ts); + ts_str.erase(ts_str.find("\n")); + out << "Frame: " << anna::functions::asString(it->first) << std::endl; + out << "Date: " << ts_str << std::endl; + out << "Timestamp: " << anna::functions::asString((int)ts) << "." + << anna::functions::asString((int)tsu) << std::endl; + out << "Origin IP: " << (it->second).getSourceIP() << std::endl; + out << "Destination IP: " << (it->second).getDestinationIP() << std::endl; + out << "Destination IP: " << (it->second).getDestinationIP() << std::endl; + out << "Hex String: " << (it->second).getDataAsHex() << std::endl; + + // Create hex file: + if (writeHex) { + std::string hexFile = anna::functions::asString(it->first) + ".hex"; + std::ofstream hex(hexFile.c_str(), std::ifstream::out); + hex << (it->second).getDataAsHex(); + hex.close(); + } + + out << std::endl; + } -//------------------------------------------------------------------- -int main(int argc, char **argv) -{ - std::string exec = argv[0]; - - std::cout << std::endl; - - //check command line arguments - if (argc < 3) { - std::cout << "Usage: " << exec << " [--ignore-flags: non-strict validation]" << std::endl << std::endl; - return 1; - } - - // Command-line parameters: - std::string dictionaries = argv[1]; - std::string pcapFile = argv[2]; - std::string optional = argv[3] ? argv[3] : ""; - bool ignoreFlags = ((argc == 4) && (optional == "--ignore-flags")); - std::cout << "Dictionary(ies) provided: " << dictionaries << std::endl; - std::cout << "Pcap file provided: " << pcapFile << std::endl; - std::cout << "Validation kindness: " << (ignoreFlags ? "non strict":"strict") << std::endl; - - // Logger and engines: - Logger::setLevel(Logger::Debug); - Logger::initialize("pcapDecoder", new TraceWriter("file.trace", 2048000)); - anna::diameter::codec::Engine *codecEngine = new anna::diameter::codec::Engine(); - anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate(); - - try { - anna::diameter::stack::Dictionary * d = stackEngine.createDictionary(0 /* stack id */); - // Analyze comma-separated list: - anna::Tokenizer lst; - lst.apply(dictionaries, ","); - - if (lst.size() >= 1) { // always true (at least one, because -dictionary is mandatory) - anna::Tokenizer::const_iterator tok_min(lst.begin()); - anna::Tokenizer::const_iterator tok_max(lst.end()); - anna::Tokenizer::const_iterator tok_iter; - std::string pathFile; - d->allowUpdates(); - - for (tok_iter = tok_min; tok_iter != tok_max; tok_iter++) { - pathFile = anna::Tokenizer::data(tok_iter); - d->load(pathFile); - } - } - - codecEngine->setDictionary(d); - //LOGDEBUG(anna::Logger::debug(codecEngine->asString(), ANNA_FILE_LOCATION)); - - if (lst.size() > 1) { - std::string all_in_one = "./dictionary-all-in-one.xml"; - std::ofstream out(all_in_one, std::ifstream::out); - std::string buffer = d->asXMLString(); - out.write(buffer.c_str(), buffer.size()); - out.close(); - std::cout << "Written '" << all_in_one << "' (provide it next time to be more comfortable)." << std::endl; - } - - } catch (anna::RuntimeException &ex) { - std::cerr << ex.asString() << std::endl << std::endl; - return 1; - } - - codecEngine->ignoreFlagsOnValidation(ignoreFlags); - // Tracing: - //if (cl.exists("trace")) - // anna::Logger::setLevel(anna::Logger::asLevel(cl.getValue("trace"))); - - - - // SNIFFING //////////////////////////////////////////////////////////////////////////////////////////////7 - - //temporary packet buffers - struct pcap_pkthdr header; // The header that pcap gives us - const u_char *packet; // The actual packet - - //------------------ - //open the pcap file - pcap_t *handle; - char errbuf[PCAP_ERRBUF_SIZE]; //not sure what to do with this, oh well - handle = pcap_open_offline(pcapFile.c_str(), errbuf); //call pcap library function - - if (handle == NULL) { - std::cerr << errbuf << std::endl << std::endl; - return 2; - } - - - //begin processing the packets in this particular file - int packets = -1; - try { - while (packets != 0) - packets = pcap_dispatch(handle, -1, (pcap_handler)my_callback, NULL); - } - catch (RuntimeException &ex) { - std::cerr << ex.asString() << std::endl << std::endl; - return 1; - } - pcap_close(handle); //close the pcap file - - // Print payloads ////////////////////////////////////////////////////////////////////////////////////////////// - - // Open output file: - std::string output = pcapFile; output += ".report"; - std::ofstream out(output, std::ifstream::out); - std::string xmlStr; - anna::DataBlock db_aux(true); - - //out.write(str.c_str(), str.size()); - - - for (payloads_it it = G_payloads.begin(); it != G_payloads.end(); it++) { - LOGDEBUG (Logger::debug(anna::functions::asString("Dumping frame %d", it->first), ANNA_FILE_LOCATION)); - time_t ts = (it->second).getTimestamp(); - int tsu = (it->second).getTimestampU(); - std::string ts_str = ctime(&ts); - ts_str.erase (ts_str.find ("\n")); - - out << std::endl; - out << "===================================================================================================" << std::endl; - out << "Date: " << ts_str << std::endl; - out << "Timestamp: " << std::to_string(ts) << "." << std::to_string(tsu) << std::endl; - out << "Origin IP: " << (it->second).getSourceIP() << std::endl; - out << "Destination IP: " << (it->second).getDestinationIP() << std::endl; - out << std::endl; - - // decode hex string: - anna::functions::fromHexString((it->second).getDataAsHex(), db_aux); - try { - G_codecMsg.decode(db_aux); - } - catch (RuntimeException &ex) { - std::cerr << ex.asString() << std::endl << std::endl; - return 1; - } - out << G_codecMsg.asXMLString(); - } - - - // Close output file: - out.close(); - - std::cout << "Open 'file.trace' in order to see process traces." << std::endl; - std::cout << "Open '" << output << "' to see conversion results." << std::endl; - std::cout << std::endl; - return 0; + // Close output file: + out.close(); + std::string msg = "Open '"; msg += filetrace; msg += "' in order to see process traces.\n"; + msg += "Open '"; msg += outputFile; msg += "' to see decoding results.\n"; + if (writeHex) msg += "Open '.hex' to see specific frame data."; + _exit(msg, 0); }