1 #include "output_sqlite.h"
2 #include "util.h"
3
4 #include <stdlib.h>
5
6 static const char sqlite_create_template[] = "\
7 CREATE TABLE IF NOT EXISTS %s(\
8 timestamp UNSIGNED BIG INT, \
9 interface varchar(16), \
10 vlan_tag UNSIGNED INT, \
11 mac_address varchar(17), \
12 ip_address varchar(42), \
13 origin TINYINT\
14 );";
15
16 static const char sqlite_insert_template[] = "INSERT INTO %s VALUES(?, ?, ?, ?, ?, ?);";
17
output_sqlite_init()18 void output_sqlite_init()
19 {
20 #if HAVE_LIBSQLITE3
21 int rc;
22 char create_query[sizeof(sqlite_create_template) + 64];
23 char insert_query[sizeof(sqlite_insert_template) + 64];
24
25 if (!cfg.sqlite_file) {
26 return;
27 }
28
29 snprintf(create_query, sizeof(create_query), sqlite_create_template, cfg.sqlite_table);
30 snprintf(insert_query, sizeof(insert_query), sqlite_insert_template, cfg.sqlite_table);
31
32 rc = sqlite3_open(cfg.sqlite_file, &cfg.sqlite_conn);
33 if (rc) {
34 log_msg(LOG_ERR, "Unable to open sqlite3 database file %s", cfg.sqlite_file);
35 }
36
37 log_msg(LOG_DEBUG, "Using sqlite create query: %s", create_query);
38 rc = sqlite3_exec(cfg.sqlite_conn, create_query, 0, 0, 0);
39 if (rc) {
40 log_msg(LOG_ERR, "Error creating table `addrwatch` in sqlite3 database");
41 }
42
43 log_msg(LOG_DEBUG, "Using sqlite insert query: %s", insert_query);
44 rc = sqlite3_prepare_v2(cfg.sqlite_conn, insert_query,
45 sizeof(insert_query), &cfg.sqlite_stmt, NULL);
46 if (rc) {
47 log_msg(LOG_ERR, "Error preparing sqlite insert statement");
48 }
49
50 sqlite3_busy_timeout(cfg.sqlite_conn, 100);
51 log_msg(LOG_DEBUG, "Saving results to %s sqlite database", cfg.sqlite_file);
52 #endif
53 }
54
output_sqlite_reload()55 void output_sqlite_reload()
56 {
57 output_sqlite_close();
58 output_sqlite_init();
59 }
60
output_sqlite_save(struct pkt * p,char * mac_str,char * ip_str)61 void output_sqlite_save(struct pkt *p, char *mac_str, char *ip_str)
62 {
63 #if HAVE_LIBSQLITE3
64 int rc;
65
66 if (!cfg.sqlite_conn) {
67 return;
68 }
69
70 rc = sqlite3_bind_int64(cfg.sqlite_stmt, 1, p->pcap_header->ts.tv_sec);
71 rc += sqlite3_bind_text(cfg.sqlite_stmt, 2, p->ifc->name, -1, NULL);
72 rc += sqlite3_bind_int(cfg.sqlite_stmt, 3, p->vlan_tag);
73 rc += sqlite3_bind_text(cfg.sqlite_stmt, 4, mac_str, -1, NULL);
74 rc += sqlite3_bind_text(cfg.sqlite_stmt, 5, ip_str, -1, NULL);
75 rc += sqlite3_bind_int(cfg.sqlite_stmt, 6, p->origin);
76 if (rc) {
77 log_msg(LOG_ERR, "Unable to bind values to sql statement");
78 }
79
80 rc = sqlite3_step(cfg.sqlite_stmt);
81 switch (rc) {
82 case SQLITE_DONE:
83 break;
84 case SQLITE_BUSY:
85 log_msg(LOG_WARNING, "Unable to execute sqlite prepared statement, database is locked (%ld, %s, %s, %s)",
86 p->pcap_header->ts.tv_sec, p->ifc->name, mac_str, ip_str);
87 break;
88 default:
89 log_msg(LOG_ERR, "Error executing sqlite prepared statement (%d)", rc);
90 break;
91 }
92
93 rc = sqlite3_reset(cfg.sqlite_stmt);
94 if (rc && rc != SQLITE_BUSY) {
95 log_msg(LOG_ERR, "Error reseting sqlite prepared statement (%d)", rc);
96 }
97 #endif
98 }
99
output_sqlite_close()100 void output_sqlite_close()
101 {
102 #if HAVE_LIBSQLITE3
103 if (cfg.sqlite_conn) {
104 sqlite3_finalize(cfg.sqlite_stmt);
105 sqlite3_close(cfg.sqlite_conn);
106 }
107 #endif
108 }
109