1
2 #ifndef NCP_H
3 #include "sancp.h"
4 #endif
5 /**************************************************************************
6 **SA Network Connection Profiler [sancp] - A TCP/IP statistical/collection tool
7 * ************************************************************************
8 * * Copyright (C) 2003 John Curry <john.curry@metre.net>
9 * *
10 * * This program is distributed under the terms of version 1.0 of the
11 * * Q Public License. See LICENSE.QPL for further details.
12 * *
13 * * This program is distributed in the hope that it will be useful,
14 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * *
17 * ***********************************************************************/
18
print_schemas()19 void print_schemas(){
20 extern struct gvars gVars;
21 if(gVars.stats_fname){
22 write_schema(gVars.stats_fname, gVars.stats_fmt, gVars.stats_fmt_len);
23 }
24 if(gVars.realtime_fname){
25 write_schema(gVars.realtime_fname, gVars.realtime_fmt, gVars.realtime_fmt_len);
26 }
27 }
28
write_schema(char * name,char * fmt,int fmtlen)29 void write_schema(char *name, char *fmt, int fmtlen){
30 if(name && fmtlen){
31 char *tmp;
32 char BUF[MAXENTRYLEN];
33 bzero(BUF,MAXENTRYLEN);
34 // Create the schema filename
35 snprintf(BUF,MAXENTRYLEN-1,"%s.schema",name);
36 tmp=createFileName(BUF,false);
37 outputFileHandle *fH = new outputFileHandle(tmp,fmt,fmtlen,WRITE_MODE);
38 bzero(BUF,MAXENTRYLEN);
39 // Print table header
40 fH->write(BUF,snprintf(BUF,MAXENTRYLEN,"\nCREATE TABLE %s ( \n",name));
41 // Print field entries in order
42 print_output_schema(fH,fmt,fmtlen);
43 bzero(BUF,MAXENTRYLEN);
44 // Print table footer
45 fH->write(BUF,snprintf(BUF,MAXENTRYLEN,") TYPE=InnoDB; \n\n"));
46 fH->destroy();
47 syslog(LOG_INFO,"Created %s\n",tmp);
48 if(tmp) free(tmp);
49 }
50 }
51
erase_idle(int a)52 void erase_idle(int a) {
53 extern struct gvars gVars;
54 struct cnx *cn, *tmpptr;
55 char *tmp;
56 // Since this is the only function that gets the timer alarm, we better
57 // check for expired connections (just in case we haven't processed any packets for a while)
58 if((gVars.timeptr.tv_sec - gVars.lastrun)>gVars.default_expire_interval){
59 expire_connections();
60 gVars.lastrun=gVars.timeptr.tv_sec;
61 }
62 reopen_files(2);
63 // Now check for connections to erase
64 cn=gVars.expired_cnxs.head;
65 while(cn) {
66 #ifdef DEBUG
67 printf("Erasing key:%d id:%lld\n",cn->hash,cn->cid);
68 #endif
69 if(cn->stats){
70 // We really need to check whether we actually received
71 // any bytes from the source 'first' before we record.
72 if(cn->reversed==CNX_REVERSED && cn->d_total_pkts==0){
73 cn->reversed=CNX_REREVERSED;
74 }
75 if(gVars.sfH) record(cn,gVars.sfH);
76 }
77 if(cn->fH){ cn->fH->destroy(); cn->fH=0; }
78 tmpptr=cn;
79 cn=tmpptr->next;
80 if(gVars.expired_cnxs.tail==tmpptr){
81 gVars.expired_cnxs.head=NULL;
82 gVars.expired_cnxs.tail=NULL;
83 }
84 tmpptr->CBufferPtr->Free();
85 tmpptr=NULL;
86 }
87 gVars.lastrun=gVars.timeptr.tv_sec;
88 if(gVars.burst_mode){
89 // Close current stats filehandle now, and prepare the name for the next output file
90 // it won't actually 'open' till we try to write to the file (when we're called again
91 // or when we exit and clear connections from memory)
92 if(gVars.sfH){
93 gVars.sfH->destroy(); gVars.sfH=NULL;
94 }
95 if(!gVars.sfH && gVars.smode){
96 tmp=createFileName(gVars.stats_fname,gVars.smode == OMODE_TSFILENAME);
97 gVars.sfH = new outputFileHandle(tmp,gVars.stats_fmt,gVars.stats_fmt_len,APPEND_MODE);
98 gVars.sfH->setFormat(gVars.stats_fmt,gVars.stats_fmt_len);
99 gVars.sfH->setEor(gVars.stats_eor);
100 gVars.sfH->setDelimiter(gVars.stats_delimiter);
101 free(tmp);
102 }
103
104 }else{
105 // We do nothing and leave the file open
106 // We'll close the file when we terminate or receive a kill HUP signal
107
108 }
109 // Call pthread_wait here - when we decide to use threads
110 #ifdef DEBUG
111 printf("Rearming alarm for %d secs\n",gVars.default_flush_interval);
112 #endif
113 alarm(gVars.default_flush_interval);
114 }
115
expire_connections()116 void expire_connections()
117 {
118 extern gvars gVars;
119 struct cnx *cn, *tmpptr;
120 int x, y;
121 int cKey = 0;
122 #ifdef DEBUG
123 printf("Expiring connections (%d secs)\n",gVars.default_expire_interval);
124 #endif
125 y=0;
126 for( cKey = 0; cKey < HASH_KEYS; cKey++)
127 {
128 cn=gVars.cnx_tail[cKey];
129 x=0;
130
131 while((cn!=NULL) && ( ((gVars.timeptr.tv_sec - cn->last_pkt) > cn->timeout) || ( cn->proto==IPPROTO_TCP && (((cn->tcpCFlags & 0x33) == 0x33) || ((cn->tcpCFlags & 0x0c)>0) ) && ( (gVars.timeptr.tv_sec - cn->last_pkt) > cn->tcplag) )) ) {
132 #ifdef DEBUG
133 printf("Erasing key:%d #:%d id:%lld\n",cKey,x,cn->cid);
134 #endif
135
136 // Remove connection from current list
137 tmpptr=cn;
138 if(tmpptr->prev){
139 tmpptr->prev->next=NULL;
140 gVars.cnx_tail[cKey]=tmpptr->prev;
141 }else{
142 gVars.cnx_head[cKey]=NULL;
143 gVars.cnx_tail[cKey]=NULL;
144 }
145 cn=tmpptr->prev;
146
147 // Add expired connection to a different list to be recorded and freed from memory
148 if(!gVars.expired_cnxs.head){
149 gVars.expired_cnxs.head=tmpptr;
150 gVars.expired_cnxs.tail=tmpptr;
151 tmpptr->next=tmpptr->prev=0;
152 }else{
153 gVars.expired_cnxs.tail->next=tmpptr;
154 gVars.expired_cnxs.tail=tmpptr;
155 }
156 }
157
158 }
159
160 }
161
snprintf_inaddr_toa(char * buf,int len,struct in_addr * in_addr,const char delimiter)162 void snprintf_inaddr_toa(char *buf, int len, struct in_addr *in_addr, const char delimiter)
163 {
164 snprintf(buf,len,"%s",inet_ntoa(*in_addr));
165 }
166
snprintf_inaddr_tohl(char * buf,int len,struct in_addr * inaddr,const char delimiter)167 void snprintf_inaddr_tohl(char *buf, int len, struct in_addr *inaddr, const char delimiter)
168 {
169 snprintf(buf,len,"%lu",(unsigned long) ntohl(*(unsigned long*)(inaddr)));
170 }
171
snprintf_gmtime(char * buf,int len,time_t timeval,const char delimiter)172 void snprintf_gmtime(char *buf, int len, time_t timeval, const char delimiter)
173 {
174 char currenttime[80];
175 strftime(currenttime,80,"%Y-%m-%d %T",(struct tm*)gmtime(&timeval));
176 snprintf(buf,len,"%s",currenttime);
177 }
178
snprintf_localtime(char * buf,int len,time_t timeval,const char delimiter)179 void snprintf_localtime(char *buf, int len, time_t timeval, const char delimiter)
180 {
181 char currenttime[80];
182 strftime(currenttime,80,"%Y-%m-%d %T",(struct tm*)localtime(&timeval));
183 snprintf(buf,len,"%s",currenttime);
184 }
185
186
record(struct cnx * cn,outputFileHandle * fH)187 void record(struct cnx *cn, outputFileHandle *fH)
188 {
189 extern struct gvars gVars;
190 char LOG[MAXENTRYLEN];
191
192 time_t timeval=gVars.timeptr.tv_sec;
193
194 char *fmtcols=fH->getFormat();
195
196 int fmtlen=fH->getFormatLen();
197
198 char delimiter=fH->getDelimiter();
199
200 char eor=fH->getEor();
201
202 bzero(LOG,MAXENTRYLEN);
203
204
205 /*
206 * Structure of a 48-bit Ethernet address.
207 *
208 struct ether_addr {
209 u_char octet[ETHER_ADDR_LEN];
210 };
211
212
213
214
215
216
217 */
218
219 for(char x=0; x<fmtlen; x++)
220 {
221 switch ((int)*(fmtcols+x))
222 {
223 case src_mac: {
224 struct myether_addr *es=(struct myether_addr *)&cn->eth_hdr.ether_shost;
225 snprintf(LOG,MAXENTRYLEN,"%0x:%0x:%0x:%0x:%0x:%0x",es->octet[0],es->octet[1],es->octet[2],es->octet[3],es->octet[4],es->octet[5]);
226 es=NULL;
227 break;
228 }
229 case dst_mac: {
230 struct myether_addr *ed=(struct myether_addr *)&cn->eth_hdr.ether_dhost;
231 snprintf(LOG,MAXENTRYLEN,"%0x:%0x:%0x:%0x:%0x:%0x",ed->octet[0],ed->octet[1],ed->octet[2],ed->octet[3],ed->octet[4],ed->octet[5]);
232 ed=NULL;
233 break;
234 }
235 case sancp_id: {
236 snprintf(LOG,MAXENTRYLEN,"%lld",cn->cid);
237 break;
238 }
239 case start_time_gmt: {
240 snprintf_gmtime(LOG,MAXENTRYLEN,cn->start_time,delimiter);
241 break;
242 }
243 case start_time_local: {
244 snprintf_localtime(LOG,MAXENTRYLEN,cn->start_time,delimiter);
245 break;
246 }
247 case stop_time_gmt: {
248 snprintf_gmtime(LOG,MAXENTRYLEN,cn->last_pkt,delimiter);
249 break;
250 }
251 case stop_time_local: {
252 snprintf_localtime(LOG,MAXENTRYLEN,cn->last_pkt,delimiter);
253 break;
254 }
255 case erased_time_gmt: {
256 snprintf_gmtime(LOG,MAXENTRYLEN,timeval,delimiter);
257 break;
258 }
259 case erased_time_local: {
260 snprintf_localtime(LOG,MAXENTRYLEN,timeval,delimiter);
261 break;
262 }
263 case src_ip_decimal: {
264 if(cn->reversed==CNX_REVERSED){
265 snprintf_inaddr_tohl(LOG,MAXENTRYLEN,(struct in_addr*) &cn->d_ip,delimiter);
266 }else{
267 snprintf_inaddr_tohl(LOG,MAXENTRYLEN,(struct in_addr*) &cn->s_ip,delimiter);
268 }
269 break;
270 }
271 case src_ip_dotted: {
272 if(cn->reversed==CNX_REVERSED){
273 snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->d_ip,delimiter);
274 }else{
275 snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->s_ip,delimiter);
276 }
277 break;
278 }
279 case dst_ip_decimal: {
280 if(cn->reversed==CNX_REVERSED){
281 snprintf_inaddr_tohl(LOG,MAXENTRYLEN,(struct in_addr*) &cn->s_ip,delimiter);
282 }else{
283 snprintf_inaddr_tohl(LOG,MAXENTRYLEN,(struct in_addr*) &cn->d_ip,delimiter);
284 }
285 break;
286 }
287 case dst_ip_dotted: {
288 if(cn->reversed==CNX_REVERSED){
289 snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->s_ip,delimiter);
290 }else{
291 snprintf_inaddr_toa(LOG,MAXENTRYLEN,(struct in_addr*) &cn->d_ip,delimiter);
292 }
293 break;
294 }
295 case eth_proto_hex: {
296 snprintf(LOG,MAXENTRYLEN,"%02X",ntohs(cn->h_proto));
297 break;
298 }
299 case eth_proto: {
300 snprintf(LOG,MAXENTRYLEN,"%u",(cn->h_proto));
301 break;
302 }
303 case ip_proto: {
304 snprintf(LOG,MAXENTRYLEN,"%u",(cn->proto));
305 break;
306 }
307 case src_port: {
308 if(cn->reversed==CNX_REVERSED){
309 snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->d_port));
310 }else{
311 snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->s_port));
312 }
313 break;
314 }
315 case dst_port: {
316 if(cn->reversed==CNX_REVERSED){
317 snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->s_port));
318 }else{
319 snprintf(LOG,MAXENTRYLEN,"%u",ntohs(cn->d_port));
320 }
321 break;
322 }
323 case duration: {
324 snprintf(LOG,MAXENTRYLEN,"%lu",(long)(cn->last_pkt-cn->start_time));
325 break;
326 }
327 case timeout: {
328 snprintf(LOG,MAXENTRYLEN,"%u",cn->timeout);
329 break;
330 }
331 case src_pkts: {
332 if(cn->reversed==CNX_REVERSED){
333 snprintf(LOG,MAXENTRYLEN,"%llu",cn->d_total_pkts);
334 }else{
335 snprintf(LOG,MAXENTRYLEN,"%llu",cn->s_total_pkts);
336 }
337 break;
338 }
339 case dst_pkts: {
340 if(cn->reversed==CNX_REVERSED){
341 snprintf(LOG,MAXENTRYLEN,"%llu",cn->s_total_pkts);
342 }else{
343 snprintf(LOG,MAXENTRYLEN,"%llu",cn->d_total_pkts);
344 }
345 break;
346 }
347 case src_bytes: {
348 if(cn->reversed==CNX_REVERSED){
349 snprintf(LOG,MAXENTRYLEN,"%llu",cn->d_total_bytes);
350 }else{
351 snprintf(LOG,MAXENTRYLEN,"%llu",cn->s_total_bytes);
352 }
353 break;
354 }
355 case dst_bytes: {
356 if(cn->reversed==CNX_REVERSED){
357 snprintf(LOG,MAXENTRYLEN,"%llu",cn->s_total_bytes);
358 }else{
359 snprintf(LOG,MAXENTRYLEN,"%llu",cn->d_total_bytes);
360 }
361 break;
362 }
363 case sflags_hex: {
364 snprintf(LOG,MAXENTRYLEN,"%02X",cn->tcpFlags[(cn->reversed==1?1:0)]);
365 break;
366 }
367 case sflags: {
368 snprintf(LOG,MAXENTRYLEN,"%u",cn->tcpFlags[(cn->reversed==1?1:0)]);
369 break;
370 }
371 case dflags_hex: {
372 snprintf(LOG,MAXENTRYLEN,"%02X",cn->tcpFlags[(cn->reversed==1?0:1)]);
373 break;
374 }
375 case dflags: {
376 snprintf(LOG,MAXENTRYLEN,"%u",cn->tcpFlags[(cn->reversed==1?0:1)]);
377 break;
378 }
379 case cflags_hex: {
380 snprintf(LOG,MAXENTRYLEN,"%02X",cn->reversed==1?((cn->tcpCFlags&0x15)<<1)|((cn->tcpCFlags&0x2A)>>1):cn->tcpCFlags);
381 break;
382 }
383 case cflags: {
384 snprintf(LOG,MAXENTRYLEN,"%u",cn->reversed==1?((cn->tcpCFlags&0x15)<<1)|((cn->tcpCFlags&0x2A)>>1):cn->tcpCFlags);
385 break;
386 }
387 case ip_len_s: {
388 if(cn->reversed==1){
389 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.len);
390 }else{
391 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.len);
392 }
393 break;
394 }
395 case ip_ttl_s: {
396 if(cn->reversed==1){
397 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.ttl);
398 }else{
399 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.ttl);
400 }
401 break;
402 }
403 case ip_df_s: {
404 if(cn->reversed==1){
405 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.df?Y:N);
406 }else{
407 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.df?Y:N);
408 }
409 break;
410 }
411 case tcp_wss_s: {
412 if(cn->reversed==1){
413 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.wss);
414 }else{
415 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.wss);
416 }
417 break;
418 }
419 #ifdef EXPERIMENTAL_TCPOPTIONS
420 case tcp_mss_s: {
421 if(cn->reversed==1){
422 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.mss);
423 }else{
424 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.mss);
425 }
426 break;
427 }
428 case tcp_wscale_s: {
429 if(cn->reversed==1){
430 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.wscale);
431 }else{
432 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.wscale);
433 }
434 break;
435 }
436 case tcp_sack_ok_s: {
437 if(cn->reversed==1){
438 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info2.sack_ok?Y:N);
439 }else{
440 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info.sack_ok?Y:N);
441 }
442 break;
443 }
444 case tcp_nop_s: {
445 if(cn->reversed==1){
446 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info2.nop?Y:N);
447 }else{
448 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info.nop?Y:N);
449 }
450 break;
451 }
452 #endif
453 case ip_len_d: {
454 if(cn->reversed==1){
455 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.len);
456 }else{
457 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.len);
458 }
459 break;
460 }
461 case ip_ttl_d: {
462 if(cn->reversed==1){
463 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.ttl);
464 }else{
465 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.ttl);
466 }
467 break;
468 }
469 case ip_df_d: {
470 if(cn->reversed==1){
471 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.df?Y:N);
472 }else{
473 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.df?Y:N);
474 }
475 break;
476 }
477 case tcp_wss_d: {
478 if(cn->reversed==1){
479 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.wss);
480 }else{
481 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.wss);
482 }
483 break;
484 }
485 #ifdef EXPERIMENTAL_TCPOPTIONS
486 case tcp_mss_d: {
487 if(cn->reversed==1){
488 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.mss);
489 }else{
490 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.mss);
491 }
492 break;
493 }
494 case tcp_wscale_d: {
495 if(cn->reversed==1){
496 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info.wscale);
497 }else{
498 snprintf(LOG,MAXENTRYLEN,"%u",cn->os_info2.wscale);
499 }
500 break;
501 }
502 case tcp_sack_ok_d: {
503 if(cn->reversed==1){
504 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info.sack_ok?Y:N);
505 }else{
506 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info2.sack_ok?Y:N);
507 }
508 break;
509 }
510 case tcp_nop_d: {
511 if(cn->reversed==1){
512 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info.nop?Y:N);
513 }else{
514 snprintf(LOG,MAXENTRYLEN,"%c",cn->os_info2.nop?Y:N);
515 }
516 break;
517 }
518 #endif
519 case total_bytes: {
520 snprintf(LOG,MAXENTRYLEN,"%llu",cn->total_bytes);
521 break;
522 }
523 case collect: {
524 snprintf(LOG,MAXENTRYLEN,"%u",cn->cmode);
525 break;
526 }
527 case collected: {
528 snprintf(LOG,MAXENTRYLEN,"%llu",cn->collected);
529 break;
530 }
531 case climit: {
532 snprintf(LOG,MAXENTRYLEN,"%llu",cn->limit);
533 break;
534 }
535 case tcplag: {
536 snprintf(LOG,MAXENTRYLEN,"%u",cn->tcplag);
537 break;
538 }
539 case pcap: {
540 snprintf(LOG,MAXENTRYLEN,"%c",cn->pcap?Y:N);
541 break;
542 }
543 case realtime: {
544 snprintf(LOG,MAXENTRYLEN,"%c",cn->realtime?Y:N);
545 break;
546 }
547 case stats: {
548 snprintf(LOG,MAXENTRYLEN,"%c",cn->stats?Y:N);
549 break;
550 }
551 case reversed: {
552 snprintf(LOG,MAXENTRYLEN,"%u",cn->reversed);
553 break;
554 }
555 case hash: {
556 snprintf(LOG,MAXENTRYLEN,"%u",cn->hash);
557 break;
558 }
559 case rid: {
560 snprintf(LOG,MAXENTRYLEN,"%u",cn->rid);
561 break;
562 }
563 case rgid: {
564 snprintf(LOG,MAXENTRYLEN,"%u",cn->rgid);
565 break;
566 }
567 case node: {
568 snprintf(LOG,MAXENTRYLEN,"%u",cn->node);
569 break;
570 }
571 case zone: {
572 snprintf(LOG,MAXENTRYLEN,"%u",cn->zone);
573 break;
574 }
575 case status: {
576 snprintf(LOG,MAXENTRYLEN,"%u",cn->status);
577 break;
578 }
579 case retro: {
580 snprintf(LOG,MAXENTRYLEN,"%c",cn->retro?Y:N);
581 break;
582 }
583 case sflags_1: {
584 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x80)?Y:N);
585 break;
586 }
587 case sflags_2: {
588 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x40)?Y:N);
589 break;
590 }
591 case sflags_U: {
592 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x20)?Y:N);
593 break;
594 }
595 case sflags_A: {
596 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x10)?Y:N);
597 break;
598 }
599 case sflags_P: {
600 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x08)?Y:N);
601 break;
602 }
603 case sflags_R: {
604 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x04)?Y:N);
605 break;
606 }
607 case sflags_S: {
608 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x02)?Y:N);
609 break;
610 }
611 case sflags_F: {
612 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?1:0)]&0x01)?Y:N);
613 break;
614 }
615 case dflags_1: {
616 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x80)?Y:N);
617 break;
618 }
619 case dflags_2: {
620 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x40)?Y:N);
621 break;
622 }
623 case dflags_U: {
624 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x20)?Y:N);
625 break;
626 }
627 case dflags_A: {
628 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x10)?Y:N);
629 break;
630 }
631 case dflags_P: {
632 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x08)?Y:N);
633 break;
634 }
635 case dflags_R: {
636 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x04)?Y:N);
637 break;
638 }
639 case dflags_S: {
640 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x02)?Y:N);
641 break;
642 }
643 case dflags_F: {
644 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpFlags[(cn->reversed==1?0:1)]&0x01)?Y:N);
645 break;
646 }
647 case cflags_DA: {
648 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpCFlags&(cn->reversed==1)?0x10:0x20)?Y:N);
649 break;
650 }
651 case cflags_SA: {
652 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpCFlags&(cn->reversed==1)?0x20:0x10)?Y:N);
653 break;
654 }
655 case cflags_DR: {
656 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpCFlags&(cn->reversed==1)?0x04:0x08)?Y:N);
657 break;
658 }
659 case cflags_SR: {
660 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpCFlags&(cn->reversed==1)?0x08:0x04)?Y:N);
661 break;
662 }
663 case cflags_DF: {
664 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpCFlags&(cn->reversed==1)?0x01:0x02)?Y:N);
665 break;
666 }
667 case cflags_SF: {
668 snprintf(LOG,MAXENTRYLEN,"%c",(cn->tcpCFlags&(cn->reversed==1)?0x02:0x01)?Y:N);
669 break;
670 }
671
672 default:
673 break;
674
675 }
676 if(x>0)
677 fH->write(&delimiter,sizeof(char));
678 fH->write(LOG,strlen(LOG)); bzero(LOG,MAXENTRYLEN);
679 }
680 fH->write(&eor,sizeof(char));
681 }
682
683 /* vim: set ts=4 sw=4 expandtab: */
684
685 /*
686 * We define our DB field types here, so we can change
687 * them easier... need config options
688 */
689
690 #define DB_8BIT "INT1"
691 #define DB_16BIT "INT2"
692 #define DB_32BIT "INT4"
693 #define DB_64BIT "INT8"
694 #define DB_CHAR1 "CHAR(1)"
695 #define DB_CHAR4 "CHAR(4)"
696 #define DB_CHAR16 "CHAR(16)"
697 #define DB_DATETIME "datetime"
698
print_output_schema(outputFileHandle * fH,char * fmtcols,int fmtlen)699 void print_output_schema(outputFileHandle *fH, char *fmtcols, int fmtlen)
700 {
701 char LOG[MAXENTRYLEN];
702
703 bzero(LOG,MAXENTRYLEN);
704
705 for(char x=0; x<fmtlen; x++)
706 {
707 switch ((int)*(fmtcols+x))
708 {
709 // Print 64 bit field
710 case sancp_id:
711 snprintf(LOG,MAXENTRYLEN,"\tsancp_id %s NOT NULL,\n",DB_64BIT);
712 break;
713 // Print Date/Time field
714 case start_time_gmt:
715 snprintf(LOG,MAXENTRYLEN,"\tstart_time_gmt %s NOT NULL default '0000-00-00 00:00:00',\n",DB_DATETIME);
716 break;
717 case start_time_local:
718 snprintf(LOG,MAXENTRYLEN,"\tstart_time_local %s NOT NULL default '0000-00-00 00:00:00',\n",DB_DATETIME);
719 break;
720 case stop_time_gmt:
721 snprintf(LOG,MAXENTRYLEN,"\tstop_time_gmt %s NOT NULL default '0000-00-00 00:00:00',\n",DB_DATETIME);
722 break;
723 case stop_time_local:
724 snprintf(LOG,MAXENTRYLEN,"\tstop_time_local %s NOT NULL default '0000-00-00 00:00:00',\n",DB_DATETIME);
725 break;
726 case erased_time_gmt:
727 snprintf(LOG,MAXENTRYLEN,"\terased_time_gmt %s NOT NULL default '0000-00-00 00:00:00',\n",DB_DATETIME);
728 break;
729 case erased_time_local:
730 snprintf(LOG,MAXENTRYLEN,"\terased_time_gmt %s NOT NULL default '0000-00-00 00:00:00',\n",DB_DATETIME);
731 break;
732 // Print 32 bit field
733 case src_ip_decimal:
734 snprintf(LOG,MAXENTRYLEN,"\tsrc_ip %s NOT NULL,\n",DB_32BIT);
735 break;
736 case dst_ip_decimal:
737 snprintf(LOG,MAXENTRYLEN,"\tsrc_ip %s NOT NULL,\n",DB_32BIT);
738 break;
739 case duration:
740 snprintf(LOG,MAXENTRYLEN,"\tduration %s NOT NULL,\n",DB_32BIT);
741 break;
742 case src_pkts:
743 snprintf(LOG,MAXENTRYLEN,"\tsrc_pkts %s NOT NULL,\n",DB_64BIT);
744 break;
745 case dst_pkts:
746 snprintf(LOG,MAXENTRYLEN,"\tdst_pkts %s NOT NULL,\n",DB_64BIT);
747 break;
748 case src_bytes:
749 snprintf(LOG,MAXENTRYLEN,"\tsrc_bytes %s NOT NULL,\n",DB_64BIT);
750 break;
751 case dst_bytes:
752 snprintf(LOG,MAXENTRYLEN,"\tdst_bytes %s NOT NULL,\n",DB_64BIT);
753 break;
754 case total_bytes:
755 snprintf(LOG,MAXENTRYLEN,"\ttotal_bytes %s NOT NULL,\n",DB_64BIT);
756 break;
757 case collected:
758 snprintf(LOG,MAXENTRYLEN,"\tcollected %s NOT NULL,\n",DB_64BIT);
759 break;
760 case climit:
761 snprintf(LOG,MAXENTRYLEN,"\tclimit %s NOT NULL,\n",DB_64BIT);
762 break;
763 case rid:
764 snprintf(LOG,MAXENTRYLEN,"\trid %s NOT NULL,\n",DB_32BIT);
765 break;
766 case rgid:
767 snprintf(LOG,MAXENTRYLEN,"\trgid %s NOT NULL,\n",DB_32BIT);
768 break;
769 // Print text field
770 case src_ip_dotted:
771 snprintf(LOG,MAXENTRYLEN,"\tsrc_ip_dotted %s NOT NULL,\n",DB_CHAR16);
772 break;
773 case dst_ip_dotted:
774 snprintf(LOG,MAXENTRYLEN,"\tdst_ip_dotted %s NOT NULL,\n",DB_CHAR16);
775 break;
776 case eth_proto_hex:
777 snprintf(LOG,MAXENTRYLEN,"\teth_proto_hex %s NOT NULL,\n",DB_CHAR4);
778 break;
779 case sflags_hex:
780 snprintf(LOG,MAXENTRYLEN,"\tsflags_hex %s NOT NULL,\n",DB_CHAR4);
781 break;
782 case dflags_hex:
783 snprintf(LOG,MAXENTRYLEN,"\tdflags_hex %s NOT NULL,\n",DB_CHAR4);
784 break;
785 case cflags_hex:
786 snprintf(LOG,MAXENTRYLEN,"\tcflags_hex %s NOT NULL,\n",DB_CHAR4);
787 break;
788 // Print 16bit field
789 case eth_proto:
790 snprintf(LOG,MAXENTRYLEN,"\teth_proto %s NOT NULL,\n",DB_16BIT);
791 break;
792 case src_port:
793 snprintf(LOG,MAXENTRYLEN,"\tsrc_port %s NOT NULL,\n",DB_16BIT);
794 break;
795 case dst_port:
796 snprintf(LOG,MAXENTRYLEN,"\tdst_port %s NOT NULL,\n",DB_16BIT);
797 break;
798 case timeout:
799 snprintf(LOG,MAXENTRYLEN,"\ttimeout %s NOT NULL,\n",DB_16BIT);
800 break;
801 case ip_len_s:
802 snprintf(LOG,MAXENTRYLEN,"\tip_len_s %s NOT NULL,\n",DB_16BIT);
803 break;
804 case ip_len_d:
805 snprintf(LOG,MAXENTRYLEN,"\tip_len_d %s NOT NULL,\n",DB_16BIT);
806 break;
807 case tcp_wss_s:
808 snprintf(LOG,MAXENTRYLEN,"\ttcp_wss_s %s NOT NULL,\n",DB_16BIT);
809 break;
810 case tcp_wss_d:
811 snprintf(LOG,MAXENTRYLEN,"\ttcp_wss_d %s NOT NULL,\n",DB_16BIT);
812 break;
813 case tcp_mss_s:
814 snprintf(LOG,MAXENTRYLEN,"\ttcp_mss_s %s NOT NULL,\n",DB_16BIT);
815 break;
816 case tcp_mss_d:
817 snprintf(LOG,MAXENTRYLEN,"\ttcp_mss_d %s NOT NULL,\n",DB_16BIT);
818 break;
819 case tcplag:
820 snprintf(LOG,MAXENTRYLEN,"\ttcplag %s NOT NULL,\n",DB_16BIT);
821 break;
822 case hash:
823 snprintf(LOG,MAXENTRYLEN,"\thash %s NOT NULL,\n",DB_16BIT);
824 break;
825 case node:
826 snprintf(LOG,MAXENTRYLEN,"\tnode %s NOT NULL,\n",DB_16BIT);
827 break;
828 case zone:
829 snprintf(LOG,MAXENTRYLEN,"\tzone %s NOT NULL,\n",DB_16BIT);
830 break;
831 // Print 8bit field
832 case ip_proto:
833 snprintf(LOG,MAXENTRYLEN,"\tip_proto %s NOT NULL,\n",DB_8BIT);
834 break;
835 case sflags:
836 snprintf(LOG,MAXENTRYLEN,"\tsflags %s NOT NULL,\n",DB_8BIT);
837 break;
838 case dflags:
839 snprintf(LOG,MAXENTRYLEN,"\tdflags %s NOT NULL,\n",DB_8BIT);
840 break;
841 case cflags:
842 snprintf(LOG,MAXENTRYLEN,"\tcflags %s NOT NULL,\n",DB_8BIT);
843 break;
844 case ip_ttl_s:
845 snprintf(LOG,MAXENTRYLEN,"\tip_ttl_s %s NOT NULL,\n",DB_8BIT);
846 break;
847 case ip_ttl_d:
848 snprintf(LOG,MAXENTRYLEN,"\tip_ttl_d %s NOT NULL,\n",DB_8BIT);
849 break;
850 case collect:
851 snprintf(LOG,MAXENTRYLEN,"\tcollect %s NOT NULL,\n",DB_8BIT);
852 break;
853 case reversed:
854 snprintf(LOG,MAXENTRYLEN,"\treversed %s NOT NULL,\n",DB_8BIT);
855 break;
856 case status:
857 snprintf(LOG,MAXENTRYLEN,"\tstatus %s NOT NULL,\n",DB_8BIT);
858 break;
859
860 // Print a char(1) field
861 case retro:
862 snprintf(LOG,MAXENTRYLEN,"\tretro %s NOT NULL,\n",DB_CHAR1);
863 break;
864 case pcap:
865 snprintf(LOG,MAXENTRYLEN,"\tpcap %s NOT NULL,\n",DB_CHAR1);
866 break;
867 case realtime:
868 snprintf(LOG,MAXENTRYLEN,"\trealtime %s NOT NULL,\n",DB_CHAR1);
869 break;
870 case stats:
871 snprintf(LOG,MAXENTRYLEN,"\tstats %s NOT NULL,\n",DB_CHAR1);
872 break;
873 case ip_df_s:
874 snprintf(LOG,MAXENTRYLEN,"\tip_df_s %s NOT NULL,\n",DB_CHAR1);
875 break;
876 case tcp_wscale_s:
877 snprintf(LOG,MAXENTRYLEN,"\ttcp_wscale_s %s NOT NULL,\n",DB_CHAR1);
878 break;
879 case tcp_sack_ok_s:
880 snprintf(LOG,MAXENTRYLEN,"\ttcp_sack_ok_s %s NOT NULL,\n",DB_CHAR1);
881 break;
882 case tcp_nop_s:
883 snprintf(LOG,MAXENTRYLEN,"\ttcp_nop_s %s NOT NULL,\n",DB_CHAR1);
884 break;
885 case ip_df_d:
886 snprintf(LOG,MAXENTRYLEN,"\tip_df_d %s NOT NULL,\n",DB_CHAR1);
887 break;
888 case tcp_wscale_d:
889 snprintf(LOG,MAXENTRYLEN,"\ttcp_wscale_d %s NOT NULL,\n",DB_CHAR1);
890 break;
891 case tcp_sack_ok_d:
892 snprintf(LOG,MAXENTRYLEN,"\ttcp_sack_ok_d %s NOT NULL,\n",DB_CHAR1);
893 break;
894 case tcp_nop_d:
895 snprintf(LOG,MAXENTRYLEN,"\ttcp_nop_d %s NOT NULL,\n",DB_CHAR1);
896 break;
897 case sflags_1:
898 snprintf(LOG,MAXENTRYLEN,"\tsflags_1 %s NOT NULL,\n",DB_CHAR1);
899 break;
900 case sflags_2:
901 snprintf(LOG,MAXENTRYLEN,"\tsflags_2 %s NOT NULL,\n",DB_CHAR1);
902 break;
903 case sflags_U:
904 snprintf(LOG,MAXENTRYLEN,"\tsflags_U %s NOT NULL,\n",DB_CHAR1);
905 break;
906 case sflags_A:
907 snprintf(LOG,MAXENTRYLEN,"\tsflags_A %s NOT NULL,\n",DB_CHAR1);
908 break;
909 case sflags_P:
910 snprintf(LOG,MAXENTRYLEN,"\tsflags_P %s NOT NULL,\n",DB_CHAR1);
911 break;
912 case sflags_R:
913 snprintf(LOG,MAXENTRYLEN,"\tsflags_R %s NOT NULL,\n",DB_CHAR1);
914 break;
915 case sflags_S:
916 snprintf(LOG,MAXENTRYLEN,"\tsflags_S %s NOT NULL,\n",DB_CHAR1);
917 break;
918 case sflags_F:
919 snprintf(LOG,MAXENTRYLEN,"\tsflags_F %s NOT NULL,\n",DB_CHAR1);
920 break;
921 case dflags_1:
922 snprintf(LOG,MAXENTRYLEN,"\tdflags_1 %s NOT NULL,\n",DB_CHAR1);
923 break;
924 case dflags_2:
925 snprintf(LOG,MAXENTRYLEN,"\tdflags_2 %s NOT NULL,\n",DB_CHAR1);
926 break;
927 case dflags_U:
928 snprintf(LOG,MAXENTRYLEN,"\tdflags_U %s NOT NULL,\n",DB_CHAR1);
929 break;
930 case dflags_A:
931 snprintf(LOG,MAXENTRYLEN,"\tdflags_A %s NOT NULL,\n",DB_CHAR1);
932 break;
933 case dflags_P:
934 snprintf(LOG,MAXENTRYLEN,"\tdflags_P %s NOT NULL,\n",DB_CHAR1);
935 break;
936 case dflags_R:
937 snprintf(LOG,MAXENTRYLEN,"\tdflags_R %s NOT NULL,\n",DB_CHAR1);
938 break;
939 case dflags_S:
940 snprintf(LOG,MAXENTRYLEN,"\tdflags_S %s NOT NULL,\n",DB_CHAR1);
941 break;
942 case dflags_F:
943 snprintf(LOG,MAXENTRYLEN,"\tdflags_F %s NOT NULL,\n",DB_CHAR1);
944 break;
945 case cflags_DA:
946 snprintf(LOG,MAXENTRYLEN,"\tcflags_DA %s NOT NULL,\n",DB_CHAR1);
947 break;
948 case cflags_SA:
949 snprintf(LOG,MAXENTRYLEN,"\tcflags_SA %s NOT NULL,\n",DB_CHAR1);
950 break;
951 case cflags_DR:
952 snprintf(LOG,MAXENTRYLEN,"\tcflags_DR %s NOT NULL,\n",DB_CHAR1);
953 break;
954 case cflags_SR:
955 snprintf(LOG,MAXENTRYLEN,"\tcflags_SR %s NOT NULL,\n",DB_CHAR1);
956 break;
957 case cflags_DF:
958 snprintf(LOG,MAXENTRYLEN,"\tcflags_DF %s NOT NULL,\n",DB_CHAR1);
959 break;
960 case cflags_SF:
961 snprintf(LOG,MAXENTRYLEN,"\tcflags_SF %s NOT NULL,\n",DB_CHAR1);
962 break;
963 default:
964 break;
965
966 }
967 if(x>0)
968 fH->write(LOG,strlen(LOG)); bzero(LOG,MAXENTRYLEN);
969 }
970 fH->write("\n",sizeof(char));
971 }
972
973 /* vim: set ts=4 sw=4 expandtab: */
974