Browse Source

Merge branch 'port_services' of stefan.schmidt/ID2T-toolkit into master

Carlos Garcia 6 years ago
parent
commit
c9e9712304

+ 4 - 4
code_boost/src/cxx/pcap_processor.cpp

@@ -277,16 +277,16 @@ void pcap_processor::process_packets(const Packet &pkt) {
             } catch (Tins::option_not_found) {
                 // Ignore MSS if option not set
             }
-            stats.incrementPortCount(ipAddressSender, tcpPkt.sport(), ipAddressReceiver, tcpPkt.dport());
-            stats.increasePortByteCount(ipAddressSender, tcpPkt.sport(), ipAddressReceiver, tcpPkt.dport(), sizeCurrentPacket);
+            stats.incrementPortCount(ipAddressSender, tcpPkt.sport(), ipAddressReceiver, tcpPkt.dport(), "TCP");
+            stats.increasePortByteCount(ipAddressSender, tcpPkt.sport(), ipAddressReceiver, tcpPkt.dport(), sizeCurrentPacket, "TCP");
             
           // UDP Packet
         } else if (p == PDU::PDUType::UDP) {
             const UDP udpPkt = (const UDP &) *pdu_l4;
             stats.incrementProtocolCount(ipAddressSender, "UDP");
             stats.increaseProtocolByteCount(ipAddressSender, "UDP", sizeCurrentPacket);
-            stats.incrementPortCount(ipAddressSender, udpPkt.sport(), ipAddressReceiver, udpPkt.dport());
-            stats.increasePortByteCount(ipAddressSender, udpPkt.sport(), ipAddressReceiver, udpPkt.dport(), sizeCurrentPacket);
+            stats.incrementPortCount(ipAddressSender, udpPkt.sport(), ipAddressReceiver, udpPkt.dport(), "UDP");
+            stats.increasePortByteCount(ipAddressSender, udpPkt.sport(), ipAddressReceiver, udpPkt.dport(), sizeCurrentPacket, "UDP");
           
         } else if (p == PDU::PDUType::ICMP) {
             stats.incrementProtocolCount(ipAddressSender, "ICMP");

+ 6 - 6
code_boost/src/cxx/statistics.cpp

@@ -336,11 +336,11 @@ float statistics::getProtocolByteCount(std::string ipAddress, std::string protoc
  * @param incomingPort The port used by the receiver.
  */
 void statistics::incrementPortCount(std::string ipAddressSender, int outgoingPort, std::string ipAddressReceiver,
-                                    int incomingPort) {
+                                    int incomingPort, std::string protocol) {
     port_values[outgoingPort]++;
     port_values[incomingPort]++;
-    ip_ports[{ipAddressSender, "out", outgoingPort}].count++;
-    ip_ports[{ipAddressReceiver, "in", incomingPort}].count++;
+    ip_ports[{ipAddressSender, "out", outgoingPort, protocol}].count++;
+    ip_ports[{ipAddressReceiver, "in", incomingPort, protocol}].count++;
 }
 
 /**
@@ -354,9 +354,9 @@ void statistics::incrementPortCount(std::string ipAddressSender, int outgoingPor
  * @param byteSent The packet's size.
  */
 void statistics::increasePortByteCount(std::string ipAddressSender, int outgoingPort, std::string ipAddressReceiver,
-                                       int incomingPort, long bytesSent) {
-    ip_ports[{ipAddressSender, "out", outgoingPort}].byteCount += bytesSent;
-    ip_ports[{ipAddressReceiver, "in", incomingPort}].byteCount += bytesSent;
+                                       int incomingPort, long bytesSent, std::string protocol) {
+    ip_ports[{ipAddressSender, "out", outgoingPort, protocol}].byteCount += bytesSent;
+    ip_ports[{ipAddressReceiver, "in", incomingPort, protocol}].byteCount += bytesSent;
 }
 
 /**

+ 5 - 3
code_boost/src/cxx/statistics.h

@@ -275,11 +275,13 @@ struct ipAddress_inOut_port {
     std::string ipAddress;
     std::string trafficDirection;
     int portNumber;
+    std::string protocol;
 
     bool operator==(const ipAddress_inOut_port &other) const {
         return ipAddress == other.ipAddress
                && trafficDirection == other.trafficDirection
-               && portNumber == other.portNumber;
+               && portNumber == other.portNumber
+               && protocol == other.protocol;
     }
 };
 
@@ -414,10 +416,10 @@ public:
     void increaseProtocolByteCount(std::string ipAddress, std::string protocol, long bytesSent);
 
     void incrementPortCount(std::string ipAddressSender, int outgoingPort, std::string ipAddressReceiver,
-                            int incomingPort);
+                            int incomingPort, std::string protocol);
 
     void increasePortByteCount(std::string ipAddressSender, int outgoingPort, std::string ipAddressReceiver,
-                               int incomingPort, long bytesSent);
+                               int incomingPort, long bytesSent, std::string protocol);
 
     int getProtocolCount(std::string ipAddress, std::string protocol);
 

+ 116 - 1
code_boost/src/cxx/statistics_db.cpp

@@ -2,6 +2,9 @@
 #include <math.h>
 #include <iostream>
 #include <sstream>
+#include <fstream>
+#include <unistd.h>
+#include <stdio.h>
 
 /**
  * Creates a new statistics_db object. Opens an existing database located at database_path. If not existing, creates
@@ -15,6 +18,9 @@ statistics_db::statistics_db(std::string database_path) {
     }
     // creates the DB if not existing, opens the DB for read+write access
     db.reset(new SQLite::Database(database_path, SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE));
+
+    // Read ports and services into portServices vector
+    readPortServicesFromNmap();
 }
 
 /**
@@ -223,16 +229,27 @@ void statistics_db::writeStatisticsPorts(std::unordered_map<ipAddress_inOut_port
                 "portNumber INTEGER,"
                 "portCount INTEGER,"
                 "byteCount REAL,"
+                "portProtocol TEXT COLLATE NOCASE,"
+                "portService TEXT COLLATE NOCASE,"
                 "PRIMARY KEY(ipAddress,portDirection,portNumber));";
         db->exec(createTable);
-        SQLite::Statement query(*db, "INSERT INTO ip_ports VALUES (?, ?, ?, ?, ?)");
+        SQLite::Statement query(*db, "INSERT INTO ip_ports VALUES (?, ?, ?, ?, ?, ?, ?)");
         for (auto it = portsStatistics.begin(); it != portsStatistics.end(); ++it) {
             ipAddress_inOut_port e = it->first;
+
+            std::string portService = portServices[e.portNumber];
+            if(portService.empty()) {
+                if(portServices[{0}] == "unavailable") {portService = "unavailable";}
+                else {portService = "unknown";}
+            }
+
             query.bind(1, e.ipAddress);
             query.bind(2, e.trafficDirection);
             query.bind(3, e.portNumber);
             query.bind(4, it->second.count);
             query.bind(5, it->second.byteCount);
+            query.bind(6, e.protocol);
+            query.bind(7, portService);
             query.exec();
             query.reset();
         }
@@ -453,3 +470,101 @@ void statistics_db::writeDbVersion(){
         std::cout << "Exception in statistics_db: " << e.what() << std::endl;
     }
 }
+
+/**
+ * Reads all ports and their corresponding services from nmap-services-tcp.csv and stores them into portServices vector.
+ */
+void statistics_db::readPortServicesFromNmap()
+{
+    std::string portnumber;
+    std::string service;
+    std::string dump;
+    std::string nmapPath = getNmapPath();
+    std::ifstream reader;
+
+    reader.open(nmapPath, std::ios::in);
+
+    if(reader.is_open())
+    {
+        getline(reader, dump);
+
+        while(!reader.eof())
+        {
+            getline(reader, portnumber, ',');
+            getline(reader, service, ',');
+            getline(reader, dump);
+            if(!service.empty() && !portnumber.empty())
+            {
+                portServices.insert({std::stoi(portnumber), service});
+            }
+        }
+
+        reader.close();
+    }
+
+    else
+    {
+        std::cerr << "WARNING: " << nmapPath << " could not be opened! PortServices can't be read!" << std::endl;
+        portServices.insert({0, "unavailable"});
+    }
+}
+
+/**
+ * Gets the path to nmap-services-tcp.csv and makes sure the file is reached from any working directory within "/code"
+ * because the working directory can be different when running tests. Checks if the file/path exists and warns the user.
+ */
+std::string statistics_db::getNmapPath()
+{
+    //The different working directory paths according to how the database is built:
+    //<ID2T> stands for the directory id2t.sh is located in
+    //From tests(e.g. pycharm)  /<ID2T>/code/Test
+    //From run_tests.sh         /<ID2T>/code
+    //From id2t.sh              /<ID2T>
+    std::string filename = "nmap-services-tcp.csv";
+    std::string resourcesDir = "/resources/";
+    std::string codeDir = "/code";
+    std::string testDir = "/code/Test";
+    char buff[FILENAME_MAX];
+    // Working directory
+    std::string dir(getcwd(buff, FILENAME_MAX));
+
+    // Check if working directory is id2t.sh directory(try to reach file from working directory)
+    if(pathExists(dir + resourcesDir + filename))
+    {
+        return dir + resourcesDir + filename;
+    }
+
+    // If working directory is test directory(happens if tests are called from pycharm for example)
+    else if(dir.rfind(testDir) == (dir.size()-testDir.size()))
+    {
+        // Remove test directory from path
+        dir = dir.substr(0, (dir.size()-testDir.size()));
+    }
+
+    // If working directory is code directory(happens if tests are called with testscript)
+    else if(dir.rfind(codeDir) == (dir.size()-codeDir.size()))
+    {
+        // Remove code directory from path
+        dir = dir.substr(0, (dir.size()-codeDir.size()));
+    }
+
+    dir = dir + resourcesDir + filename;
+
+    return dir;
+}
+
+bool statistics_db::pathExists(std::string path)
+{
+    std::ifstream file;
+    file.open(path, std::ios::in);
+    if(file.is_open())
+    {
+        file.close();
+        return true;
+    }
+
+    else
+    {
+        return false;
+    }
+}

+ 11 - 2
code_boost/src/cxx/statistics_db.h

@@ -10,6 +10,8 @@
 #include <string>
 #include "statistics.h"
 #include <SQLiteCpp/SQLiteCpp.h>
+#include <unordered_map>
+
 
 class statistics_db {
 public:
@@ -21,7 +23,7 @@ public:
     /*
      * Database version: Increment number on every change in the C++ code!
      */
-    static const int DB_VERSION = 2;
+    static const int DB_VERSION = 3;
 
     /*
      * Methods for writing values into database
@@ -52,11 +54,18 @@ public:
 
     void writeDbVersion();
 
+    void readPortServicesFromNmap();
+
+    std::string getNmapPath();
+
+    bool pathExists(std::string path);
+
 private:
     // Pointer to the SQLite database
     std::unique_ptr<SQLite::Database> db;
 
-
+    // Vector which contains all ports and their corresponding services
+    std::unordered_map<int, std::string> portServices;
 };