1 #include <config.h>
2
3 #include <unistd.h>
4
5 #include <scan_progs/scanopts.h>
6 #include <scan_progs/scan_export.h>
7 #include <sqlinterface.h>
8 #include <settings.h>
9 #include <unilib/qfifo.h>
10 #include <unilib/output.h>
11
12 static int db_disable=0;
13 static uint64_t scanid;
14
15 static void database_walk_func(const void *);
16
m_database_init(void)17 void m_database_init(void) {
18 int results=0;
19 char query[2048];
20 seo_t scanopts;
21
22 if (s->verbose > 3) MSG(M_DBG1, "Database module is enabled");
23
24 if (initdb() < 0) {
25 db_disable=1;
26 return;
27 }
28
29 CLEAR(query);
30 if (get_scanopts(&scanopts) < 0) {
31 MSG(M_ERR, "Serious problems getting scan options for insertion into database");
32 _exit(1);
33 }
34 snprintf(query, sizeof(query) -1, "insert into scan(s_time, e_time, srcaddr, portstr, addrmin, addrmax, scanmode, pps, "
35 "active_plgroups, pcapfilter, dronestr, fingerprint, iptos, ipttl, ipoffset, tcpflags, srcport, repeats)"
36 " values(%lld, %lld, %llu, '%s', %llu, %llu, %u, %u, %u, '%s', '%s', %u, %u, %u, %u, %u, %d, %u); "
37 "select currval('scan_id_seq') as myid;",
38 (long long int)s->s_time, (long long int)0, (uint64_t )ntohl(s->vi->myaddr.sin_addr.s_addr), s->port_str,
39 (uint64_t )s->_low_ip, (uint64_t )s->_high_ip, (uint8_t)s->mode, s->pps, s->payload_flags,
40 (s->extra_pcapfilter != NULL ? s->extra_pcapfilter : "None"), s->drone_str,
41 scanopts.fingerprint, scanopts.tos, scanopts.ttl, scanopts.ip_off, scanopts.tcphdrflgs, scanopts.src_port, s->repeats);
42
43 aquerydb(query);
44 results=dbnumrows();
45 if (results == 1) {
46 char *res_ptr=NULL;
47
48 res_ptr=dbgetvalue(0, 0);
49 if (sscanf(res_ptr, "%llu", &scanid) != 1) {
50 MSG(M_ERR, "Malformed scanid from database");
51 _exit(1);
52 }
53 }
54 else {
55 MSG(M_ERR, "Database is acting very weird, exiting");
56 _exit(1);
57 }
58 aquerydb("begin;");
59
60 return;
61 }
62
63 static char db_banner[256];
64 static char db_os[256];
65
m_database_output(const void * r)66 int m_database_output(const void *r) {
67 union {
68 const ip_report_t *ir;
69 const arp_report_t *ar;
70 const void *ptr;
71 const uint16_t *r_magic;
72 } r_u;
73 char query[2048];
74 uint64_t sb_id=0;
75 int results=0;
76
77 if (db_disable) return 1;
78
79 CLEAR(db_banner);
80 CLEAR(db_os);
81 CLEAR(query);
82
83 r_u.ptr=r;
84 if (*r_u.r_magic != IP_REPORT_MAGIC) {
85 return 0;
86 }
87
88 fifo_walk(r_u.ir->od_q, &database_walk_func);
89
90 snprintf(query, sizeof(query) -1, "insert into scan_bucket(scan_id, protocol, type, subtype, dport, sport, ttl, host_addr, trace_addr, u_tstamp, u_utstamp) "
91 "values(%lld, %u, %u, %u, %u, %u, %u, %u, %u, %lld, %llu); select currval('scan_bucket_id_seq') as myid;",
92 scanid, r_u.ir->proto, r_u.ir->type, r_u.ir->subtype, r_u.ir->dport, r_u.ir->sport, r_u.ir->ttl,
93 htonl(r_u.ir->host_addr), htonl(r_u.ir->trace_addr), (long long unsigned int )r_u.ir->recv_time.tv_sec,
94 (long long unsigned int)r_u.ir->recv_time.tv_usec);
95
96 aquerydb(query);
97 results=dbnumrows();
98 if (results == 1) {
99 char *res_ptr=NULL;
100
101 res_ptr=dbgetvalue(0, 0);
102 if (sscanf(res_ptr, "%llu", &sb_id) != 1) {
103 MSG(M_ERR, "Malformed scanid from database");
104 db_disable=1;
105 return 0;
106 }
107 }
108
109 if (strlen(db_banner)) {
110 CLEAR(query);
111 snprintf(query, sizeof(query) -1, "insert into banner(scan_bucket_id, banner) values(%llu, '%s');", sb_id, db_banner);
112 aquerydb(query);
113 }
114 else {
115 /*
116 * right about now, you are likely wondering why in gods name anyone would do this?
117 * well it turns out this is a hack, that was requested to make sure the views
118 * are more _portable_, even though the other db code is missing, it wont be for long.
119 */
120 CLEAR(query);
121 snprintf(query, sizeof(query) -1, "insert into banner(scan_bucket_id) values(%llu);", sb_id);
122 aquery(query);
123 }
124
125 if (strlen(db_os)) {
126 CLEAR(query);
127 snprintf(query, sizeof(query) -1, "insert into os_fingerprint(scan_bucket_id, os) values(%llu, '%s');", sb_id, db_os);
128 aquerydb(query);
129 }
130 else {
131 CLEAR(query);
132 snprintf(query, sizeof(query) -1, "insert into os_fingerprint(scan_bucket_id) values(%llu);", sb_id);
133 aquery(query);
134 }
135
136 return 1;
137 }
138
m_database_fini(void)139 void m_database_fini(void) {
140 char query[512];
141
142 if (db_disable) return;
143 CLEAR(query);
144 snprintf(query, sizeof(query) -1, "update scan set e_time=%lld where scan_id=%lld;commit;", (long long int)s->e_time, scanid);
145 aquerydb(query);
146
147 closedb();
148
149 return;
150 }
151
database_walk_func(const void * item)152 static void database_walk_func(const void *item) {
153 union {
154 const void *ptr;
155 const output_data_t *d;
156 } d_u;
157
158 d_u.ptr=item;
159 switch (d_u.d->type) {
160 case OD_TYPE_BANNER:
161 CLEAR(db_banner);
162 snprintf(db_banner, sizeof(db_banner) -1, "%s", d_u.d->t_u.banner);
163 break;
164 case OD_TYPE_OS:
165 CLEAR(db_os);
166 snprintf(db_os, sizeof(db_os) -1, "%s", d_u.d->t_u.os);
167 break;
168 default:
169 MSG(M_ERR, "Unknown output format type %d in database push", d_u.d->type);
170 break;
171 }
172
173 return;
174 }
175