Browse Source

add tests functions to statistics calss, add argument -t to do tests, add checksum and payload tests results to db

aidmar.wainakh 6 years ago
parent
commit
a6347fbd9c

+ 3 - 1
code/CLI.py

@@ -29,7 +29,7 @@ class CLI(object):
         given queries.
         """
         # Create ID2T Controller
-        controller = Controller(self.args.input)
+        controller = Controller(self.args.input, self.args.tests)
 
         # Load PCAP statistics
         controller.load_pcap_statistics(self.args.export, self.args.recalculate, self.args.statistics)
@@ -82,6 +82,8 @@ class CLI(object):
         parser.add_argument('-q', '--query', metavar="QUERY",
                             action='append', nargs='?',
                             help='queries the statistics database. If no query is provided, the application enters into query mode.')
+        # Aidmar
+        parser.add_argument('-t', '--tests', help='perform defects tests on input pcap file.', action='store_true')
 
         # Parse arguments
         self.args = parser.parse_args(args)

+ 6 - 1
code/ID2TLib/Controller.py

@@ -8,7 +8,7 @@ from ID2TLib.Statistics import Statistics
 
 
 class Controller:
-    def __init__(self, pcap_file_path: str):
+    def __init__(self, pcap_file_path: str, do_tests: bool): #Aidmar - do_tests
         """
         Creates a new Controller, acting as a central coordinator for the whole application.
         :param pcap_file_path:
@@ -17,12 +17,17 @@ class Controller:
         self.pcap_src_path = pcap_file_path.strip()
         self.pcap_dest_path = ''
         self.written_pcaps = []
+        # Aidmar
+        self.do_tests = do_tests
 
         # Initialize class instances
         print("Input file: %s" % self.pcap_src_path)
         self.pcap_file = PcapFile(self.pcap_src_path)
         self.label_manager = LabelManager(self.pcap_src_path)
         self.statistics = Statistics(self.pcap_file)
+        # Aidmar
+        self.statistics.do_tests = self.do_tests
+
         self.statisticsDB = self.statistics.get_statistics_database()
         self.attack_controller = AttackController(self.pcap_file, self.statistics, self.label_manager)
 

+ 3 - 1
code/ID2TLib/Statistics.py

@@ -22,6 +22,8 @@ class Statistics:
         # Fields
         self.pcap_filepath = pcap_file.pcap_file_path
         self.pcap_proc = None
+        # Aidmar
+        self.do_tests = False
 
         # Create folder for statistics database if required
         self.path_db = pcap_file.get_db_path()
@@ -52,7 +54,7 @@ class Statistics:
 
         # Recalculate statistics if database not exists OR param -r/--recalculate was provided
         if (not self.stats_db.get_db_exists()) or flag_recalculate_stats:
-            self.pcap_proc = pr.pcap_processor(self.pcap_filepath)
+            self.pcap_proc = pr.pcap_processor(self.pcap_filepath, str(self.do_tests)) # Aidmar - do_tests
             self.pcap_proc.collect_statistics()
             self.pcap_proc.write_to_database(self.path_db)
             outstring_datasource = "by PCAP file processor."

+ 1 - 1
code_boost/src/CMakeLists.txt

@@ -23,7 +23,7 @@ SET(CMAKE_CXX_STANDARD 11)
 SET(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 # Add the library source files
-SET(SOURCE_FILES cxx/pcap_processor.cpp cxx/pcap_processor.h cxx/statistics.cpp cxx/statistics.h cxx/statistics_db.cpp cxx/statistics_db.h cxx/artifacts_tests.h cxx/artifacts_tests.cpp cxx/utilities.h cxx/utilities.cpp)
+SET(SOURCE_FILES cxx/pcap_processor.cpp cxx/pcap_processor.h cxx/statistics.cpp cxx/statistics.h cxx/statistics_db.cpp cxx/statistics_db.h cxx/utilities.h cxx/utilities.cpp)
 
 # Include SQLiteCpp library and build it
 option(SQLITECPP_RUN_CPPLINT OFF)

+ 4 - 0
code_boost/src/cmake-build-debug/CMakeFiles/cpp-pcapreader.dir/CXX.includecache

@@ -67,6 +67,8 @@ sstream
 -
 artifacts_tests.h
 /home/anonymous/Downloads/ID2T-toolkit/code_boost/src/cxx/artifacts_tests.h
+utilities.h
+/home/anonymous/Downloads/ID2T-toolkit/code_boost/src/cxx/utilities.h
 
 /home/anonymous/Downloads/ID2T-toolkit/code_boost/src/cxx/artifacts_tests.h
 tins/tins.h
@@ -119,6 +121,8 @@ statistics_db.h
 /home/anonymous/Downloads/ID2T-toolkit/code_boost/src/cxx/statistics_db.h
 statistics.h
 /home/anonymous/Downloads/ID2T-toolkit/code_boost/src/cxx/statistics.h
+utilities.h
+/home/anonymous/Downloads/ID2T-toolkit/code_boost/src/cxx/utilities.h
 
 /home/anonymous/Downloads/ID2T-toolkit/code_boost/src/cxx/statistics.h
 vector

BIN
code_boost/src/cmake-build-debug/cpp-pcapreader


+ 0 - 2
code_boost/src/cxx/CMakeLists.txt

@@ -10,8 +10,6 @@ set(SOURCE_FILES
         statistics.h
         statistics_db.cpp
         statistics_db.h
-        artifacts_tests.cpp
-        artifacts_tests.h
         utilities.cpp
         utilities.h)
 

+ 0 - 201
code_boost/src/cxx/artifacts_tests.cpp

@@ -1,201 +0,0 @@
-#include <iostream>
-#include <fstream>
-#include <sstream>
-
-#include "artifacts_tests.h"
-
-
-using namespace Tins;
-
-/**
- * Creates a new artifacts_tests object.
- */
-artifacts_tests::artifacts_tests() {
-     correctChecksum = 0;
-     incorrectChecksum= 0;
-     checksumIncorrectRatio= 0;
-    
-     noPayloadCount= 0;
-     payloadCount= 0;
-}
-
-
-/*
-**************************************************************************
-Function: tcp_sum_calc()
-**************************************************************************
-Description: 
-	Calculate TCP checksum
-***************************************************************************
-*/
-
-typedef unsigned short u16;
-typedef unsigned long u32;
-
-u16 tcp_sum_calc(u16 len_tcp, u16 src_addr[],u16 dest_addr[], bool padding, u16 buff[])
-{
-    u16 prot_tcp=6;
-    u16 padd=0;
-    u16 word16;
-    u32 sum;	
-        
-        // Find out if the length of data is even or odd number. If odd,
-        // add a padding byte = 0 at the end of packet
-        //if ((padding&1)==1){
-        if(padding){
-            padd=1;
-            buff[len_tcp]=0;
-        }
-        
-        //initialize sum to zero
-        sum=0;
-        
-        // make 16 bit words out of every two adjacent 8 bit words and 
-        // calculate the sum of all 16 vit words
-        for (int i=0;i<len_tcp+padd;i=i+2){
-            word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
-            sum = sum + (unsigned long)word16;
-        }	
-        // add the TCP pseudo header which contains:
-        // the IP source and destinationn addresses,
-        for (int i=0;i<4;i=i+2){
-            word16 =((src_addr[i]<<8)&0xFF00)+(src_addr[i+1]&0xFF);
-            sum=sum+word16;	
-        }
-        for (int i=0;i<4;i=i+2){
-            word16 =((dest_addr[i]<<8)&0xFF00)+(dest_addr[i+1]&0xFF);
-            sum=sum+word16; 	
-        }
-        // the protocol number and the length of the TCP packet
-        sum = sum + prot_tcp + len_tcp;
-
-        // keep only the last 16 bits of the 32 bit calculated sum and add the carries
-            while (sum>>16)
-            sum = (sum & 0xFFFF)+(sum >> 16);
-            
-        // Take the one's complement of sum
-        sum = ~sum;
-
-    return ((unsigned short) sum);
-}
-
-
-void convertIPv4toArray(std::string IP, unsigned short IP_bytes[]){
-    std::vector<std::string> temp_v;
-    split_str(IP,'.',temp_v);    
-    IP_bytes[0] = std::stoi(temp_v[0]);
-    IP_bytes[1] = std::stoi(temp_v[1]);
-    IP_bytes[2] = std::stoi(temp_v[2]);
-    IP_bytes[3] = std::stoi(temp_v[3]);
-}
-
-/**
- * Checks the TCP checksum of a given packet.
- * @param tcpPkt The packet to get checked.
- */
-void artifacts_tests::check_checksum(std::string ipAddressSender, std::string ipAddressReceiver, TCP tcpPkt){
-    uint16_t checksum = tcpPkt.checksum();
-       
-    unsigned short calculatedChecsum = 0;
-    
-    int headerSize = tcpPkt.header_size();
-    std::vector<uint8_t> bufferArray_8;
-      
-    try {
-        bufferArray_8 = tcpPkt.serialize();
-    } catch (serialization_error) {        
-        std::cout << "Error: Could not serialize TCP packet with sender: " << ipAddressSender << ", receiver: " 
-        << ipAddressReceiver << ", seq: " << tcpPkt.seq() << std::endl;
-        return;
-    }
-            
-    std::vector<unsigned short> bufferArray_16;
-     for(int i=0; (unsigned)i<bufferArray_8.size();i++){
-         bufferArray_16.push_back(bufferArray_8[i]);
-       }
-
-    /*for(int i=0; i<bufferArray_8.size();i+=2){
-        uint8_t temp[2];
-        temp[0] = bufferArray_8[i];
-        if(i!=(bufferArray_8.size()-1))
-            temp[1] = bufferArray_8[i+1];
-        else
-            temp[1] = 0;
-        unsigned short n;
-        memcpy(&n, temp, sizeof(unsigned short));
-        bufferArray_16.push_back(n);
-    } */  
-        
-    unsigned short* buff_16 = &bufferArray_16[0];
-    unsigned short ipAddressSender_bytes[4];
-    unsigned short ipAddressReceiver_bytes[4];
-    convertIPv4toArray(ipAddressSender, ipAddressSender_bytes);
-    convertIPv4toArray(ipAddressReceiver, ipAddressReceiver_bytes);
-
-    //tcp_sum_calc(unsigned short len_tcp, unsigned short src_addr[],unsigned short dest_addr[], bool padding, unsigned short buff[])
-    bool padding = false; 
-    int dataSize = bufferArray_8.size() - headerSize;  // TO-DO: why don't you use pkt.size()
-    if(dataSize != 0)
-        if(dataSize % 2 != 0)
-            padding = true; // padding if the data size is odd
-
-    calculatedChecsum = tcp_sum_calc(bufferArray_8.size(), ipAddressSender_bytes, ipAddressReceiver_bytes, padding, buff_16);
-
-
-    if(calculatedChecsum == checksum)
-        correctChecksum++;
-    else{
-        std::cout<<"Sender:"<<ipAddressSender<<", Receiver:"<<ipAddressReceiver<<"\n";
-        std::cout<<"Packet checksum:"<<checksum<<"\n";
-        std::cout<<"Calculated checksum:"<<calculatedChecsum<<"\n";
-         
-        incorrectChecksum++;
-    }
-}
-
-/**
- * Gets the ratio of incorrect TCP checksums to total number of TCP packets.
- */
-float artifacts_tests::get_checksum_incorrect_ratio(){
-    int totalPktsNum = incorrectChecksum+correctChecksum;
-    float ratio = 0;
-    if(totalPktsNum!=0)
-        ratio = (float)incorrectChecksum/totalPktsNum;
-    
-    std::cout<<"Incorrect checksums: "<<incorrectChecksum<<"\n";
-    std::cout<<"Total TCP packets: "<<totalPktsNum<<"\n";
-    std::cout<<"get_checksum_incorrect_ratio: "<<ratio<<"\n";
-    
-    return ratio;
-}
-
-void artifacts_tests::check_payload(const PDU *pkt){
-    int pktSize = pkt->size();
-    int headerSize = pkt->header_size();
-    int payloadSize = pktSize - headerSize;
-    if(payloadSize>0)
-        payloadCount++;
-    else
-        noPayloadCount++;
-}
-
-/**
- * Gets the ratio of packets that have payload to total number of packets.
- */
-float artifacts_tests::get_payload_ratio(){
-    int totalPktsNum = noPayloadCount+payloadCount;
-    float ratio = 0;
-    if(totalPktsNum!=0)
-        ratio = (float)payloadCount/totalPktsNum;
-    
-    std::cout<<"Payload packets: "<<payloadCount<<"\n";
-    std::cout<<"Total packets: "<<totalPktsNum<<"\n";
-    std::cout<<"get_payload_ratio: "<<ratio<<"\n";
-    
-    return ratio;
-}
-
-void artifacts_tests::check_tos(uint8_t ToS){
-    //if((unsigned)ToS != 0)
-      //  std::cout<<"ToS: "<<(unsigned)ToS<<"\n";
-}

+ 0 - 70
code_boost/src/cxx/artifacts_tests.h

@@ -1,70 +0,0 @@
-/**
- * Class for performing artifacts tests.
- */
-
-#ifndef CPP_ARTIFACTS_TESTS_H
-#define CPP_ARTIFACTS_TESTS_H
-
-// Aidmar
-//#include <iomanip>
-
-#include <tins/tins.h>
-#include <iostream>
-//#include <time.h>
-#include <stdio.h>
-//#include <sys/stat.h>
-//#include <unordered_map>
-//#include "statistics.h"
-
-#include "utilities.h"
-
-using namespace Tins;
-
-class artifacts_tests {
-
-public:
-    /*
-    * Class constructor
-    */
-    artifacts_tests();
-
-    /*
-     * Attributes
-     */
-    int correctChecksum;
-    int incorrectChecksum;
-    float checksumIncorrectRatio;
-    
-    int noPayloadCount;
-    int payloadCount;
-    
-    //std::string timstampPrecision;
-    
-    //statistics stats;
-    //std::string filePath;
-
-    /*
-     * Methods
-     */
-    void check_checksum(std::string ipAddressSender, std::string ipAddressReceiver, TCP tcpPkt);
-    float get_checksum_incorrect_ratio();
-    void check_payload(const PDU *pkt);
-    float get_payload_ratio();
-    void check_tos(uint8_t ToS);
-    //bool check_timestamp_precision(const Packet &pkt);
-
-    /*
-    inline bool file_exists(const std::string &filePath);
-
-    long double get_timestamp_mu_sec(const int after_packet_number);
-
-    std::string merge_pcaps(const std::string pcap_path);
-
-    void collect_statistics();
-
-    void write_to_database(std::string database_path);
-    */
-};
-
-
-#endif //CPP_ARTIFACTS_TESTS_H

+ 25 - 22
code_boost/src/cxx/pcap_processor.cpp

@@ -6,7 +6,12 @@ using namespace Tins;
  * Creates a new pcap_processor object.
  * @param path The path where the PCAP to get analyzed is locatated.
  */
-pcap_processor::pcap_processor(std::string path) : filePath(path) {
+pcap_processor::pcap_processor(std::string path, std::string tests) {
+    filePath = path;
+    // Aidmar
+    if(tests == "True")
+        stats.setDoTests(true);
+    else  stats.setDoTests(false);;
 }
 
 /**
@@ -115,10 +120,8 @@ void pcap_processor::collect_statistics() {
 
         // Save timestamp of first packet
         stats.setTimestampFirstPacket(i->timestamp());
-    
-        // Aidmar
-        //int counter=0;
-        int timeIntervalCounter = 1;   
+
+        int timeIntervalCounter = 1;
         int timeIntervalsNum = 100;
         std::chrono::microseconds intervalStartTimestamp = stats.getTimestampFirstPacket();
         std::chrono::microseconds firstTimestamp = stats.getTimestampFirstPacket(); 
@@ -158,15 +161,15 @@ void pcap_processor::collect_statistics() {
             stats.incrementPacketCount();
             this->process_packets(*i);                    
             lastProcessedPacket = i->timestamp();
-            //counter++;
         }
         
         // Save timestamp of last packet into statistics
         stats.setTimestampLastPacket(lastProcessedPacket);
-        
-        // Aidmar
-        //tests.get_checksum_incorrect_ratio();
-        //tests.get_payload_ratio();
+
+        // TO-DO: to delete
+        //for (auto it = stats.dscp_distribution.begin(); it != stats.dscp_distribution.end(); ++it) {
+          //  std::cout<<it->first<<","<<it->second<<"\n";
+        //}
     }
 }
 
@@ -215,7 +218,7 @@ void pcap_processor::process_packets(const Packet &pkt) {
         stats.assignMacAddress(ipAddressReceiver, macAddressReceiver);        
 
         // Aidmar - Artifacts Tests: contemporary (ToS)
-        //tests.check_tos(ipLayer.tos());
+        stats.checkToS(ipLayer.tos());
         
     } // PDU is IPv6
     else if (pdu_l3_type == PDU::PDUType::IPv6) {
@@ -235,7 +238,6 @@ void pcap_processor::process_packets(const Packet &pkt) {
         // Assign IP Address to MAC Address
         stats.assignMacAddress(ipAddressSender, macAddressSender);
         stats.assignMacAddress(ipAddressReceiver, macAddressReceiver);
-
     } else {
         //std::cout << "Unknown PDU Type on L3: " << pdu_l3_type << std::endl;
         // TO-DO: add this to tests
@@ -247,18 +249,19 @@ void pcap_processor::process_packets(const Packet &pkt) {
         // Protocol distribution - layer 4
         PDU::PDUType p = pdu_l4->pdu_type();  
         
-        // Aidmar - Artifacts Tests: payload
-        /*if (pdu_l3_type == PDU::PDUType::IP) {            
-            tests.check_payload(pdu_l4);
+        // Aidmar - Tests for IPv4: payload
+        if (pdu_l3_type == PDU::PDUType::IP) {
+            stats.checkPayload(pdu_l4);
           }
-         */ 
+
         if (p == PDU::PDUType::TCP) {
             TCP tcpPkt = (const TCP &) *pdu_l4;
             
-          // Aidmar - Artifacts Tests: checksum
-          /*if (pdu_l3_type == PDU::PDUType::IP) {            
-            tests.check_checksum(ipAddressSender, ipAddressReceiver, tcpPkt);
-          }*/            
+          // Aidmar - Tests TCP checksum
+          if (pdu_l3_type == PDU::PDUType::IP) {
+            stats.checkTCPChecksum(ipAddressSender, ipAddressReceiver, tcpPkt);
+          }
+
             stats.incrementProtocolCount(ipAddressSender, "TCP");                        
                     
             // Aidmar
@@ -323,7 +326,7 @@ bool inline pcap_processor::file_exists(const std::string &filePath) {
  */
 //int main() {
 //    std::cout << "Starting application." << std::endl;
-//    pcap_processor pcap = pcap_processor("/home/anonymous/Downloads/ID2T-toolkit/captures/darpa/darpa_w1_mon_inside.pcap");
+//    pcap_processor pcap = pcap_processor("/home/anonymous/Downloads/ID2T-toolkit/captures/iscx/1h_iscx_11jun.pcap", "False");
 //
 //    long double t = pcap.get_timestamp_mu_sec(87);
 //    std::cout << t << std::endl;
@@ -351,7 +354,7 @@ bool inline pcap_processor::file_exists(const std::string &filePath) {
 using namespace boost::python;
 
 BOOST_PYTHON_MODULE (libpcapreader) {
-    class_<pcap_processor>("pcap_processor", init<std::string>())
+    class_<pcap_processor>("pcap_processor", init<std::string, std::string>()) // Aidmar - added , std::string
             .def("merge_pcaps", &pcap_processor::merge_pcaps)
             .def("collect_statistics", &pcap_processor::collect_statistics)
             .def("get_timestamp_mu_sec", &pcap_processor::get_timestamp_mu_sec)

+ 1 - 4
code_boost/src/cxx/pcap_processor.h

@@ -15,7 +15,6 @@
 #include <sys/stat.h>
 #include <unordered_map>
 #include "statistics.h"
-#include "artifacts_tests.h"
 
 using namespace Tins;
 
@@ -25,7 +24,7 @@ public:
     /*
     * Class constructor
     */
-    pcap_processor(std::string path);
+    pcap_processor(std::string path, std::string tests);
 
     /*
      * Attributes
@@ -33,8 +32,6 @@ public:
     statistics stats;
     std::string filePath;
 
-    // Aidmar
-    //artifacts_tests tests;
     /*
      * Methods
      */

+ 162 - 54
code_boost/src/cxx/statistics.cpp

@@ -8,6 +8,78 @@
 #include <SQLiteCpp/SQLiteCpp.h>
 #include "statistics_db.h"
 #include "statistics.h"
+#include "utilities.h"
+
+// Aidmar
+using namespace Tins;
+
+
+// Aidmar
+/**
+ * Checks if ToS is valid according to RFC2472 and increments counter.
+ * @param uint8_t ToS ToS values to be checked.
+ */
+void statistics::checkToS(uint8_t ToS) {
+    if(this->getDoTests()) {
+        //std::cout <<"ToS bin: "<< integral_to_binary_string(ToS)<<"\n";
+        if((unsigned)ToS != 0) {
+            std::bitset<8> tosBit(ToS); //convent number into bit array
+
+            std::stringstream dscpStream;
+            dscpStream <<tosBit[7]<<tosBit[6]<<tosBit[5]<<tosBit[4]<<tosBit[3]<<tosBit[2];
+            std::bitset<6> dscpBit(dscpStream.str());
+            int dscpInt = (int)(dscpBit.to_ulong());
+
+//            std::stringstream ipPrecStream;
+//            ipPrecStream <<tosBit[7]<<tosBit[6]<<tosBit[5];
+//            std::bitset<6> ipPrecedenceBit(ipPrecStream.str());
+//            int ipPrecedenceInt = (int)(ipPrecedenceBit.to_ulong());
+
+            // Commonly Used DSCP Values according to RFC2472
+            int validValues[] = {0,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,46,48,56};
+            bool exists = std::find(std::begin(validValues), std::end(validValues), dscpInt) != std::end(validValues);
+
+            // According to RFC791 ipPrecedenceInt <= 7 && tosBit[0] must be 0
+            if(!exists && tosBit[0] == 0)
+                invalidToSCount++;
+            else
+                validToSCount++;
+
+            dscp_distribution[dscpInt]++;
+        }
+    }
+}
+
+// Aidmar
+/**
+ * Checks if there is a payload and increments payloads counter.
+ * @param pdu_l4 The packet that should be checked if it has a payload or not.
+ */
+void statistics::checkPayload(const PDU *pdu_l4) {
+    if(this->getDoTests()) {
+        // pdu_l4: Tarnsport layer 4
+        int pktSize = pdu_l4->size();
+        int headerSize = pdu_l4->header_size(); // TCP/UDP header
+        int payloadSize = pktSize - headerSize;
+        if (payloadSize > 0)
+            payloadCount++;
+    }
+}
+
+// Aidmar
+/**
+ * Checks the correctness of TCP checksum and increments counter if the checksum was incorrect.
+ * @param ipAddressSender The source IP.
+ * @param ipAddressReceiver The destination IP.
+ * @param tcpPkt The packet to get checked.
+ */
+void statistics::checkTCPChecksum(std::string ipAddressSender, std::string ipAddressReceiver, TCP tcpPkt) {
+    if(this->getDoTests()) {
+        if(check_tcpChecksum(ipAddressSender, ipAddressReceiver, tcpPkt))
+            correctTCPChecksumCount++;
+        else incorrectTCPChecksumCount++;
+    }
+}
 
 // Aidmar
 /**
@@ -15,47 +87,52 @@
  * @param intervalStartTimestamp The timstamp where the interval starts.
  */
 std::vector<float> statistics::calculateLastIntervalIPsEntropy(std::chrono::microseconds intervalStartTimestamp){
-        std::vector <int> IPsSrcPktsCounts; 
-        std::vector <int> IPsDstPktsCounts; 
+    if(this->getDoTests()) {
+        std::vector<int> IPsSrcPktsCounts;
+        std::vector<int> IPsDstPktsCounts;
+
+        std::vector<float> IPsSrcProb;
+        std::vector<float> IPsDstProb;
 
-        std::vector <float> IPsSrcProb; 
-        std::vector <float> IPsDstProb;
-    
         int pktsSent = 0, pktsReceived = 0;
-        
+
         for (auto i = ip_statistics.begin(); i != ip_statistics.end(); i++) {
             int indexStartSent = getClosestIndex(i->second.pktsSentTimestamp, intervalStartTimestamp);
             int IPsSrcPktsCount = i->second.pktsSentTimestamp.size() - indexStartSent;
             IPsSrcPktsCounts.push_back(IPsSrcPktsCount);
-            pktsSent += IPsSrcPktsCount;                        
-            int indexStartReceived = getClosestIndex(i->second.pktsReceivedTimestamp, intervalStartTimestamp);   
-            int IPsDstPktsCount = i->second.pktsReceivedTimestamp.size() - indexStartReceived;       
+            pktsSent += IPsSrcPktsCount;
+            int indexStartReceived = getClosestIndex(i->second.pktsReceivedTimestamp, intervalStartTimestamp);
+            int IPsDstPktsCount = i->second.pktsReceivedTimestamp.size() - indexStartReceived;
             IPsDstPktsCounts.push_back(IPsDstPktsCount);
             pktsReceived += IPsDstPktsCount;
         }
 
-         for (auto i = IPsSrcPktsCounts.begin(); i != IPsSrcPktsCounts.end(); i++) {
-                IPsSrcProb.push_back((float)*i/pktsSent);
-         }
-         for (auto i = IPsDstPktsCounts.begin(); i != IPsDstPktsCounts.end(); i++) {
-                IPsDstProb.push_back((float)*i/pktsReceived);
-         }
-         
-         // Calculate IP source entropy 
+        for (auto i = IPsSrcPktsCounts.begin(); i != IPsSrcPktsCounts.end(); i++) {
+            IPsSrcProb.push_back((float) *i / pktsSent);
+        }
+        for (auto i = IPsDstPktsCounts.begin(); i != IPsDstPktsCounts.end(); i++) {
+            IPsDstProb.push_back((float) *i / pktsReceived);
+        }
+
+        // Calculate IP source entropy
         float IPsSrcEntropy = 0;
-        for(unsigned i=0; i < IPsSrcProb.size();i++){
+        for (unsigned i = 0; i < IPsSrcProb.size(); i++) {
             if (IPsSrcProb[i] > 0)
-                IPsSrcEntropy += - IPsSrcProb[i]*log2(IPsSrcProb[i]);
+                IPsSrcEntropy += -IPsSrcProb[i] * log2(IPsSrcProb[i]);
         }
         // Calculate IP destination entropy
         float IPsDstEntropy = 0;
-        for(unsigned i=0; i < IPsDstProb.size();i++){
+        for (unsigned i = 0; i < IPsDstProb.size(); i++) {
             if (IPsDstProb[i] > 0)
-                IPsDstEntropy += - IPsDstProb[i]*log2(IPsDstProb[i]);
-        }                    
-        
+                IPsDstEntropy += -IPsDstProb[i] * log2(IPsDstProb[i]);
+        }
+
         std::vector<float> entropies = {IPsSrcEntropy, IPsDstEntropy};
         return entropies;
+    }
+    else {
+        return {-1, -1};
+    }
 }
 
 // Aidmar
@@ -63,41 +140,46 @@ std::vector<float> statistics::calculateLastIntervalIPsEntropy(std::chrono::micr
  * Calculates cumulative entropy of source and destination IPs, i.e., the entropy for packets from the beginning of the pcap file. 
  */
 std::vector<float> statistics::calculateIPsCumEntropy(){
-    std::vector <std::string> IPs; 
-    std::vector <float> IPsSrcProb; 
-    std::vector <float> IPsDstProb;
+    if(this->getDoTests()) {
+        std::vector <std::string> IPs;
+        std::vector <float> IPsSrcProb;
+        std::vector <float> IPsDstProb;
 
-    //std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
+        //std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
 
-    for (auto i = ip_statistics.begin(); i != ip_statistics.end(); i++) {
-        IPs.push_back(i->first);
-        IPsSrcProb.push_back((float)i->second.pkts_sent/packetCount);
-        IPsDstProb.push_back((float)i->second.pkts_received/packetCount);
-    }
+        for (auto i = ip_statistics.begin(); i != ip_statistics.end(); i++) {
+            IPs.push_back(i->first);
+            IPsSrcProb.push_back((float)i->second.pkts_sent/packetCount);
+            IPsDstProb.push_back((float)i->second.pkts_received/packetCount);
+        }
+
+        //std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
+        //auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count()*1e-6;
+        //std::cout<< "CumEntCalc -> ip_statistics loop: " << duration << " sec" << std::endl;
 
-    //std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
-    //auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count()*1e-6;
-    //std::cout<< "CumEntCalc -> ip_statistics loop: " << duration << " sec" << std::endl;
 
+        // Calculate IP source entropy
+        float IPsSrcEntropy = 0;
+        for(unsigned i=0; i < IPsSrcProb.size();i++){
+            if (IPsSrcProb[i] > 0)
+                IPsSrcEntropy += - IPsSrcProb[i]*log2(IPsSrcProb[i]);
+        }
+        //std::cout << packetCount << ": SrcEnt: " << IPsSrcEntropy << "\n";
+
+        // Calculate IP destination entropy
+        float IPsDstEntropy = 0;
+        for(unsigned i=0; i < IPsDstProb.size();i++){
+            if (IPsDstProb[i] > 0)
+                IPsDstEntropy += - IPsDstProb[i]*log2(IPsDstProb[i]);
+        }
+        //std::cout << packetCount << ": DstEnt: " << IPsDstEntropy << "\n";
 
-    // Calculate IP source entropy 
-    float IPsSrcEntropy = 0;
-    for(unsigned i=0; i < IPsSrcProb.size();i++){
-        if (IPsSrcProb[i] > 0)
-            IPsSrcEntropy += - IPsSrcProb[i]*log2(IPsSrcProb[i]);
+        std::vector<float> entropies = {IPsSrcEntropy, IPsDstEntropy};
+        return entropies;
     }
-    //std::cout << packetCount << ": SrcEnt: " << IPsSrcEntropy << "\n";
-    
-    // Calculate IP destination entropy
-    float IPsDstEntropy = 0;
-    for(unsigned i=0; i < IPsDstProb.size();i++){
-        if (IPsDstProb[i] > 0)
-            IPsDstEntropy += - IPsDstProb[i]*log2(IPsDstProb[i]);
+    else {
+    return {-1, -1};
     }
-    //std::cout << packetCount << ": DstEnt: " << IPsDstEntropy << "\n";
-    
-    std::vector<float> entropies = {IPsSrcEntropy, IPsDstEntropy};
-    return entropies;
 }
 
 
@@ -133,10 +215,26 @@ void statistics::addIntervalStat(std::chrono::duration<int, std::micro> interval
     std::vector<float> ipEntopies = calculateLastIntervalIPsEntropy(intervalStartTimestamp);
     std::vector<float> ipCumEntopies = calculateIPsCumEntropy();
     std::string lastPktTimestamp_s = std::to_string(intervalEndTimestamp.count());
-    
+
     interval_statistics[lastPktTimestamp_s].pkts_count = packetCount - previousPacketCount;  
     interval_statistics[lastPktTimestamp_s].kbytes = (float(sumPacketSize - previousSumPacketSize) / 1024);
-    
+
+    interval_statistics[lastPktTimestamp_s].payload_count = payloadCount;
+    interval_statistics[lastPktTimestamp_s].incorrect_checksum_count = incorrectTCPChecksumCount;
+    interval_statistics[lastPktTimestamp_s].correct_checksum_count = correctTCPChecksumCount;
+    interval_statistics[lastPktTimestamp_s].invalid_tos_count = invalidToSCount;
+    interval_statistics[lastPktTimestamp_s].valid_tos_count = validToSCount;
+
+    std::cout<<invalidToSCount<<","<<validToSCount<<"\n";
+
+
+    // Reset variables for next interval
+    payloadCount = 0;
+    incorrectTCPChecksumCount = 0;
+    correctTCPChecksumCount = 0;
+    invalidToSCount = 0;
+    validToSCount = 0;
+
     if(ipEntopies.size()>1){
         interval_statistics[lastPktTimestamp_s].ip_src_entropy = ipEntopies[0];
         interval_statistics[lastPktTimestamp_s].ip_dst_entropy = ipEntopies[1];
@@ -577,7 +675,8 @@ void statistics::writeToDatabase(std::string database_path) {
     db.writeStatisticsConv(conv_statistics);
     db.writeStatisticsInterval(interval_statistics);
 
-    
+    // Aidmar - Tests
+
 }
 
 /**
@@ -597,6 +696,15 @@ void statistics::addPacketSize(uint32_t packetSize) {
     sumPacketSize += ((float) packetSize);
 }
 
+// Aidmar
+void statistics::setDoTests(bool var) {
+    doTests = var;
+}
+
+bool statistics::getDoTests() {
+    return doTests;
+}
+
 
 
 

+ 30 - 2
code_boost/src/cxx/statistics.h

@@ -15,6 +15,8 @@
 
 #include "utilities.h"
 
+using namespace Tins;
+
 /*
  * Definition of structs used in unordered_map fields
  */
@@ -189,6 +191,11 @@ struct entry_intervalStat {
     float ip_dst_entropy;
     float ip_src_cum_entropy; 
     float ip_dst_cum_entropy;
+    int payload_count;
+    int incorrect_checksum_count;
+    int correct_checksum_count;
+    int invalid_tos_count;
+    int valid_tos_count;
     // Predictability score
     //float ip_src_pred_score;
     //float ip_dst_pred_score;
@@ -200,7 +207,11 @@ struct entry_intervalStat {
                && ip_src_entropy == other.ip_src_entropy
                && ip_dst_entropy == other.ip_dst_entropy
                && ip_src_cum_entropy == other.ip_src_cum_entropy
-               && ip_dst_cum_entropy == other.ip_dst_cum_entropy;              
+               && ip_dst_cum_entropy == other.ip_dst_cum_entropy
+               && payload_count == other.payload_count
+               && incorrect_checksum_count == other.incorrect_checksum_count
+               && invalid_tos_count == other.invalid_tos_count
+               && valid_tos_count == other.valid_tos_count;
     }
 };
 
@@ -349,6 +360,9 @@ public:
     std::vector<float> calculateIPsCumEntropy();
     std::vector<float> calculateLastIntervalIPsEntropy(std::chrono::microseconds intervalStartTimestamp);        
     void addIntervalStat(std::chrono::duration<int, std::micro> interval, std::chrono::microseconds intervalStartTimestamp, std::chrono::microseconds lastPktTimestamp, int previousPacketCount, float previousSumPacketSize);
+    void checkPayload(const PDU *pdu_l4);
+    void checkTCPChecksum(std::string ipAddressSender, std::string ipAddressReceiver, TCP tcpPkt);
+    void checkToS(uint8_t ToS);
 
     void incrementTTLcount(std::string ipAddress, int ttlValue);
 
@@ -393,6 +407,11 @@ public:
      */
     ip_stats getStatsForIP(std::string ipAddress);
 
+    // Aidmar
+    bool getDoTests();
+    void setDoTests(bool var);
+    // TO-DO: move to private section
+    std::unordered_map<int, int> dscp_distribution;
 
 private:
     /*
@@ -403,6 +422,14 @@ private:
     float sumPacketSize = 0;
     int packetCount = 0;
 
+    // Aidmar
+    bool doTests = false;
+    int payloadCount = 0;
+    int incorrectTCPChecksumCount = 0;
+    int correctTCPChecksumCount = 0;
+    int validToSCount = 0;
+    int invalidToSCount = 0;
+
     /*
      * Data containers
      */
@@ -417,7 +444,8 @@ private:
     // {IP Address A, Port A, IP Address B, Port B,   #packets_A_B, #packets_B_A}
     std::unordered_map<conv, entry_convStat> conv_statistics;
     std::unordered_map<std::string, entry_intervalStat> interval_statistics;
-    
+
+
     // {IP Address, Protocol, count}
     std::unordered_map<ipAddress_protocol, int> protocol_distribution;
 

+ 9 - 3
code_boost/src/cxx/statistics_db.cpp

@@ -390,10 +390,13 @@ void statistics_db::writeStatisticsInterval(std::unordered_map<std::string, entr
                 "ipSrcEntropy REAL,"      
                 "ipDstEntropy REAL,"  
                 "ipSrcCumEntropy REAL,"      
-                "ipDstCumEntropy REAL," 
+                "ipDstCumEntropy REAL,"
+                "payloadCount INTEGER,"
+                "incorrectTCPChecksumCount INTEGER,"
+                "correctTCPChecksumCount INTEGER,"
                 "PRIMARY KEY(lastPktTimestamp));";
         db->exec(createTable);
-        SQLite::Statement query(*db, "INSERT INTO interval_statistics VALUES (?, ?, ?, ?, ?, ?, ?)");
+        SQLite::Statement query(*db, "INSERT INTO interval_statistics VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
         for (auto it = intervalStatistics.begin(); it != intervalStatistics.end(); ++it) {
             std::string t = it->first;
             entry_intervalStat e = it->second;        
@@ -405,7 +408,9 @@ void statistics_db::writeStatisticsInterval(std::unordered_map<std::string, entr
             query.bind(5, e.ip_dst_entropy);
             query.bind(6, e.ip_src_cum_entropy);
             query.bind(7, e.ip_dst_cum_entropy);
-
+            query.bind(8, e.payload_count);
+            query.bind(9, e.incorrect_checksum_count);
+            query.bind(10, e.correct_checksum_count);
             query.exec();
             query.reset();
         }
@@ -415,3 +420,4 @@ void statistics_db::writeStatisticsInterval(std::unordered_map<std::string, entr
         std::cout << "Exception in statistics_db: " << e.what() << std::endl;
     }
 }
+

+ 111 - 10
code_boost/src/cxx/utilities.cpp

@@ -2,6 +2,14 @@
 
 #include "utilities.h"
 
+using namespace Tins;
+
+template<class T>
+std::string integral_to_binary_string(T byte)
+{
+    std::bitset<sizeof(T) * CHAR_BIT> bs(byte);
+    return bs.to_string();
+}
 
 /**
  * Split a string.
@@ -9,16 +17,6 @@
  * @param delimiter delimiter to use in splitting
  * @return vector of substrings
  */
-/*std::vector<std::string> split(std::string str, char delimiter) {
-  std::vector<std::string> internal;
-  std::stringstream ss(str); // Turn the string into a stream.
-  std::string tok;  
-  while(getline(ss, tok, delimiter)) {
-    internal.push_back(tok);
-  }  
-  return internal;
-}*/
-
 void split_str(const std::string& s, char delim,std::vector<std::string>& v) {
     auto i = 0;
     auto pos = s.find(delim);
@@ -105,3 +103,106 @@ int getClosestIndex(std::vector<std::chrono::microseconds> v, std::chrono::micro
 void snifferIteratorIncrement(Tins::SnifferIterator& iterator){
     (((((((((iterator++)++)++)++)++)++)++)++)++)++;  
 }
+
+
+void convertIPv4toArray(std::string IP, unsigned short IP_bytes[]){
+    std::vector<std::string> temp_v;
+    split_str(IP,'.',temp_v);
+    IP_bytes[0] = std::stoi(temp_v[0]);
+    IP_bytes[1] = std::stoi(temp_v[1]);
+    IP_bytes[2] = std::stoi(temp_v[2]);
+    IP_bytes[3] = std::stoi(temp_v[3]);
+}
+
+//Calculate TCP checksum
+u16 tcp_sum_calc(u16 len_tcp, u16 src_addr[],u16 dest_addr[], bool padding, u16 buff[])
+{
+    u16 prot_tcp=6;
+    u16 padd=0;
+    u16 word16;
+    u32 sum;
+
+    // Find out if the length of data is even or odd number. If odd,
+    // add a padding byte = 0 at the end of packet
+    //if ((padding&1)==1){
+    if(padding){
+        padd=1;
+        buff[len_tcp]=0;
+    }
+
+    //initialize sum to zero
+    sum=0;
+
+    // make 16 bit words out of every two adjacent 8 bit words and
+    // calculate the sum of all 16 vit words
+    for (int i=0;i<len_tcp+padd;i=i+2){
+        word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
+        sum = sum + (unsigned long)word16;
+    }
+    // add the TCP pseudo header which contains:
+    // the IP source and destinationn addresses,
+    for (int i=0;i<4;i=i+2){
+        word16 =((src_addr[i]<<8)&0xFF00)+(src_addr[i+1]&0xFF);
+        sum=sum+word16;
+    }
+    for (int i=0;i<4;i=i+2){
+        word16 =((dest_addr[i]<<8)&0xFF00)+(dest_addr[i+1]&0xFF);
+        sum=sum+word16;
+    }
+    // the protocol number and the length of the TCP packet
+    sum = sum + prot_tcp + len_tcp;
+
+    // keep only the last 16 bits of the 32 bit calculated sum and add the carries
+    while (sum>>16)
+        sum = (sum & 0xFFFF)+(sum >> 16);
+
+    // Take the one's complement of sum
+    sum = ~sum;
+
+    return ((unsigned short) sum);
+}
+
+/**
+ * Checks the TCP checksum of a given packet.
+ * @param ipAddressSender The source IP.
+ * @param ipAddressReceiver The destination IP.
+ * @param tcpPkt The packet to get checked.
+ */
+bool check_tcpChecksum(std::string ipAddressSender, std::string ipAddressReceiver, TCP tcpPkt){
+    uint16_t checksum = tcpPkt.checksum();
+
+    unsigned short calculatedChecsum = 0;
+
+    int headerSize = tcpPkt.header_size();
+    std::vector<uint8_t> bufferArray_8;
+
+    try {
+        bufferArray_8 = tcpPkt.serialize();
+    } catch (serialization_error) {
+        std::cout << "Error: Could not serialize TCP packet with sender: " << ipAddressSender << ", receiver: "
+                  << ipAddressReceiver << ", seq: " << tcpPkt.seq() << std::endl;
+        return false;
+    }
+
+    std::vector<unsigned short> bufferArray_16;
+    for(int i=0; (unsigned)i<bufferArray_8.size();i++){
+        bufferArray_16.push_back(bufferArray_8[i]);
+    }
+
+    unsigned short* buff_16 = &bufferArray_16[0];
+    unsigned short ipAddressSender_bytes[4];
+    unsigned short ipAddressReceiver_bytes[4];
+    convertIPv4toArray(ipAddressSender, ipAddressSender_bytes);
+    convertIPv4toArray(ipAddressReceiver, ipAddressReceiver_bytes);
+
+    //tcp_sum_calc(unsigned short len_tcp, unsigned short src_addr[],unsigned short dest_addr[], bool padding, unsigned short buff[])
+    bool padding = false;
+    int dataSize = bufferArray_8.size() - headerSize;  // TO-DO: why don't you use pkt.size()
+    if(dataSize != 0)
+        if(dataSize % 2 != 0)
+            padding = true; // padding if the data size is odd
+
+    calculatedChecsum = tcp_sum_calc(bufferArray_8.size(), ipAddressSender_bytes, ipAddressReceiver_bytes, padding, buff_16);
+
+    return (calculatedChecsum == checksum);
+}

+ 12 - 16
code_boost/src/cxx/utilities.h

@@ -8,27 +8,23 @@
 #include <chrono>
 #include <algorithm>
 #include <tins/tins.h>
+#include <bitset>
+#include <type_traits>
 
-// Aidmar
-/**
- * Split a string.
- * @param str string to be splitted 
- * @param delimiter delimiter to use in splitting
- * @return vector of substrings
- */
-/*std::vector<std::string> split(std::string str, char delimiter) {
-  std::vector<std::string> internal;
-  std::stringstream ss(str); // Turn the string into a stream.
-  std::string tok;  
-  while(getline(ss, tok, delimiter)) {
-    internal.push_back(tok);
-  }  
-  return internal;
-}*/
+typedef unsigned short u16;
+typedef unsigned long u32;
+
+using namespace Tins;
 
 void split_str(const std::string& s, char delim,std::vector<std::string>& v);
 std::string getIPv4Class(std::string ipAddress);
 int getClosestIndex(std::vector<std::chrono::microseconds> v, std::chrono::microseconds refElem);
 void snifferIteratorIncrement(Tins::SnifferIterator& iterator);
+void convertIPv4toArray(std::string IP, unsigned short IP_bytes[]);
+u16 tcp_sum_calc(u16 len_tcp, u16 src_addr[],u16 dest_addr[], bool padding, u16 buff[]);
+bool check_tcpChecksum(std::string ipAddressSender, std::string ipAddressReceiver, TCP tcpPkt);
+
+template<class T>
+std::string integral_to_binary_string(T byte);
 
 #endif //UTILITIES_H