1 /*
2 pmacct (Promiscuous mode IP Accounting package)
3 pmacct is Copyright (C) 2003-2020 by Paolo Lucente
4 */
5
6 /*
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 /* includes */
23 #include "pmacct.h"
24 #include "pmacct-data.h"
25 #include "plugin_hooks.h"
26 #include "sql_common.h"
27 #include "sql_common_m.h"
28 #include "crc32.h"
29
30 /* Global variables */
31 char sql_data[LARGEBUFLEN];
32 char lock_clause[LONGSRVBUFLEN];
33 char unlock_clause[LONGSRVBUFLEN];
34 char update_clause[LONGSRVBUFLEN];
35 char set_clause[LONGSRVBUFLEN];
36 char copy_clause[LONGSRVBUFLEN];
37 char insert_clause[LONGSRVBUFLEN];
38 char insert_counters_clause[LONGSRVBUFLEN];
39 char insert_nocounters_clause[LONGSRVBUFLEN];
40 char insert_full_clause[LONGSRVBUFLEN];
41 char values_clause[LONGLONGSRVBUFLEN];
42 char *multi_values_buffer;
43 char where_clause[LONGLONGSRVBUFLEN];
44 unsigned char *pipebuf;
45 struct db_cache *sql_cache;
46 struct db_cache **sql_queries_queue, **sql_pending_queries_queue;
47 struct db_cache *collision_queue;
48 int cq_ptr, qq_size;
49 int cq_size;
50 struct db_cache lru_head, *lru_tail;
51 struct frags where[N_PRIMITIVES+2];
52 struct frags values[N_PRIMITIVES+2];
53 struct frags copy_values[N_PRIMITIVES+2];
54 struct frags set[N_PRIMITIVES+2];
55 struct frags set_event[N_PRIMITIVES+2];
56 int glob_num_primitives; /* last resort for signal handling */
57 int glob_basetime; /* last resort for signal handling */
58 time_t glob_new_basetime; /* last resort for signal handling */
59 time_t glob_committed_basetime; /* last resort for signal handling */
60 int glob_dyn_table, glob_dyn_table_time_only; /* last resort for signal handling */
61 int glob_timeslot; /* last resort for sql handlers */
62
63 struct sqlfunc_cb_registry sqlfunc_cbr;
64 struct DBdesc p;
65 struct DBdesc b;
66 struct BE_descs bed;
67 struct largebuf_s envbuf;
68 time_t now; /* PostgreSQL */
69
70 /* Functions */
sql_set_signals()71 void sql_set_signals()
72 {
73 signal(SIGINT, sql_exit_gracefully);
74 signal(SIGHUP, reload); /* handles reopening of syslog channel */
75 signal(SIGUSR1, SIG_IGN);
76 signal(SIGUSR2, reload_maps);
77 signal(SIGPIPE, SIG_IGN);
78 signal(SIGCHLD, ignore_falling_child);
79 }
80
sql_set_insert_func()81 void sql_set_insert_func()
82 {
83 if (config.what_to_count & (COUNT_SUM_HOST|COUNT_SUM_NET))
84 insert_func = sql_sum_host_insert;
85 else if (config.what_to_count & COUNT_SUM_PORT) insert_func = sql_sum_port_insert;
86 else if (config.what_to_count & COUNT_SUM_AS) insert_func = sql_sum_as_insert;
87 #if defined (HAVE_L2)
88 else if (config.what_to_count & COUNT_SUM_MAC) insert_func = sql_sum_mac_insert;
89 #endif
90 else insert_func = sql_cache_insert;
91 }
92
sql_init_maps(struct extra_primitives * extras,struct primitives_ptrs * prim_ptrs,struct networks_table * nt,struct networks_cache * nc,struct ports_table * pt)93 void sql_init_maps(struct extra_primitives *extras, struct primitives_ptrs *prim_ptrs,
94 struct networks_table *nt, struct networks_cache *nc, struct ports_table *pt)
95 {
96 memset(prim_ptrs, 0, sizeof(struct primitives_ptrs));
97 set_primptrs_funcs(extras);
98
99 memset(nt, 0, sizeof(struct networks_table));
100 memset(nc, 0, sizeof(struct networks_cache));
101 memset(pt, 0, sizeof(struct ports_table));
102
103 load_networks(config.networks_file, nt, nc);
104 set_net_funcs(nt);
105
106 if (config.ports_file) load_ports(config.ports_file, pt);
107 }
108
sql_init_global_buffers()109 void sql_init_global_buffers()
110 {
111 memset(sql_data, 0, sizeof(sql_data));
112 memset(lock_clause, 0, sizeof(lock_clause));
113 memset(unlock_clause, 0, sizeof(unlock_clause));
114 memset(update_clause, 0, sizeof(update_clause));
115 memset(set_clause, 0, sizeof(set_clause));
116 memset(copy_clause, 0, sizeof(copy_clause));
117 memset(insert_clause, 0, sizeof(insert_clause));
118 memset(insert_counters_clause, 0, sizeof(insert_counters_clause));
119 memset(insert_nocounters_clause, 0, sizeof(insert_nocounters_clause));
120 memset(where, 0, sizeof(where));
121 memset(values, 0, sizeof(values));
122 memset(set, 0, sizeof(set));
123 memset(set_event, 0, sizeof(set_event));
124 memset(&lru_head, 0, sizeof(lru_head));
125 lru_tail = &lru_head;
126
127 Log(LOG_INFO, "INFO ( %s/%s ): cache entries=%d base cache memory=%luu bytes\n", config.name, config.type,
128 config.sql_cache_entries, (unsigned long) ((config.sql_cache_entries * sizeof(struct db_cache)) +
129 (2 * (qq_size * sizeof(struct db_cache *)))) );
130
131 pipebuf = (unsigned char *) malloc(config.buffer_size);
132 sql_cache = (struct db_cache *) malloc(config.sql_cache_entries*sizeof(struct db_cache));
133 sql_queries_queue = (struct db_cache **) malloc(qq_size*sizeof(struct db_cache *));
134 sql_pending_queries_queue = (struct db_cache **) malloc(qq_size*sizeof(struct db_cache *));
135
136 if (!pipebuf || !sql_cache || !sql_queries_queue || !sql_pending_queries_queue) {
137 Log(LOG_ERR, "ERROR ( %s/%s ): malloc() failed (sql_init_global_buffers). Exiting ..\n", config.name, config.type);
138 exit_gracefully(1);
139 }
140
141 memset(pipebuf, 0, config.buffer_size);
142 memset(sql_cache, 0, config.sql_cache_entries*sizeof(struct db_cache));
143 memset(sql_queries_queue, 0, qq_size*sizeof(struct db_cache *));
144 memset(sql_pending_queries_queue, 0, qq_size*sizeof(struct db_cache *));
145 }
146
147 /* being the first routine to be called by each SQL plugin, this is
148 also the place for some initial common configuration consistency
149 check */
sql_init_default_values(struct extra_primitives * extras)150 void sql_init_default_values(struct extra_primitives *extras)
151 {
152 memset(empty_mem_area_256b, 0, sizeof(empty_mem_area_256b));
153
154 if (config.proc_priority) {
155 int ret;
156
157 ret = setpriority(PRIO_PROCESS, 0, config.proc_priority);
158 if (ret) Log(LOG_WARNING, "WARN ( %s/%s ): proc_priority failed (errno: %d)\n", config.name, config.type, errno);
159 else Log(LOG_INFO, "INFO ( %s/%s ): proc_priority set to %d\n", config.name, config.type, getpriority(PRIO_PROCESS, 0));
160 }
161
162 if (!config.sql_refresh_time) config.sql_refresh_time = DEFAULT_DB_REFRESH_TIME;
163 if (!config.sql_table_version) config.sql_table_version = DEFAULT_SQL_TABLE_VERSION;
164 if (!config.sql_cache_entries) config.sql_cache_entries = CACHE_ENTRIES;
165 if (!config.dump_max_writers) config.dump_max_writers = DEFAULT_SQL_WRITERS_NO;
166
167 dump_writers.list = malloc(config.dump_max_writers * sizeof(pid_t));
168 dump_writers_init();
169
170 /* SQL table type parsing; basically mapping everything down to a SQL table version */
171 /* ie. BGP == 1000 */
172 if (config.sql_table_type) {
173 if (!strcmp(config.sql_table_type, "bgp")) config.sql_table_version += SQL_TABLE_VERSION_BGP;
174 else {
175 Log(LOG_ERR, "ERROR ( %s/%s ): Unknown sql_table_type value: '%s'.\n", config.name, config.type, config.sql_table_type);
176 exit_gracefully(1);
177 }
178 }
179 else {
180 if (extras->off_pkt_bgp_primitives) {
181 config.sql_table_version += SQL_TABLE_VERSION_BGP;
182 Log(LOG_INFO, "INFO ( %s/%s ): sql_table_type set to 'bgp' (aggregate includes one or more BGP primitives).\n", config.name, config.type);
183 }
184 }
185
186 if (config.nfacctd_stitching) {
187 if (config.nfacctd_pro_rating) {
188 Log(LOG_ERR, "ERROR ( %s/%s ): Pro-rating (ie. nfacctd_pro_rating) and stitching (ie. nfacctd_stitching) are mutual exclusive. Exiting.\n", config.name, config.type);
189 exit_gracefully(1);
190 }
191
192 if (!config.sql_dont_try_update) {
193 Log(LOG_WARNING, "WARN ( %s/%s ): stitching (ie. nfacctd_stitching) behaviour is undefined when sql_dont_try_update is set to false.\n", config.name, config.type);
194 }
195 }
196
197 qq_ptr = 0;
198 pqq_ptr = 0;
199 qq_size = config.sql_cache_entries+(config.sql_refresh_time*REASONABLE_NUMBER);
200 pp_size = sizeof(struct pkt_primitives);
201 pb_size = sizeof(struct pkt_bgp_primitives);
202 pn_size = sizeof(struct pkt_nat_primitives);
203 pm_size = sizeof(struct pkt_mpls_primitives);
204 pt_size = sizeof(struct pkt_tunnel_primitives);
205 pc_size = config.cpptrs.len;
206 dbc_size = sizeof(struct db_cache);
207
208 /* handling purge preprocessor */
209 set_preprocess_funcs(config.sql_preprocess, &prep, PREP_DICT_SQL);
210 }
211
sql_init_historical_acct(time_t now,struct insert_data * idata)212 void sql_init_historical_acct(time_t now, struct insert_data *idata)
213 {
214 time_t t;
215
216 if (config.sql_history) {
217 idata->basetime = now;
218 if (config.sql_history == COUNT_SECONDLY) idata->timeslot = config.sql_history_howmany;
219 else if (config.sql_history == COUNT_MINUTELY) idata->timeslot = config.sql_history_howmany*60;
220 else if (config.sql_history == COUNT_HOURLY) idata->timeslot = config.sql_history_howmany*3600;
221 else if (config.sql_history == COUNT_DAILY) idata->timeslot = config.sql_history_howmany*86400;
222 else if (config.sql_history == COUNT_WEEKLY) idata->timeslot = config.sql_history_howmany*86400*7;
223 else if (config.sql_history == COUNT_MONTHLY) {
224 idata->basetime = roundoff_time(idata->basetime, "d"); /* resetting day of month */
225 idata->timeslot = calc_monthly_timeslot(idata->basetime, config.sql_history_howmany, ADD);
226 }
227
228 /* round off stuff */
229 t = roundoff_time(idata->basetime, config.sql_history_roundoff);
230
231 while ((t+idata->timeslot) < idata->basetime) {
232 t += idata->timeslot;
233 if (config.sql_history == COUNT_MONTHLY) idata->timeslot = calc_monthly_timeslot(t, config.sql_history_howmany, ADD);
234 }
235
236 if (config.sql_history_offset) {
237 if (config.sql_history_offset >= idata->timeslot) {
238 Log(LOG_ERR, "ERROR ( %s/%s ): History offset (ie. sql_history_offset) must be < history (ie. sql_history).\n", config.name, config.type);
239 exit_gracefully(1);
240 }
241
242 t = t - (idata->timeslot + config.sql_history_offset);
243 }
244
245 idata->basetime = t;
246 glob_basetime = idata->basetime;
247 idata->new_basetime = idata->basetime;
248 glob_new_basetime = idata->basetime;
249 glob_timeslot = idata->timeslot;
250 idata->committed_basetime = 0;
251 glob_committed_basetime = 0;
252 }
253 }
254
255 /* NOTE: sql triggers time init: deadline; if a trigger exec is specified but
256 no time is supplied, use 'sql_refresh_time' as interval; this will result
257 in a trigger being executed each time data is purged into the DB */
sql_init_triggers(time_t now,struct insert_data * idata)258 void sql_init_triggers(time_t now, struct insert_data *idata)
259 {
260 time_t t, deadline;
261
262 if (config.sql_trigger_exec) {
263 deadline = now;
264
265 if (config.sql_trigger_time == COUNT_MINUTELY) idata->t_timeslot = config.sql_trigger_time_howmany*60;
266 else if (config.sql_trigger_time == COUNT_HOURLY) idata->t_timeslot = config.sql_trigger_time_howmany*3600;
267 else if (config.sql_trigger_time == COUNT_DAILY) idata->t_timeslot = config.sql_trigger_time_howmany*86400;
268 else if (config.sql_trigger_time == COUNT_WEEKLY) idata->t_timeslot = config.sql_trigger_time_howmany*86400*7;
269 else if (config.sql_trigger_time == COUNT_MONTHLY) {
270 deadline = roundoff_time(deadline, "d"); /* resetting day of month */
271 idata->t_timeslot = calc_monthly_timeslot(deadline, config.sql_trigger_time_howmany, ADD);
272 }
273 else idata->t_timeslot = config.sql_refresh_time;
274
275 /* round off stuff */
276 t = roundoff_time(deadline, config.sql_history_roundoff);
277 while ((t+idata->t_timeslot) < deadline) {
278 t += idata->t_timeslot;
279 if (config.sql_trigger_time == COUNT_MONTHLY)
280 idata->t_timeslot = calc_monthly_timeslot(t, config.sql_trigger_time_howmany, ADD);
281 }
282 idata->triggertime = (t + config.sql_startup_delay);
283
284 /* adding a trailer timeslot: it's a deadline not a basetime */
285 idata->triggertime += idata->t_timeslot;
286 if (config.sql_trigger_time == COUNT_MONTHLY)
287 idata->t_timeslot = calc_monthly_timeslot(t, config.sql_trigger_time_howmany, ADD);
288 }
289 }
290
sql_init_refresh_deadline(time_t * rd)291 void sql_init_refresh_deadline(time_t *rd)
292 {
293 time_t t;
294
295 t = roundoff_time(*rd, config.sql_history_roundoff);
296 while ((t+config.sql_refresh_time) < *rd) t += config.sql_refresh_time;
297 *rd = t;
298 *rd += (config.sql_refresh_time+config.sql_startup_delay); /* it's a deadline not a basetime */
299 }
300
sql_link_backend_descriptors(struct BE_descs * registry,struct DBdesc * p,struct DBdesc * b)301 void sql_link_backend_descriptors(struct BE_descs *registry, struct DBdesc *p, struct DBdesc *b)
302 {
303 memset(registry, 0, sizeof(struct BE_descs));
304 memset(p, 0, sizeof(struct DBdesc));
305 memset(b, 0, sizeof(struct DBdesc));
306
307 registry->p = p;
308 registry->b = b;
309 registry->p->type = BE_TYPE_PRIMARY;
310 registry->b->type = BE_TYPE_BACKUP;
311
312 if (*sqlfunc_cbr.create_backend) {
313 (*sqlfunc_cbr.create_backend)(registry->p);
314 (*sqlfunc_cbr.create_backend)(registry->b);
315 }
316 }
317
sql_cache_modulo(struct primitives_ptrs * prim_ptrs,struct insert_data * idata)318 void sql_cache_modulo(struct primitives_ptrs *prim_ptrs, struct insert_data *idata)
319 {
320 struct pkt_data *pdata = prim_ptrs->data;
321 struct pkt_primitives *srcdst = &pdata->primitives;
322 struct pkt_bgp_primitives *pbgp = prim_ptrs->pbgp;
323 struct pkt_nat_primitives *pnat = prim_ptrs->pnat;
324 struct pkt_mpls_primitives *pmpls = prim_ptrs->pmpls;
325 struct pkt_tunnel_primitives *ptun = prim_ptrs->ptun;
326 u_char *pcust = prim_ptrs->pcust;
327 struct pkt_vlen_hdr_primitives *pvlen = prim_ptrs->pvlen;
328
329 idata->hash = cache_crc32((unsigned char *)srcdst, pp_size);
330 if (pbgp) idata->hash ^= cache_crc32((unsigned char *)pbgp, pb_size);
331 if (pnat) idata->hash ^= cache_crc32((unsigned char *)pnat, pn_size);
332 if (pmpls) idata->hash ^= cache_crc32((unsigned char *)pmpls, pm_size);
333 if (ptun) idata->hash ^= cache_crc32((unsigned char *)ptun, pt_size);
334 if (pcust) idata->hash ^= cache_crc32((unsigned char *)pcust, pc_size);
335 if (pvlen) idata->hash ^= cache_crc32((unsigned char *)pvlen, (PvhdrSz + pvlen->tot_len));
336
337 idata->modulo = idata->hash % config.sql_cache_entries;
338 }
339
sql_cache_flush(struct db_cache * queue[],int index,struct insert_data * idata,int exiting)340 int sql_cache_flush(struct db_cache *queue[], int index, struct insert_data *idata, int exiting)
341 {
342 int j, delay = 0, new_basetime = FALSE;
343
344 /* We are seeking how many time-bins data has to be delayed by; residual
345 time is taken into account by scanner deadlines (sql_refresh_time) */
346 if (config.sql_startup_delay) {
347 if (idata->timeslot) delay = config.sql_startup_delay/idata->timeslot;
348 delay = delay*idata->timeslot;
349 }
350
351 /* check-pointing: we record last committed time-bin; part of this is
352 checking whether basetime was moved forward yet (as this is not for
353 sure). */
354 if (idata->new_basetime && idata->new_basetime < idata->basetime &&
355 idata->new_basetime > idata->committed_basetime) {
356 new_basetime = TRUE;
357 idata->committed_basetime = idata->new_basetime;
358 }
359 else idata->committed_basetime = idata->basetime;
360
361 if (!exiting) {
362 for (j = 0, pqq_ptr = 0; j < index; j++) {
363 if (new_basetime && queue[j]->basetime+delay >= idata->basetime) {
364 sql_pending_queries_queue[pqq_ptr] = queue[j];
365 pqq_ptr++;
366 }
367 else if (!new_basetime && queue[j]->basetime+delay > idata->basetime) {
368 sql_pending_queries_queue[pqq_ptr] = queue[j];
369 pqq_ptr++;
370 }
371 else queue[j]->valid = SQL_CACHE_COMMITTED;
372 }
373 }
374 /* If exiting instead .. */
375 else {
376 for (j = 0; j < index; j++) queue[j]->valid = SQL_CACHE_COMMITTED;
377 }
378
379 return index;
380 }
381
sql_cache_flush_pending(struct db_cache * queue[],int index,struct insert_data * idata)382 void sql_cache_flush_pending(struct db_cache *queue[], int index, struct insert_data *idata)
383 {
384 struct db_cache *Cursor, *auxCursor, *PendingElem, SavedCursor;
385 int j;
386
387 /* Not everything was purged, let's sort out the SQL cache buckets involved into that */
388 if (index) {
389 for (j = 0; j < index; j++) {
390 /* Select next element on the pending queue */
391 PendingElem = queue[j];
392
393 /* Go to the first element in the bucket */
394 for (Cursor = PendingElem, auxCursor = NULL; Cursor; auxCursor = Cursor, Cursor = Cursor->prev);
395
396 /* Check whether we are already first in the bucket */
397 if (auxCursor != PendingElem) {
398 Cursor = auxCursor;
399
400 for (; Cursor && Cursor != PendingElem && Cursor->valid == SQL_CACHE_INUSE; Cursor = Cursor->next);
401 /* Check whether a) the whole bucket chain is currently in use
402 or b) we came across the current pending element: meaning no
403 free positions are available in the chain, ahead of it */
404 if (Cursor && Cursor != PendingElem) {
405 /* Check whether we have to replace the first element in the bucket */
406 if (!Cursor->prev) {
407 memcpy(&SavedCursor, Cursor, sizeof(struct db_cache));
408 memcpy(Cursor, PendingElem, sizeof(struct db_cache));
409 Cursor->prev = NULL;
410 Cursor->next = SavedCursor.next;
411 Cursor->chained = FALSE;
412 Cursor->lru_prev = NULL;
413 Cursor->lru_next = NULL;
414
415 /* unlinking pointers from PendingElem to prevent free-up (linked by Cursor) */
416 PendingElem->pbgp = NULL;
417 PendingElem->pnat = NULL;
418 PendingElem->pmpls = NULL;
419 PendingElem->ptun = NULL;
420 PendingElem->pcust = NULL;
421 PendingElem->pvlen = NULL;
422 PendingElem->stitch = NULL;
423 RetireElem(PendingElem);
424
425 queue[j] = Cursor;
426
427 /* freeing stale allocations */
428 if (SavedCursor.pbgp) free(SavedCursor.pbgp);
429 if (SavedCursor.pnat) free(SavedCursor.pnat);
430 if (SavedCursor.pmpls) free(SavedCursor.pmpls);
431 if (SavedCursor.ptun) free(SavedCursor.ptun);
432 if (SavedCursor.pcust) free(SavedCursor.pcust);
433 if (SavedCursor.pvlen) free(SavedCursor.pvlen);
434 if (SavedCursor.stitch) free(SavedCursor.stitch);
435 }
436 /* We found at least one Cursor->valid == SQL_CACHE_INUSE */
437 else SwapChainedElems(PendingElem, Cursor);
438 }
439 }
440 }
441 }
442 }
443
sql_cache_handle_flush_event(struct insert_data * idata,time_t * refresh_deadline,struct ports_table * pt)444 void sql_cache_handle_flush_event(struct insert_data *idata, time_t *refresh_deadline, struct ports_table *pt)
445 {
446 int ret;
447
448 dump_writers_count();
449 if (dump_writers_get_flags() != CHLD_ALERT) {
450 switch (ret = fork()) {
451 case 0: /* Child */
452 /* we have to ignore signals to avoid loops: because we are already forked */
453 signal(SIGINT, SIG_IGN);
454 signal(SIGHUP, SIG_IGN);
455 pm_setproctitle("%s %s [%s]", config.type, "Plugin -- DB Writer", config.name);
456 config.is_forked = TRUE;
457
458 if (qq_ptr) {
459 if (dump_writers_get_flags() == CHLD_WARNING) sql_db_fail(&p);
460 if (!strcmp(config.type, "mysql"))
461 (*sqlfunc_cbr.connect)(&p, config.sql_host);
462 else
463 (*sqlfunc_cbr.connect)(&p, NULL);
464 }
465
466 /* qq_ptr check inside purge function along with a Log() call */
467 (*sqlfunc_cbr.purge)(sql_queries_queue, qq_ptr, idata);
468
469 if (qq_ptr) (*sqlfunc_cbr.close)(&bed);
470
471 if (config.sql_trigger_exec) {
472 if (idata->now > idata->triggertime) sql_trigger_exec(config.sql_trigger_exec);
473 }
474
475 exit_gracefully(0);
476 default: /* Parent */
477 if (ret == -1) Log(LOG_WARNING, "WARN ( %s/%s ): Unable to fork DB writer: %s\n", config.name, config.type, strerror(errno));
478 else dump_writers_add(ret);
479
480 break;
481 }
482 }
483 else Log(LOG_WARNING, "WARN ( %s/%s ): Maximum number of writer processes reached (%d).\n", config.name, config.type, dump_writers_get_active());
484
485 if (pqq_ptr) sql_cache_flush_pending(sql_pending_queries_queue, pqq_ptr, idata);
486 gettimeofday(&idata->flushtime, NULL);
487 while (idata->now > *refresh_deadline)
488 *refresh_deadline += config.sql_refresh_time;
489 while (idata->now > idata->triggertime && idata->t_timeslot > 0) {
490 idata->triggertime += idata->t_timeslot;
491 if (config.sql_trigger_time == COUNT_MONTHLY)
492 idata->t_timeslot = calc_monthly_timeslot(idata->triggertime, config.sql_trigger_time_howmany, ADD);
493 }
494
495 idata->new_basetime = FALSE;
496 glob_new_basetime = FALSE;
497 qq_ptr = pqq_ptr;
498 memcpy(sql_queries_queue, sql_pending_queries_queue, qq_ptr*sizeof(struct db_cache *));
499
500 if (reload_map) {
501 load_networks(config.networks_file, &nt, &nc);
502 load_ports(config.ports_file, pt);
503 reload_map = FALSE;
504 }
505
506 if (reload_log) {
507 reload_logs();
508 reload_log = FALSE;
509 }
510 }
511
sql_cache_search(struct primitives_ptrs * prim_ptrs,time_t basetime)512 struct db_cache *sql_cache_search(struct primitives_ptrs *prim_ptrs, time_t basetime)
513 {
514 struct pkt_data *pdata = prim_ptrs->data;
515 struct pkt_primitives *data = &pdata->primitives;
516 struct pkt_bgp_primitives *pbgp = prim_ptrs->pbgp;
517 struct pkt_nat_primitives *pnat = prim_ptrs->pnat;
518 struct pkt_mpls_primitives *pmpls = prim_ptrs->pmpls;
519 struct pkt_tunnel_primitives *ptun = prim_ptrs->ptun;
520 u_char *pcust = prim_ptrs->pcust;
521 struct pkt_vlen_hdr_primitives *pvlen = prim_ptrs->pvlen;
522 struct db_cache *Cursor;
523 struct insert_data idata;
524 int res_data = TRUE, res_bgp = TRUE, res_nat = TRUE, res_mpls = TRUE, res_tun = TRUE;
525 int res_cust = TRUE, res_vlen = TRUE;
526
527 sql_cache_modulo(prim_ptrs, &idata);
528
529 Cursor = &sql_cache[idata.modulo];
530
531 start:
532 if (idata.hash != Cursor->signature) {
533 if (Cursor->valid == SQL_CACHE_INUSE) {
534 follow_chain:
535 if (Cursor->next) {
536 Cursor = Cursor->next;
537 goto start;
538 }
539 }
540 }
541 else {
542 if (Cursor->valid == SQL_CACHE_INUSE) {
543 /* checks: pkt_primitives and pkt_bgp_primitives */
544 res_data = memcmp(&Cursor->primitives, data, sizeof(struct pkt_primitives));
545
546 if (pbgp && Cursor->pbgp) {
547 res_bgp = memcmp(Cursor->pbgp, pbgp, sizeof(struct pkt_bgp_primitives));
548 }
549 else res_bgp = FALSE;
550
551 if (pnat && Cursor->pnat) {
552 res_nat = memcmp(Cursor->pnat, pnat, sizeof(struct pkt_nat_primitives));
553 }
554 else res_nat = FALSE;
555
556 if (pmpls && Cursor->pmpls) {
557 res_mpls = memcmp(Cursor->pmpls, pmpls, sizeof(struct pkt_mpls_primitives));
558 }
559 else res_mpls = FALSE;
560
561 if (ptun && Cursor->ptun) {
562 res_tun = memcmp(Cursor->ptun, ptun, sizeof(struct pkt_tunnel_primitives));
563 }
564 else res_tun = FALSE;
565
566 if (pcust && Cursor->pcust) {
567 res_cust = memcmp(Cursor->pcust, pcust, config.cpptrs.len);
568 }
569 else res_cust = FALSE;
570
571 if (pvlen && Cursor->pvlen) {
572 res_vlen = vlen_prims_cmp(Cursor->pvlen, pvlen);
573 }
574 else res_vlen = FALSE;
575
576 if (!res_data && !res_bgp && !res_nat && !res_mpls && !res_tun && !res_cust && !res_vlen) {
577 /* additional check: time */
578 if ((Cursor->basetime < basetime) && config.sql_history)
579 goto follow_chain;
580 else return Cursor;
581 }
582 else goto follow_chain;
583 }
584 }
585
586 return NULL;
587 }
588
sql_cache_insert(struct primitives_ptrs * prim_ptrs,struct insert_data * idata)589 void sql_cache_insert(struct primitives_ptrs *prim_ptrs, struct insert_data *idata)
590 {
591 struct pkt_data *data = prim_ptrs->data;
592 struct pkt_bgp_primitives *pbgp = prim_ptrs->pbgp;
593 struct pkt_nat_primitives *pnat = prim_ptrs->pnat;
594 struct pkt_mpls_primitives *pmpls = prim_ptrs->pmpls;
595 struct pkt_tunnel_primitives *ptun = prim_ptrs->ptun;
596 u_char *pcust = prim_ptrs->pcust;
597 struct pkt_vlen_hdr_primitives *pvlen = prim_ptrs->pvlen;
598 time_t basetime = idata->basetime, timeslot = idata->timeslot;
599 struct pkt_primitives *srcdst = &data->primitives;
600 struct db_cache *Cursor, *newElem, *SafePtr = NULL, *staleElem = NULL;
601 int ret, insert_status;
602
603 /* pro_rating vars */
604 int time_delta = 0, time_total = 0;
605 pm_counter_t tot_bytes = 0, tot_packets = 0, tot_flows = 0;
606
607 /* housekeeping to start */
608 if (lru_head.lru_next && ((idata->now-lru_head.lru_next->lru_tag) > RETIRE_M*config.sql_refresh_time)) {
609 /* if element status is SQL_CACHE_INUSE it can't be retired because sits on the queue */
610 if (lru_head.lru_next->valid != SQL_CACHE_INUSE) RetireElem(lru_head.lru_next);
611 }
612
613 tot_bytes = data->pkt_len;
614 tot_packets = data->pkt_num;
615 tot_flows = data->flo_num;
616
617 if (data->time_start.tv_sec && config.sql_history) {
618 if (config.sql_history != COUNT_MONTHLY) {
619 int residual;
620
621 if (basetime > data->time_start.tv_sec) {
622 residual = timeslot - ((basetime - data->time_start.tv_sec) % timeslot);
623 }
624 else {
625 residual = ((data->time_start.tv_sec - basetime) % timeslot);
626 }
627
628 basetime = data->time_start.tv_sec - residual;
629 }
630 else {
631 while (basetime > data->time_start.tv_sec) {
632 timeslot = calc_monthly_timeslot(basetime, config.sql_history_howmany, SUB);
633 basetime -= timeslot;
634 }
635 while ((basetime + timeslot) < data->time_start.tv_sec) {
636 basetime += timeslot;
637 timeslot = calc_monthly_timeslot(basetime, config.sql_history_howmany, ADD);
638 }
639 }
640 }
641
642 new_timeslot:
643 /* pro_rating, if needed */
644 if (config.acct_type == ACCT_NF && config.nfacctd_pro_rating && config.sql_history) {
645 if (data->time_end.tv_sec > data->time_start.tv_sec) {
646 time_total = data->time_end.tv_sec - data->time_start.tv_sec;
647 time_delta = MIN(data->time_end.tv_sec, basetime + timeslot) - MAX(data->time_start.tv_sec, basetime);
648
649 if (time_delta > 0 && time_total > 0 && time_delta < time_total) {
650 float ratio = (float) time_total / (float) time_delta;
651
652 if (tot_bytes) data->pkt_len = MAX((float)tot_bytes / ratio, 1);
653 if (tot_packets) data->pkt_num = MAX((float)tot_packets / ratio, 1);
654 if (tot_flows) data->flo_num = MAX((float)tot_flows / ratio, 1);
655 }
656 }
657 }
658
659 /* We are classifing packets. We have a non-zero bytes accumulator (ba)
660 and a non-zero class. Before accounting ba to this class, we have to
661 remove ba from class zero. */
662 if (config.what_to_count & COUNT_CLASS && data->cst.ba && data->primitives.class) {
663 pm_class_t lclass = data->primitives.class;
664
665 data->primitives.class = 0;
666 Cursor = sql_cache_search(prim_ptrs, basetime);
667 data->primitives.class = lclass;
668
669 /* We can assign the flow to a new class only if we are able to subtract
670 the accumulator from the zero-class. If this is not the case, we will
671 discard the accumulators. The assumption is that accumulators are not
672 retroactive */
673
674 if (Cursor) {
675 if (timeval_cmp(&data->cst.stamp, &idata->flushtime) >= 0) {
676 Cursor->bytes_counter -= MIN(Cursor->bytes_counter, data->cst.ba);
677 Cursor->packet_counter -= MIN(Cursor->packet_counter, data->cst.pa);
678 Cursor->flows_counter -= MIN(Cursor->flows_counter, data->cst.fa);
679 }
680 else memset(&data->cst, 0, CSSz);
681 }
682 else memset(&data->cst, 0, CSSz);
683 }
684
685 sql_cache_modulo(prim_ptrs, idata);
686 Cursor = &sql_cache[idata->modulo];
687
688 start:
689 insert_status = SQL_INSERT_INSERT;
690
691 if (idata->hash != Cursor->signature) {
692 if (Cursor->valid == SQL_CACHE_INUSE) {
693 follow_chain:
694 if (Cursor->next) {
695 Cursor = Cursor->next;
696 goto start;
697 }
698 else {
699 if (lru_head.lru_next && lru_head.lru_next->valid != SQL_CACHE_INUSE &&
700 ((idata->now-lru_head.lru_next->lru_tag) > STALE_M*config.sql_refresh_time)) {
701 newElem = lru_head.lru_next;
702 /* if (newElem != Cursor) */
703 /* check removed: Cursor must be SQL_CACHE_INUSE; newElem must be not SQL_CACHE_INUSE */
704 ReBuildChain(Cursor, newElem);
705 Cursor = newElem;
706 /* we have successfully reused a stale element */
707 }
708 else {
709 newElem = (struct db_cache *) malloc(sizeof(struct db_cache));
710 if (newElem) {
711 memset(newElem, 0, sizeof(struct db_cache));
712 BuildChain(Cursor, newElem);
713 Cursor = newElem;
714 /* creating a new element */
715 }
716 else insert_status = SQL_INSERT_SAFE_ACTION; /* we should have finished memory */
717 }
718 }
719 }
720 /* we found a no more valid entry; let's insert here our data */
721 }
722 else {
723 if (Cursor->valid == SQL_CACHE_INUSE) {
724 int res_data = TRUE, res_bgp = TRUE, res_nat = TRUE, res_mpls = TRUE, res_tun = TRUE;
725 int res_cust = TRUE, res_vlen = TRUE;
726
727 /* checks: pkt_primitives and pkt_bgp_primitives */
728 res_data = memcmp(&Cursor->primitives, srcdst, sizeof(struct pkt_primitives));
729
730 if (pbgp && Cursor->pbgp) {
731 res_bgp = memcmp(Cursor->pbgp, pbgp, sizeof(struct pkt_bgp_primitives));
732 }
733 else res_bgp = FALSE;
734
735 if (pnat && Cursor->pnat) {
736 res_nat = memcmp(Cursor->pnat, pnat, sizeof(struct pkt_nat_primitives));
737 }
738 else res_nat = FALSE;
739
740 if (pmpls && Cursor->pmpls) {
741 res_mpls = memcmp(Cursor->pmpls, pmpls, sizeof(struct pkt_mpls_primitives));
742 }
743 else res_mpls = FALSE;
744
745 if (ptun && Cursor->ptun) {
746 res_tun = memcmp(Cursor->ptun, ptun, sizeof(struct pkt_tunnel_primitives));
747 }
748 else res_tun = FALSE;
749
750 if (pcust && Cursor->pcust) {
751 res_cust = memcmp(Cursor->pcust, pcust, config.cpptrs.len);
752 }
753 else res_cust = FALSE;
754
755 if (pvlen && Cursor->pvlen) {
756 res_vlen = vlen_prims_cmp(Cursor->pvlen, pvlen);
757 }
758 else res_vlen = FALSE;
759
760 if (!res_data && !res_bgp && !res_nat && !res_mpls && !res_tun && !res_cust && !res_vlen) {
761 /* additional check: time */
762 if ((Cursor->basetime != basetime) && config.sql_history) goto follow_chain;
763
764 /* additional check: bytes counter overflow */
765 if (Cursor->bytes_counter > CACHE_THRESHOLD) goto follow_chain;
766
767 /* All is good: let's update the matching entry */
768 insert_status = SQL_INSERT_UPDATE;
769 }
770 else goto follow_chain;
771 }
772 }
773
774 if (insert_status == SQL_INSERT_INSERT) {
775 if (qq_ptr < qq_size) {
776 sql_queries_queue[qq_ptr] = Cursor;
777 qq_ptr++;
778 }
779 else SafePtr = Cursor;
780
781 /* we add the new entry in the cache */
782 memcpy(&Cursor->primitives, srcdst, sizeof(struct pkt_primitives));
783
784 if (pbgp) {
785 if (!Cursor->pbgp) {
786 Cursor->pbgp = (struct pkt_bgp_primitives *) malloc(pb_size);
787 if (!Cursor->pbgp) goto safe_action;
788 }
789 memcpy(Cursor->pbgp, pbgp, pb_size);
790 }
791 else {
792 if (Cursor->pbgp) free(Cursor->pbgp);
793 Cursor->pbgp = NULL;
794 }
795
796 if (pnat) {
797 if (!Cursor->pnat) {
798 Cursor->pnat = (struct pkt_nat_primitives *) malloc(pn_size);
799 if (!Cursor->pnat) goto safe_action;
800 }
801 memcpy(Cursor->pnat, pnat, pn_size);
802 }
803 else {
804 if (Cursor->pnat) free(Cursor->pnat);
805 Cursor->pnat = NULL;
806 }
807
808 if (pmpls) {
809 if (!Cursor->pmpls) {
810 Cursor->pmpls = (struct pkt_mpls_primitives *) malloc(pm_size);
811 if (!Cursor->pmpls) goto safe_action;
812 }
813 memcpy(Cursor->pmpls, pmpls, pm_size);
814 }
815 else {
816 if (Cursor->pmpls) free(Cursor->pmpls);
817 Cursor->pmpls = NULL;
818 }
819
820 if (ptun) {
821 if (!Cursor->ptun) {
822 Cursor->ptun = (struct pkt_tunnel_primitives *) malloc(pt_size);
823 if (!Cursor->ptun) goto safe_action;
824 }
825 memcpy(Cursor->ptun, ptun, pt_size);
826 }
827 else {
828 if (Cursor->ptun) free(Cursor->ptun);
829 Cursor->ptun = NULL;
830 }
831
832 if (pcust) {
833 if (!Cursor->pcust) {
834 Cursor->pcust = malloc(pc_size);
835 if (!Cursor->pcust) goto safe_action;
836 }
837 memcpy(Cursor->pcust, pcust, pc_size);
838 }
839 else {
840 if (Cursor->pcust) free(Cursor->pcust);
841 Cursor->pcust = NULL;
842 }
843
844 /* if we have a pvlen from before let's free it
845 up due to the vlen nature of the memory area */
846 if (Cursor->pvlen) {
847 vlen_prims_free(Cursor->pvlen);
848 Cursor->pvlen = NULL;
849 }
850
851 if (pvlen) {
852 Cursor->pvlen = (struct pkt_vlen_hdr_primitives *) vlen_prims_copy(pvlen);
853 if (!Cursor->pvlen) goto safe_action;
854 }
855
856 Cursor->packet_counter = data->pkt_num;
857 Cursor->flows_counter = data->flo_num;
858 Cursor->bytes_counter = data->pkt_len;
859 Cursor->flow_type = data->flow_type;
860 Cursor->tcp_flags = data->tcp_flags;
861
862 if (config.what_to_count & COUNT_CLASS) {
863 Cursor->bytes_counter += data->cst.ba;
864 Cursor->packet_counter += data->cst.pa;
865 Cursor->flows_counter += data->cst.fa;
866 Cursor->tentatives = data->cst.tentatives;
867 }
868
869 if (config.nfacctd_stitching) {
870 if (!Cursor->stitch) Cursor->stitch = (struct pkt_stitching *) malloc(sizeof(struct pkt_stitching));
871 if (Cursor->stitch) {
872 if (data->time_start.tv_sec) {
873 memcpy(&Cursor->stitch->timestamp_min, &data->time_start, sizeof(struct timeval));
874 }
875 else {
876 Cursor->stitch->timestamp_min.tv_sec = idata->now;
877 Cursor->stitch->timestamp_min.tv_usec = 0;
878 }
879
880 if (data->time_end.tv_sec) {
881 memcpy(&Cursor->stitch->timestamp_max, &data->time_end, sizeof(struct timeval));
882 }
883 else {
884 Cursor->stitch->timestamp_max.tv_sec = idata->now;
885 Cursor->stitch->timestamp_max.tv_usec = 0;
886 }
887 }
888 else Log(LOG_WARNING, "WARN ( %s/%s ): Finished memory for flow stitching.\n", config.name, config.type);
889 }
890 else assert(!Cursor->stitch);
891
892 Cursor->valid = SQL_CACHE_INUSE;
893 Cursor->basetime = basetime;
894 Cursor->start_tag = idata->now;
895 Cursor->lru_tag = idata->now;
896 Cursor->signature = idata->hash;
897 /* We are not so fancy to reuse elements which have
898 not been malloc()'d before */
899 if (Cursor->chained) AddToLRUTail(Cursor);
900 if (SafePtr) goto safe_action;
901 if (staleElem) SwapChainedElems(Cursor, staleElem);
902 insert_status = SQL_INSERT_PRO_RATING;
903 }
904
905 if (insert_status == SQL_INSERT_UPDATE) {
906 Cursor->packet_counter += data->pkt_num;
907 Cursor->flows_counter += data->flo_num;
908 Cursor->bytes_counter += data->pkt_len;
909 Cursor->flow_type = data->flow_type;
910 Cursor->tcp_flags |= data->tcp_flags;
911
912 if (config.what_to_count & COUNT_CLASS) {
913 Cursor->bytes_counter += data->cst.ba;
914 Cursor->packet_counter += data->cst.pa;
915 Cursor->flows_counter += data->cst.fa;
916 Cursor->tentatives = data->cst.tentatives;
917 }
918
919 if (config.nfacctd_stitching) {
920 if (Cursor->stitch) {
921 if (data->time_end.tv_sec) {
922 if (data->time_end.tv_sec > Cursor->stitch->timestamp_max.tv_sec &&
923 data->time_end.tv_usec > Cursor->stitch->timestamp_max.tv_usec)
924 memcpy(&Cursor->stitch->timestamp_max, &data->time_end, sizeof(struct timeval));
925 }
926 else {
927 Cursor->stitch->timestamp_max.tv_sec = idata->now;
928 Cursor->stitch->timestamp_max.tv_usec = 0;
929 }
930 }
931 }
932
933 insert_status = SQL_INSERT_PRO_RATING;
934 }
935
936 if (insert_status == SQL_INSERT_PRO_RATING) {
937 if (config.acct_type == ACCT_NF && config.nfacctd_pro_rating && config.sql_history) {
938 if ((basetime + timeslot) < data->time_end.tv_sec) {
939 basetime += timeslot;
940 goto new_timeslot;
941 }
942 }
943 }
944
945 if (insert_status == SQL_INSERT_SAFE_ACTION) {
946 safe_action:
947
948 Log(LOG_INFO, "INFO ( %s/%s ): Finished cache entries (ie. sql_cache_entries). Purging.\n", config.name, config.type);
949
950 if (qq_ptr) sql_cache_flush(sql_queries_queue, qq_ptr, idata, FALSE);
951
952 dump_writers_count();
953 if (dump_writers_get_flags() != CHLD_ALERT) {
954 switch (ret = fork()) {
955 case 0: /* Child */
956 signal(SIGINT, SIG_IGN);
957 signal(SIGHUP, SIG_IGN);
958 pm_setproctitle("%s [%s]", "SQL Plugin -- DB Writer (urgent)", config.name);
959 config.is_forked = TRUE;
960
961 if (qq_ptr) {
962 if (dump_writers_get_flags() == CHLD_WARNING) sql_db_fail(&p);
963 (*sqlfunc_cbr.connect)(&p, config.sql_host);
964 (*sqlfunc_cbr.purge)(sql_queries_queue, qq_ptr, idata);
965 (*sqlfunc_cbr.close)(&bed);
966 }
967
968 exit_gracefully(0);
969 default: /* Parent */
970 if (ret == -1) Log(LOG_WARNING, "WARN ( %s/%s ): Unable to fork DB writer (urgent): %s\n", config.name, config.type, strerror(errno));
971 else dump_writers_add(ret);
972
973 break;
974 }
975 }
976 else Log(LOG_WARNING, "WARN ( %s/%s ): Maximum number of writer processes reached (%d).\n", config.name, config.type, dump_writers_get_active());
977
978 qq_ptr = pqq_ptr;
979 memcpy(sql_queries_queue, sql_pending_queries_queue, sizeof(*sql_queries_queue));
980
981 if (SafePtr) {
982 sql_queries_queue[qq_ptr] = Cursor;
983 qq_ptr++;
984 }
985 else {
986 Cursor = &sql_cache[idata->modulo];
987 goto start;
988 }
989 }
990 }
991
sql_sum_host_insert(struct primitives_ptrs * prim_ptrs,struct insert_data * idata)992 void sql_sum_host_insert(struct primitives_ptrs *prim_ptrs, struct insert_data *idata)
993 {
994 struct pkt_data *data = prim_ptrs->data;
995 struct host_addr tmp;
996
997 memcpy(&tmp, &data->primitives.dst_ip, HostAddrSz);
998 memset(&data->primitives.dst_ip, 0, HostAddrSz);
999 sql_cache_insert(prim_ptrs, idata);
1000 memcpy(&data->primitives.src_ip, &tmp, HostAddrSz);
1001 sql_cache_insert(prim_ptrs, idata);
1002 }
1003
sql_sum_port_insert(struct primitives_ptrs * prim_ptrs,struct insert_data * idata)1004 void sql_sum_port_insert(struct primitives_ptrs *prim_ptrs, struct insert_data *idata)
1005 {
1006 struct pkt_data *data = prim_ptrs->data;
1007 u_int16_t port;
1008
1009 port = data->primitives.dst_port;
1010 data->primitives.dst_port = 0;
1011 sql_cache_insert(prim_ptrs, idata);
1012 data->primitives.src_port = port;
1013 sql_cache_insert(prim_ptrs, idata);
1014 }
1015
sql_sum_as_insert(struct primitives_ptrs * prim_ptrs,struct insert_data * idata)1016 void sql_sum_as_insert(struct primitives_ptrs *prim_ptrs, struct insert_data *idata)
1017 {
1018 struct pkt_data *data = prim_ptrs->data;
1019 as_t asn;
1020
1021 asn = data->primitives.dst_as;
1022 data->primitives.dst_as = 0;
1023 sql_cache_insert(prim_ptrs, idata);
1024 data->primitives.src_as = asn;
1025 sql_cache_insert(prim_ptrs, idata);
1026 }
1027
1028 #if defined (HAVE_L2)
sql_sum_mac_insert(struct primitives_ptrs * prim_ptrs,struct insert_data * idata)1029 void sql_sum_mac_insert(struct primitives_ptrs *prim_ptrs, struct insert_data *idata)
1030 {
1031 struct pkt_data *data = prim_ptrs->data;
1032 u_char macaddr[ETH_ADDR_LEN];
1033
1034 memcpy(macaddr, &data->primitives.eth_dhost, ETH_ADDR_LEN);
1035 memset(data->primitives.eth_dhost, 0, ETH_ADDR_LEN);
1036 sql_cache_insert(prim_ptrs, idata);
1037 memcpy(&data->primitives.eth_shost, macaddr, ETH_ADDR_LEN);
1038 sql_cache_insert(prim_ptrs, idata);
1039 }
1040 #endif
1041
sql_trigger_exec(char * filename)1042 int sql_trigger_exec(char *filename)
1043 {
1044 char *args[2] = { filename, NULL };
1045 int pid;
1046
1047 switch (pid = vfork()) {
1048 case -1:
1049 return -1;
1050 case 0:
1051 execv(filename, args);
1052 _exit(0);
1053 }
1054
1055 return 0;
1056 }
1057
sql_db_ok(struct DBdesc * db)1058 void sql_db_ok(struct DBdesc *db)
1059 {
1060 db->fail = FALSE;
1061 db->connected = TRUE;
1062 }
1063
sql_db_fail(struct DBdesc * db)1064 void sql_db_fail(struct DBdesc *db)
1065 {
1066 db->fail = TRUE;
1067 db->connected = FALSE;
1068 }
1069
sql_db_errmsg(struct DBdesc * db)1070 void sql_db_errmsg(struct DBdesc *db)
1071 {
1072 if (db->type == BE_TYPE_PRIMARY)
1073 Log(LOG_ERR, "ERROR ( %s/%s ): PRIMARY '%s' backend trouble.\n", config.name, config.type, config.type);
1074 else if (db->type == BE_TYPE_BACKUP)
1075 Log(LOG_ERR, "ERROR ( %s/%s ): BACKUP '%s' backend trouble.\n", config.name, config.type, config.type);
1076
1077 if (db->errmsg) Log(LOG_ERR, "ERROR ( %s/%s ): The SQL server says: %s\n", config.name, config.type, db->errmsg);
1078 }
1079
sql_db_warnmsg(struct DBdesc * db)1080 void sql_db_warnmsg(struct DBdesc *db)
1081 {
1082 if (db->errmsg) Log(LOG_WARNING, "WARN ( %s/%s ): The SQL server says: %s\n", config.name, config.type, db->errmsg);
1083 }
1084
sql_exit_gracefully(int signum)1085 void sql_exit_gracefully(int signum)
1086 {
1087 struct insert_data idata;
1088
1089 signal(SIGINT, SIG_IGN);
1090 signal(SIGHUP, SIG_IGN);
1091
1092 Log(LOG_DEBUG, "( %s/%s ) *** Purging queries queue ***\n", config.name, config.type);
1093 if (config.syslog) closelog();
1094
1095 memset(&idata, 0, sizeof(idata));
1096 idata.num_primitives = glob_num_primitives;
1097 idata.now = time(NULL);
1098 idata.basetime = glob_basetime;
1099 idata.dyn_table = glob_dyn_table;
1100 idata.dyn_table_time_only = glob_dyn_table_time_only;
1101 idata.new_basetime = glob_new_basetime;
1102 idata.timeslot = glob_timeslot;
1103 idata.committed_basetime = glob_committed_basetime;
1104 if (config.sql_backup_host) idata.recover = TRUE;
1105 if (config.sql_locking_style) idata.locks = sql_select_locking_style(config.sql_locking_style);
1106
1107 sql_cache_flush(sql_queries_queue, qq_ptr, &idata, TRUE);
1108
1109 dump_writers_count();
1110 if (dump_writers_get_flags() != CHLD_ALERT) {
1111 if (dump_writers_get_flags() == CHLD_WARNING) sql_db_fail(&p);
1112 (*sqlfunc_cbr.connect)(&p, config.sql_host);
1113 (*sqlfunc_cbr.purge)(sql_queries_queue, qq_ptr, &idata);
1114 (*sqlfunc_cbr.close)(&bed);
1115 }
1116 else Log(LOG_WARNING, "WARN ( %s/%s ): Maximum number of writer processes reached (%d).\n", config.name, config.type, dump_writers_get_active());
1117
1118 if (config.pidfile) remove_pid_file(config.pidfile);
1119
1120 exit_gracefully(0);
1121 }
1122
sql_evaluate_primitives(int primitive)1123 int sql_evaluate_primitives(int primitive)
1124 {
1125 pm_cfgreg_t what_to_count = 0, what_to_count_2 = 0, fakes = 0;
1126 short int assume_custom_table = FALSE;
1127 char *insert_clause_start_ptr = insert_clause + strlen(insert_clause);
1128 char default_delim[] = ",", delim_buf[SRVBUFLEN];
1129
1130 /* SQL tables < v6 multiplex IP addresses and AS numbers on the same field, thus are
1131 unable to use both them for a same direction (ie. src, dst). Tables v6 break such
1132 assumption */
1133 if (((config.what_to_count & (COUNT_SRC_HOST|COUNT_SRC_NET|COUNT_SUM_HOST|COUNT_SUM_NET) &&
1134 config.what_to_count & (COUNT_SRC_AS|COUNT_SUM_AS)) || (config.what_to_count & COUNT_DST_AS
1135 && config.what_to_count & (COUNT_DST_HOST|COUNT_DST_NET))) && config.sql_table_version < 6) {
1136 Log(LOG_ERR, "ERROR ( %s/%s ): SQL tables < v6 are unable to mix IP addresses and AS numbers (ie. src_ip, src_as).\n", config.name, config.type);
1137 exit_gracefully(1);
1138 }
1139
1140 if (config.sql_optimize_clauses) {
1141 what_to_count = config.what_to_count;
1142 what_to_count_2 = config.what_to_count_2;
1143 assume_custom_table = TRUE;
1144 }
1145 else {
1146 /* It is being requested to avoid SQL query optmization;
1147 then we will build an all-true bitmap */
1148 if (config.what_to_count & COUNT_SRC_MAC) what_to_count |= COUNT_SRC_MAC;
1149 else if (config.what_to_count & COUNT_SUM_MAC) what_to_count |= COUNT_SUM_MAC;
1150 else fakes |= FAKE_SRC_MAC;
1151
1152 if (config.what_to_count & COUNT_DST_MAC) what_to_count |= COUNT_DST_MAC;
1153 else fakes |= FAKE_DST_MAC;
1154
1155 if (config.what_to_count & COUNT_SUM_PORT) what_to_count |= COUNT_SUM_PORT;
1156
1157 what_to_count |= COUNT_SRC_PORT|COUNT_DST_PORT|COUNT_TCPFLAGS|COUNT_IP_PROTO|COUNT_CLASS|COUNT_VLAN|COUNT_IP_TOS;
1158
1159 if (config.what_to_count & COUNT_SRC_HOST) what_to_count |= COUNT_SRC_HOST;
1160 else if (config.what_to_count & COUNT_SUM_HOST) what_to_count |= COUNT_SUM_HOST;
1161 else if (config.what_to_count & COUNT_SUM_NET) what_to_count |= COUNT_SUM_NET;
1162 else fakes |= FAKE_SRC_HOST;
1163
1164 if (config.what_to_count & COUNT_SRC_NET) what_to_count |= COUNT_SRC_NET;
1165
1166 if (config.what_to_count & COUNT_DST_HOST) what_to_count |= COUNT_DST_HOST;
1167 else fakes |= FAKE_DST_HOST;
1168
1169 if (config.what_to_count & COUNT_DST_NET) what_to_count |= COUNT_DST_NET;
1170
1171 if (config.what_to_count & COUNT_AS_PATH) what_to_count |= COUNT_AS_PATH;
1172 else fakes |= FAKE_AS_PATH;
1173
1174 if (config.what_to_count & COUNT_SRC_AS_PATH) what_to_count |= COUNT_SRC_AS_PATH;
1175
1176 if (config.what_to_count & COUNT_STD_COMM) what_to_count |= COUNT_STD_COMM;
1177 else if (config.what_to_count & COUNT_EXT_COMM) what_to_count |= COUNT_EXT_COMM;
1178 else fakes |= FAKE_COMMS;
1179
1180 if (config.what_to_count & COUNT_SRC_STD_COMM) what_to_count |= COUNT_SRC_STD_COMM;
1181 else if (config.what_to_count & COUNT_SRC_EXT_COMM) what_to_count |= COUNT_SRC_EXT_COMM;
1182
1183 if (config.what_to_count & COUNT_PEER_SRC_AS) what_to_count |= COUNT_PEER_SRC_AS;
1184 else fakes |= FAKE_PEER_SRC_AS;
1185
1186 if (config.what_to_count & COUNT_PEER_DST_AS) what_to_count |= COUNT_PEER_DST_AS;
1187 else fakes |= FAKE_PEER_DST_AS;
1188
1189 if (config.what_to_count & COUNT_PEER_SRC_IP) what_to_count |= COUNT_PEER_SRC_IP;
1190 else fakes |= FAKE_PEER_SRC_IP;
1191
1192 if (config.what_to_count & COUNT_PEER_DST_IP) what_to_count |= COUNT_PEER_DST_IP;
1193 else fakes |= FAKE_PEER_DST_IP;
1194
1195 what_to_count |= COUNT_LOCAL_PREF|COUNT_MED;
1196
1197 if (config.what_to_count & COUNT_SRC_LOCAL_PREF) what_to_count |= COUNT_SRC_LOCAL_PREF;
1198 if (config.what_to_count & COUNT_SRC_MED) what_to_count |= COUNT_SRC_MED;
1199
1200 if (config.what_to_count_2 & COUNT_SRC_ROA) what_to_count_2 |= COUNT_SRC_ROA;
1201 if (config.what_to_count_2 & COUNT_DST_ROA) what_to_count_2 |= COUNT_DST_ROA;
1202
1203 if (config.sql_table_version < 6) {
1204 if (config.what_to_count & COUNT_SRC_AS) what_to_count |= COUNT_SRC_AS;
1205 else if (config.what_to_count & COUNT_SUM_AS) what_to_count |= COUNT_SUM_AS;
1206 else fakes |= FAKE_SRC_AS;
1207 }
1208 else {
1209 what_to_count |= COUNT_SRC_AS;
1210 if (config.what_to_count & COUNT_SUM_AS) what_to_count |= COUNT_SUM_AS;
1211 }
1212
1213 if (config.sql_table_version < 6) {
1214 if (config.what_to_count & COUNT_DST_AS) what_to_count |= COUNT_DST_AS;
1215 else fakes |= FAKE_DST_AS;
1216 }
1217 else what_to_count |= COUNT_DST_AS;
1218
1219 if (config.sql_table_version < 6) {
1220 if (what_to_count & (COUNT_SRC_AS|COUNT_SUM_AS)) {
1221 if (fakes & FAKE_SRC_HOST) fakes ^= FAKE_SRC_HOST;
1222 }
1223 else {
1224 if (fakes & FAKE_SRC_AS) fakes ^= FAKE_SRC_AS;
1225 }
1226 if (what_to_count & COUNT_DST_AS) {
1227 if (fakes & FAKE_DST_HOST) fakes ^= FAKE_DST_HOST;
1228 }
1229 else {
1230 if (fakes & FAKE_DST_AS) fakes ^= FAKE_DST_AS;
1231 }
1232 }
1233
1234 what_to_count |= COUNT_TAG;
1235
1236 /* aggregation primitives listed below are not part of any default SQL schema; hence
1237 no matter if SQL statements optimization is enabled or not, they have to be passed
1238 on blindly */
1239 if (config.what_to_count & COUNT_TAG2) what_to_count |= COUNT_TAG2;
1240 if (config.what_to_count & COUNT_COS) what_to_count |= COUNT_COS;
1241 if (config.what_to_count & COUNT_ETHERTYPE) what_to_count |= COUNT_ETHERTYPE;
1242 if (config.what_to_count & COUNT_MPLS_VPN_RD) what_to_count |= COUNT_MPLS_VPN_RD;
1243 if (config.what_to_count & COUNT_IN_IFACE) what_to_count |= COUNT_IN_IFACE;
1244 if (config.what_to_count & COUNT_OUT_IFACE) what_to_count |= COUNT_OUT_IFACE;
1245 if (config.what_to_count & COUNT_SRC_NMASK) what_to_count |= COUNT_SRC_NMASK;
1246 if (config.what_to_count & COUNT_DST_NMASK) what_to_count |= COUNT_DST_NMASK;
1247
1248 #if defined (WITH_GEOIP) || defined (WITH_GEOIPV2)
1249 if (config.what_to_count_2 & COUNT_SRC_HOST_COUNTRY) what_to_count_2 |= COUNT_SRC_HOST_COUNTRY;
1250 if (config.what_to_count_2 & COUNT_DST_HOST_COUNTRY) what_to_count_2 |= COUNT_DST_HOST_COUNTRY;
1251 #endif
1252 #if defined (WITH_GEOIPV2)
1253 if (config.what_to_count_2 & COUNT_SRC_HOST_POCODE) what_to_count_2 |= COUNT_SRC_HOST_POCODE;
1254 if (config.what_to_count_2 & COUNT_DST_HOST_POCODE) what_to_count_2 |= COUNT_DST_HOST_POCODE;
1255 if (config.what_to_count_2 & COUNT_SRC_HOST_COORDS) what_to_count_2 |= COUNT_SRC_HOST_COORDS;
1256 if (config.what_to_count_2 & COUNT_DST_HOST_COORDS) what_to_count_2 |= COUNT_DST_HOST_COORDS;
1257 #endif
1258
1259 if (config.what_to_count_2 & COUNT_SAMPLING_RATE) what_to_count_2 |= COUNT_SAMPLING_RATE;
1260
1261 if (config.what_to_count_2 & COUNT_POST_NAT_SRC_HOST) what_to_count_2 |= COUNT_POST_NAT_SRC_HOST;
1262 if (config.what_to_count_2 & COUNT_POST_NAT_DST_HOST) what_to_count_2 |= COUNT_POST_NAT_DST_HOST;
1263 if (config.what_to_count_2 & COUNT_POST_NAT_SRC_PORT) what_to_count_2 |= COUNT_POST_NAT_SRC_PORT;
1264 if (config.what_to_count_2 & COUNT_POST_NAT_DST_PORT) what_to_count_2 |= COUNT_POST_NAT_DST_PORT;
1265 if (config.what_to_count_2 & COUNT_NAT_EVENT) what_to_count_2 |= COUNT_NAT_EVENT;
1266
1267 if (config.what_to_count_2 & COUNT_MPLS_LABEL_TOP) what_to_count_2 |= COUNT_MPLS_LABEL_TOP;
1268 if (config.what_to_count_2 & COUNT_MPLS_LABEL_BOTTOM) what_to_count_2 |= COUNT_MPLS_LABEL_BOTTOM;
1269 if (config.what_to_count_2 & COUNT_MPLS_STACK_DEPTH) what_to_count_2 |= COUNT_MPLS_STACK_DEPTH;
1270
1271 if (config.what_to_count_2 & COUNT_TUNNEL_SRC_MAC) what_to_count_2 |= COUNT_TUNNEL_SRC_MAC;
1272 if (config.what_to_count_2 & COUNT_TUNNEL_DST_MAC) what_to_count_2 |= COUNT_TUNNEL_DST_MAC;
1273 if (config.what_to_count_2 & COUNT_TUNNEL_SRC_HOST) what_to_count_2 |= COUNT_TUNNEL_SRC_HOST;
1274 if (config.what_to_count_2 & COUNT_TUNNEL_DST_HOST) what_to_count_2 |= COUNT_TUNNEL_DST_HOST;
1275 if (config.what_to_count_2 & COUNT_TUNNEL_IP_PROTO) what_to_count_2 |= COUNT_TUNNEL_IP_PROTO;
1276 if (config.what_to_count_2 & COUNT_TUNNEL_IP_TOS) what_to_count_2 |= COUNT_TUNNEL_IP_TOS;
1277 if (config.what_to_count_2 & COUNT_TUNNEL_SRC_PORT) what_to_count_2 |= COUNT_TUNNEL_SRC_PORT;
1278 if (config.what_to_count_2 & COUNT_TUNNEL_DST_PORT) what_to_count_2 |= COUNT_TUNNEL_DST_PORT;
1279
1280 if (config.what_to_count_2 & COUNT_TIMESTAMP_START) what_to_count_2 |= COUNT_TIMESTAMP_START;
1281 if (config.what_to_count_2 & COUNT_TIMESTAMP_END) what_to_count_2 |= COUNT_TIMESTAMP_END;
1282 if (config.what_to_count_2 & COUNT_TIMESTAMP_ARRIVAL) what_to_count_2 |= COUNT_TIMESTAMP_ARRIVAL;
1283
1284 if (config.what_to_count_2 & COUNT_EXPORT_PROTO_SEQNO) what_to_count_2 |= COUNT_EXPORT_PROTO_SEQNO;
1285 if (config.what_to_count_2 & COUNT_EXPORT_PROTO_VERSION) what_to_count_2 |= COUNT_EXPORT_PROTO_VERSION;
1286 if (config.what_to_count_2 & COUNT_EXPORT_PROTO_SYSID) what_to_count_2 |= COUNT_EXPORT_PROTO_SYSID;
1287 if (config.what_to_count_2 & COUNT_LABEL) what_to_count_2 |= COUNT_LABEL;
1288
1289 #if defined (WITH_NDPI)
1290 if (config.what_to_count_2 & COUNT_NDPI_CLASS) what_to_count_2 |= COUNT_NDPI_CLASS;
1291 #endif
1292 }
1293
1294 /* sorting out delimiter */
1295 if (!config.sql_delimiter || !config.sql_use_copy)
1296 snprintf(delim_buf, SRVBUFLEN, "%s ", default_delim);
1297 else
1298 snprintf(delim_buf, SRVBUFLEN, "%s ", config.sql_delimiter);
1299
1300 /* 1st part: arranging pointers to an opaque structure and
1301 composing the static selection (WHERE) string */
1302
1303 #if defined (HAVE_L2)
1304 if (what_to_count & (COUNT_SRC_MAC|COUNT_SUM_MAC)) {
1305 int count_it = FALSE;
1306
1307 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1308 Log(LOG_ERR, "ERROR ( %s/%s ): MAC accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1309 exit_gracefully(1);
1310 }
1311 else count_it = TRUE;
1312
1313 if (count_it) {
1314 if (primitive) {
1315 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1316 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1317 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1318 }
1319 strncat(insert_clause, "mac_src", SPACELEFT(insert_clause));
1320 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1321 strncat(where[primitive].string, "mac_src=\'%s\'", SPACELEFT(where[primitive].string));
1322 values[primitive].type = where[primitive].type = COUNT_INT_SRC_MAC;
1323 values[primitive].handler = where[primitive].handler = count_src_mac_handler;
1324 primitive++;
1325 }
1326 }
1327
1328 if (what_to_count & COUNT_DST_MAC) {
1329 int count_it = FALSE;
1330
1331 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1332 Log(LOG_ERR, "ERROR ( %s/%s ): MAC accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1333 exit_gracefully(1);
1334 }
1335 else count_it = TRUE;
1336
1337 if (count_it) {
1338 if (primitive) {
1339 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1340 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1341 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1342 }
1343 strncat(insert_clause, "mac_dst", SPACELEFT(insert_clause));
1344 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1345 strncat(where[primitive].string, "mac_dst=\'%s\'", SPACELEFT(where[primitive].string));
1346 values[primitive].type = where[primitive].type = COUNT_INT_DST_MAC;
1347 values[primitive].handler = where[primitive].handler = count_dst_mac_handler;
1348 primitive++;
1349 }
1350 }
1351
1352 if (what_to_count & COUNT_VLAN) {
1353 int count_it = FALSE;
1354
1355 if ((config.sql_table_version < 2 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1356 if (config.what_to_count & COUNT_VLAN) {
1357 Log(LOG_ERR, "ERROR ( %s/%s ): VLAN accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1358 exit_gracefully(1);
1359 }
1360 else what_to_count ^= COUNT_VLAN;
1361 }
1362 else count_it = TRUE;
1363
1364 if (count_it) {
1365 if (primitive) {
1366 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1367 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1368 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1369 }
1370 strncat(insert_clause, "vlan", SPACELEFT(insert_clause));
1371 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1372 strncat(where[primitive].string, "vlan=%u", SPACELEFT(where[primitive].string));
1373 values[primitive].type = where[primitive].type = COUNT_INT_VLAN;
1374 values[primitive].handler = where[primitive].handler = count_vlan_handler;
1375 primitive++;
1376 }
1377 }
1378
1379 if (what_to_count & COUNT_COS) {
1380 if (primitive) {
1381 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1382 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1383 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1384 }
1385 strncat(insert_clause, "cos", SPACELEFT(insert_clause));
1386 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1387 strncat(where[primitive].string, "cos=%u", SPACELEFT(where[primitive].string));
1388 values[primitive].type = where[primitive].type = COUNT_INT_COS;
1389 values[primitive].handler = where[primitive].handler = count_cos_handler;
1390 primitive++;
1391 }
1392
1393 if (what_to_count & COUNT_ETHERTYPE) {
1394 if (primitive) {
1395 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1396 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1397 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1398 }
1399 strncat(insert_clause, "etype", SPACELEFT(insert_clause));
1400 strncat(values[primitive].string, "\'%x\'", SPACELEFT(values[primitive].string));
1401 strncat(where[primitive].string, "etype=\'%x\'", SPACELEFT(where[primitive].string));
1402 values[primitive].type = where[primitive].type = COUNT_INT_ETHERTYPE;
1403 values[primitive].handler = where[primitive].handler = count_etype_handler;
1404 primitive++;
1405 }
1406 #endif
1407
1408 if (what_to_count & (COUNT_SRC_HOST|COUNT_SUM_HOST)) {
1409 int count_it = FALSE;
1410
1411 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1412 Log(LOG_ERR, "ERROR ( %s/%s ): IP host accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1413 exit_gracefully(1);
1414 }
1415 else count_it = TRUE;
1416
1417 if (count_it) {
1418 if (primitive) {
1419 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1420 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1421 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1422 }
1423 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
1424 strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
1425 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
1426 strncat(where[primitive].string, "ip_src=%s(\'%s\')", SPACELEFT(where[primitive].string));
1427 values[primitive].type = where[primitive].type = COUNT_INT_SRC_HOST;
1428 values[primitive].handler = where[primitive].handler = count_src_host_aton_handler;
1429 primitive++;
1430 }
1431 else {
1432 strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
1433 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1434 strncat(where[primitive].string, "ip_src=\'%s\'", SPACELEFT(where[primitive].string));
1435 values[primitive].type = where[primitive].type = COUNT_INT_SRC_HOST;
1436 values[primitive].handler = where[primitive].handler = count_src_host_handler;
1437 primitive++;
1438 }
1439 }
1440 }
1441
1442 if (what_to_count & (COUNT_SRC_NET|COUNT_SUM_NET)) {
1443 if (primitive) {
1444 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1445 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1446 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1447 }
1448 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
1449 strncat(insert_clause, "net_src", SPACELEFT(insert_clause));
1450 strncat(where[primitive].string, "net_src=%s(\'%s\')", SPACELEFT(where[primitive].string));
1451 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
1452 values[primitive].type = where[primitive].type = COUNT_INT_SRC_NET;
1453 values[primitive].handler = where[primitive].handler = count_src_net_aton_handler;
1454 primitive++;
1455 }
1456 else {
1457 strncat(insert_clause, "net_src", SPACELEFT(insert_clause));
1458 strncat(where[primitive].string, "net_src=\'%s\'", SPACELEFT(where[primitive].string));
1459 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1460 values[primitive].type = where[primitive].type = COUNT_INT_SRC_NET;
1461 values[primitive].handler = where[primitive].handler = count_src_net_handler;
1462 primitive++;
1463 }
1464 }
1465
1466 if (what_to_count & COUNT_DST_HOST) {
1467 int count_it = FALSE;
1468
1469 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1470 Log(LOG_ERR, "ERROR ( %s/%s ): IP host accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1471 exit_gracefully(1);
1472 }
1473 else count_it = TRUE;
1474
1475 if (count_it) {
1476 if (primitive) {
1477 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1478 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1479 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1480 }
1481 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
1482 strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
1483 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
1484 strncat(where[primitive].string, "ip_dst=%s(\'%s\')", SPACELEFT(where[primitive].string));
1485 values[primitive].type = where[primitive].type = COUNT_INT_DST_HOST;
1486 values[primitive].handler = where[primitive].handler = count_dst_host_aton_handler;
1487 primitive++;
1488 }
1489 else {
1490 strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
1491 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1492 strncat(where[primitive].string, "ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
1493 values[primitive].type = where[primitive].type = COUNT_INT_DST_HOST;
1494 values[primitive].handler = where[primitive].handler = count_dst_host_handler;
1495 primitive++;
1496 }
1497 }
1498 }
1499
1500 if (what_to_count & COUNT_DST_NET) {
1501 if (primitive) {
1502 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1503 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1504 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1505 }
1506 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
1507 strncat(insert_clause, "net_dst", SPACELEFT(insert_clause));
1508 strncat(where[primitive].string, "net_dst=%s(\'%s\')", SPACELEFT(where[primitive].string));
1509 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
1510 values[primitive].type = where[primitive].type = COUNT_INT_DST_NET;
1511 values[primitive].handler = where[primitive].handler = count_dst_net_aton_handler;
1512 primitive++;
1513 }
1514 else {
1515 strncat(insert_clause, "net_dst", SPACELEFT(insert_clause));
1516 strncat(where[primitive].string, "net_dst=\'%s\'", SPACELEFT(where[primitive].string));
1517 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1518 values[primitive].type = where[primitive].type = COUNT_INT_DST_NET;
1519 values[primitive].handler = where[primitive].handler = count_dst_net_handler;
1520 primitive++;
1521 }
1522 }
1523
1524 if (what_to_count & (COUNT_SRC_AS|COUNT_SUM_AS)) {
1525 if (primitive) {
1526 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1527 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1528 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1529 }
1530
1531 if (config.sql_table_version >= 6) {
1532 strncat(insert_clause, "as_src", SPACELEFT(insert_clause));
1533 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1534 strncat(where[primitive].string, "as_src=%u", SPACELEFT(where[primitive].string));
1535 }
1536 else {
1537 strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
1538 if (!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3") ||
1539 (!strcmp(config.type, "pgsql") && !strcmp(config.sql_data, "unified"))) {
1540 strncat(values[primitive].string, "\'%u\'", SPACELEFT(values[primitive].string));
1541 strncat(where[primitive].string, "ip_src=\'%u\'", SPACELEFT(where[primitive].string));
1542 }
1543 else {
1544 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1545 strncat(where[primitive].string, "ip_src=%u", SPACELEFT(where[primitive].string));
1546 }
1547 }
1548 values[primitive].type = where[primitive].type = COUNT_INT_SRC_AS;
1549 values[primitive].handler = where[primitive].handler = count_src_as_handler;
1550 primitive++;
1551 }
1552
1553 if (what_to_count & COUNT_IN_IFACE) {
1554 if (primitive) {
1555 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1556 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1557 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1558 }
1559 strncat(insert_clause, "iface_in", SPACELEFT(insert_clause));
1560 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1561 strncat(where[primitive].string, "iface_in=%u", SPACELEFT(where[primitive].string));
1562 values[primitive].type = where[primitive].type = COUNT_INT_IN_IFACE;
1563 values[primitive].handler = where[primitive].handler = count_in_iface_handler;
1564 primitive++;
1565 }
1566
1567 if (what_to_count & COUNT_OUT_IFACE) {
1568 if (primitive) {
1569 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1570 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1571 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1572 }
1573 strncat(insert_clause, "iface_out", SPACELEFT(insert_clause));
1574 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1575 strncat(where[primitive].string, "iface_out=%u", SPACELEFT(where[primitive].string));
1576 values[primitive].type = where[primitive].type = COUNT_INT_OUT_IFACE;
1577 values[primitive].handler = where[primitive].handler = count_out_iface_handler;
1578 primitive++;
1579 }
1580
1581 if (what_to_count & COUNT_SRC_NMASK) {
1582 if (primitive) {
1583 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1584 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1585 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1586 }
1587 strncat(insert_clause, "mask_src", SPACELEFT(insert_clause));
1588 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1589 strncat(where[primitive].string, "mask_src=%u", SPACELEFT(where[primitive].string));
1590 values[primitive].type = where[primitive].type = COUNT_INT_SRC_NMASK;
1591 values[primitive].handler = where[primitive].handler = count_src_nmask_handler;
1592 primitive++;
1593 }
1594
1595 if (what_to_count & COUNT_DST_NMASK) {
1596 if (primitive) {
1597 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1598 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1599 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1600 }
1601 strncat(insert_clause, "mask_dst", SPACELEFT(insert_clause));
1602 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1603 strncat(where[primitive].string, "mask_dst=%u", SPACELEFT(where[primitive].string));
1604 values[primitive].type = where[primitive].type = COUNT_INT_DST_NMASK;
1605 values[primitive].handler = where[primitive].handler = count_dst_nmask_handler;
1606 primitive++;
1607 }
1608
1609 if (what_to_count & COUNT_DST_AS) {
1610 if (primitive) {
1611 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1612 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1613 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1614 }
1615
1616 if (config.sql_table_version >= 6) {
1617 strncat(insert_clause, "as_dst", SPACELEFT(insert_clause));
1618 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1619 strncat(where[primitive].string, "as_dst=%u", SPACELEFT(where[primitive].string));
1620 }
1621 else {
1622 strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
1623 if (!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3") ||
1624 (!strcmp(config.type, "pgsql") && !strcmp(config.sql_data, "unified"))) {
1625 strncat(values[primitive].string, "\'%u\'", SPACELEFT(values[primitive].string));
1626 strncat(where[primitive].string, "ip_dst=\'%u\'", SPACELEFT(where[primitive].string));
1627 }
1628 else {
1629 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1630 strncat(where[primitive].string, "ip_dst=%u", SPACELEFT(where[primitive].string));
1631 }
1632 }
1633 values[primitive].type = where[primitive].type = COUNT_INT_DST_AS;
1634 values[primitive].handler = where[primitive].handler = count_dst_as_handler;
1635 primitive++;
1636 }
1637
1638 if (what_to_count & COUNT_STD_COMM) {
1639 int count_it = FALSE;
1640
1641 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1642 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1643 exit_gracefully(1);
1644 }
1645 else count_it = TRUE;
1646
1647 if (count_it) {
1648 if (primitive) {
1649 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1650 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1651 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1652 }
1653 strncat(insert_clause, "comms", SPACELEFT(insert_clause));
1654 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1655 strncat(where[primitive].string, "comms=\'%s\'", SPACELEFT(where[primitive].string));
1656 values[primitive].type = where[primitive].type = COUNT_INT_STD_COMM;
1657 values[primitive].handler = where[primitive].handler = count_std_comm_handler;
1658 primitive++;
1659 }
1660 }
1661
1662 if (what_to_count & COUNT_EXT_COMM) {
1663 int count_it = FALSE;
1664
1665 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1666 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1667 exit_gracefully(1);
1668 }
1669 else count_it = TRUE;
1670
1671 if (count_it) {
1672 if (primitive) {
1673 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1674 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1675 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1676 }
1677
1678 strncat(insert_clause, "ecomms", SPACELEFT(insert_clause));
1679 strncat(where[primitive].string, "ecomms=\'%s\'", SPACELEFT(where[primitive].string));
1680
1681 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1682 values[primitive].type = where[primitive].type = COUNT_INT_EXT_COMM;
1683 values[primitive].handler = where[primitive].handler = count_ext_comm_handler;
1684 primitive++;
1685 }
1686 }
1687
1688 if (what_to_count_2 & COUNT_LRG_COMM) {
1689 if (primitive) {
1690 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1691 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1692 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1693 }
1694
1695 strncat(insert_clause, "lcomms", SPACELEFT(insert_clause));
1696 strncat(where[primitive].string, "lcomms=\'%s\'", SPACELEFT(where[primitive].string));
1697
1698 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1699 values[primitive].type = where[primitive].type = COUNT_INT_LRG_COMM;
1700 values[primitive].handler = where[primitive].handler = count_lrg_comm_handler;
1701 primitive++;
1702 }
1703
1704 if (what_to_count & COUNT_SRC_STD_COMM) {
1705 if (primitive) {
1706 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1707 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1708 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1709 }
1710 strncat(insert_clause, "comms_src", SPACELEFT(insert_clause));
1711 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1712 strncat(where[primitive].string, "comms_src=\'%s\'", SPACELEFT(where[primitive].string));
1713 values[primitive].type = where[primitive].type = COUNT_INT_SRC_STD_COMM;
1714 values[primitive].handler = where[primitive].handler = count_src_std_comm_handler;
1715 primitive++;
1716 }
1717
1718 if (what_to_count & COUNT_SRC_EXT_COMM) {
1719 if (primitive) {
1720 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1721 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1722 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1723 }
1724 strncat(insert_clause, "ecomms_src", SPACELEFT(insert_clause));
1725 strncat(where[primitive].string, "ecomms_src=\'%s\'", SPACELEFT(where[primitive].string));
1726 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1727 values[primitive].type = where[primitive].type = COUNT_INT_SRC_EXT_COMM;
1728 values[primitive].handler = where[primitive].handler = count_src_ext_comm_handler;
1729 primitive++;
1730 }
1731
1732 if (what_to_count_2 & COUNT_SRC_LRG_COMM) {
1733 if (primitive) {
1734 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1735 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1736 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1737 }
1738
1739 strncat(insert_clause, "lcomms_src", SPACELEFT(insert_clause));
1740 strncat(where[primitive].string, "lcomms_src=\'%s\'", SPACELEFT(where[primitive].string));
1741
1742 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1743 values[primitive].type = where[primitive].type = COUNT_INT_SRC_LRG_COMM;
1744 values[primitive].handler = where[primitive].handler = count_src_lrg_comm_handler;
1745 primitive++;
1746 }
1747
1748 if (what_to_count & COUNT_AS_PATH) {
1749 int count_it = FALSE;
1750
1751 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1752 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1753 exit_gracefully(1);
1754 }
1755 else count_it = TRUE;
1756
1757 if (count_it) {
1758 if (primitive) {
1759 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1760 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1761 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1762 }
1763 strncat(insert_clause, "as_path", SPACELEFT(insert_clause));
1764 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1765 strncat(where[primitive].string, "as_path=\'%s\'", SPACELEFT(where[primitive].string));
1766 values[primitive].type = where[primitive].type = COUNT_INT_AS_PATH;
1767 values[primitive].handler = where[primitive].handler = count_as_path_handler;
1768 primitive++;
1769 }
1770 }
1771
1772 if (what_to_count & COUNT_SRC_AS_PATH) {
1773 if (primitive) {
1774 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1775 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1776 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1777 }
1778 strncat(insert_clause, "as_path_src", SPACELEFT(insert_clause));
1779 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1780 strncat(where[primitive].string, "as_path_src=\'%s\'", SPACELEFT(where[primitive].string));
1781 values[primitive].type = where[primitive].type = COUNT_INT_SRC_AS_PATH;
1782 values[primitive].handler = where[primitive].handler = count_src_as_path_handler;
1783 primitive++;
1784 }
1785
1786 if (what_to_count & COUNT_LOCAL_PREF) {
1787 int count_it = FALSE;
1788
1789 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1790 if (config.what_to_count & COUNT_LOCAL_PREF) {
1791 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1792 exit_gracefully(1);
1793 }
1794 else what_to_count ^= COUNT_LOCAL_PREF;
1795 }
1796 else count_it = TRUE;
1797
1798 if (count_it) {
1799 if (primitive) {
1800 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1801 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1802 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1803 }
1804 strncat(insert_clause, "local_pref", SPACELEFT(insert_clause));
1805 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1806 strncat(where[primitive].string, "local_pref=%u", SPACELEFT(where[primitive].string));
1807 values[primitive].type = where[primitive].type = COUNT_INT_LOCAL_PREF;
1808 values[primitive].handler = where[primitive].handler = count_local_pref_handler;
1809 primitive++;
1810 }
1811 }
1812
1813 if (what_to_count & COUNT_SRC_LOCAL_PREF) {
1814 if (primitive) {
1815 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1816 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1817 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1818 }
1819 strncat(insert_clause, "local_pref_src", SPACELEFT(insert_clause));
1820 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1821 strncat(where[primitive].string, "local_pref_src=%u", SPACELEFT(where[primitive].string));
1822 values[primitive].type = where[primitive].type = COUNT_INT_SRC_LOCAL_PREF;
1823 values[primitive].handler = where[primitive].handler = count_src_local_pref_handler;
1824 primitive++;
1825 }
1826
1827 if (what_to_count & COUNT_MED) {
1828 int count_it = FALSE;
1829
1830 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1831 if (config.what_to_count & COUNT_MED) {
1832 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1833 exit_gracefully(1);
1834 }
1835 else what_to_count ^= COUNT_MED;
1836 }
1837 else count_it = TRUE;
1838
1839 if (count_it) {
1840 if (primitive) {
1841 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1842 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1843 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1844 }
1845 strncat(insert_clause, "med", SPACELEFT(insert_clause));
1846 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1847 strncat(where[primitive].string, "med=%u", SPACELEFT(where[primitive].string));
1848 values[primitive].type = where[primitive].type = COUNT_INT_MED;
1849 values[primitive].handler = where[primitive].handler = count_med_handler;
1850 primitive++;
1851 }
1852 }
1853
1854 if (what_to_count & COUNT_SRC_MED) {
1855 if (primitive) {
1856 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1857 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1858 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1859 }
1860 strncat(insert_clause, "med_src", SPACELEFT(insert_clause));
1861 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1862 strncat(where[primitive].string, "med_src=%u", SPACELEFT(where[primitive].string));
1863 values[primitive].type = where[primitive].type = COUNT_INT_SRC_MED;
1864 values[primitive].handler = where[primitive].handler = count_src_med_handler;
1865 primitive++;
1866 }
1867
1868 if (what_to_count_2 & COUNT_SRC_ROA) {
1869 if (primitive) {
1870 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1871 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1872 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1873 }
1874 strncat(insert_clause, "roa_src", SPACELEFT(insert_clause));
1875 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
1876 strncat(where[primitive].string, "roa_src=%s", SPACELEFT(where[primitive].string));
1877 values[primitive].type = where[primitive].type = COUNT_INT_SRC_ROA;
1878 values[primitive].handler = where[primitive].handler = count_src_roa_handler;
1879 primitive++;
1880 }
1881
1882 if (what_to_count_2 & COUNT_DST_ROA) {
1883 if (primitive) {
1884 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1885 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1886 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1887 }
1888 strncat(insert_clause, "roa_dst", SPACELEFT(insert_clause));
1889 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
1890 strncat(where[primitive].string, "roa_dst=%s", SPACELEFT(where[primitive].string));
1891 values[primitive].type = where[primitive].type = COUNT_INT_DST_ROA;
1892 values[primitive].handler = where[primitive].handler = count_dst_roa_handler;
1893 primitive++;
1894 }
1895
1896 if (what_to_count & COUNT_MPLS_VPN_RD) {
1897 if (primitive) {
1898 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1899 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1900 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1901 }
1902 strncat(insert_clause, "mpls_vpn_rd", SPACELEFT(insert_clause));
1903 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
1904 strncat(where[primitive].string, "mpls_vpn_rd=\'%s\'", SPACELEFT(where[primitive].string));
1905 values[primitive].type = where[primitive].type = COUNT_INT_MPLS_VPN_RD;
1906 values[primitive].handler = where[primitive].handler = count_mpls_vpn_rd_handler;
1907 primitive++;
1908 }
1909
1910 if (what_to_count_2 & COUNT_MPLS_PW_ID) {
1911 if (primitive) {
1912 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1913 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1914 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1915 }
1916 strncat(insert_clause, "mpls_pw_id", SPACELEFT(insert_clause));
1917 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1918 strncat(where[primitive].string, "mpls_pw_id=%u", SPACELEFT(where[primitive].string));
1919 values[primitive].type = where[primitive].type = COUNT_INT_MPLS_PW_ID;
1920 values[primitive].handler = where[primitive].handler = count_mpls_pw_id_handler;
1921 primitive++;
1922 }
1923
1924 if (what_to_count & COUNT_PEER_SRC_AS) {
1925 int count_it = FALSE;
1926
1927 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1928 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1929 exit_gracefully(1);
1930 }
1931 else count_it = TRUE;
1932
1933 if (count_it) {
1934 if (primitive) {
1935 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1936 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1937 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1938 }
1939
1940 strncat(insert_clause, "peer_as_src", SPACELEFT(insert_clause));
1941 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1942 strncat(where[primitive].string, "peer_as_src=%u", SPACELEFT(where[primitive].string));
1943 values[primitive].type = where[primitive].type = COUNT_INT_PEER_SRC_AS;
1944 values[primitive].handler = where[primitive].handler = count_peer_src_as_handler;
1945 primitive++;
1946 }
1947 }
1948
1949 if (what_to_count & COUNT_PEER_DST_AS) {
1950 int count_it = FALSE;
1951
1952 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1953 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1954 exit_gracefully(1);
1955 }
1956 else count_it = TRUE;
1957
1958 if (count_it) {
1959 if (primitive) {
1960 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1961 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1962 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1963 }
1964
1965 strncat(insert_clause, "peer_as_dst", SPACELEFT(insert_clause));
1966 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
1967 strncat(where[primitive].string, "peer_as_dst=%u", SPACELEFT(where[primitive].string));
1968 values[primitive].type = where[primitive].type = COUNT_INT_PEER_DST_AS;
1969 values[primitive].handler = where[primitive].handler = count_peer_dst_as_handler;
1970 primitive++;
1971 }
1972 }
1973
1974 if (what_to_count & COUNT_PEER_SRC_IP) {
1975 int count_it = FALSE;
1976
1977 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
1978 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
1979 exit_gracefully(1);
1980 }
1981 else count_it = TRUE;
1982
1983 if (count_it) {
1984 if (primitive) {
1985 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
1986 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
1987 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
1988 }
1989 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
1990 strncat(insert_clause, "peer_ip_src", SPACELEFT(insert_clause));
1991 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
1992 strncat(where[primitive].string, "peer_ip_src=%s(\'%s\')", SPACELEFT(where[primitive].string));
1993 values[primitive].type = where[primitive].type = COUNT_INT_PEER_SRC_IP;
1994 values[primitive].handler = where[primitive].handler = count_peer_src_ip_aton_handler;
1995 primitive++;
1996 }
1997 else {
1998 strncat(insert_clause, "peer_ip_src", SPACELEFT(insert_clause));
1999 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2000 strncat(where[primitive].string, "peer_ip_src=\'%s\'", SPACELEFT(where[primitive].string));
2001 values[primitive].type = where[primitive].type = COUNT_INT_PEER_SRC_IP;
2002 values[primitive].handler = where[primitive].handler = count_peer_src_ip_handler;
2003 primitive++;
2004 }
2005 }
2006 }
2007
2008 if (what_to_count & COUNT_PEER_DST_IP) {
2009 int count_it = FALSE;
2010
2011 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
2012 Log(LOG_ERR, "ERROR ( %s/%s ): BGP accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
2013 exit_gracefully(1);
2014 }
2015 else count_it = TRUE;
2016
2017 if (count_it) {
2018 if (primitive) {
2019 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2020 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2021 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2022 }
2023 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
2024 strncat(insert_clause, "peer_ip_dst", SPACELEFT(insert_clause));
2025 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
2026 strncat(where[primitive].string, "peer_ip_dst=%s(\'%s\')", SPACELEFT(where[primitive].string));
2027 values[primitive].type = where[primitive].type = COUNT_INT_PEER_DST_IP;
2028 values[primitive].handler = where[primitive].handler = count_peer_dst_ip_aton_handler;
2029 primitive++;
2030 }
2031 else {
2032 strncat(insert_clause, "peer_ip_dst", SPACELEFT(insert_clause));
2033 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2034 strncat(where[primitive].string, "peer_ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
2035 values[primitive].type = where[primitive].type = COUNT_INT_PEER_DST_IP;
2036 values[primitive].handler = where[primitive].handler = count_peer_dst_ip_handler;
2037 primitive++;
2038 }
2039 }
2040 }
2041
2042 if (what_to_count & (COUNT_SRC_PORT|COUNT_SUM_PORT)) {
2043 int count_it = FALSE;
2044
2045 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
2046 if (config.what_to_count & (COUNT_SRC_PORT|COUNT_SUM_PORT)) {
2047 Log(LOG_ERR, "ERROR ( %s/%s ): TCP/UDP port accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
2048 exit_gracefully(1);
2049 }
2050 else {
2051 if (what_to_count & COUNT_SRC_PORT) what_to_count ^= COUNT_SRC_PORT;
2052 if (what_to_count & COUNT_SUM_PORT) what_to_count ^= COUNT_SUM_PORT;
2053 }
2054 }
2055 else count_it = TRUE;
2056
2057 if (count_it) {
2058 if (primitive) {
2059 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2060 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2061 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2062 }
2063 if ((!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3")) && (config.sql_table_version < 8 ||
2064 (config.sql_table_version >= SQL_TABLE_VERSION_BGP && config.sql_table_version < SQL_TABLE_VERSION_BGP+8))) {
2065 strncat(insert_clause, "src_port", SPACELEFT(insert_clause));
2066 strncat(where[primitive].string, "src_port=%u", SPACELEFT(where[primitive].string));
2067 }
2068 else {
2069 strncat(insert_clause, "port_src", SPACELEFT(insert_clause));
2070 strncat(where[primitive].string, "port_src=%u", SPACELEFT(where[primitive].string));
2071 }
2072 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2073 values[primitive].type = where[primitive].type = COUNT_INT_SRC_PORT;
2074 values[primitive].handler = where[primitive].handler = count_src_port_handler;
2075 primitive++;
2076 }
2077 }
2078
2079 if (what_to_count & COUNT_DST_PORT) {
2080 int count_it = FALSE;
2081
2082 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
2083 if (config.what_to_count & COUNT_DST_PORT) {
2084 Log(LOG_ERR, "ERROR ( %s/%s ): TCP/UDP port accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
2085 exit_gracefully(1);
2086 }
2087 else what_to_count ^= COUNT_DST_PORT;
2088 }
2089 else count_it = TRUE;
2090
2091 if (count_it) {
2092 if (primitive) {
2093 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2094 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2095 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2096 }
2097 if ((!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3")) && (config.sql_table_version < 8 ||
2098 (config.sql_table_version >= SQL_TABLE_VERSION_BGP && config.sql_table_version < SQL_TABLE_VERSION_BGP+8))) {
2099 strncat(insert_clause, "dst_port", SPACELEFT(insert_clause));
2100 strncat(where[primitive].string, "dst_port=%u", SPACELEFT(where[primitive].string));
2101 }
2102 else {
2103 strncat(insert_clause, "port_dst", SPACELEFT(insert_clause));
2104 strncat(where[primitive].string, "port_dst=%u", SPACELEFT(where[primitive].string));
2105 }
2106 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2107 values[primitive].type = where[primitive].type = COUNT_INT_DST_PORT;
2108 values[primitive].handler = where[primitive].handler = count_dst_port_handler;
2109 primitive++;
2110 }
2111 }
2112
2113 if (what_to_count & COUNT_TCPFLAGS) {
2114 int count_it = FALSE;
2115
2116 if ((config.sql_table_version < 7 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
2117 if (config.what_to_count & COUNT_TCPFLAGS) {
2118 Log(LOG_ERR, "ERROR ( %s/%s ): TCP flags accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
2119 exit_gracefully(1);
2120 }
2121 else what_to_count ^= COUNT_TCPFLAGS;
2122 }
2123 else count_it = TRUE;
2124
2125 if (count_it) {
2126 if (primitive) {
2127 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2128 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2129 }
2130 strncat(insert_clause, "tcp_flags", SPACELEFT(insert_clause));
2131 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2132 values[primitive].type = where[primitive].type = COUNT_INT_TCPFLAGS;
2133 values[primitive].handler = where[primitive].handler = count_tcpflags_handler;
2134 primitive++;
2135 }
2136 }
2137
2138 if (what_to_count & COUNT_IP_TOS) {
2139 int count_it = FALSE;
2140
2141 if ((config.sql_table_version < 3 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
2142 if (config.what_to_count & COUNT_IP_TOS) {
2143 Log(LOG_ERR, "ERROR ( %s/%s ): IP ToS accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
2144 exit_gracefully(1);
2145 }
2146 else what_to_count ^= COUNT_IP_TOS;
2147 }
2148 else count_it = TRUE;
2149
2150 if (count_it) {
2151 if (primitive) {
2152 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2153 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2154 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2155 }
2156 strncat(insert_clause, "tos", SPACELEFT(insert_clause));
2157 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2158 strncat(where[primitive].string, "tos=%u", SPACELEFT(where[primitive].string));
2159 values[primitive].type = where[primitive].type = COUNT_INT_IP_TOS;
2160 values[primitive].handler = where[primitive].handler = count_ip_tos_handler;
2161 primitive++;
2162 }
2163 }
2164
2165 if (what_to_count & COUNT_IP_PROTO) {
2166 int count_it = FALSE;
2167
2168 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
2169 if (config.what_to_count & COUNT_IP_PROTO) {
2170 Log(LOG_ERR, "ERROR ( %s/%s ): IP proto accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
2171 exit_gracefully(1);
2172 }
2173 else what_to_count ^= COUNT_IP_PROTO;
2174 }
2175 else count_it = TRUE;
2176
2177 if (count_it) {
2178 if (primitive) {
2179 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2180 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2181 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2182 }
2183 strncat(insert_clause, "ip_proto", SPACELEFT(insert_clause));
2184 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && !config.num_protos) {
2185 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2186 strncat(where[primitive].string, "ip_proto=\'%s\'", SPACELEFT(where[primitive].string));
2187 values[primitive].handler = where[primitive].handler = MY_count_ip_proto_handler;
2188 }
2189 else {
2190 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2191 strncat(where[primitive].string, "ip_proto=%u", SPACELEFT(where[primitive].string));
2192 values[primitive].handler = where[primitive].handler = PG_count_ip_proto_handler;
2193 }
2194 values[primitive].type = where[primitive].type = COUNT_INT_IP_PROTO;
2195 primitive++;
2196 }
2197 }
2198
2199 #if defined (WITH_GEOIP) || defined (WITH_GEOIPV2)
2200 if (what_to_count_2 & COUNT_SRC_HOST_COUNTRY) {
2201 if (primitive) {
2202 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2203 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2204 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2205 }
2206 strncat(insert_clause, "country_ip_src", SPACELEFT(insert_clause));
2207 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2208 strncat(where[primitive].string, "country_ip_src=\'%s\'", SPACELEFT(where[primitive].string));
2209 values[primitive].type = where[primitive].type = COUNT_INT_SRC_HOST_COUNTRY;
2210 values[primitive].handler = where[primitive].handler = count_src_host_country_handler;
2211 primitive++;
2212 }
2213
2214 if (what_to_count_2 & COUNT_DST_HOST_COUNTRY) {
2215 if (primitive) {
2216 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2217 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2218 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2219 }
2220 strncat(insert_clause, "country_ip_dst", SPACELEFT(insert_clause));
2221 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2222 strncat(where[primitive].string, "country_ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
2223 values[primitive].type = where[primitive].type = COUNT_INT_DST_HOST_COUNTRY;
2224 values[primitive].handler = where[primitive].handler = count_dst_host_country_handler;
2225 primitive++;
2226 }
2227 #endif
2228
2229 #if defined (WITH_GEOIPV2)
2230 if (what_to_count_2 & COUNT_SRC_HOST_POCODE) {
2231 if (primitive) {
2232 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2233 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2234 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2235 }
2236 strncat(insert_clause, "pocode_ip_src", SPACELEFT(insert_clause));
2237 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2238 strncat(where[primitive].string, "pocode_ip_src=\'%s\'", SPACELEFT(where[primitive].string));
2239 values[primitive].type = where[primitive].type = COUNT_INT_SRC_HOST_POCODE;
2240 values[primitive].handler = where[primitive].handler = count_src_host_pocode_handler;
2241 primitive++;
2242 }
2243
2244 if (what_to_count_2 & COUNT_DST_HOST_POCODE) {
2245 if (primitive) {
2246 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2247 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2248 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2249 }
2250 strncat(insert_clause, "pocode_ip_dst", SPACELEFT(insert_clause));
2251 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2252 strncat(where[primitive].string, "pocode_ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
2253 values[primitive].type = where[primitive].type = COUNT_INT_DST_HOST_POCODE;
2254 values[primitive].handler = where[primitive].handler = count_dst_host_pocode_handler;
2255 primitive++;
2256 }
2257
2258 if (what_to_count_2 & COUNT_SRC_HOST_COORDS) {
2259 if (primitive) {
2260 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2261 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2262 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2263 }
2264 strncat(insert_clause, "lat_ip_src", SPACELEFT(insert_clause));
2265 strncat(values[primitive].string, "\'%f\'", SPACELEFT(values[primitive].string));
2266 strncat(where[primitive].string, "lat_ip_src=\'%f\'", SPACELEFT(where[primitive].string));
2267
2268 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2269 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2270 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2271
2272 strncat(insert_clause, "lon_ip_src", SPACELEFT(insert_clause));
2273 strncat(values[primitive].string, "\'%f\'", SPACELEFT(values[primitive].string));
2274 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2275 strncat(where[primitive].string, "lon_ip_src=\'%f\'", SPACELEFT(where[primitive].string));
2276 values[primitive].type = where[primitive].type = COUNT_INT_SRC_HOST_COORDS;
2277 values[primitive].handler = where[primitive].handler = count_src_host_coords_handler;
2278 primitive++;
2279 }
2280
2281 if (what_to_count_2 & COUNT_DST_HOST_COORDS) {
2282 if (primitive) {
2283 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2284 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2285 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2286 }
2287 strncat(insert_clause, "lat_ip_dst", SPACELEFT(insert_clause));
2288 strncat(values[primitive].string, "\'%f\'", SPACELEFT(values[primitive].string));
2289 strncat(where[primitive].string, "lat_ip_dst=\'%f\'", SPACELEFT(where[primitive].string));
2290
2291 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2292 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2293 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2294
2295 strncat(insert_clause, "lon_ip_dst", SPACELEFT(insert_clause));
2296 strncat(values[primitive].string, "\'%f\'", SPACELEFT(values[primitive].string));
2297 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2298 strncat(where[primitive].string, "lon_ip_dst=\'%f\'", SPACELEFT(where[primitive].string));
2299 values[primitive].type = where[primitive].type = COUNT_INT_DST_HOST_COORDS;
2300 values[primitive].handler = where[primitive].handler = count_dst_host_coords_handler;
2301 primitive++;
2302 }
2303 #endif
2304
2305 if (what_to_count_2 & COUNT_SAMPLING_RATE) {
2306 if (primitive) {
2307 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2308 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2309 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2310 }
2311 strncat(insert_clause, "sampling_rate", SPACELEFT(insert_clause));
2312 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2313 strncat(where[primitive].string, "sampling_rate=%u", SPACELEFT(where[primitive].string));
2314 values[primitive].type = where[primitive].type = COUNT_INT_SAMPLING_RATE;
2315 values[primitive].handler = where[primitive].handler = count_sampling_rate_handler;
2316 primitive++;
2317 }
2318
2319 if (what_to_count_2 & COUNT_SAMPLING_DIRECTION) {
2320 if (primitive) {
2321 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2322 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2323 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2324 }
2325 strncat(insert_clause, "sampling_direction", SPACELEFT(insert_clause));
2326 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2327 strncat(where[primitive].string, "sampling_direction=\'%s\'", SPACELEFT(where[primitive].string));
2328 values[primitive].type = where[primitive].type = COUNT_INT_SAMPLING_DIRECTION;
2329 values[primitive].handler = where[primitive].handler = count_sampling_direction_handler;
2330 primitive++;
2331 }
2332
2333 if (what_to_count_2 & COUNT_POST_NAT_SRC_HOST) {
2334 if (primitive) {
2335 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2336 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2337 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2338 }
2339 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
2340 strncat(insert_clause, "post_nat_ip_src", SPACELEFT(insert_clause));
2341 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
2342 strncat(where[primitive].string, "post_nat_ip_src=%s(\'%s\')", SPACELEFT(where[primitive].string));
2343 values[primitive].type = where[primitive].type = COUNT_INT_POST_NAT_SRC_HOST;
2344 values[primitive].handler = where[primitive].handler = count_post_nat_src_ip_aton_handler;
2345 primitive++;
2346 }
2347 else {
2348 strncat(insert_clause, "post_nat_ip_src", SPACELEFT(insert_clause));
2349 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2350 strncat(where[primitive].string, "post_nat_ip_src=\'%s\'", SPACELEFT(where[primitive].string));
2351 values[primitive].type = where[primitive].type = COUNT_INT_POST_NAT_SRC_HOST;
2352 values[primitive].handler = where[primitive].handler = count_post_nat_src_ip_handler;
2353 primitive++;
2354 }
2355 }
2356
2357 if (what_to_count_2 & COUNT_POST_NAT_DST_HOST) {
2358 if (primitive) {
2359 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2360 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2361 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2362 }
2363 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
2364 strncat(insert_clause, "post_nat_ip_dst", SPACELEFT(insert_clause));
2365 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
2366 strncat(where[primitive].string, "post_nat_ip_dst=%s(\'%s\')", SPACELEFT(where[primitive].string));
2367 values[primitive].type = where[primitive].type = COUNT_INT_POST_NAT_DST_HOST;
2368 values[primitive].handler = where[primitive].handler = count_post_nat_dst_ip_aton_handler;
2369 primitive++;
2370 }
2371 else {
2372 strncat(insert_clause, "post_nat_ip_dst", SPACELEFT(insert_clause));
2373 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2374 strncat(where[primitive].string, "post_nat_ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
2375 values[primitive].type = where[primitive].type = COUNT_INT_POST_NAT_DST_HOST;
2376 values[primitive].handler = where[primitive].handler = count_post_nat_dst_ip_handler;
2377 primitive++;
2378 }
2379 }
2380
2381 if (what_to_count_2 & COUNT_POST_NAT_SRC_PORT) {
2382 if (primitive) {
2383 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2384 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2385 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2386 }
2387 strncat(insert_clause, "post_nat_port_src", SPACELEFT(insert_clause));
2388 strncat(where[primitive].string, "post_nat_port_src=%u", SPACELEFT(where[primitive].string));
2389 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2390 values[primitive].type = where[primitive].type = COUNT_INT_POST_NAT_SRC_PORT;
2391 values[primitive].handler = where[primitive].handler = count_post_nat_src_port_handler;
2392 primitive++;
2393 }
2394
2395 if (what_to_count_2 & COUNT_POST_NAT_DST_PORT) {
2396 if (primitive) {
2397 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2398 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2399 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2400 }
2401 strncat(insert_clause, "post_nat_port_dst", SPACELEFT(insert_clause));
2402 strncat(where[primitive].string, "post_nat_port_dst=%u", SPACELEFT(where[primitive].string));
2403 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2404 values[primitive].type = where[primitive].type = COUNT_INT_POST_NAT_DST_PORT;
2405 values[primitive].handler = where[primitive].handler = count_post_nat_dst_port_handler;
2406 primitive++;
2407 }
2408
2409 if (what_to_count_2 & COUNT_NAT_EVENT) {
2410 if (primitive) {
2411 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2412 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2413 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2414 }
2415 strncat(insert_clause, "nat_event", SPACELEFT(insert_clause));
2416 strncat(where[primitive].string, "nat_event=%u", SPACELEFT(where[primitive].string));
2417 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2418 values[primitive].type = where[primitive].type = COUNT_INT_NAT_EVENT;
2419 values[primitive].handler = where[primitive].handler = count_nat_event_handler;
2420 primitive++;
2421 }
2422
2423 if (what_to_count_2 & COUNT_MPLS_LABEL_TOP) {
2424 if (primitive) {
2425 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2426 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2427 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2428 }
2429 strncat(insert_clause, "mpls_label_top", SPACELEFT(insert_clause));
2430 strncat(where[primitive].string, "mpls_label_top=%u", SPACELEFT(where[primitive].string));
2431 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2432 values[primitive].type = where[primitive].type = COUNT_INT_MPLS_LABEL_TOP;
2433 values[primitive].handler = where[primitive].handler = count_mpls_label_top_handler;
2434 primitive++;
2435 }
2436
2437 if (what_to_count_2 & COUNT_MPLS_LABEL_BOTTOM) {
2438 if (primitive) {
2439 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2440 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2441 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2442 }
2443 strncat(insert_clause, "mpls_label_bottom", SPACELEFT(insert_clause));
2444 strncat(where[primitive].string, "mpls_label_bottom=%u", SPACELEFT(where[primitive].string));
2445 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2446 values[primitive].type = where[primitive].type = COUNT_INT_MPLS_LABEL_BOTTOM;
2447 values[primitive].handler = where[primitive].handler = count_mpls_label_bottom_handler;
2448 primitive++;
2449 }
2450
2451 if (what_to_count_2 & COUNT_MPLS_STACK_DEPTH) {
2452 if (primitive) {
2453 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2454 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2455 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2456 }
2457 strncat(insert_clause, "mpls_stack_depth", SPACELEFT(insert_clause));
2458 strncat(where[primitive].string, "mpls_stack_depth=%u", SPACELEFT(where[primitive].string));
2459 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2460 values[primitive].type = where[primitive].type = COUNT_INT_MPLS_STACK_DEPTH;
2461 values[primitive].handler = where[primitive].handler = count_mpls_stack_depth_handler;
2462 primitive++;
2463 }
2464
2465 if (what_to_count_2 & COUNT_TUNNEL_SRC_MAC) {
2466 if (primitive) {
2467 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2468 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2469 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2470 }
2471 strncat(insert_clause, "tunnel_mac_src", SPACELEFT(insert_clause));
2472 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2473 strncat(where[primitive].string, "tunnel_mac_src=\'%s\'", SPACELEFT(where[primitive].string));
2474 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_SRC_MAC;
2475 values[primitive].handler = where[primitive].handler = count_tunnel_src_mac_handler;
2476 primitive++;
2477 }
2478
2479 if (what_to_count_2 & COUNT_TUNNEL_DST_MAC) {
2480 if (primitive) {
2481 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2482 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2483 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2484 }
2485 strncat(insert_clause, "tunnel_mac_dst", SPACELEFT(insert_clause));
2486 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2487 strncat(where[primitive].string, "tunnel_mac_dst=\'%s\'", SPACELEFT(where[primitive].string));
2488 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_DST_MAC;
2489 values[primitive].handler = where[primitive].handler = count_tunnel_dst_mac_handler;
2490 primitive++;
2491 }
2492
2493 if (what_to_count_2 & COUNT_TUNNEL_SRC_HOST) {
2494 if (primitive) {
2495 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2496 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2497 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2498 }
2499 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
2500 strncat(insert_clause, "tunnel_ip_src", SPACELEFT(insert_clause));
2501 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
2502 strncat(where[primitive].string, "tunnel_ip_src=%s(\'%s\')", SPACELEFT(where[primitive].string));
2503 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_SRC_HOST;
2504 values[primitive].handler = where[primitive].handler = count_tunnel_src_ip_aton_handler;
2505 primitive++;
2506 }
2507 else {
2508 strncat(insert_clause, "tunnel_ip_src", SPACELEFT(insert_clause));
2509 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2510 strncat(where[primitive].string, "tunnel_ip_src=\'%s\'", SPACELEFT(where[primitive].string));
2511 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_SRC_HOST;
2512 values[primitive].handler = where[primitive].handler = count_tunnel_src_ip_handler;
2513 primitive++;
2514 }
2515 }
2516
2517 if (what_to_count_2 & COUNT_TUNNEL_DST_HOST) {
2518 if (primitive) {
2519 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2520 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2521 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2522 }
2523 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
2524 strncat(insert_clause, "tunnel_ip_dst", SPACELEFT(insert_clause));
2525 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
2526 strncat(where[primitive].string, "tunnel_ip_dst=%s(\'%s\')", SPACELEFT(where[primitive].string));
2527 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_DST_HOST;
2528 values[primitive].handler = where[primitive].handler = count_tunnel_dst_ip_aton_handler;
2529 primitive++;
2530 }
2531 else {
2532 strncat(insert_clause, "tunnel_ip_dst", SPACELEFT(insert_clause));
2533 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2534 strncat(where[primitive].string, "tunnel_ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
2535 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_DST_HOST;
2536 values[primitive].handler = where[primitive].handler = count_tunnel_dst_ip_handler;
2537 primitive++;
2538 }
2539 }
2540
2541 if (what_to_count_2 & COUNT_TUNNEL_IP_PROTO) {
2542 if (primitive) {
2543 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2544 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2545 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2546 }
2547 strncat(insert_clause, "tunnel_ip_proto", SPACELEFT(insert_clause));
2548 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && !config.num_protos) {
2549 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2550 strncat(where[primitive].string, "tunnel_ip_proto=\'%s\'", SPACELEFT(where[primitive].string));
2551 values[primitive].handler = where[primitive].handler = MY_count_tunnel_ip_proto_handler;
2552 }
2553 else {
2554 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2555 strncat(where[primitive].string, "tunnel_ip_proto=%u", SPACELEFT(where[primitive].string));
2556 values[primitive].handler = where[primitive].handler = PG_count_tunnel_ip_proto_handler;
2557 }
2558 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_IP_PROTO;
2559 primitive++;
2560 }
2561
2562 if (what_to_count_2 & COUNT_TUNNEL_IP_TOS) {
2563 if (primitive) {
2564 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2565 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2566 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2567 }
2568 strncat(insert_clause, "tunnel_tos", SPACELEFT(insert_clause));
2569 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2570 strncat(where[primitive].string, "tunnel_tos=%u", SPACELEFT(where[primitive].string));
2571 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_IP_TOS;
2572 values[primitive].handler = where[primitive].handler = count_tunnel_ip_tos_handler;
2573 primitive++;
2574 }
2575
2576 if (what_to_count_2 & COUNT_TUNNEL_SRC_PORT) {
2577 if (primitive) {
2578 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2579 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2580 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2581 }
2582 strncat(insert_clause, "tunnel_port_src", SPACELEFT(insert_clause));
2583 strncat(where[primitive].string, "tunnel_port_src=%u", SPACELEFT(where[primitive].string));
2584 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2585 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_SRC_PORT;
2586 values[primitive].handler = where[primitive].handler = count_tunnel_src_port_handler;
2587 primitive++;
2588 }
2589
2590 if (what_to_count_2 & COUNT_TUNNEL_DST_PORT) {
2591 if (primitive) {
2592 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2593 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2594 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2595 }
2596 strncat(insert_clause, "tunnel_port_dst", SPACELEFT(insert_clause));
2597 strncat(where[primitive].string, "tunnel_port_dst=%u", SPACELEFT(where[primitive].string));
2598 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2599 values[primitive].type = where[primitive].type = COUNT_INT_TUNNEL_DST_PORT;
2600 values[primitive].handler = where[primitive].handler = count_tunnel_dst_port_handler;
2601 primitive++;
2602 }
2603
2604 if (what_to_count_2 & COUNT_VXLAN) {
2605 if (primitive) {
2606 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2607 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2608 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2609 }
2610 strncat(insert_clause, "vxlan", SPACELEFT(insert_clause));
2611 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2612 strncat(where[primitive].string, "vxlan=%u", SPACELEFT(where[primitive].string));
2613 values[primitive].type = where[primitive].type = COUNT_INT_VXLAN;
2614 values[primitive].handler = where[primitive].handler = count_vxlan_handler;
2615 primitive++;
2616 }
2617
2618 if (what_to_count_2 & COUNT_TIMESTAMP_START) {
2619 int use_copy=0;
2620
2621 if (primitive) {
2622 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2623 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2624 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2625 }
2626 strncat(insert_clause, "timestamp_start", SPACELEFT(insert_clause));
2627 if (config.timestamps_since_epoch) {
2628 strncat(where[primitive].string, "timestamp_start=%u", SPACELEFT(where[primitive].string));
2629 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2630 }
2631 else {
2632 if (!strcmp(config.type, "mysql")) {
2633 strncat(where[primitive].string, "timestamp_start=FROM_UNIXTIME(%u)", SPACELEFT(where[primitive].string));
2634 strncat(values[primitive].string, "FROM_UNIXTIME(%u)", SPACELEFT(values[primitive].string));
2635 }
2636 else if (!strcmp(config.type, "pgsql")) {
2637 if (config.sql_use_copy) {
2638 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
2639 use_copy = TRUE;
2640 }
2641 else {
2642 strncat(where[primitive].string, "timestamp_start=to_timestamp(%u)", SPACELEFT(where[primitive].string));
2643 strncat(values[primitive].string, "to_timestamp(%u)", SPACELEFT(values[primitive].string));
2644 }
2645 }
2646 else if (!strcmp(config.type, "sqlite3")) {
2647 if (!config.timestamps_utc) {
2648 strncat(where[primitive].string, "timestamp_start=DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(where[primitive].string));
2649 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(values[primitive].string));
2650 }
2651 else {
2652 strncat(where[primitive].string, "timestamp_start=DATETIME(%u, 'unixepoch')", SPACELEFT(where[primitive].string));
2653 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch')", SPACELEFT(values[primitive].string));
2654 }
2655 }
2656 }
2657 if (!use_copy) values[primitive].handler = where[primitive].handler = count_timestamp_start_handler;
2658 else values[primitive].handler = where[primitive].handler = PG_copy_count_timestamp_start_handler;
2659 values[primitive].type = where[primitive].type = COUNT_INT_TIMESTAMP_START;
2660 primitive++;
2661
2662 if (!config.timestamps_secs) {
2663 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2664 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2665 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2666
2667 strncat(insert_clause, "timestamp_start_residual", SPACELEFT(insert_clause));
2668 strncat(where[primitive].string, "timestamp_start_residual=%u", SPACELEFT(where[primitive].string));
2669 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2670 values[primitive].type = where[primitive].type = COUNT_INT_TIMESTAMP_START;
2671 values[primitive].handler = where[primitive].handler = count_timestamp_start_residual_handler;
2672 primitive++;
2673 }
2674 }
2675
2676 if (what_to_count_2 & COUNT_TIMESTAMP_END) {
2677 int use_copy=0;
2678
2679 if (primitive) {
2680 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2681 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2682 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2683 }
2684 strncat(insert_clause, "timestamp_end", SPACELEFT(insert_clause));
2685 if (config.timestamps_since_epoch) {
2686 strncat(where[primitive].string, "timestamp_end=%u", SPACELEFT(where[primitive].string));
2687 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2688 }
2689 else {
2690 if (!strcmp(config.type, "mysql")) {
2691 strncat(where[primitive].string, "timestamp_end=FROM_UNIXTIME(%u)", SPACELEFT(where[primitive].string));
2692 strncat(values[primitive].string, "FROM_UNIXTIME(%u)", SPACELEFT(values[primitive].string));
2693 }
2694 else if (!strcmp(config.type, "pgsql")) {
2695 if (config.sql_use_copy) {
2696 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
2697 use_copy = TRUE;
2698 }
2699 else {
2700 strncat(where[primitive].string, "timestamp_end=to_timestamp(%u)", SPACELEFT(where[primitive].string));
2701 strncat(values[primitive].string, "to_timestamp(%u)", SPACELEFT(values[primitive].string));
2702 }
2703 }
2704 else if (!strcmp(config.type, "sqlite3")) {
2705 if (!config.timestamps_utc) {
2706 strncat(where[primitive].string, "timestamp_end=DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(where[primitive].string));
2707 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(values[primitive].string));
2708 }
2709 else {
2710 strncat(where[primitive].string, "timestamp_end=DATETIME(%u, 'unixepoch')", SPACELEFT(where[primitive].string));
2711 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch')", SPACELEFT(values[primitive].string));
2712 }
2713 }
2714 }
2715 if (!use_copy) values[primitive].handler = where[primitive].handler = count_timestamp_end_handler;
2716 else values[primitive].handler = where[primitive].handler = PG_copy_count_timestamp_end_handler;
2717 values[primitive].type = where[primitive].type = COUNT_INT_TIMESTAMP_END;
2718 primitive++;
2719
2720 if (!config.timestamps_secs) {
2721 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2722 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2723 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2724
2725 strncat(insert_clause, "timestamp_end_residual", SPACELEFT(insert_clause));
2726 strncat(where[primitive].string, "timestamp_end_residual=%u", SPACELEFT(where[primitive].string));
2727 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2728 values[primitive].type = where[primitive].type = COUNT_INT_TIMESTAMP_END;
2729 values[primitive].handler = where[primitive].handler = count_timestamp_end_residual_handler;
2730 primitive++;
2731 }
2732 }
2733
2734 if (what_to_count_2 & COUNT_TIMESTAMP_ARRIVAL) {
2735 int use_copy=0;
2736
2737 if (primitive) {
2738 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2739 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2740 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2741 }
2742 strncat(insert_clause, "timestamp_arrival", SPACELEFT(insert_clause));
2743 if (config.timestamps_since_epoch) {
2744 strncat(where[primitive].string, "timestamp_arrival=%u", SPACELEFT(where[primitive].string));
2745 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2746 }
2747 else {
2748 if (!strcmp(config.type, "mysql")) {
2749 strncat(where[primitive].string, "timestamp_arrival=FROM_UNIXTIME(%u)", SPACELEFT(where[primitive].string));
2750 strncat(values[primitive].string, "FROM_UNIXTIME(%u)", SPACELEFT(values[primitive].string));
2751 }
2752 else if (!strcmp(config.type, "pgsql")) {
2753 if (config.sql_use_copy) {
2754 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
2755 use_copy = TRUE;
2756 }
2757 else {
2758 strncat(where[primitive].string, "timestamp_arrival=to_timestamp(%u)", SPACELEFT(where[primitive].string));
2759 strncat(values[primitive].string, "to_timestamp(%u)", SPACELEFT(values[primitive].string));
2760 }
2761 }
2762 else if (!strcmp(config.type, "sqlite3")) {
2763 if (!config.timestamps_utc) {
2764 strncat(where[primitive].string, "timestamp_arrival=DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(where[primitive].string));
2765 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(values[primitive].string));
2766 }
2767 else {
2768 strncat(where[primitive].string, "timestamp_arrival=DATETIME(%u, 'unixepoch')", SPACELEFT(where[primitive].string));
2769 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch')", SPACELEFT(values[primitive].string));
2770 }
2771 }
2772 }
2773 if (!use_copy) values[primitive].handler = where[primitive].handler = count_timestamp_arrival_handler;
2774 else values[primitive].handler = where[primitive].handler = PG_copy_count_timestamp_arrival_handler;
2775 values[primitive].type = where[primitive].type = COUNT_INT_TIMESTAMP_ARRIVAL;
2776 primitive++;
2777
2778 if (!config.timestamps_secs) {
2779 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2780 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2781 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2782
2783 strncat(insert_clause, "timestamp_arrival_residual", SPACELEFT(insert_clause));
2784 strncat(where[primitive].string, "timestamp_arrival_residual=%u", SPACELEFT(where[primitive].string));
2785 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2786 values[primitive].type = where[primitive].type = COUNT_INT_TIMESTAMP_ARRIVAL;
2787 values[primitive].handler = where[primitive].handler = count_timestamp_arrival_residual_handler;
2788 primitive++;
2789 }
2790 }
2791
2792 if (config.nfacctd_stitching) {
2793 int use_copy=0;
2794
2795 /* timestamp_min */
2796 if (primitive) {
2797 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2798 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2799 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2800 }
2801 strncat(insert_clause, "timestamp_min", SPACELEFT(insert_clause));
2802 if (config.timestamps_since_epoch) {
2803 strncat(where[primitive].string, "timestamp_min=%u", SPACELEFT(where[primitive].string));
2804 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2805 }
2806 else {
2807 if (!strcmp(config.type, "mysql")) {
2808 strncat(where[primitive].string, "timestamp_min=FROM_UNIXTIME(%u)", SPACELEFT(where[primitive].string));
2809 strncat(values[primitive].string, "FROM_UNIXTIME(%u)", SPACELEFT(values[primitive].string));
2810 }
2811 else if (!strcmp(config.type, "pgsql")) {
2812 if (config.sql_use_copy) {
2813 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
2814 use_copy = TRUE;
2815 }
2816 else {
2817 strncat(where[primitive].string, "timestamp_min=to_timestamp(%u)", SPACELEFT(where[primitive].string));
2818 strncat(values[primitive].string, "to_timestamp(%u)", SPACELEFT(values[primitive].string));
2819 }
2820 }
2821 else if (!strcmp(config.type, "sqlite3")) {
2822 if (!config.timestamps_utc) {
2823 strncat(where[primitive].string, "timestamp_min=DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(where[primitive].string));
2824 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(values[primitive].string));
2825 }
2826 else {
2827 strncat(where[primitive].string, "timestamp_min=DATETIME(%u, 'unixepoch')", SPACELEFT(where[primitive].string));
2828 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch')", SPACELEFT(values[primitive].string));
2829 }
2830 }
2831 }
2832 if (!use_copy) values[primitive].handler = where[primitive].handler = count_timestamp_min_handler;
2833 else values[primitive].handler = where[primitive].handler = PG_copy_count_timestamp_min_handler;
2834 values[primitive].type = where[primitive].type = FALSE;
2835 primitive++;
2836
2837 if (!config.timestamps_secs) {
2838 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2839 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2840 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2841
2842 strncat(insert_clause, "timestamp_min_residual", SPACELEFT(insert_clause));
2843 strncat(where[primitive].string, "timestamp_min_residual=%u", SPACELEFT(where[primitive].string));
2844 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2845 values[primitive].type = where[primitive].type = FALSE;
2846 values[primitive].handler = where[primitive].handler = count_timestamp_min_residual_handler;
2847 primitive++;
2848 }
2849
2850 /* timestamp_max */
2851 if (primitive) {
2852 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2853 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2854 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2855 }
2856 strncat(insert_clause, "timestamp_max", SPACELEFT(insert_clause));
2857 if (config.timestamps_since_epoch) {
2858 strncat(where[primitive].string, "timestamp_max=%u", SPACELEFT(where[primitive].string));
2859 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2860 }
2861 else {
2862 if (!strcmp(config.type, "mysql")) {
2863 strncat(where[primitive].string, "timestamp_max=FROM_UNIXTIME(%u)", SPACELEFT(where[primitive].string));
2864 strncat(values[primitive].string, "FROM_UNIXTIME(%u)", SPACELEFT(values[primitive].string));
2865 }
2866 else if (!strcmp(config.type, "pgsql")) {
2867 if (config.sql_use_copy) {
2868 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
2869 use_copy = TRUE;
2870 }
2871 else {
2872 strncat(where[primitive].string, "timestamp_max=to_timestamp(%u)", SPACELEFT(where[primitive].string));
2873 strncat(values[primitive].string, "to_timestamp(%u)", SPACELEFT(values[primitive].string));
2874 }
2875 }
2876 else if (!strcmp(config.type, "sqlite3")) {
2877 if (!config.timestamps_utc) {
2878 strncat(where[primitive].string, "timestamp_max=DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(where[primitive].string));
2879 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch', 'localtime')", SPACELEFT(values[primitive].string));
2880 }
2881 else {
2882 strncat(where[primitive].string, "timestamp_max=DATETIME(%u, 'unixepoch')", SPACELEFT(where[primitive].string));
2883 strncat(values[primitive].string, "DATETIME(%u, 'unixepoch')", SPACELEFT(values[primitive].string));
2884 }
2885 }
2886 }
2887
2888 if (!use_copy) values[primitive].handler = where[primitive].handler = count_timestamp_max_handler;
2889 else values[primitive].handler = where[primitive].handler = PG_copy_count_timestamp_max_handler;
2890 values[primitive].type = where[primitive].type = FALSE;
2891 primitive++;
2892
2893 if (!config.timestamps_secs) {
2894 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2895 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2896 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2897
2898 strncat(insert_clause, "timestamp_max_residual", SPACELEFT(insert_clause));
2899 strncat(where[primitive].string, "timestamp_max_residual=%u", SPACELEFT(where[primitive].string));
2900 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2901 values[primitive].type = where[primitive].type = FALSE;
2902 values[primitive].handler = where[primitive].handler = count_timestamp_max_residual_handler;
2903 primitive++;
2904 }
2905 }
2906
2907 if (what_to_count_2 & COUNT_EXPORT_PROTO_SEQNO) {
2908 if (primitive) {
2909 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2910 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2911 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2912 }
2913 strncat(insert_clause, "export_proto_seqno", SPACELEFT(insert_clause));
2914 strncat(where[primitive].string, "export_proto_seqno=%u", SPACELEFT(where[primitive].string));
2915 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2916 values[primitive].handler = where[primitive].handler = count_export_proto_seqno_handler;
2917 values[primitive].type = where[primitive].type = COUNT_INT_EXPORT_PROTO_SEQNO;
2918 primitive++;
2919 }
2920
2921 if (what_to_count_2 & COUNT_EXPORT_PROTO_VERSION) {
2922 if (primitive) {
2923 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2924 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2925 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2926 }
2927 strncat(insert_clause, "export_proto_version", SPACELEFT(insert_clause));
2928 strncat(where[primitive].string, "export_proto_version=%u", SPACELEFT(where[primitive].string));
2929 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2930 values[primitive].handler = where[primitive].handler = count_export_proto_version_handler;
2931 values[primitive].type = where[primitive].type = COUNT_INT_EXPORT_PROTO_VERSION;
2932 primitive++;
2933 }
2934
2935 if (what_to_count_2 & COUNT_EXPORT_PROTO_SYSID) {
2936 if (primitive) {
2937 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2938 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2939 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2940 }
2941 strncat(insert_clause, "export_proto_sysid", SPACELEFT(insert_clause));
2942 strncat(where[primitive].string, "export_proto_sysid=%u", SPACELEFT(where[primitive].string));
2943 strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
2944 values[primitive].handler = where[primitive].handler = count_export_proto_sysid_handler;
2945 values[primitive].type = where[primitive].type = COUNT_INT_EXPORT_PROTO_SYSID;
2946 primitive++;
2947 }
2948
2949 /* all custom primitives printed here */
2950 {
2951 struct custom_primitive_ptrs *cp_entry;
2952 int cp_idx;
2953
2954 for (cp_idx = 0; cp_idx < config.cpptrs.num; cp_idx++) {
2955 if (primitive) {
2956 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2957 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2958 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2959 }
2960
2961 cp_entry = &config.cpptrs.primitive[cp_idx];
2962 strncat(insert_clause, cp_entry->name, SPACELEFT(insert_clause));
2963 strncat(where[primitive].string, cp_entry->name, SPACELEFT(where[primitive].string));
2964 if (cp_entry->ptr->semantics == CUSTOM_PRIMITIVE_TYPE_UINT) {
2965 strncat(where[primitive].string, "=%s", SPACELEFT(where[primitive].string));
2966 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
2967 }
2968 else {
2969 strncat(where[primitive].string, "=\'%s\'", SPACELEFT(where[primitive].string));
2970 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
2971 }
2972 values[primitive].type = where[primitive].type = COUNT_INT_CUSTOM_PRIMITIVES;
2973 values[primitive].handler = where[primitive].handler = count_custom_primitives_handler;
2974 primitive++;
2975 }
2976 }
2977
2978 if (what_to_count & COUNT_TAG) {
2979 int count_it = FALSE;
2980
2981 if ((config.sql_table_version < 2) && !assume_custom_table) {
2982 if (config.what_to_count & COUNT_TAG) {
2983 Log(LOG_ERR, "ERROR ( %s/%s ): Tag/ID accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
2984 exit_gracefully(1);
2985 }
2986 else what_to_count ^= COUNT_TAG;
2987 }
2988 else count_it = TRUE;
2989
2990 if (count_it) {
2991 if (primitive) {
2992 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
2993 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
2994 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
2995 }
2996 if (config.sql_table_version < 9 || (config.sql_table_version >= SQL_TABLE_VERSION_BGP
2997 && config.sql_table_version < SQL_TABLE_VERSION_BGP+9)) {
2998 strncat(insert_clause, "agent_id", SPACELEFT(insert_clause));
2999 strncat(where[primitive].string, "agent_id=%llu", SPACELEFT(where[primitive].string));
3000 }
3001 else {
3002 strncat(insert_clause, "tag", SPACELEFT(insert_clause));
3003 strncat(where[primitive].string, "tag=%llu", SPACELEFT(where[primitive].string));
3004 }
3005 strncat(values[primitive].string, "%llu", SPACELEFT(values[primitive].string));
3006 values[primitive].type = where[primitive].type = COUNT_INT_TAG;
3007 values[primitive].handler = where[primitive].handler = count_tag_handler;
3008 primitive++;
3009 }
3010 }
3011
3012 if (what_to_count & COUNT_TAG2) {
3013 if (primitive) {
3014 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3015 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3016 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3017 }
3018 strncat(insert_clause, "tag2", SPACELEFT(insert_clause));
3019 strncat(values[primitive].string, "%llu", SPACELEFT(values[primitive].string));
3020 strncat(where[primitive].string, "tag2=%llu", SPACELEFT(where[primitive].string));
3021 values[primitive].type = where[primitive].type = COUNT_INT_TAG2;
3022 values[primitive].handler = where[primitive].handler = count_tag2_handler;
3023 primitive++;
3024 }
3025
3026 if (what_to_count_2 & COUNT_LABEL) {
3027 if (primitive) {
3028 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3029 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3030 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3031 }
3032 strncat(insert_clause, "label", SPACELEFT(insert_clause));
3033 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3034 strncat(where[primitive].string, "label=%\'%s\'", SPACELEFT(where[primitive].string));
3035 values[primitive].type = where[primitive].type = COUNT_INT_LABEL;
3036 values[primitive].handler = where[primitive].handler = count_label_handler;
3037 primitive++;
3038 }
3039
3040 if (what_to_count & COUNT_CLASS) {
3041 int count_it = FALSE;
3042
3043 if ((config.sql_table_version < 5 || config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3044 if (config.what_to_count & COUNT_CLASS) {
3045 Log(LOG_ERR, "ERROR ( %s/%s ): L7 classification accounting not supported for selected sql_table_version/_type. Read about SQL table versioning or consider using sql_optimize_clauses.\n", config.name, config.type);
3046 exit_gracefully(1);
3047 }
3048 else what_to_count ^= COUNT_CLASS;
3049 }
3050 else count_it = TRUE;
3051
3052 if (count_it) {
3053 if (primitive) {
3054 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3055 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3056 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3057 }
3058 strncat(insert_clause, "class_id", SPACELEFT(insert_clause));
3059 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3060 strncat(where[primitive].string, "class_id=\'%s\'", SPACELEFT(where[primitive].string));
3061 values[primitive].type = where[primitive].type = COUNT_INT_CLASS;
3062 values[primitive].handler = where[primitive].handler = count_class_id_handler;
3063 primitive++;
3064 }
3065 }
3066
3067 #if defined (WITH_NDPI)
3068 if (what_to_count_2 & COUNT_NDPI_CLASS) {
3069 if (primitive) {
3070 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3071 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3072 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3073 }
3074 strncat(insert_clause, "class", SPACELEFT(insert_clause));
3075 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3076 strncat(where[primitive].string, "class=\'%s\'", SPACELEFT(where[primitive].string));
3077 values[primitive].type = where[primitive].type = COUNT_INT_CLASS;
3078 values[primitive].handler = where[primitive].handler = count_ndpi_class_handler;
3079 primitive++;
3080 }
3081 #endif
3082
3083 #if defined (HAVE_L2)
3084 if (fakes & FAKE_SRC_MAC) {
3085 int count_it = FALSE;
3086
3087 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3088 fakes ^= FAKE_SRC_MAC;
3089 }
3090 else count_it = TRUE;
3091
3092 if (count_it) {
3093 if (primitive) {
3094 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3095 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3096 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3097 }
3098 strncat(insert_clause, "mac_src", SPACELEFT(insert_clause));
3099 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3100 strncat(where[primitive].string, "mac_src=\'%s\'", SPACELEFT(where[primitive].string));
3101 values[primitive].type = where[primitive].type = FAKE_SRC_MAC;
3102 values[primitive].handler = where[primitive].handler = fake_mac_handler;
3103 primitive++;
3104 }
3105 }
3106
3107 if (fakes & FAKE_DST_MAC) {
3108 int count_it = FALSE;
3109
3110 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3111 fakes ^= FAKE_DST_MAC;
3112 }
3113 else count_it = TRUE;
3114
3115 if (count_it) {
3116 if (primitive) {
3117 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3118 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3119 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3120 }
3121 strncat(insert_clause, "mac_dst", SPACELEFT(insert_clause));
3122 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3123 strncat(where[primitive].string, "mac_dst=\'%s\'", SPACELEFT(where[primitive].string));
3124 values[primitive].type = where[primitive].type = FAKE_DST_MAC;
3125 values[primitive].handler = where[primitive].handler = fake_mac_handler;
3126 primitive++;
3127 }
3128 }
3129 #endif
3130
3131 if (fakes & FAKE_SRC_HOST) {
3132 int count_it = FALSE;
3133
3134 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3135 fakes ^= FAKE_SRC_HOST;
3136 }
3137 else count_it = TRUE;
3138
3139 if (count_it) {
3140 if (primitive) {
3141 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3142 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3143 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3144 }
3145 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
3146 strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
3147 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
3148 strncat(where[primitive].string, "ip_src=%s(\'%s\')", SPACELEFT(where[primitive].string));
3149 values[primitive].type = where[primitive].type = FAKE_SRC_HOST;
3150 values[primitive].handler = where[primitive].handler = fake_host_aton_handler;
3151 primitive++;
3152 }
3153 else {
3154 strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
3155 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3156 strncat(where[primitive].string, "ip_src=\'%s\'", SPACELEFT(where[primitive].string));
3157 values[primitive].type = where[primitive].type = FAKE_SRC_HOST;
3158 values[primitive].handler = where[primitive].handler = fake_host_handler;
3159 primitive++;
3160 }
3161 }
3162 }
3163
3164 if (fakes & FAKE_DST_HOST) {
3165 int count_it = FALSE;
3166
3167 if ((config.sql_table_version >= SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3168 fakes ^= FAKE_DST_HOST;
3169 }
3170 else count_it = TRUE;
3171
3172 if (count_it) {
3173 if (primitive) {
3174 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3175 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3176 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3177 }
3178 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
3179 strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
3180 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
3181 strncat(where[primitive].string, "ip_dst=%s(\'%s\')", SPACELEFT(where[primitive].string));
3182 values[primitive].type = where[primitive].type = FAKE_DST_HOST;
3183 values[primitive].handler = where[primitive].handler = fake_host_aton_handler;
3184 primitive++;
3185 }
3186 else {
3187 strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
3188 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3189 strncat(where[primitive].string, "ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
3190 values[primitive].type = where[primitive].type = FAKE_DST_HOST;
3191 values[primitive].handler = where[primitive].handler = fake_host_handler;
3192 primitive++;
3193 }
3194 }
3195 }
3196
3197 if (fakes & FAKE_SRC_AS) {
3198 if (primitive) {
3199 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3200 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3201 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3202 }
3203 strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
3204 if (!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3") ||
3205 (!strcmp(config.type, "pgsql") && !strcmp(config.sql_data, "unified"))) {
3206 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3207 strncat(where[primitive].string, "ip_src=\'%s\'", SPACELEFT(where[primitive].string));
3208 }
3209 else {
3210 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
3211 strncat(where[primitive].string, "ip_src=%s", SPACELEFT(where[primitive].string));
3212 }
3213 values[primitive].type = where[primitive].type = FAKE_SRC_AS;
3214 values[primitive].handler = where[primitive].handler = fake_as_handler;
3215 primitive++;
3216 }
3217
3218 if (fakes & FAKE_DST_AS) {
3219 if (primitive) {
3220 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3221 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3222 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3223 }
3224 strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
3225 if (!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3") ||
3226 (!strcmp(config.type, "pgsql") && !strcmp(config.sql_data, "unified"))) {
3227 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3228 strncat(where[primitive].string, "ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
3229 }
3230 else {
3231 strncat(values[primitive].string, "%s", SPACELEFT(values[primitive].string));
3232 strncat(where[primitive].string, "ip_dst=%s", SPACELEFT(where[primitive].string));
3233 }
3234 values[primitive].type = where[primitive].type = FAKE_DST_AS;
3235 values[primitive].handler = where[primitive].handler = fake_as_handler;
3236 primitive++;
3237 }
3238
3239 if (fakes & FAKE_COMMS) {
3240 int count_it = FALSE;
3241
3242 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3243 fakes ^= FAKE_COMMS;
3244 }
3245 else count_it = TRUE;
3246
3247 if (count_it) {
3248 if (primitive) {
3249 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3250 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3251 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3252 }
3253 strncat(insert_clause, "comms", SPACELEFT(insert_clause));
3254 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3255 strncat(where[primitive].string, "comms=\'%s\'", SPACELEFT(where[primitive].string));
3256 values[primitive].type = where[primitive].type = FAKE_COMMS;
3257 values[primitive].handler = where[primitive].handler = fake_comms_handler;
3258 primitive++;
3259 }
3260 }
3261
3262 if (fakes & FAKE_AS_PATH) {
3263 int count_it = FALSE;
3264
3265 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3266 fakes ^= FAKE_AS_PATH;
3267 }
3268 else count_it = TRUE;
3269
3270 if (count_it) {
3271 if (primitive) {
3272 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3273 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3274 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3275 }
3276 strncat(insert_clause, "as_path", SPACELEFT(insert_clause));
3277 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3278 strncat(where[primitive].string, "as_path=\'%s\'", SPACELEFT(where[primitive].string));
3279 values[primitive].type = where[primitive].type = FAKE_AS_PATH;
3280 values[primitive].handler = where[primitive].handler = fake_as_path_handler;
3281 primitive++;
3282 }
3283 }
3284
3285 if (fakes & FAKE_PEER_SRC_AS) {
3286 int count_it = FALSE;
3287
3288 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3289 fakes ^= FAKE_PEER_SRC_AS;
3290 }
3291 else count_it = TRUE;
3292
3293 if (count_it) {
3294 if (primitive) {
3295 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3296 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3297 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3298 }
3299 strncat(insert_clause, "peer_as_src", SPACELEFT(insert_clause));
3300 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3301 strncat(where[primitive].string, "peer_as_src=\'%s\'", SPACELEFT(where[primitive].string));
3302 values[primitive].type = where[primitive].type = FAKE_PEER_SRC_AS;
3303 values[primitive].handler = where[primitive].handler = fake_as_handler;
3304 primitive++;
3305 }
3306 }
3307
3308 if (fakes & FAKE_PEER_DST_AS) {
3309 int count_it = FALSE;
3310
3311 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3312 fakes ^= FAKE_PEER_DST_AS;
3313 }
3314 else count_it = TRUE;
3315
3316 if (count_it) {
3317 if (primitive) {
3318 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3319 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3320 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3321 }
3322 strncat(insert_clause, "peer_as_dst", SPACELEFT(insert_clause));
3323 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3324 strncat(where[primitive].string, "peer_as_dst=\'%s\'", SPACELEFT(where[primitive].string));
3325 values[primitive].type = where[primitive].type = FAKE_PEER_DST_AS;
3326 values[primitive].handler = where[primitive].handler = fake_as_handler;
3327 primitive++;
3328 }
3329 }
3330
3331 if (fakes & FAKE_PEER_SRC_IP) {
3332 int count_it = FALSE;
3333
3334 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3335 fakes ^= FAKE_PEER_SRC_IP;
3336 }
3337 else count_it = TRUE;
3338
3339 if (count_it) {
3340 if (primitive) {
3341 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3342 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3343 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3344 }
3345 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
3346 strncat(insert_clause, "peer_ip_src", SPACELEFT(insert_clause));
3347 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
3348 strncat(where[primitive].string, "peer_ip_src=%s(\'%s\')", SPACELEFT(where[primitive].string));
3349 values[primitive].type = where[primitive].type = FAKE_PEER_SRC_IP;
3350 values[primitive].handler = where[primitive].handler = fake_host_aton_handler;
3351 primitive++;
3352 }
3353 else {
3354 strncat(insert_clause, "peer_ip_src", SPACELEFT(insert_clause));
3355 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3356 strncat(where[primitive].string, "peer_ip_src=\'%s\'", SPACELEFT(where[primitive].string));
3357 values[primitive].type = where[primitive].type = FAKE_PEER_SRC_IP;
3358 values[primitive].handler = where[primitive].handler = fake_host_handler;
3359 primitive++;
3360 }
3361 }
3362 }
3363
3364 if (fakes & FAKE_PEER_DST_IP) {
3365 int count_it = FALSE;
3366
3367 if ((config.sql_table_version < SQL_TABLE_VERSION_BGP) && !assume_custom_table) {
3368 fakes ^= FAKE_PEER_DST_IP;
3369 }
3370 else count_it = TRUE;
3371
3372 if (count_it) {
3373 if (primitive) {
3374 strncat(insert_clause, ", ", SPACELEFT(insert_clause));
3375 strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
3376 strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
3377 }
3378 if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
3379 strncat(insert_clause, "peer_ip_dst", SPACELEFT(insert_clause));
3380 strncat(values[primitive].string, "%s(\'%s\')", SPACELEFT(values[primitive].string));
3381 strncat(where[primitive].string, "peer_ip_dst=%s(\'%s\')", SPACELEFT(where[primitive].string));
3382 values[primitive].type = where[primitive].type = FAKE_PEER_DST_IP;
3383 values[primitive].handler = where[primitive].handler = fake_host_aton_handler;
3384 primitive++;
3385 }
3386 else {
3387 strncat(insert_clause, "peer_ip_dst", SPACELEFT(insert_clause));
3388 strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
3389 strncat(where[primitive].string, "peer_ip_dst=\'%s\'", SPACELEFT(where[primitive].string));
3390 values[primitive].type = where[primitive].type = FAKE_PEER_DST_IP;
3391 values[primitive].handler = where[primitive].handler = fake_host_handler;
3392 primitive++;
3393 }
3394 }
3395 }
3396
3397 strncat(copy_clause, insert_clause_start_ptr, SPACELEFT(copy_clause));
3398
3399 return primitive;
3400 }
3401
sql_query(struct BE_descs * bed,struct db_cache * elem,struct insert_data * idata)3402 int sql_query(struct BE_descs *bed, struct db_cache *elem, struct insert_data *idata)
3403 {
3404 if (!bed->p->fail && elem->valid == SQL_CACHE_COMMITTED) {
3405 if ((*sqlfunc_cbr.op)(bed->p, elem, idata)); /* failed */
3406 else {
3407 idata->qn++;
3408 return FALSE;
3409 }
3410 }
3411
3412 if ( elem->valid == SQL_CACHE_ERROR || (bed->p->fail && !(elem->valid == SQL_CACHE_INUSE)) ) {
3413 if (config.sql_backup_host) {
3414 if (!bed->b->fail) {
3415 if (!bed->b->connected) {
3416 (*sqlfunc_cbr.connect)(bed->b, config.sql_backup_host);
3417 if (config.sql_table_schema) {
3418 time_t stamp = idata->new_basetime ? idata->new_basetime : idata->basetime;
3419
3420 sql_create_table(bed->b, &stamp, NULL); // XXX: should not be null
3421 }
3422 (*sqlfunc_cbr.lock)(bed->b);
3423 }
3424 if (!bed->b->fail) {
3425 if ((*sqlfunc_cbr.op)(bed->b, elem, idata)) sql_db_fail(bed->b);
3426 }
3427 }
3428 }
3429 }
3430
3431 return TRUE;
3432 }
3433
sql_create_table(struct DBdesc * db,time_t * basetime,struct primitives_ptrs * prim_ptrs)3434 void sql_create_table(struct DBdesc *db, time_t *basetime, struct primitives_ptrs *prim_ptrs)
3435 {
3436 char buf[LARGEBUFLEN], tmpbuf[LARGEBUFLEN];
3437 int ret;
3438
3439 ret = read_SQLquery_from_file(config.sql_table_schema, buf, LARGEBUFLEN);
3440 if (ret) {
3441 handle_dynname_internal_strings_same(buf, LARGEBUFLEN, tmpbuf, prim_ptrs, DYN_STR_SQL_TABLE);
3442 pm_strftime_same(buf, LARGEBUFLEN, tmpbuf, basetime, config.timestamps_utc);
3443 (*sqlfunc_cbr.create_table)(db, buf);
3444 }
3445 }
3446
sql_invalidate_shadow_entries(struct db_cache * queue[],int * num)3447 void sql_invalidate_shadow_entries(struct db_cache *queue[], int *num)
3448 {
3449 int x;
3450
3451 for (x = 0; x < *num; x++) {
3452 if (!queue[x]->bytes_counter && !queue[x]->packet_counter && !queue[x]->flows_counter)
3453 queue[x]->valid = SQL_CACHE_FREE;
3454 }
3455 }
3456
sql_select_locking_style(char * lock)3457 int sql_select_locking_style(char *lock)
3458 {
3459 int i = 0, len = strlen(lock);
3460
3461 while (i < len) {
3462 lock[i] = tolower(lock[i]);
3463 i++;
3464 }
3465
3466 if (!strcmp(lock, "table")) return PM_LOCK_EXCLUSIVE;
3467 else if (!strcmp(lock, "row")) return PM_LOCK_ROW_EXCLUSIVE;
3468 else if (!strcmp(lock, "none")) return PM_LOCK_NONE;
3469
3470 Log(LOG_WARNING, "WARN ( %s/%s ): sql_locking_style value '%s' is unknown. Ignored.\n", config.name, config.type, lock);
3471
3472 return PM_LOCK_EXCLUSIVE;
3473 }
3474
sql_compose_static_set_event()3475 int sql_compose_static_set_event()
3476 {
3477 int set_primitives=0;
3478
3479 if (config.what_to_count & COUNT_TCPFLAGS) {
3480 strncat(set_event[set_primitives].string, "SET tcp_flags=tcp_flags|%u", SPACELEFT(set_event[set_primitives].string));
3481 set_event[set_primitives].type = COUNT_INT_TCPFLAGS;
3482 set_event[set_primitives].handler = count_tcpflags_setclause_handler;
3483 set_primitives++;
3484 }
3485
3486 return set_primitives;
3487 }
3488
sql_compose_static_set(int have_flows)3489 int sql_compose_static_set(int have_flows)
3490 {
3491 int set_primitives=0;
3492
3493 strncpy(set[set_primitives].string, "SET packets=packets+%llu, bytes=bytes+%llu", SPACELEFT(set[set_primitives].string));
3494 set[set_primitives].type = COUNT_INT_COUNTERS;
3495 set[set_primitives].handler = count_counters_setclause_handler;
3496 set_primitives++;
3497
3498 if (have_flows) {
3499 strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string));
3500 strncat(set[set_primitives].string, "flows=flows+%llu", SPACELEFT(set[set_primitives].string));
3501 set[set_primitives].type = COUNT_INT_FLOWS;
3502 set[set_primitives].handler = count_flows_setclause_handler;
3503 set_primitives++;
3504 }
3505
3506 if (config.what_to_count & COUNT_TCPFLAGS) {
3507 strncpy(set[set_primitives].string, ", ", SPACELEFT(set[set_primitives].string));
3508 strncat(set[set_primitives].string, "tcp_flags=tcp_flags|%u", SPACELEFT(set[set_primitives].string));
3509 set[set_primitives].type = COUNT_INT_TCPFLAGS;
3510 set[set_primitives].handler = count_tcpflags_setclause_handler;
3511 set_primitives++;
3512 }
3513
3514 return set_primitives;
3515 }
3516
primptrs_set_all_from_db_cache(struct primitives_ptrs * prim_ptrs,struct db_cache * entry)3517 void primptrs_set_all_from_db_cache(struct primitives_ptrs *prim_ptrs, struct db_cache *entry)
3518 {
3519 struct pkt_data *data = prim_ptrs->data;
3520
3521 if (prim_ptrs && data && entry) {
3522 memset(data, 0, PdataSz);
3523 data->primitives = entry->primitives;
3524 prim_ptrs->pbgp = entry->pbgp;
3525 prim_ptrs->pnat = entry->pnat;
3526 prim_ptrs->pmpls = entry->pmpls;
3527 prim_ptrs->ptun = entry->ptun;
3528 prim_ptrs->pcust = entry->pcust;
3529 prim_ptrs->pvlen = entry->pvlen;
3530 }
3531 }
3532