statistics.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. * Class providing containers and access methods for statistical data collection.
  3. */
  4. #ifndef CPP_PCAPREADER_STATISTICS_H
  5. #define CPP_PCAPREADER_STATISTICS_H
  6. #include <unordered_map>
  7. #include <list>
  8. #include <tuple>
  9. #include <tins/timestamp.h>
  10. #include <tins/ip_address.h>
  11. /*
  12. * Definition of structs used in unordered_map fields
  13. */
  14. /*
  15. * Struct used as data structure for method get_stats_for_ip, represents:
  16. * - Incoming bandwidth in KBits
  17. * - Outgoing bandwidth in KBits
  18. * - Number of incoming packets per second
  19. * - Number of outgoing packets per second
  20. * - Average size of sent packets in kbytes
  21. * - Average size of received packets in kybtes
  22. * - Average value of TCP option Maximum Segment Size (MSS)
  23. */
  24. struct ip_stats {
  25. float bandwidthKBitsIn;
  26. float bandwidthKBitsOut;
  27. float packetPerSecondIn;
  28. float packetPerSecondOut;
  29. float AvgPacketSizeSent;
  30. float AvgPacketSizeRecv;
  31. long AvgMaxSegmentSizeTCP;
  32. };
  33. // Aidmar
  34. /*
  35. * Struct used to represent a flow by:
  36. * - IP address A
  37. * - Port A
  38. * - IP address B
  39. * - Port B
  40. */
  41. struct flow{
  42. std::string ipAddressA;
  43. int portA;
  44. std::string ipAddressB;
  45. int portB;
  46. bool operator==(const flow &other) const {
  47. return ipAddressA == other.ipAddressA
  48. && portA == other.portA
  49. &&ipAddressB == other.ipAddressB
  50. && portB == other.portB;
  51. }
  52. };
  53. // Aidmar
  54. /*
  55. * Struct used to represent:
  56. * - IP address (IPv4 or IPv6)
  57. * - MSS value
  58. */
  59. struct ipAddress_mss {
  60. std::string ipAddress;
  61. int mssValue;
  62. bool operator==(const ipAddress_mss &other) const {
  63. return ipAddress == other.ipAddress
  64. && mssValue == other.mssValue;
  65. }
  66. };
  67. // Aidmar
  68. /*
  69. * Struct used to represent:
  70. * - IP address (IPv4 or IPv6)
  71. * - Window size
  72. */
  73. struct ipAddress_win {
  74. std::string ipAddress;
  75. int winSize;
  76. bool operator==(const ipAddress_win &other) const {
  77. return ipAddress == other.ipAddress
  78. && winSize == other.winSize;
  79. }
  80. };
  81. /*
  82. * Struct used to represent:
  83. * - IP address (IPv4 or IPv6)
  84. * - TTL value
  85. */
  86. struct ipAddress_ttl {
  87. std::string ipAddress;
  88. int ttlValue;
  89. bool operator==(const ipAddress_ttl &other) const {
  90. return ipAddress == other.ipAddress
  91. && ttlValue == other.ttlValue;
  92. }
  93. };
  94. /*
  95. * Struct used to represent:
  96. * - IP address (IPv4 or IPv6)
  97. * - Protocol (e.g. TCP, UDP, IPv4, IPv6)
  98. */
  99. struct ipAddress_protocol {
  100. std::string ipAddress;
  101. std::string protocol;
  102. bool operator==(const ipAddress_protocol &other) const {
  103. return ipAddress == other.ipAddress
  104. && protocol == other.protocol;
  105. }
  106. };
  107. /*
  108. * Struct used to represent:
  109. * - Number of received packets
  110. * - Number of sent packets
  111. * - Data received in kbytes
  112. * - Data sent in kbytes
  113. */
  114. struct entry_ipStat {
  115. long pkts_received;
  116. long pkts_sent;
  117. float kbytes_received;
  118. float kbytes_sent;
  119. // Aidmar - to calculate tn/r score
  120. long firstAppearAsSenderPktCount;
  121. long firstAppearAsReceiverPktCount;
  122. long sourceAnomalyScore;
  123. long destinationAnomalyScore;
  124. bool operator==(const entry_ipStat &other) const {
  125. return pkts_received == other.pkts_received
  126. && pkts_sent == other.pkts_sent
  127. && kbytes_sent == other.kbytes_sent
  128. && kbytes_received == other.kbytes_received
  129. // Aidmar
  130. && firstAppearAsSenderPktCount == other.firstAppearAsSenderPktCount
  131. && firstAppearAsReceiverPktCount == other.firstAppearAsReceiverPktCount
  132. && sourceAnomalyScore == other.sourceAnomalyScore
  133. && destinationAnomalyScore == other.destinationAnomalyScore;
  134. }
  135. };
  136. // Aidmar
  137. /*
  138. * Struct used to represent:
  139. * - Number of packets from A to B
  140. * - Number of packets from B to A
  141. */
  142. struct entry_flowStat {
  143. long pkts_A_B;
  144. long pkts_B_A;
  145. bool operator==(const entry_flowStat &other) const {
  146. return pkts_A_B == other.pkts_A_B
  147. && pkts_B_A == other.pkts_B_A;
  148. }
  149. };
  150. /*
  151. * Struct used to represent:
  152. * - IP address (IPv4 or IPv6)
  153. - Traffic direction (out: outgoing connection, in: incoming connection)
  154. * - Port number
  155. */
  156. struct ipAddress_inOut_port {
  157. std::string ipAddress;
  158. std::string trafficDirection;
  159. int portNumber;
  160. bool operator==(const ipAddress_inOut_port &other) const {
  161. return ipAddress == other.ipAddress
  162. && trafficDirection == other.trafficDirection
  163. && portNumber == other.portNumber;
  164. }
  165. };
  166. /*
  167. * Definition of hash functions for structs used as key in unordered_map
  168. */
  169. namespace std {
  170. template<>
  171. struct hash<ipAddress_ttl> {
  172. std::size_t operator()(const ipAddress_ttl &k) const {
  173. using std::size_t;
  174. using std::hash;
  175. using std::string;
  176. return ((hash<string>()(k.ipAddress)
  177. ^ (hash<int>()(k.ttlValue) << 1)) >> 1);
  178. }
  179. };
  180. // Aidmar
  181. template<>
  182. struct hash<ipAddress_mss> {
  183. std::size_t operator()(const ipAddress_mss &k) const {
  184. using std::size_t;
  185. using std::hash;
  186. using std::string;
  187. return ((hash<string>()(k.ipAddress)
  188. ^ (hash<int>()(k.mssValue) << 1)) >> 1);
  189. }
  190. };
  191. // Aidmar
  192. template<>
  193. struct hash<ipAddress_win> {
  194. std::size_t operator()(const ipAddress_win &k) const {
  195. using std::size_t;
  196. using std::hash;
  197. using std::string;
  198. return ((hash<string>()(k.ipAddress)
  199. ^ (hash<int>()(k.winSize) << 1)) >> 1);
  200. }
  201. };
  202. // Aidmar: TO-DO:??
  203. template<>
  204. struct hash<flow> {
  205. std::size_t operator()(const flow &k) const {
  206. using std::size_t;
  207. using std::hash;
  208. using std::string;
  209. return ((hash<string>()(k.ipAddressA)
  210. ^ (hash<int>()(k.portA) << 1)) >> 1)
  211. ^ ((hash<string>()(k.ipAddressB)
  212. ^ (hash<int>()(k.portB) << 1)) >> 1);
  213. }
  214. };
  215. template<>
  216. struct hash<ipAddress_protocol> {
  217. std::size_t operator()(const ipAddress_protocol &k) const {
  218. using std::size_t;
  219. using std::hash;
  220. using std::string;
  221. return ((hash<string>()(k.ipAddress)
  222. ^ (hash<string>()(k.protocol) << 1)) >> 1);
  223. }
  224. };
  225. template<>
  226. struct hash<ipAddress_inOut_port> {
  227. std::size_t operator()(const ipAddress_inOut_port &k) const {
  228. using std::size_t;
  229. using std::hash;
  230. using std::string;
  231. return ((hash<string>()(k.ipAddress)
  232. ^ (hash<string>()(k.trafficDirection) << 1)) >> 1)
  233. ^ (hash<int>()(k.portNumber) << 1);
  234. }
  235. };
  236. }
  237. class statistics {
  238. public:
  239. /*
  240. * Constructor
  241. */
  242. statistics();
  243. /*
  244. * Methods
  245. */
  246. std::string getFormattedTimestamp(time_t seconds, suseconds_t microseconds) const;
  247. /*
  248. * Access methods for containers
  249. */
  250. void incrementPacketCount();
  251. // Adimar
  252. void incrementMSScount(std::string ipAddress, int mssValue);
  253. void incrementWinCount(std::string ipAddress, int winSize);
  254. void addIPEntropy();
  255. void addFlowStat(std::string ipAddressSender,int sport,std::string ipAddressReceiver,int dport);
  256. void incrementTTLcount(std::string ipAddress, int ttlValue);
  257. void incrementProtocolCount(std::string ipAddress, std::string protocol);
  258. void incrementPortCount(std::string ipAddressSender, int outgoingPort, std::string ipAddressReceiver,
  259. int incomingPort);
  260. int getProtocolCount(std::string ipAddress, std::string protocol);
  261. void setTimestampFirstPacket(Tins::Timestamp ts);
  262. void setTimestampLastPacket(Tins::Timestamp ts);
  263. void assignMacAddress(std::string ipAddress, std::string macAddress);
  264. void addIpStat_packetSent(std::string ipAddressSender, std::string ipAddressReceiver, long bytesSent);
  265. void addMSS(std::string ipAddress, int MSSvalue);
  266. void writeToDatabase(std::string database_path);
  267. void addPacketSize(uint32_t packetSize);
  268. std::string getCaptureDurationTimestamp() const;
  269. float getCaptureDurationSeconds() const;
  270. float getAvgPacketSize() const;
  271. void printStats(std::string ipAddress);
  272. /*
  273. * IP Address-specific statistics
  274. */
  275. ip_stats getStatsForIP(std::string ipAddress);
  276. private:
  277. /*
  278. * Data fields
  279. */
  280. Tins::Timestamp timestamp_firstPacket;
  281. Tins::Timestamp timestamp_lastPacket;
  282. float sumPacketSize = 0;
  283. int packetCount = 0;
  284. /*
  285. * Data containers
  286. */
  287. // {IP Address, TTL value, count}
  288. std::unordered_map<ipAddress_ttl, int> ttl_distribution;
  289. // Aidmar
  290. // {IP Address, MSS value, count}
  291. std::unordered_map<ipAddress_mss, int> mss_distribution;
  292. // {IP Address, Win size, count}
  293. std::unordered_map<ipAddress_win, int> win_distribution;
  294. // {IP Address A, Port A, IP Address B, Port B, #packets_A_B, #packets_B_A}
  295. std::unordered_map<flow, entry_flowStat> flow_statistics;
  296. // {IP Address, Protocol, count}
  297. std::unordered_map<ipAddress_protocol, int> protocol_distribution;
  298. // {IP Address, #received packets, #sent packets, Data received in kbytes, Data sent in kbytes}
  299. std::unordered_map<std::string, entry_ipStat> ip_statistics;
  300. // {IP Address, in_out, Port Number, count}
  301. std::unordered_map<ipAddress_inOut_port, int> ip_ports;
  302. // {IP Address, MAC Address}
  303. std::unordered_map<std::string, std::string> ip_mac_mapping;
  304. // {IP Address, avg MSS}
  305. std::unordered_map<std::string, int> ip_sumMss;
  306. };
  307. #endif //CPP_PCAPREADER_STATISTICS_H