Skip to Content
[CAIDA - Center for Applied Internet Data Analysis logo]
The Center for Applied Internet Data Analysis
cors-ft-aggregate.c
Go to the documentation of this file.
1 /*
2  * corsaro
3  *
4  * Alistair King, CAIDA, UC San Diego
5  * corsaro-info@caida.org
6  *
7  * Copyright (C) 2012 The Regents of the University of California.
8  *
9  * This file is part of corsaro.
10  *
11  * corsaro is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * corsaro is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with corsaro. If not, see <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #include <arpa/inet.h>
27 #include <assert.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 
33 #include "libtrace.h"
34 
35 #include "corsaro.h"
36 #include "corsaro_log.h"
37 #include "corsaro_io.h"
38 
39 #include "corsaro_flowtuple.h"
40 
55 KHASH_SET_INIT_INT64(64xx)
56 
57 /*KHASH_INIT(sixt, corsaro_flowtuple_t*, khint32_t, 1,*/
58 KHASH_INIT(sixt_map, corsaro_flowtuple_t*, kh_64xx_t*, 1,
60 
62 KHASH_INIT(sixt_int, corsaro_flowtuple_t*, uint64_t, 1,
63  corsaro_flowtuple_hash_func, corsaro_flowtuple_hash_equal);
64 
66 static kh_sixt_map_t *sixt_f = NULL;
68 static kh_sixt_int_t *sixt_v = NULL;
69 
71 static corsaro_in_t *corsaro = NULL;
73 static corsaro_in_record_t *record = NULL;
74 
76 static int interval = 0;
77 
79 typedef enum field_index {
81  SRC_IP = 0,
83  DST_IP = 1,
85  SRC_PORT = 2,
87  DST_PORT = 3,
89  PROTO = 4,
91  TTL = 5,
93  TCP_FLAGS = 6,
95  IP_LEN = 7,
97  VALUE = 8,
98 
101 } field_index_t;
102 
104 #define FIELD_ENABLED 1
105 
107 static char *field_names[] = {
108  "src_ip",
109  "dst_ip",
110  "src_port",
111  "dst_port",
112  "protocol",
113  "ttl",
114  "tcp_flags",
115  "ip_len",
116  "packet_cnt",
117 };
118 
120 static int legacy = 0;
121 
124 
126 static int value_field = -1;
127 
129 static uint64_t flowtuple_cnt = 0;
130 
135  0,
136  0
137 };
138 
140 static int next_interval = 0;
145  0,
146  0
147 };
148 
150 static void clean()
151 {
152  if(record != NULL)
153  {
155  record = NULL;
156  }
157 
158  if(corsaro != NULL)
159  {
161  corsaro = NULL;
162  }
163 }
164 
166 static int init_corsaro(char *corsarouri)
167 {
168  /* get an corsaro_in object */
169  if((corsaro = corsaro_alloc_input(corsarouri)) == NULL)
170  {
171  fprintf(stderr, "could not alloc corsaro_in\n");
172  clean();
173  return -1;
174  }
175 
176  /* get a record */
177  if ((record = corsaro_in_alloc_record(corsaro)) == NULL) {
178  fprintf(stderr, "could not alloc record\n");
179  clean();
180  return -1;
181  }
182 
183  /* start corsaro */
184  if(corsaro_start_input(corsaro) != 0)
185  {
186  fprintf(stderr, "could not start corsaro\n");
187  clean();
188  return -1;
189  }
190 
191  return 0;
192 }
193 
195 static int add_inc_map(void *h, corsaro_flowtuple_t *t, uint32_t value)
196 {
197  kh_sixt_map_t *hash = (kh_sixt_map_t *)h;
198  int khret;
199  khiter_t khiter;
200  corsaro_flowtuple_t *new_6t = NULL;
201  kh_64xx_t *val_map = NULL;
202 
203  assert(hash != NULL);
204 
205  /* this function must not be used to aggregate for packet counts */
206  assert(value_field != VALUE);
207 
208  /* check if this is in the hash already */
209  if((khiter = kh_get(sixt_map, hash, t)) == kh_end(hash))
210  {
211  /* create a new tuple struct */
212  if((new_6t = malloc(sizeof(corsaro_flowtuple_t))) == NULL)
213  {
214  corsaro_log_file(__func__, NULL, "malloc failed");
215  return -1;
216  }
217 
218  /* fill it */
219  memcpy(new_6t, t, sizeof(corsaro_flowtuple_t));
220 
221  /* add it to the hash */
222  khiter = kh_put(sixt_map, hash, new_6t, &khret);
223 
224  /* create a new map for this key */
225  val_map = kh_init(64xx);
226 
227  /* add this value to the map */
228  kh_put(64xx, val_map, value, &khret);
229 
230  /* set the value in the hash to the map */
231  kh_value(hash, khiter) = val_map;
232  }
233  else
234  {
235  /* simply add this value to the map */
236  kh_put(64xx, kh_value(hash, khiter), value, &khret);
237  }
238  return 0;
239 }
240 
242 int add_inc_hash(kh_sixt_int_t *hash, corsaro_flowtuple_t *t, uint32_t increment)
243 {
244  int khret;
245  khiter_t khiter;
246  corsaro_flowtuple_t *new_6t = NULL;
247 
248  assert(hash != NULL);
249 
250  /* check if this is in the hash already */
251  if((khiter = kh_get(sixt_int, hash, t)) == kh_end(hash))
252  {
253  /* create a new tuple struct */
254  if((new_6t = malloc(sizeof(corsaro_flowtuple_t))) == NULL)
255  {
256  corsaro_log_file(__func__, NULL, "malloc failed");
257  return -1;
258  }
259 
260  /* fill it */
261  memcpy(new_6t, t, sizeof(corsaro_flowtuple_t));
262 
263  /* add it to the hash */
264  khiter = kh_put(sixt_int, hash, new_6t, &khret);
265  /* set the count to one */
266  kh_value(hash, khiter) = increment;
267  /*new_6t->packet_cnt = htonl(increment);*/
268  }
269  else
270  {
271  /* will this cause a wrap? */
272  assert((UINT64_MAX - kh_value(hash, khiter)) > increment);
273  /* simply increment the existing one */
274  kh_value(hash, khiter)+=increment;
275  /*new_6t = kh_key(hash, khiter);*/
276  /*new_6t->packet_cnt = htonl(ntohl(new_6t->packet_cnt)+increment);*/
277  }
278  return 0;
279 }
280 
282 static void flowtuple_print_64(corsaro_flowtuple_t *flowtuple, uint64_t value)
283 {
284  char ip_a[16];
285  char ip_b[16];
286  uint32_t tmp;
287 
288  assert(flowtuple != NULL);
289 
290  tmp = flowtuple->src_ip;
291  inet_ntop(AF_INET,&tmp, &ip_a[0], 16);
292  tmp = CORSARO_FLOWTUPLE_SIXT_TO_IP(flowtuple);
293  inet_ntop(AF_INET, &tmp, &ip_b[0], 16);
294 
295  fprintf(stdout, "%s|%s"
296  "|%"PRIu16"|%"PRIu16
297  "|%"PRIu8"|%"PRIu8"|0x%02"PRIx8
298  "|%"PRIu16
299  ",%"PRIu64"\n",
300  ip_a, ip_b,
301  ntohs(flowtuple->src_port),
302  ntohs(flowtuple->dst_port),
303  flowtuple->protocol,
304  flowtuple->ttl,
305  flowtuple->tcp_flags,
306  ntohs(flowtuple->ip_len),
307  value);
308 }
309 
311 static void dump_hash_map(kh_sixt_map_t *hash)
312 {
313  khiter_t k;
314  corsaro_flowtuple_t *key;
315 
316  /* dump the hash */
317  if(kh_size(hash) > 0)
318  {
319  for(k = kh_begin(hash); k != kh_end(hash); ++k)
320  {
321  if(kh_exist(hash, k))
322  {
323  key = kh_key(hash, k);
324  /*key->packet_cnt = htonl(kh_val(hash,k));*/
325  flowtuple_print_64(key, kh_size(kh_val(hash, k)));
326  /* free the map while we still have a pointer to it */
327  kh_destroy(64xx, kh_val(hash, k));
328  }
329  }
330  }
331 
332  /* empty the hash */
333  kh_free(sixt_map, hash, &corsaro_flowtuple_free);
334  kh_clear(sixt_map, hash);
335 }
336 
338 static void dump_hash_int(kh_sixt_int_t *hash)
339 {
340  khiter_t k;
341  corsaro_flowtuple_t *key;
342 
343  /* dump the hash */
344  if(kh_size(hash) > 0)
345  {
346  for(k = kh_begin(hash); k != kh_end(hash); ++k)
347  {
348  if(kh_exist(hash, k))
349  {
350  key = kh_key(hash, k);
351  /*key->packet_cnt = htonl(kh_val(hash,k));*/
352  flowtuple_print_64(key, kh_val(hash,k));
353  }
354  }
355  }
356 
357  /* empty the hash */
358  kh_free(sixt_int, hash, &corsaro_flowtuple_free);
359  kh_clear(sixt_int, hash);
360 }
361 
363 static void dump_hash()
364 {
365  assert(sixt_f || sixt_v);
366 
367  corsaro_io_print_interval_start(&last_dump_end);
368 
369  if(sixt_f != NULL)
370  {
372  }
373  else
374  {
376  }
377 
378  corsaro_io_print_interval_end(&last_interval_end);
379 
380  /* move on to the next interval start */
381  last_dump_end.number++;
382  /* move on to the next interval end */
383  last_interval_end.number++;
384  /* translate from int_end to int_start */
385  last_dump_end.time = last_interval_end.time+1;
386 }
387 
389 static int process_flowtuple(corsaro_flowtuple_t *tuple)
390 {
391  int i;
392 
393  int value;
394 
395  /* work out which field from the tuple we want to use as the value */
396  switch(value_field)
397  {
398  case SRC_IP:
399  value = ntohl(tuple->src_ip);
400  break;
401  case DST_IP:
402  value = ntohl(CORSARO_FLOWTUPLE_SIXT_TO_IP(tuple));
403  break;
404  case SRC_PORT:
405  value = ntohs(tuple->src_port);
406  break;
407  case DST_PORT:
408  value = ntohs(tuple->dst_port);
409  break;
410  case PROTO:
411  value = tuple->protocol;
412  break;
413  case TTL:
414  value = tuple->ttl;
415  break;
416  case TCP_FLAGS:
417  value = tuple->tcp_flags;
418  break;
419  case IP_LEN:
420  value = ntohs(tuple->ip_len);
421  break;
422  case VALUE:
423  value = ntohl(tuple->packet_cnt);
424  break;
425  default:
426  fprintf(stderr, "ERROR: invalid value field number\n");
427  clean();
428  return -1;
429  }
430 
431  /* zero out the fields we do not care about */
432  for(i = 0; i < FIELD_CNT; i++)
433  {
434  if(fields[i] != FIELD_ENABLED)
435  {
436  switch(i)
437  {
438  case SRC_IP:
439  tuple->src_ip = 0;
440  break;
441  case DST_IP:
443  break;
444  case SRC_PORT:
445  tuple->src_port = 0;
446  break;
447  case DST_PORT:
448  tuple->dst_port = 0;
449  break;
450  case PROTO:
451  tuple->protocol = 0;
452  break;
453  case TTL:
454  tuple->ttl = 0;
455  break;
456  case TCP_FLAGS:
457  tuple->tcp_flags = 0;
458  break;
459  case IP_LEN:
460  tuple->ip_len = 0;
461  break;
462  case VALUE:
463  tuple->packet_cnt = 0;
464  break;
465  default:
466  fprintf(stderr, "ERROR: invalid field number\n");
467  clean();
468  return -1;
469  }
470  }
471  }
472 
473  /* check if this stripped down flowtuple is already in the hash,
474  if not, add it.*/
475  if(value_field == VALUE)
476  {
477  if(add_inc_hash(sixt_v, tuple, value) != 0)
478  {
479  fprintf(stderr, "couldn't increment flowtuple packet_cnt value\n");
480  return -1;
481  }
482  }
483  else
484  {
485  if(add_inc_map(sixt_f, tuple, value) != 0)
486  {
487  fprintf(stderr, "could not add value to map");
488  return -1;
489  }
490  }
491 
492  return 0;
493 }
494 
496 int process_flowtuple_file(char *file)
497 {
498  off_t len = 0;
500  corsaro_interval_t *interval_record;
501  corsaro_flowtuple_t *tuple;
502 
503  fprintf(stderr, "processing %s\n", file);
504 
505  /* this must be done before corsaro_init_output */
506  if(init_corsaro(file) != 0)
507  {
508  fprintf(stderr, "failed to init corsaro\n");
509  clean();
510  return -1;
511  }
512 
513  /* dirty hack to not -1 on the last interval in the previous file */
514  if(last_interval_end.time > 0)
515  {
516  last_interval_end.time+=legacy;
517  }
518 
519  while ((len = corsaro_in_read_record(corsaro, &type, record)) > 0) {
520  /* we want to know the current time, so we will watch for interval start
521  records */
523  {
524  interval_record = (corsaro_interval_t *)
526 
527  if(interval_record->time <= last_dump_end.time)
528  {
529  fprintf(stderr, "ERROR: decrease in timestamp.\n"
530  "Are the input files sorted properly?\n");
531  clean();
532  return -1;
533  }
534 
535  if(flowtuple_cnt == 0)
536  {
537  last_dump_end.time = interval_record->time;
538  next_interval = interval_record->time + interval;
539  }
540 
541  /* an interval of 0 means dump at the source interval */
542  if(last_interval_end.time > 0)
543  {
544  /* this was a non-end interval, if it is legacy, subtract
545  one from the last_interval_end time */
546  last_interval_end.time-=legacy;
547  if(interval == 0)
548  {
549  dump_hash();
550  }
551  else if(interval > 0)
552  {
553  while(interval_record->time >= next_interval)
554  {
555  dump_hash();
557  }
558  }
559  /* else, if interval < 0, only dump at the end */
560  }
561  }
563  {
564  interval_record = (corsaro_interval_t *)
566 
567  last_interval_end.time = interval_record->time;
568 
569  }
571  {
572  tuple = (corsaro_flowtuple_t *)corsaro_in_get_record_data(record);
573  flowtuple_cnt++;
574 
575  process_flowtuple(tuple);
576  }
577 
578  /* reset the type to NULL to indicate we don't care */
580  }
581 
582  if(len < 0)
583  {
584  fprintf(stderr, "corsaro_in_read_record failed to read record\n");
585  clean();
586  return -1;
587  }
588 
589  clean();
590 
591  return 0;
592 
593 }
594 
595 
597 static void usage(const char *name)
598 {
599  fprintf(stderr,
600  "usage: %s [-l] [-i interval] [-v value_field] [-f field]... [-F file_list] \n"
601  " flowtuple_file [flowtuple_file]\n"
602  " -l treat the input files as containing legacy format data\n"
603  " -i <interval> new distribution interval in seconds. (default: 0)\n"
604  " a value of -1 aggregates to a single interval\n"
605  " a value of 0 uses the original interval\n"
606  " -v <value> field to use as aggregation value (default: packet_cnt)\n"
607  " -f <field> a tuple field to re-aggregate with\n"
608  " -F <file_list> a file with the list flowtuple files\n"
609  " use '-' to read the list from standard input\n"
610  "\n"
611  "Supported field names are:\n"
612  " src_ip, dst_ip, src_port, dst_port, protocol, ttl, tcp_flags, \n"
613  " ip_len, packet_cnt\n",
614  name);
615 }
616 
618 int main(int argc, char *argv[])
619 {
620  int opt;
621  int i;
622 
623  int field_cnt = 0;
624 
626  FILE *flist = NULL;
628  char file[1024];
629 
630  int wanted_n_fields = 0;
631 
632  while((opt = getopt(argc, argv, "li:f:F:v:?")) >= 0)
633  {
634  switch(opt)
635  {
636  case 'l':
637  /* the user has indicated they're giving us old format data
638  which has the interval end at +1 than we currently use */
639  legacy = 1;
640  break;
641 
642  case 'i':
643  interval = atoi(optarg);
644  break;
645 
646  case 'f':
647  wanted_n_fields++;
648  /* figure out what field they have asked for and then set the
649  appropriate field in the bitmap */
650  for(i = 0; i < FIELD_CNT; i++)
651  {
652  if(strcmp(optarg, field_names[i]) == 0)
653  {
654  fields[i] = FIELD_ENABLED;
655  field_cnt++;
656  break;
657  }
658  }
659  break;
660 
661  case 'F':
662  /* check if a list of files has been already specified */
663  if (flist != NULL) {
664  fprintf(stderr,"a list of file has been already specified \n"
665  "this file is ignored: %s\n",optarg);
666  break;
667  }
668 
669  /* check if the list of file is on stdin or in a file */
670  if(strcmp(optarg, "-") == 0)
671  {
672  flist = stdin;
673  }
674  else if((flist = fopen(optarg, "r")) == NULL)
675  {
676  fprintf(stderr, "failed to open list of input files (%s)\n"
677  "NB: File List MUST be sorted\n", optarg);
678  return -1;
679  }
680  break;
681 
682  case 'v':
683  if(value_field >= 0)
684  {
685  fprintf(stderr, "WARNING: Multiple value fields detected\n"
686  "Last specified will be used\n");
687  }
688  /* figure out what value they have asked for */
689  for(i = 0; i < FIELD_CNT; i++)
690  {
691  if(strcmp(optarg, field_names[i]) == 0)
692  {
693  value_field = i;
694  break;
695  }
696  }
697  break;
698 
699  case '?':
700  usage(argv[0]);
701  exit(0);
702  break;
703 
704  default:
705  usage(argv[0]);
706  exit(-1);
707  }
708  }
709 
710  /*
711  * ak comments this 10/11/12 after talking with Tanja
712  * it seems to make sense to allow *no* fields to be set so that users
713  * can get 'overall' counts of field values
714  * e.g. specifying no fields and using a 'src_ip' value will give the total
715  * number of source ips in the interval
716  */
717  /*
718  if(field_cnt < 1)
719  {
720  for(i = 0; i < FIELD_CNT; i++)
721  {
722  fields[i] = FIELD_ENABLED;
723  }
724  }
725  */
726 
727  if(wanted_n_fields != field_cnt)
728  {
729  fprintf(stderr, "Invalid field name\n");
730  usage(argv[0]);
731  exit(-1);
732  }
733 
734  if(value_field < 0)
735  {
736  fprintf(stderr, "No value field specified. Defaulting to packet count\n");
737  value_field = VALUE;
738  }
739 
740  /* initialize the hash */
741  if(value_field == VALUE)
742  {
743  sixt_v = kh_init(sixt_int);
744  }
745  else
746  {
747  sixt_f = kh_init(sixt_map);
748  }
749 
750  /* check if the user specified a list file */
751  if(flist != NULL)
752  {
753  /* flist point to a file of list of paths */
754  while(fgets(file, sizeof(file), flist) != NULL)
755  {
756  /* chomp off the newline */
757  file[strlen(file)-1] = '\0';
758  /* process flowtuple file */
759  if(process_flowtuple_file(file) == -1)
760  {
761  return -1;
762  }
763  }
764  fclose(flist);
765  }
766  else /* user specified file directly on the command line */
767  {
768  if(optind >= argc)
769  {
770  /* no files has been specified */
771  usage(argv[0]);
772  exit(-1);
773  }
774  /* iterate over all the files on the command line */
775  for (int i = optind; i < argc; i++)
776  {
777  if(process_flowtuple_file(argv[i]) == -1)
778  {
779  return -1;
780  }
781  }
782  }
783 
784  /* dump again if the hash is not empty */
785  if((sixt_f != NULL && kh_size(sixt_f) > 0)
786  || (sixt_v != NULL && kh_size(sixt_v) > 0))
787  {
788  dump_hash();
789  }
790 
791  if(sixt_f != NULL)
792  {
793  kh_free(sixt_map, sixt_f, &corsaro_flowtuple_free);
794  kh_destroy(sixt_map, sixt_f);
795  sixt_f = NULL;
796  }
797 
798  if(sixt_v != NULL)
799  {
800  kh_free(sixt_int, sixt_v, &corsaro_flowtuple_free);
801  kh_destroy(sixt_int, sixt_v);
802  sixt_v = NULL;
803  }
804 
805  return 0;
806 }
Structure representing the start or end of an interval.
Definition: corsaro_int.h:156
void corsaro_in_free_record(corsaro_in_record_t *record)
Free an corsaro record object.
Definition: corsaro.c:1542
corsaro_in_t * corsaro_alloc_input(const char *corsarouri)
Allocate an corsaro object for reading an corsaro file.
Definition: corsaro.c:1414
Header file which exports the public libcorsaro API.
void corsaro_io_print_interval_start(corsaro_interval_t *int_start)
Write the interval headers to stdout.
Definition: corsaro_io.c:865
The Source Port field of the FlowTuple.
int add_inc_hash(kh_sixt_int_t *hash, corsaro_flowtuple_t *t, uint32_t increment)
Either add the given flowtuple to the hash, or increment the current count.
Header file dealing with the corsaro logging sub-system.
#define CORSARO_FLOWTUPLE_IP_TO_SIXT(n32, flowtuple)
Convert a 32bit network order IP address into the 3 byte flowtuple format.
#define FIELD_ENABLED
Value if field is enabled.
static corsaro_interval_t last_interval_end
The time that the last interval ended.
The Protocol field of the FlowTuple.
static int init_corsaro(char *corsarouri)
Initialize a corsaro_in instance for the given input file name.
A reusable opaque structure for corsaro to read an input record into.
Definition: corsaro_int.h:350
static int value_field
The field to use as the value in aggregation.
void corsaro_io_print_interval_end(corsaro_interval_t *int_end)
Write the interval trailers to stdout.
Definition: corsaro_io.c:881
The TCP Flags field of the FlowTuple.
static void dump_hash_map(kh_sixt_map_t *hash)
Dump a map of flowtuple records.
int process_flowtuple_file(char *file)
Process a flowtuple file.
#define corsaro_flowtuple_hash_equal(alpha, bravo)
Tests two flowtuples for equality.
static uint64_t flowtuple_cnt
The number of flowtuple records we have processed.
Header file which exports corsaro_flowtuple plugin API.
enum field_index field_index_t
Set of FlowTuple fields that can be used for aggregation.
uint16_t number
The interval number (starts at 0)
Definition: corsaro_int.h:163
int corsaro_finalize_input(corsaro_in_t *corsaro)
Close the input file and free resources allocated by corsaro.
Definition: corsaro.c:1588
static void clean()
Cleanup and free state.
Overall corsaro magic number - "EDGR".
Definition: corsaro_int.h:73
void corsaro_flowtuple_free(corsaro_flowtuple_t *t)
Free a FlowTuple record.
static char * field_names[]
Array of strings corresponding to FlowTuple fields.
The corsaro_flowtuple flowtuple record.
Definition: corsaro.h:134
static kh_sixt_map_t * sixt_f
A map of aggregated flowtuple records.
int corsaro_start_input(corsaro_in_t *corsaro)
Initialize an corsaro input object that has already been allocated.
Definition: corsaro.c:1428
The end of an interval.
Definition: corsaro.h:115
static int interval
The amount of time to wait until we dump the hash.
#define CORSARO_FLOWTUPLE_SIXT_TO_IP(flowtuple)
Convert the 3byte flowtuple dest ip to 32bits of network ordered uint32.
The Destination IP address field of the FlowTuple.
khint32_t corsaro_flowtuple_hash_func(struct corsaro_flowtuple *ft)
Hash the given flowtuple into a 32bit value.
static corsaro_interval_t last_dump_end
the END time of the interval that we last dumped data
KHASH_INIT(sixt_map, corsaro_flowtuple_t *, kh_64xx_t *, 1, corsaro_flowtuple_hash_func, corsaro_flowtuple_hash_equal)
Initialize the hash functions and datatypes.
int main(int argc, char *argv[])
Entry point for the cors-ft-aggregate tool.
static field_index_t fields[FIELD_CNT]
An array of enabled fields for aggregation.
corsaro_in_record_t * corsaro_in_alloc_record(corsaro_in_t *corsaro)
Allocate a reusable corsaro record object.
Definition: corsaro.c:1514
static int process_flowtuple(corsaro_flowtuple_t *tuple)
Process a FlowTuple record.
corsaro interval magic number - "INTR"
Definition: corsaro_int.h:77
void corsaro_log_file(const char *func, corsaro_file_t *logfile, const char *format,...)
Write a formatted string to a generic log file.
Definition: corsaro_log.c:132
static corsaro_in_record_t * record
The record object to read into.
uint32_t time
The time this interval started/ended.
Definition: corsaro_int.h:165
static void usage(const char *name)
Print usage information to stderr.
Corsaro input state.
Definition: corsaro_int.h:323
The start of an interval.
Definition: corsaro.h:112
static int next_interval
The time that we need to dump the next interval at.
static void dump_hash()
Dump the aggregated FlowTuple records.
The Destination Port field of the FlowTuple.
Header file dealing with the corsaro file IO.
static void dump_hash_int(kh_sixt_int_t *hash)
Dump a hash of flowtuple records.
The Source IP address field of the FlowTuple.
The IP Length field of the FlowTuple.
The TTL field of the FlowTuple.
The null type used for wildcard matching.
Definition: corsaro.h:100
static int add_inc_map(void *h, corsaro_flowtuple_t *t, uint32_t value)
Either add the given flowtuple to the hash, or add the value to the map.
void * corsaro_in_get_record_data(corsaro_in_record_t *record)
Get a pointer data in a record.
Definition: corsaro.c:1583
The number of possible FlowTuple fields.
Corsaro output state.
Definition: corsaro_int.h:230
static int legacy
Set if reading from a legacy FlowTuple file.
off_t corsaro_in_read_record(corsaro_in_t *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read the next corsaro record from the given corsaro input file.
Definition: corsaro.c:1562
enum corsaro_in_record_type corsaro_in_record_type_t
Corsaro input record types.
The Packet Count field of the FlowTuple.
static kh_sixt_int_t * sixt_v
A hash of aggregated flowtuple records.
field_index
Set of FlowTuple fields that can be used for aggregation.
static void flowtuple_print_64(corsaro_flowtuple_t *flowtuple, uint64_t value)
Print a flowtuple with a 64 bit value field.