statistics_db.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. #include "statistics_db.h"
  2. #include <iostream>
  3. #include <sstream>
  4. /**
  5. * Creates a new statistics_db object. Opens an existing database located at database_path. If not existing, creates
  6. * a new database at database_path.
  7. * @param database_path The file path of the database.
  8. */
  9. statistics_db::statistics_db(std::string database_path) {
  10. // Append file extension if not present
  11. if (database_path.find(".sqlite3") == database_path.npos) {
  12. database_path += ".sqlite3";
  13. }
  14. // creates the DB if not existing, opens the DB for read+write access
  15. db.reset(new SQLite::Database(database_path, SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE));
  16. }
  17. /**
  18. * Writes the IP statistics into the database.
  19. * @param ipStatistics The IP statistics from class statistics.
  20. */
  21. void statistics_db::writeStatisticsIP(std::unordered_map<std::string, entry_ipStat> ipStatistics) {
  22. try {
  23. db->exec("DROP TABLE IF EXISTS ip_statistics");
  24. SQLite::Transaction transaction(*db);
  25. const char *createTable = "CREATE TABLE ip_statistics ( "
  26. "ipAddress TEXT, "
  27. "pktsReceived INTEGER, "
  28. "pktsSent INTEGER, "
  29. "kbytesReceived REAL, "
  30. "kbytesSent REAL, "
  31. "maxPktRate REAL,"
  32. "minPktRate REAL,"
  33. "class TEXT, "
  34. "PRIMARY KEY(ipAddress));";
  35. db->exec(createTable);
  36. SQLite::Statement query(*db, "INSERT INTO ip_statistics VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
  37. for (auto it = ipStatistics.begin(); it != ipStatistics.end(); ++it) {
  38. entry_ipStat e = it->second;
  39. query.bind(1, it->first);
  40. query.bind(2, (int) e.pkts_received);
  41. query.bind(3, (int) e.pkts_sent);
  42. query.bind(4, e.kbytes_received);
  43. query.bind(5, e.kbytes_sent);
  44. // Aidmar
  45. query.bind(6, e.max_pkt_rate);
  46. query.bind(7, e.min_pkt_rate);
  47. query.bind(8, e.ip_class);
  48. query.exec();
  49. query.reset();
  50. }
  51. transaction.commit();
  52. }
  53. catch (std::exception &e) {
  54. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  55. }
  56. }
  57. /**
  58. * Writes the TTL distribution into the database.
  59. * @param ttlDistribution The TTL distribution from class statistics.
  60. */
  61. void statistics_db::writeStatisticsTTL(std::unordered_map<ipAddress_ttl, int> ttlDistribution) {
  62. try {
  63. db->exec("DROP TABLE IF EXISTS ip_ttl");
  64. SQLite::Transaction transaction(*db);
  65. const char *createTable = "CREATE TABLE ip_ttl ("
  66. "ipAddress TEXT,"
  67. "ttlValue INTEGER,"
  68. "ttlCount INTEGER,"
  69. "PRIMARY KEY(ipAddress,ttlValue));";
  70. db->exec(createTable);
  71. SQLite::Statement query(*db, "INSERT INTO ip_ttl VALUES (?, ?, ?)");
  72. for (auto it = ttlDistribution.begin(); it != ttlDistribution.end(); ++it) {
  73. ipAddress_ttl e = it->first;
  74. query.bind(1, e.ipAddress);
  75. query.bind(2, e.ttlValue);
  76. query.bind(3, it->second);
  77. query.exec();
  78. query.reset();
  79. }
  80. transaction.commit();
  81. }
  82. catch (std::exception &e) {
  83. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  84. }
  85. }
  86. /**
  87. * Writes the protocol distribution into the database.
  88. * @param protocolDistribution The protocol distribution from class statistics.
  89. */
  90. void statistics_db::writeStatisticsProtocols(std::unordered_map<ipAddress_protocol, int> protocolDistribution) {
  91. try {
  92. db->exec("DROP TABLE IF EXISTS ip_protocols");
  93. SQLite::Transaction transaction(*db);
  94. const char *createTable = "CREATE TABLE ip_protocols ("
  95. "ipAddress TEXT,"
  96. "protocolName TEXT,"
  97. "protocolCount INTEGER,"
  98. "PRIMARY KEY(ipAddress,protocolName));";
  99. db->exec(createTable);
  100. SQLite::Statement query(*db, "INSERT INTO ip_protocols VALUES (?, ?, ?)");
  101. for (auto it = protocolDistribution.begin(); it != protocolDistribution.end(); ++it) {
  102. ipAddress_protocol e = it->first;
  103. query.bind(1, e.ipAddress);
  104. query.bind(2, e.protocol);
  105. query.bind(3, it->second);
  106. query.exec();
  107. query.reset();
  108. }
  109. transaction.commit();
  110. }
  111. catch (std::exception &e) {
  112. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  113. }
  114. }
  115. /**
  116. * Writes the port statistics into the database.
  117. * @param portsStatistics The ports statistics from class statistics.
  118. */
  119. void statistics_db::writeStatisticsPorts(std::unordered_map<ipAddress_inOut_port, int> portsStatistics) {
  120. try {
  121. db->exec("DROP TABLE IF EXISTS ip_ports");
  122. SQLite::Transaction transaction(*db);
  123. const char *createTable = "CREATE TABLE ip_ports ("
  124. "ipAddress TEXT,"
  125. "portDirection TEXT,"
  126. "portNumber INTEGER,"
  127. "portCount INTEGER,"
  128. "PRIMARY KEY(ipAddress,portDirection,portNumber));";
  129. db->exec(createTable);
  130. SQLite::Statement query(*db, "INSERT INTO ip_ports VALUES (?, ?, ?, ?)");
  131. for (auto it = portsStatistics.begin(); it != portsStatistics.end(); ++it) {
  132. ipAddress_inOut_port e = it->first;
  133. query.bind(1, e.ipAddress);
  134. query.bind(2, e.trafficDirection);
  135. query.bind(3, e.portNumber);
  136. query.bind(4, it->second);
  137. query.exec();
  138. query.reset();
  139. }
  140. transaction.commit();
  141. }
  142. catch (std::exception &e) {
  143. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  144. }
  145. }
  146. /**
  147. * Writes the IP address -> MAC address mapping into the database.
  148. * @param IpMacStatistics The IP address -> MAC address mapping from class statistics.
  149. */
  150. void statistics_db::writeStatisticsIpMac(std::unordered_map<std::string, std::string> IpMacStatistics) {
  151. try {
  152. db->exec("DROP TABLE IF EXISTS ip_mac");
  153. SQLite::Transaction transaction(*db);
  154. const char *createTable = "CREATE TABLE ip_mac ("
  155. "ipAddress TEXT,"
  156. "macAddress TEXT,"
  157. "PRIMARY KEY(ipAddress));";
  158. db->exec(createTable);
  159. SQLite::Statement query(*db, "INSERT INTO ip_mac VALUES (?, ?)");
  160. for (auto it = IpMacStatistics.begin(); it != IpMacStatistics.end(); ++it) {
  161. query.bind(1, it->first);
  162. query.bind(2, it->second);
  163. query.exec();
  164. query.reset();
  165. }
  166. transaction.commit();
  167. }
  168. catch (std::exception &e) {
  169. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  170. }
  171. }
  172. /**
  173. * Writes the MSS statistics into the database.
  174. * @param mssStatistics The MSS statistics from class statistics.
  175. */
  176. void statistics_db::writeStatisticsMss(std::unordered_map<std::string, int> mssStatistics) {
  177. try {
  178. db->exec("DROP TABLE IF EXISTS tcp_mss");
  179. SQLite::Transaction transaction(*db);
  180. const char *createTable = "CREATE TABLE tcp_mss ("
  181. "ipAddress TEXT,"
  182. "mss INTEGER);";
  183. db->exec(createTable);
  184. SQLite::Statement query(*db, "INSERT INTO tcp_mss VALUES (?, ?)");
  185. for (auto it = mssStatistics.begin(); it != mssStatistics.end(); ++it) {
  186. query.bind(1, it->first);
  187. query.bind(2, it->second);
  188. query.exec();
  189. query.reset();
  190. }
  191. transaction.commit();
  192. }
  193. catch (std::exception &e) {
  194. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  195. }
  196. }
  197. /**
  198. * Writes general file statistics into the database.
  199. * @param packetCount The number of packets in the PCAP file.
  200. * @param captureDuration The duration of the capture (format: SS.mmmmmm).
  201. * @param timestampFirstPkt The timestamp of the first packet in the PCAP file.
  202. * @param timestampLastPkt The timestamp of the last packet in the PCAP file.
  203. * @param avgPacketRate The average packet rate (#packets / capture duration).
  204. * @param avgPacketSize The average packet size.
  205. * @param avgPacketsSentPerHost The average packets sent per host.
  206. * @param avgBandwidthIn The average incoming bandwidth.
  207. * @param avgBandwidthOut The average outgoing bandwidth.
  208. */
  209. void statistics_db::writeStatisticsFile(int packetCount, float captureDuration, std::string timestampFirstPkt,
  210. std::string timestampLastPkt, float avgPacketRate, float avgPacketSize,
  211. float avgPacketsSentPerHost, float avgBandwidthIn, float avgBandwidthOut) {
  212. try {
  213. db->exec("DROP TABLE IF EXISTS file_statistics");
  214. SQLite::Transaction transaction(*db);
  215. const char *createTable = "CREATE TABLE file_statistics ("
  216. "packetCount INTEGER,"
  217. "captureDuration TEXT,"
  218. "timestampFirstPacket TEXT,"
  219. "timestampLastPacket TEXT,"
  220. "avgPacketRate REAL,"
  221. "avgPacketSize REAL,"
  222. "avgPacketsSentPerHost REAL,"
  223. "avgBandwidthIn REAL,"
  224. "avgBandwidthOut REAL);";
  225. db->exec(createTable);
  226. SQLite::Statement query(*db, "INSERT INTO file_statistics VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
  227. query.bind(1, packetCount);
  228. query.bind(2, captureDuration);
  229. query.bind(3, timestampFirstPkt);
  230. query.bind(4, timestampLastPkt);
  231. query.bind(5, avgPacketRate);
  232. query.bind(6, avgPacketSize);
  233. query.bind(7, avgPacketsSentPerHost);
  234. query.bind(8, avgBandwidthIn);
  235. query.bind(9, avgBandwidthOut);
  236. query.exec();
  237. transaction.commit();
  238. }
  239. catch (std::exception &e) {
  240. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  241. }
  242. }
  243. // Aidamr
  244. /**
  245. * Writes the MSS distribution into the database.
  246. * @param mssDistribution The MSS distribution from class statistics.
  247. */
  248. void statistics_db::writeStatisticsMss_dist(std::unordered_map<ipAddress_mss, int> mssDistribution) {
  249. try {
  250. db->exec("DROP TABLE IF EXISTS tcp_mss_dist");
  251. SQLite::Transaction transaction(*db);
  252. const char *createTable = "CREATE TABLE tcp_mss_dist ("
  253. "ipAddress TEXT,"
  254. "mssValue INTEGER,"
  255. "mssCount INTEGER,"
  256. "PRIMARY KEY(ipAddress,mssValue));";
  257. db->exec(createTable);
  258. SQLite::Statement query(*db, "INSERT INTO tcp_mss_dist VALUES (?, ?, ?)");
  259. for (auto it = mssDistribution.begin(); it != mssDistribution.end(); ++it) {
  260. ipAddress_mss e = it->first;
  261. query.bind(1, e.ipAddress);
  262. query.bind(2, e.mssValue);
  263. query.bind(3, it->second);
  264. query.exec();
  265. query.reset();
  266. }
  267. transaction.commit();
  268. }
  269. catch (std::exception &e) {
  270. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  271. }
  272. }
  273. // Aidamr
  274. /**
  275. * Writes the window size distribution into the database.
  276. * @param winDistribution The window size distribution from class statistics.
  277. */
  278. void statistics_db::writeStatisticsWin(std::unordered_map<ipAddress_win, int> winDistribution) {
  279. try {
  280. db->exec("DROP TABLE IF EXISTS tcp_syn_win");
  281. SQLite::Transaction transaction(*db);
  282. const char *createTable = "CREATE TABLE tcp_syn_win ("
  283. "ipAddress TEXT,"
  284. "winSize INTEGER,"
  285. "winCount INTEGER,"
  286. "PRIMARY KEY(ipAddress,winSize));";
  287. db->exec(createTable);
  288. SQLite::Statement query(*db, "INSERT INTO tcp_syn_win VALUES (?, ?, ?)");
  289. for (auto it = winDistribution.begin(); it != winDistribution.end(); ++it) {
  290. ipAddress_win e = it->first;
  291. query.bind(1, e.ipAddress);
  292. query.bind(2, e.winSize);
  293. query.bind(3, it->second);
  294. query.exec();
  295. query.reset();
  296. }
  297. transaction.commit();
  298. }
  299. catch (std::exception &e) {
  300. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  301. }
  302. }
  303. // Aidamr
  304. /**
  305. * Writes the conversation statistics into the database.
  306. * @param convStatistics The conversation from class statistics.
  307. */
  308. void statistics_db::writeStatisticsConv(std::unordered_map<conv, entry_convStat> convStatistics){
  309. try {
  310. db->exec("DROP TABLE IF EXISTS conv_statistics");
  311. SQLite::Transaction transaction(*db);
  312. const char *createTable = "CREATE TABLE conv_statistics ("
  313. "ipAddressA TEXT,"
  314. "portA INTEGER,"
  315. "ipAddressB TEXT,"
  316. "portB INTEGER,"
  317. "pkts_A_B INTEGER,"
  318. "pkts_B_A INTEGER,"
  319. "avgDelay INTEGER,"
  320. //"medianDelay TEXT,"
  321. "PRIMARY KEY(ipAddressA,portA,ipAddressB,portB));";
  322. db->exec(createTable);
  323. SQLite::Statement query(*db, "INSERT INTO conv_statistics VALUES (?, ?, ?, ?, ?, ?, ?)");
  324. for (auto it = convStatistics.begin(); it != convStatistics.end(); ++it) {
  325. conv f = it->first;
  326. entry_convStat e = it->second;
  327. // Compute the median delay
  328. //e.median_delay = e.pkts_delay[e.pkts_delay.size()/2];
  329. int sumDelay = 0;
  330. for(int i=0; (unsigned)i<e.pkts_delay.size();i++){
  331. sumDelay += e.pkts_delay[i].count();
  332. }
  333. e.avg_delay = (std::chrono::microseconds)sumDelay/e.pkts_delay.size(); // average
  334. query.bind(1, f.ipAddressA);
  335. query.bind(2, f.portA);
  336. query.bind(3, f.ipAddressB);
  337. query.bind(4, f.portB);
  338. query.bind(5, (int) e.pkts_A_B);
  339. query.bind(6, (int) e.pkts_B_A);
  340. query.bind(7, (int) e.avg_delay.count());
  341. //query.bind(7, std::to_string(e.median_delay.count()));
  342. query.exec();
  343. query.reset();
  344. }
  345. transaction.commit();
  346. }
  347. catch (std::exception &e) {
  348. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  349. }
  350. }
  351. // Aidamr
  352. /**
  353. * Writes the interval statistics into the database.
  354. * @param intervalStatistics The interval entries from class statistics.
  355. */
  356. void statistics_db::writeStatisticsInterval(std::unordered_map<std::string, entry_intervalStat> intervalStatistics){
  357. try {
  358. db->exec("DROP TABLE IF EXISTS interval_statistics");
  359. SQLite::Transaction transaction(*db);
  360. const char *createTable = "CREATE TABLE interval_statistics ("
  361. "timestamp TEXT,"
  362. "pktsCount INTEGER,"
  363. "ipSrcEntropy REAL,"
  364. "ipDstEntropy REAL,"
  365. "ipSrcCumEntropy REAL,"
  366. "ipDstCumEntropy REAL,"
  367. "PRIMARY KEY(timestamp));";
  368. db->exec(createTable);
  369. SQLite::Statement query(*db, "INSERT INTO interval_statistics VALUES (?, ?, ?, ?, ?, ?)");
  370. for (auto it = intervalStatistics.begin(); it != intervalStatistics.end(); ++it) {
  371. std::string t = it->first;
  372. entry_intervalStat e = it->second;
  373. query.bind(1, t);
  374. query.bind(2, (int)e.pkts_count);
  375. query.bind(3, e.ip_src_entropy);
  376. query.bind(4, e.ip_dst_entropy);
  377. query.bind(5, e.ip_src_cum_entropy);
  378. query.bind(6, e.ip_dst_cum_entropy);
  379. query.exec();
  380. query.reset();
  381. }
  382. transaction.commit();
  383. }
  384. catch (std::exception &e) {
  385. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  386. }
  387. }