statistics_db.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. }