statistics_db.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. "class TEXT, "
  32. "PRIMARY KEY(ipAddress));";
  33. db->exec(createTable);
  34. SQLite::Statement query(*db, "INSERT INTO ip_statistics VALUES (?, ?, ?, ?, ?, ?)");
  35. for (auto it = ipStatistics.begin(); it != ipStatistics.end(); ++it) {
  36. entry_ipStat e = it->second;
  37. query.bind(1, it->first);
  38. query.bind(2, (int) e.pkts_received);
  39. query.bind(3, (int) e.pkts_sent);
  40. query.bind(4, e.kbytes_received);
  41. query.bind(5, e.kbytes_sent);
  42. // Aidmar
  43. query.bind(6, e.ip_class);
  44. query.exec();
  45. query.reset();
  46. }
  47. transaction.commit();
  48. }
  49. catch (std::exception &e) {
  50. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  51. }
  52. }
  53. /**
  54. * Writes the TTL distribution into the database.
  55. * @param ttlDistribution The TTL distribution from class statistics.
  56. */
  57. void statistics_db::writeStatisticsTTL(std::unordered_map<ipAddress_ttl, int> ttlDistribution) {
  58. try {
  59. db->exec("DROP TABLE IF EXISTS ip_ttl");
  60. SQLite::Transaction transaction(*db);
  61. const char *createTable = "CREATE TABLE ip_ttl ("
  62. "ipAddress TEXT,"
  63. "ttlValue INTEGER,"
  64. "ttlCount INTEGER,"
  65. "PRIMARY KEY(ipAddress,ttlValue));";
  66. db->exec(createTable);
  67. SQLite::Statement query(*db, "INSERT INTO ip_ttl VALUES (?, ?, ?)");
  68. for (auto it = ttlDistribution.begin(); it != ttlDistribution.end(); ++it) {
  69. ipAddress_ttl e = it->first;
  70. query.bind(1, e.ipAddress);
  71. query.bind(2, e.ttlValue);
  72. query.bind(3, it->second);
  73. query.exec();
  74. query.reset();
  75. }
  76. transaction.commit();
  77. }
  78. catch (std::exception &e) {
  79. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  80. }
  81. }
  82. /**
  83. * Writes the protocol distribution into the database.
  84. * @param protocolDistribution The protocol distribution from class statistics.
  85. */
  86. void statistics_db::writeStatisticsProtocols(std::unordered_map<ipAddress_protocol, int> protocolDistribution) {
  87. try {
  88. db->exec("DROP TABLE IF EXISTS ip_protocols");
  89. SQLite::Transaction transaction(*db);
  90. const char *createTable = "CREATE TABLE ip_protocols ("
  91. "ipAddress TEXT,"
  92. "protocolName TEXT,"
  93. "protocolCount INTEGER,"
  94. "PRIMARY KEY(ipAddress,protocolName));";
  95. db->exec(createTable);
  96. SQLite::Statement query(*db, "INSERT INTO ip_protocols VALUES (?, ?, ?)");
  97. for (auto it = protocolDistribution.begin(); it != protocolDistribution.end(); ++it) {
  98. ipAddress_protocol e = it->first;
  99. query.bind(1, e.ipAddress);
  100. query.bind(2, e.protocol);
  101. query.bind(3, it->second);
  102. query.exec();
  103. query.reset();
  104. }
  105. transaction.commit();
  106. }
  107. catch (std::exception &e) {
  108. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  109. }
  110. }
  111. /**
  112. * Writes the port statistics into the database.
  113. * @param portsStatistics The ports statistics from class statistics.
  114. */
  115. void statistics_db::writeStatisticsPorts(std::unordered_map<ipAddress_inOut_port, int> portsStatistics) {
  116. try {
  117. db->exec("DROP TABLE IF EXISTS ip_ports");
  118. SQLite::Transaction transaction(*db);
  119. const char *createTable = "CREATE TABLE ip_ports ("
  120. "ipAddress TEXT,"
  121. "portDirection TEXT,"
  122. "portNumber INTEGER,"
  123. "portCount INTEGER,"
  124. "PRIMARY KEY(ipAddress,portDirection,portNumber));";
  125. db->exec(createTable);
  126. SQLite::Statement query(*db, "INSERT INTO ip_ports VALUES (?, ?, ?, ?)");
  127. for (auto it = portsStatistics.begin(); it != portsStatistics.end(); ++it) {
  128. ipAddress_inOut_port e = it->first;
  129. query.bind(1, e.ipAddress);
  130. query.bind(2, e.trafficDirection);
  131. query.bind(3, e.portNumber);
  132. query.bind(4, it->second);
  133. query.exec();
  134. query.reset();
  135. }
  136. transaction.commit();
  137. }
  138. catch (std::exception &e) {
  139. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  140. }
  141. }
  142. /**
  143. * Writes the IP address -> MAC address mapping into the database.
  144. * @param IpMacStatistics The IP address -> MAC address mapping from class statistics.
  145. */
  146. void statistics_db::writeStatisticsIpMac(std::unordered_map<std::string, std::string> IpMacStatistics) {
  147. try {
  148. db->exec("DROP TABLE IF EXISTS ip_mac");
  149. SQLite::Transaction transaction(*db);
  150. const char *createTable = "CREATE TABLE ip_mac ("
  151. "ipAddress TEXT,"
  152. "macAddress TEXT,"
  153. "PRIMARY KEY(ipAddress));";
  154. db->exec(createTable);
  155. SQLite::Statement query(*db, "INSERT INTO ip_mac VALUES (?, ?)");
  156. for (auto it = IpMacStatistics.begin(); it != IpMacStatistics.end(); ++it) {
  157. query.bind(1, it->first);
  158. query.bind(2, it->second);
  159. query.exec();
  160. query.reset();
  161. }
  162. transaction.commit();
  163. }
  164. catch (std::exception &e) {
  165. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  166. }
  167. }
  168. /**
  169. * Writes the MSS statistics into the database.
  170. * @param mssStatistics The MSS statistics from class statistics.
  171. */
  172. void statistics_db::writeStatisticsMss(std::unordered_map<std::string, int> mssStatistics) {
  173. try {
  174. db->exec("DROP TABLE IF EXISTS tcp_mss");
  175. SQLite::Transaction transaction(*db);
  176. const char *createTable = "CREATE TABLE tcp_mss ("
  177. "ipAddress TEXT,"
  178. "mss INTEGER);";
  179. db->exec(createTable);
  180. SQLite::Statement query(*db, "INSERT INTO tcp_mss VALUES (?, ?)");
  181. for (auto it = mssStatistics.begin(); it != mssStatistics.end(); ++it) {
  182. query.bind(1, it->first);
  183. query.bind(2, it->second);
  184. query.exec();
  185. query.reset();
  186. }
  187. transaction.commit();
  188. }
  189. catch (std::exception &e) {
  190. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  191. }
  192. }
  193. /**
  194. * Writes general file statistics into the database.
  195. * @param packetCount The number of packets in the PCAP file.
  196. * @param captureDuration The duration of the capture (format: SS.mmmmmm).
  197. * @param timestampFirstPkt The timestamp of the first packet in the PCAP file.
  198. * @param timestampLastPkt The timestamp of the last packet in the PCAP file.
  199. * @param avgPacketRate The average packet rate (#packets / capture duration).
  200. * @param avgPacketSize The average packet size.
  201. * @param avgPacketsSentPerHost The average packets sent per host.
  202. * @param avgBandwidthIn The average incoming bandwidth.
  203. * @param avgBandwidthOut The average outgoing bandwidth.
  204. */
  205. void statistics_db::writeStatisticsFile(int packetCount, float captureDuration, std::string timestampFirstPkt,
  206. std::string timestampLastPkt, float avgPacketRate, float avgPacketSize,
  207. float avgPacketsSentPerHost, float avgBandwidthIn, float avgBandwidthOut) {
  208. try {
  209. db->exec("DROP TABLE IF EXISTS file_statistics");
  210. SQLite::Transaction transaction(*db);
  211. const char *createTable = "CREATE TABLE file_statistics ("
  212. "packetCount INTEGER,"
  213. "captureDuration TEXT,"
  214. "timestampFirstPacket TEXT,"
  215. "timestampLastPacket TEXT,"
  216. "avgPacketRate REAL,"
  217. "avgPacketSize REAL,"
  218. "avgPacketsSentPerHost REAL,"
  219. "avgBandwidthIn REAL,"
  220. "avgBandwidthOut REAL);";
  221. db->exec(createTable);
  222. SQLite::Statement query(*db, "INSERT INTO file_statistics VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
  223. query.bind(1, packetCount);
  224. query.bind(2, captureDuration);
  225. query.bind(3, timestampFirstPkt);
  226. query.bind(4, timestampLastPkt);
  227. query.bind(5, avgPacketRate);
  228. query.bind(6, avgPacketSize);
  229. query.bind(7, avgPacketsSentPerHost);
  230. query.bind(8, avgBandwidthIn);
  231. query.bind(9, avgBandwidthOut);
  232. query.exec();
  233. transaction.commit();
  234. }
  235. catch (std::exception &e) {
  236. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  237. }
  238. }
  239. // Aidamr
  240. /**
  241. * Writes the MSS distribution into the database.
  242. * @param mssDistribution The MSS distribution from class statistics.
  243. */
  244. void statistics_db::writeStatisticsMss_dist(std::unordered_map<ipAddress_mss, int> mssDistribution) {
  245. try {
  246. db->exec("DROP TABLE IF EXISTS tcp_mss_dist");
  247. SQLite::Transaction transaction(*db);
  248. const char *createTable = "CREATE TABLE tcp_mss_dist ("
  249. "ipAddress TEXT,"
  250. "mssValue INTEGER,"
  251. "mssCount INTEGER,"
  252. "PRIMARY KEY(ipAddress,mssValue));";
  253. db->exec(createTable);
  254. SQLite::Statement query(*db, "INSERT INTO tcp_mss_dist VALUES (?, ?, ?)");
  255. for (auto it = mssDistribution.begin(); it != mssDistribution.end(); ++it) {
  256. ipAddress_mss e = it->first;
  257. query.bind(1, e.ipAddress);
  258. query.bind(2, e.mssValue);
  259. query.bind(3, it->second);
  260. query.exec();
  261. query.reset();
  262. }
  263. transaction.commit();
  264. }
  265. catch (std::exception &e) {
  266. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  267. }
  268. }
  269. // Aidamr
  270. /**
  271. * Writes the window size distribution into the database.
  272. * @param winDistribution The window size distribution from class statistics.
  273. */
  274. void statistics_db::writeStatisticsWin(std::unordered_map<ipAddress_win, int> winDistribution) {
  275. try {
  276. db->exec("DROP TABLE IF EXISTS tcp_syn_win");
  277. SQLite::Transaction transaction(*db);
  278. const char *createTable = "CREATE TABLE tcp_syn_win ("
  279. "ipAddress TEXT,"
  280. "winSize INTEGER,"
  281. "winCount INTEGER,"
  282. "PRIMARY KEY(ipAddress,winSize));";
  283. db->exec(createTable);
  284. SQLite::Statement query(*db, "INSERT INTO tcp_syn_win VALUES (?, ?, ?)");
  285. for (auto it = winDistribution.begin(); it != winDistribution.end(); ++it) {
  286. ipAddress_win e = it->first;
  287. query.bind(1, e.ipAddress);
  288. query.bind(2, e.winSize);
  289. query.bind(3, it->second);
  290. query.exec();
  291. query.reset();
  292. }
  293. transaction.commit();
  294. }
  295. catch (std::exception &e) {
  296. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  297. }
  298. }
  299. // Aidamr
  300. /**
  301. * Writes the flow statistics into the database.
  302. * @param flowStatistics The flow from class statistics.
  303. */
  304. void statistics_db::writeStatisticsFlow(std::unordered_map<flow, entry_flowStat> flowStatistics){
  305. try {
  306. db->exec("DROP TABLE IF EXISTS flow_statistics");
  307. SQLite::Transaction transaction(*db);
  308. const char *createTable = "CREATE TABLE flow_statistics ("
  309. "ipAddressA TEXT,"
  310. "portA INTEGER,"
  311. "ipAddressB TEXT,"
  312. "portB INTEGER,"
  313. "pkts_A_B INTEGER,"
  314. "pkts_B_A INTEGER,"
  315. "medianDelay INTEGER,"
  316. //"medianDelay TEXT,"
  317. "PRIMARY KEY(ipAddressA,portA,ipAddressB,portB));";
  318. db->exec(createTable);
  319. SQLite::Statement query(*db, "INSERT INTO flow_statistics VALUES (?, ?, ?, ?, ?, ?, ?)");
  320. for (auto it = flowStatistics.begin(); it != flowStatistics.end(); ++it) {
  321. flow f = it->first;
  322. entry_flowStat e = it->second;
  323. // Compute the median delay
  324. e.median_delay = e.pkts_delay[e.pkts_delay.size()/2];
  325. query.bind(1, f.ipAddressA);
  326. query.bind(2, f.portA);
  327. query.bind(3, f.ipAddressB);
  328. query.bind(4, f.portB);
  329. query.bind(5, (int) e.pkts_A_B);
  330. query.bind(6, (int) e.pkts_B_A);
  331. query.bind(7, (int) e.median_delay.count());
  332. //query.bind(7, std::to_string(e.median_delay.count()));
  333. query.exec();
  334. query.reset();
  335. }
  336. transaction.commit();
  337. }
  338. catch (std::exception &e) {
  339. std::cout << "Exception in statistics_db: " << e.what() << std::endl;
  340. }
  341. }