statistics_db.cpp 13 KB

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