Skip to Content
[CAIDA - Center for Applied Internet Data Analysis logo]
The Center for Applied Internet Data Analysis
corsaro_flowtuple.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 "config.h"
27 #include "corsaro_int.h"
28 
29 #include <arpa/inet.h>
30 #include <assert.h>
31 #include <inttypes.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <unistd.h>
35 
36 #include "libtrace.h"
37 
38 #include "utils.h"
39 
40 #include "corsaro_io.h"
41 #include "corsaro_file.h"
42 #include "corsaro_log.h"
43 #include "corsaro_plugin.h"
44 
45 #include "corsaro_flowtuple.h"
46 
55 /* This magic number is a legacy number from when we used to call it the
56  'sixtuple' */
57 #ifdef CORSARO_SLASH_EIGHT
58 
59 #define CORSARO_FLOWTUPLE_MAGIC 0x53495854
60 #else
61 
62 #define CORSARO_FLOWTUPLE_MAGIC 0x53495855
63 #endif
64 
67  {
70 
73 
76 
78 
82 #define OUTFILE_POINTERS 2
83 
85 #define PLUGIN_NAME "flowtuple"
86 
89  PLUGIN_NAME, /* name */
91  CORSARO_FLOWTUPLE_MAGIC, /* magic */
92  CORSARO_PLUGIN_GENERATE_PTRS_FT(corsaro_flowtuple), /* func ptrs */
94 };
95 
97 static const char *class_names[] = {
98  "flowtuple_backscatter",
99  "flowtuple_icmpreq",
100  "flowtuple_other",
101 };
102 
104 KSORT_INIT(sixt, corsaro_flowtuple_t*, corsaro_flowtuple_lt);
105 
107 /*KHASH_INIT(sixt, corsaro_flowtuple_t*, khint32_t, 1, */
108 KHASH_INIT(sixt, corsaro_flowtuple_t*, char, 0,
110 
112 struct corsaro_flowtuple_state_t {
114  khash_t(sixt) *st_hash[CORSARO_FLOWTUPLE_CLASS_MAX+1];
116  uint16_t current_class;
118  corsaro_file_t *outfile;
120  corsaro_file_t *outfile_p[OUTFILE_POINTERS];
122  int outfile_n;
124  corsaro_flowtuple_sort_t sort_enabled;
125 };
126 
128 struct corsaro_flowtuple_in_state_t {
130  corsaro_in_record_type_t expected_type;
132  int tuple_total;
134  int tuple_cnt;
135 };
136 
138 #define STATE(corsaro) \
139  (CORSARO_PLUGIN_STATE(corsaro, flowtuple, CORSARO_PLUGIN_ID_FLOWTUPLE))
140 
141 #define STATE_IN(corsaro) \
142  (CORSARO_PLUGIN_STATE(corsaro, flowtuple_in, CORSARO_PLUGIN_ID_FLOWTUPLE))
143 
144 #define PLUGIN(corsaro) \
145  (CORSARO_PLUGIN_PLUGIN(corsaro, CORSARO_PLUGIN_ID_FLOWTUPLE))
146 
148 static void usage(corsaro_plugin_t *plugin)
149 {
150  fprintf(stderr,
151  "plugin usage: %s [-s]\n"
152  " -s disable flowtuple output sorting\n",
153  plugin->argv[0]);
154 }
155 
158 {
159  corsaro_plugin_t *plugin = PLUGIN(corsaro);
160  struct corsaro_flowtuple_state_t *state = STATE(corsaro);
161  int opt;
162 
163  if(plugin->argc <= 0)
164  {
165  return 0;
166  }
167 
168  /* NB: remember to reset optind to 1 before using getopt! */
169  optind = 1;
170 
171  while((opt = getopt(plugin->argc, plugin->argv, "s?")) >= 0)
172  {
173  switch(opt)
174  {
175  case 's':
176  state->sort_enabled = CORSARO_FLOWTUPLE_SORT_DISABLED;
177  break;
178 
179  case '?':
180  case ':':
181  default:
182  usage(plugin);
183  return -1;
184  }
185  }
186 
187  /* flowtuple doesn't take any arguments */
188  if(optind != plugin->argc)
189  {
190  usage(plugin);
191  return -1;
192  }
193 
194  return 0;
195 }
196 
205  libtrace_packet_t *packet)
206 {
207  void *temp = NULL;
208  uint8_t proto;
209  uint32_t remaining;
210 
211  libtrace_tcp_t *tcp_hdr = NULL;
212  libtrace_icmp_t *icmp_hdr = NULL;
213 
214  /* 10/19/12 ak removed check for ipv4 because it is checked in per_packet */
215 
216  /* get the transport header */
217  if((temp = trace_get_transport(packet, &proto, &remaining)) == NULL)
218  {
219  /* not enough payload */
221  }
222 
223  /* check for tcp */
224  if(proto == TRACE_IPPROTO_TCP && remaining >= 4)
225  {
226  tcp_hdr = (libtrace_tcp_t *)temp;
227 
228  /* look for SYNACK or RST */
229  if((tcp_hdr->syn && tcp_hdr->ack) || tcp_hdr->rst)
230  {
232  }
233  else
234  {
236  }
237  }
238  /* check for icmp */
239  else if(proto == TRACE_IPPROTO_ICMP && remaining >= 2)
240  {
241  icmp_hdr = (libtrace_icmp_t *)temp;
242  if(icmp_hdr->type == 0 ||
243  icmp_hdr->type == 3 ||
244  icmp_hdr->type == 4 ||
245  icmp_hdr->type == 5 ||
246  icmp_hdr->type == 11 ||
247  icmp_hdr->type == 12 ||
248  icmp_hdr->type == 14 ||
249  icmp_hdr->type == 16 ||
250  icmp_hdr->type == 18)
251  {
253  }
254  else
255  {
257  }
258  }
259  else
260  {
262  }
263 
264  return -1;
265 }
266 
268 static int sort_hash(corsaro_t *corsaro, kh_sixt_t *hash,
269  corsaro_flowtuple_t ***sorted)
270 {
271  khiter_t i;
272  corsaro_flowtuple_t **ptr;
273 
274  if((ptr = malloc(sizeof(corsaro_flowtuple_t*)*kh_size(hash))) == NULL)
275  {
276  corsaro_log(__func__, corsaro, "could not malloc array for sorted keys");
277  return -1;
278  }
279  *sorted = ptr;
280 
281  if(kh_size(hash) == 0)
282  {
283  /* no need to try and sort an empty hash */
284  return 0;
285  }
286 
287  for(i = kh_begin(hash); i != kh_end(hash); ++i)
288  {
289  if(kh_exist(hash, i))
290  {
291  *ptr = kh_key(hash, i);
292  ptr++;
293  }
294  }
295 
296  ks_introsort(sixt, kh_size(hash), *sorted);
297  return 0;
298 }
299 
302 {
303  struct corsaro_flowtuple_state_t *state = STATE(corsaro);
304  kh_sixt_t *h = state->st_hash[dist];
305 
306  int j;
307  corsaro_flowtuple_t **sorted_keys;
308  khiter_t i = 0;
309 
310  uint8_t hbuf[4+2+4];
311  uint8_t *hptr = &hbuf[0];
312 
314  hptr+=4;
315 
316  bytes_htons(hptr, dist);
317  hptr+=2;
318 
319  bytes_htonl(hptr, kh_size(h));
320 
321  if(corsaro_file_write(corsaro, STATE(corsaro)->outfile, &hbuf[0], 10) != 10)
322  {
323  corsaro_log(__func__, corsaro,
324  "could not dump byte flowtuple header to file");
325  return -1;
326  }
327 
328  if(kh_size(h) > 0)
329  {
330  if(state->sort_enabled == CORSARO_FLOWTUPLE_SORT_ENABLED)
331  {
332  /* sort the hash before dumping */
333  if(sort_hash(corsaro, h, &sorted_keys) != 0)
334  {
335  corsaro_log(__func__, corsaro, "could not sort keys");
336  return -1;
337  }
338  for(j = 0; j < kh_size(h); j++)
339  {
340  if(corsaro_file_write(corsaro, STATE(corsaro)->outfile,
341  sorted_keys[j],
344  {
345  corsaro_log(__func__, corsaro,
346  "could not write flowtuple to file");
347  return -1;
348  }
349  /* this actually frees the flowtuples themselves */
350  free(sorted_keys[j]);
351  }
352  free(sorted_keys);
353  }
354  else
355  {
356  /* do not sort the hash */
357  for(i = kh_begin(h); i != kh_end(h); ++i)
358  {
359  if(kh_exist(h, i))
360  {
361  if(corsaro_file_write(corsaro, STATE(corsaro)->outfile,
362  kh_key(h, i),
365  {
366  corsaro_log(__func__, corsaro,
367  "could not write flowtuple to file");
368  return -1;
369  }
370  free(kh_key(h, i));
371  }
372  }
373  }
374  }
375 
376  if(corsaro_file_write(corsaro, STATE(corsaro)->outfile, &hbuf[0], 6) != 6)
377  {
378  corsaro_log(__func__, corsaro, "could not dump flowtuple trailer to file");
379  return -1;
380  }
381  return 0;
382 }
383 
386 {
387  struct corsaro_flowtuple_state_t *state = STATE(corsaro);
388  kh_sixt_t *h = state->st_hash[dist];
389 
390  corsaro_flowtuple_t **sorted_keys;
391  int j;
392  khiter_t i;
393 
394  /*const char *name = class_names[dist];*/
395  corsaro_flowtuple_class_start_t class_start;
396  corsaro_flowtuple_class_end_t class_end;
397 
398  class_start.magic = CORSARO_FLOWTUPLE_MAGIC;
399  class_start.class_type = dist;
400  class_start.count = kh_size(h);
401 
402  class_end.magic = CORSARO_FLOWTUPLE_MAGIC;
403  class_end.class_type = dist;
404 
405  corsaro_flowtuple_class_start_fprint(corsaro, STATE(corsaro)->outfile,
406  &class_start);
407 
408  if(kh_size(h) > 0)
409  {
410  if(state->sort_enabled == CORSARO_FLOWTUPLE_SORT_ENABLED)
411  {
412  /* sort the hash before dumping */
413  if(sort_hash(corsaro, h, &sorted_keys) != 0)
414  {
415  corsaro_log(__func__, corsaro, "could not sort keys");
416  return -1;
417  }
418  for(j = 0; j < kh_size(h); j++)
419  {
420  corsaro_flowtuple_fprint(corsaro, STATE(corsaro)->outfile,
421  sorted_keys[j]);
422 
423  free(sorted_keys[j]);
424  }
425  free(sorted_keys);
426  }
427  else
428  {
429  /* do not sort the hash before dumping */
430  for(i = kh_begin(h); i != kh_end(h); ++i)
431  {
432  if(kh_exist(h, i))
433  {
434  corsaro_flowtuple_fprint(corsaro,
435  STATE(corsaro)->outfile,
436  kh_key(h, i));
437  free(kh_key(h, i));
438  }
439  }
440  }
441  }
442 
443  corsaro_flowtuple_class_end_fprint(corsaro, STATE(corsaro)->outfile,
444  &class_end);
445  return 0;
446 }
447 
449 static int validate_class_start(corsaro_flowtuple_class_start_t *class)
450 {
451  /* byteswap the values */
452  class->magic = ntohl(class->magic);
453  class->class_type = ntohs(class->class_type);
454  class->count = ntohl(class->count);
455 
456  /* do some sanity checking */
457  if(class->magic != CORSARO_FLOWTUPLE_MAGIC ||
458  class->class_type > CORSARO_FLOWTUPLE_CLASS_MAX)
459  {
460  return 0;
461  }
462  return 1;
463 }
464 
467  corsaro_in_record_type_t *record_type,
469 {
470  off_t bytes_read;
471 
472  if((bytes_read =
473  corsaro_io_read_bytes(corsaro, record,
474  sizeof(corsaro_flowtuple_class_start_t))) !=
475  sizeof(corsaro_flowtuple_class_start_t))
476  {
477  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
478  return bytes_read;
479  }
480 
481  if(validate_class_start((corsaro_flowtuple_class_start_t *)record->buffer) != 1)
482  {
483  corsaro_log_in(__func__, corsaro, "could not validate flowtuple class");
484  corsaro_log_in(__func__, corsaro,
485  "it is possible this flowtuple file was written "
486 #ifdef CORSARO_SLASH_EIGHT
487  "without /8 "
488 #else
489  "with /8 "
490 #endif
491  "optimizations enabled");
492  corsaro_log_in(__func__, corsaro, "try rebuilding using the "
493 #ifdef CORSARO_SLASH_EIGHT
494  "--without-slash-eight "
495 #else
496  "--with-slash-eight=0 "
497 #endif
498  "configure option");
499  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
500  return -1;
501  }
502 
503  assert(bytes_read == sizeof(corsaro_flowtuple_class_start_t));
504 
506  STATE_IN(corsaro)->tuple_total = ((corsaro_flowtuple_class_start_t *)
507  record->buffer)->count;
508 
509  STATE_IN(corsaro)->expected_type = (STATE_IN(corsaro)->tuple_total == 0) ?
512 
513  return bytes_read;
514 }
515 
517 static int validate_class_end(corsaro_flowtuple_class_end_t *class)
518 {
519  /* byteswap the values */
520  class->magic = ntohl(class->magic);
521  class->class_type = ntohs(class->class_type);
522 
523  /* do some sanity checking */
524  if(class->magic != CORSARO_FLOWTUPLE_MAGIC ||
525  class->class_type > CORSARO_FLOWTUPLE_CLASS_MAX)
526  {
527  return 0;
528  }
529  return 1;
530 }
531 
534  corsaro_in_record_type_t *record_type,
536 {
537  off_t bytes_read;
538 
539  if((bytes_read =
540  corsaro_io_read_bytes(corsaro, record,
541  sizeof(corsaro_flowtuple_class_end_t))) !=
542  sizeof(corsaro_flowtuple_class_end_t))
543  {
544  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
545  return bytes_read;
546  }
547 
548  if(validate_class_end((corsaro_flowtuple_class_end_t *)record->buffer) != 1)
549  {
550  corsaro_log_in(__func__, corsaro, "could not validate flowtuple class end");
551  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
552  return -1;
553  }
554 
555  assert(bytes_read == sizeof(corsaro_flowtuple_class_end_t));
556 
558  STATE_IN(corsaro)->expected_type = (((corsaro_flowtuple_class_end_t *)
559  record->buffer)->class_type ==
560  (uint16_t)CORSARO_FLOWTUPLE_CLASS_MAX) ?
563  STATE_IN(corsaro)->tuple_total = 0;
564  STATE_IN(corsaro)->tuple_cnt = 0;
565 
566  return bytes_read;
567 }
568 
570 static int validate_flowtuple(corsaro_flowtuple_t *flowtuple)
571 {
572  /* there is no real validation that can be done with this */
573  return 1;
574 }
575 
578  corsaro_in_record_type_t *record_type,
580 {
581  off_t bytes_read;
582 
583  if((bytes_read = corsaro_io_read_bytes(corsaro, record,
584  sizeof(corsaro_flowtuple_t))) !=
585  sizeof(corsaro_flowtuple_t))
586  {
587  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
588  return bytes_read;
589  }
590 
591  if(validate_flowtuple((corsaro_flowtuple_t *)record->buffer) != 1)
592  {
593  corsaro_log_in(__func__, corsaro, "could not validate flowtuple");
594  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
595  return -1;
596  }
597 
599 
600  if(++(STATE_IN(corsaro)->tuple_cnt) == STATE_IN(corsaro)->tuple_total)
601  {
602  STATE_IN(corsaro)->expected_type = CORSARO_IN_RECORD_TYPE_FLOWTUPLE_CLASS_END;
603  }
604 
605  assert(bytes_read == sizeof(corsaro_flowtuple_t));
606 
607  return bytes_read;
608 }
609 
610 /* == PUBLIC PLUGIN FUNCS BELOW HERE == */
611 
614 {
615  return &corsaro_flowtuple_plugin;
616 }
617 
619 int corsaro_flowtuple_probe_filename(const char *fname)
620 {
621  /* look for 'corsaro_flowtuple' in the name */
622  return corsaro_plugin_probe_filename(fname, &corsaro_flowtuple_plugin);
623 }
624 
627  corsaro_file_in_t *file)
628 {
629  char buffer[1024];
630  int len;
632 
633  len = corsaro_file_rpeek(file, buffer, sizeof(buffer));
634 
635  /* an corsaro flowtuple file will have 'SIX[TU]' at 14, 15, 16, 17 */
637  buffer[i++] == 'S' && buffer[i++] == 'I' &&
638  buffer[i++] == 'X' && (buffer[i] == 'T' || buffer[i] == 'U'))
639  {
640  return 1;
641  }
642 
643  return 0;
644 }
645 
648 {
649  int i;
650  struct corsaro_flowtuple_state_t *state;
651  corsaro_plugin_t *plugin = PLUGIN(corsaro);
652  assert(plugin != NULL);
653 
654  if((state = malloc_zero(sizeof(struct corsaro_flowtuple_state_t))) == NULL)
655  {
656  corsaro_log(__func__, corsaro,
657  "could not malloc corsaro_flowtuple_state_t");
658  goto err;
659  }
660  corsaro_plugin_register_state(corsaro->plugin_manager, plugin, state);
661 
662  /* set sort to it's default value */
663  state->sort_enabled = CORSARO_FLOWTUPLE_SORT_DEFAULT;
664 
665  /* parse the arguments */
666  if(parse_args(corsaro) != 0)
667  {
668  return -1;
669  }
670 
671  /* defer opening the output file until we start the first interval */
672 
673  for(i = 0; i <= CORSARO_FLOWTUPLE_CLASS_MAX; i++)
674  {
675  assert(state->st_hash[i] == NULL);
676  state->st_hash[i] = kh_init(sixt);
677  assert(state->st_hash[i] != NULL);
678  }
679 
680  return 0;
681 
682  err:
684  return -1;
685 }
686 
689 {
690  struct corsaro_flowtuple_in_state_t *state;
691  corsaro_plugin_t *plugin = PLUGIN(corsaro);
692  assert(plugin != NULL);
693 
694  if((state = malloc_zero(sizeof(struct corsaro_flowtuple_in_state_t))) == NULL)
695  {
696  corsaro_log_in(__func__, corsaro,
697  "could not malloc corsaro_flowtuple_state_t");
698  goto err;
699  }
700  corsaro_plugin_register_state(corsaro->plugin_manager, plugin, state);
701 
702  /* we initially expect an corsaro interval record */
703  state->expected_type = CORSARO_IN_RECORD_TYPE_IO_INTERVAL_START;
704 
705  /* don't set the tuple_cnt until we actually see a class start record */
706 
707  return 0;
708 
709  err:
711  return -1;
712 }
713 
716 {
717  struct corsaro_flowtuple_in_state_t *state = STATE_IN(corsaro);
718 
719  if(state != NULL)
720  {
721  corsaro_plugin_free_state(corsaro->plugin_manager, PLUGIN(corsaro));
722  }
723  return 0;
724 }
725 
728 {
729  int i;
730  struct corsaro_flowtuple_state_t *state = STATE(corsaro);
731 
732  if(state != NULL)
733  {
734  for(i = 0; i <= CORSARO_FLOWTUPLE_CLASS_MAX; i++)
735  {
736  if(state->st_hash[i] != NULL)
737  {
738  /* NB: flowtuples are freed in the dump functions */
739  kh_destroy(sixt, state->st_hash[i]);
740  state->st_hash[i] = NULL;
741  }
742  }
743 
744  /* close all the outfile pointers */
745  for(i = 0; i < OUTFILE_POINTERS; i++)
746  {
747  if(state->outfile_p[i] != NULL)
748  {
749  corsaro_file_close(corsaro, state->outfile_p[i]);
750  state->outfile_p[i] = NULL;
751  }
752  }
753  state->outfile = NULL;
754  corsaro_plugin_free_state(corsaro->plugin_manager, PLUGIN(corsaro));
755  }
756  return 0;
757 }
758 
761  corsaro_in_record_type_t *record_type,
763 {
764 
765  struct corsaro_flowtuple_in_state_t *state = STATE_IN(corsaro);
766 
767  off_t bytes_read = -1;
768 
769  /* we have 5 different types of records that could be in this file */
770  switch(state->expected_type)
771  {
773  /* ask the io subsystem to read it for us */
774  bytes_read = corsaro_io_read_interval_start(corsaro, corsaro->file,
775  record_type, record);
776  if(bytes_read == sizeof(corsaro_interval_t))
777  {
778  state->expected_type = CORSARO_IN_RECORD_TYPE_FLOWTUPLE_CLASS_START;
779  }
780  break;
781 
783  /* we'll handle this one */
784  bytes_read = read_class_start(corsaro, record_type, record);
785  break;
786 
788  /* we'll handle this too */
789  bytes_read = read_flowtuple(corsaro, record_type, record);
790  break;
791 
793  /* as with this */
794  bytes_read = read_class_end(corsaro, record_type, record);
795  break;
796 
798  /* ask the io subsystem to read it for us */
799  bytes_read = corsaro_io_read_interval_end(corsaro, corsaro->file,
800  record_type, record);
801  if(bytes_read == sizeof(corsaro_interval_t))
802  {
803  state->expected_type = CORSARO_IN_RECORD_TYPE_IO_INTERVAL_START;
804  }
805  break;
806 
807  default:
808  corsaro_log_in(__func__, corsaro, "invalid expected record type");
809  }
810 
811  return bytes_read;
812 }
813 
816  enum corsaro_in_record_type *record_type,
817  struct corsaro_in_record *record)
818 {
819  /* we write nothing to the global file. someone messed up */
820  return -1;
821 }
822 
825  corsaro_interval_t *int_start)
826 {
827  if(STATE(corsaro)->outfile == NULL)
828  {
829  if((
830  STATE(corsaro)->outfile_p[STATE(corsaro)->outfile_n] =
831  corsaro_io_prepare_file(corsaro,
832  PLUGIN(corsaro)->name,
833  int_start)) == NULL)
834  {
835  corsaro_log(__func__, corsaro, "could not open %s output file",
836  PLUGIN(corsaro)->name);
837  return -1;
838  }
839  STATE(corsaro)->outfile = STATE(corsaro)->
840  outfile_p[STATE(corsaro)->outfile_n];
841  }
842 
843  return 0;
844 }
845 
848  corsaro_interval_t *int_end)
849 {
850  int i;
851  struct corsaro_flowtuple_state_t *state = STATE(corsaro);
852 
853  corsaro_io_write_interval_start(corsaro, state->outfile,
854  &corsaro->interval_start);
855 
856  for(i = 0; i <= CORSARO_FLOWTUPLE_CLASS_MAX; i++)
857  {
858  assert(state->st_hash[i] != NULL);
859 
860  if(
861  (CORSARO_FILE_MODE(state->outfile)
863  binary_dump(corsaro, i) != 0)
864  ||
865  (CORSARO_FILE_MODE(state->outfile)
867  ascii_dump(corsaro, i) != 0)
868  )
869  {
870  corsaro_log(__func__, corsaro, "could not dump hash");
871  return -1;
872  }
873 
874  /* free all of the flowtuples */
875  /* 10/25/12 ak optimizes slightly by moving the frees to the dump
876  functions. makes it harder to maintain, but we dont have to
877  walk the hash twice */
878  /*kh_free(sixt, state->st_hash[i], &corsaro_flowtuple_free);*/
879  kh_clear(sixt, state->st_hash[i]);
880  }
881  corsaro_io_write_interval_end(corsaro, state->outfile, int_end);
882 
883  /* if we are rotating, now is when we should do it */
884  if(corsaro_is_rotate_interval(corsaro))
885  {
886  /* leave the current file to finish draining buffers */
887  assert(state->outfile != NULL);
888 
889  /* move on to the next output pointer */
890  state->outfile_n = (state->outfile_n+1) %
892 
893  if(state->outfile_p[state->outfile_n] != NULL)
894  {
895  /* we're gonna have to wait for this to close */
896  corsaro_file_close(corsaro,
897  state->outfile_p[state->outfile_n]);
898  state->outfile_p[state->outfile_n] = NULL;
899  }
900 
901  state->outfile = NULL;
902  }
903  return 0;
904 }
905 
909 {
910  libtrace_packet_t *ltpacket = LT_PKT(packet);
911  libtrace_ip_t *ip_hdr = NULL;
912  libtrace_icmp_t *icmp_hdr = NULL;
913  libtrace_tcp_t *tcp_hdr = NULL;
914  corsaro_flowtuple_t t;
915  int class;
916 
917  /* no point carrying on if a previous plugin has already decided we should
918  ignore this packet */
919  if((packet->state.flags & CORSARO_PACKET_STATE_IGNORE) != 0)
920  {
921  return 0;
922  }
923 
924  if((ip_hdr = trace_get_ip(ltpacket)) == NULL)
925  {
926  /* non-ipv4 packet */
927  return 0;
928  }
929 
930  t.ip_len = ip_hdr->ip_len;
931 
932  t.src_ip = ip_hdr->ip_src.s_addr;
933  CORSARO_FLOWTUPLE_IP_TO_SIXT(ip_hdr->ip_dst.s_addr, &t);
934 
935  t.protocol = ip_hdr->ip_p;
936  t.tcp_flags = 0; /* in case we don't find a tcp header */
937 
938  t.ttl = ip_hdr->ip_ttl;
939 
940  if(ip_hdr->ip_p == TRACE_IPPROTO_ICMP &&
941  (icmp_hdr = trace_get_icmp(ltpacket)) != NULL)
942  {
943  t.src_port = htons(icmp_hdr->type);
944  t.dst_port = htons(icmp_hdr->code);
945  }
946  else
947  {
948  if(ip_hdr->ip_p == TRACE_IPPROTO_TCP &&
949  (tcp_hdr = trace_get_tcp(ltpacket)) != NULL)
950  {
951  /* we have ignore the NS flag because it doesn't fit in
952  an 8 bit field. blame alberto (ak - 2/2/12) */
953  t.tcp_flags = (
954  (tcp_hdr->cwr << 7) |
955  (tcp_hdr->ece << 6) |
956  (tcp_hdr->urg << 5) |
957  (tcp_hdr->ack << 4) |
958  (tcp_hdr->psh << 3) |
959  (tcp_hdr->rst << 2) |
960  (tcp_hdr->syn << 1) |
961  (tcp_hdr->fin << 0)
962  );
963  }
964 
965  t.src_port = htons(trace_get_source_port(ltpacket));
966  t.dst_port = htons(trace_get_destination_port(ltpacket));
967  }
968 
969  /* classify this packet and increment the appropriate hash */
970  if((class = flowtuple_classify_packet(corsaro, ltpacket)) < 0)
971  {
972  corsaro_log(__func__, corsaro, "could not classify packet");
973  return -1;
974  }
975 
977  {
979  }
980 
981  if(corsaro_flowtuple_add_inc(STATE(corsaro)->st_hash[class], &t, 1) != 0)
982  {
983  corsaro_log(__func__, corsaro,
984  "could not increment value for flowtuple");
985  return -1;
986  }
987  return 0;
988 }
989 
992  corsaro_flowtuple_t *flowtuple,
993  corsaro_packet_state_t *state)
994 {
995  /* no point carrying on if a previous plugin has already decided we should
996  ignore this tuple */
997  if((state->flags & CORSARO_PACKET_STATE_IGNORE) != 0)
998  {
999  return 0;
1000  }
1001 
1002  if(corsaro_flowtuple_add_inc(STATE(corsaro)->
1003  st_hash[STATE(corsaro)->current_class],
1004  flowtuple,
1005  ntohl(flowtuple->packet_cnt)) != 0)
1006  {
1007  corsaro_log(__func__, corsaro,
1008  "could not increment value for flowtuple");
1009  return -1;
1010  }
1011  return 0;
1012 }
1013 
1016  corsaro_flowtuple_class_start_t *class)
1017 {
1018  STATE(corsaro)->current_class = class->class_type;
1019  return 0;
1020 }
1021 
1024  corsaro_flowtuple_class_end_t *class)
1025 {
1026  /* we just need the class starts really */
1027  return 0;
1028 }
1029 
1030 /* ==== FlowTuple External Convenience Functions ==== */
1031 
1034 {
1035  corsaro_file_in_t *ifile = NULL;
1036  int res = 0;
1037 
1038  if(corsaro_flowtuple_probe_filename(fturi) != 0)
1039  {
1040  return 1;
1041  }
1042 
1043  /* open the file */
1044  if((ifile = corsaro_file_ropen(fturi)) == NULL)
1045  {
1046  /* this simply means that it is likely a libtrace file */
1047  return 0;
1048  }
1049  /* We can only probe binary files */
1051  {
1052  res = corsaro_flowtuple_probe_magic(corsaro, ifile);
1053  }
1054 
1055  corsaro_file_rclose(ifile);
1056  return res;
1057 }
1058 
1060 uint32_t corsaro_flowtuple_get_source_ip(corsaro_flowtuple_t *flowtuple)
1061 {
1062  assert(flowtuple != NULL);
1063 
1064  return flowtuple->src_ip;
1065 }
1066 
1068 uint32_t corsaro_flowtuple_get_destination_ip(corsaro_flowtuple_t *flowtuple)
1069 {
1070  assert(flowtuple != NULL);
1071 
1072  return CORSARO_FLOWTUPLE_SIXT_TO_IP(flowtuple);
1073 }
1074 
1077  corsaro_flowtuple_t *flowtuple)
1078 {
1079  char ip_a[INET_ADDRSTRLEN];
1080  char ip_b[INET_ADDRSTRLEN];
1081  uint32_t tmp;
1082 
1083  assert(corsaro != NULL);
1084  assert(file != NULL);
1085  assert(flowtuple != NULL);
1086 
1087  tmp = flowtuple->src_ip;
1088  inet_ntop(AF_INET,&tmp, &ip_a[0], 16);
1089  tmp = CORSARO_FLOWTUPLE_SIXT_TO_IP(flowtuple);
1090  inet_ntop(AF_INET, &tmp, &ip_b[0], 16);
1091 
1092  return corsaro_file_printf(corsaro, file, "%s|%s"
1093  "|%"PRIu16"|%"PRIu16
1094  "|%"PRIu8"|%"PRIu8"|0x%02"PRIx8
1095  "|%"PRIu16
1096  ",%"PRIu32"\n",
1097  ip_a, ip_b,
1098  ntohs(flowtuple->src_port),
1099  ntohs(flowtuple->dst_port),
1100  flowtuple->protocol,
1101  flowtuple->ttl,
1102  flowtuple->tcp_flags,
1103  ntohs(flowtuple->ip_len),
1104  ntohl(flowtuple->packet_cnt));
1105 }
1106 
1108 void corsaro_flowtuple_print(corsaro_flowtuple_t *flowtuple)
1109 {
1110  char ip_a[16];
1111  char ip_b[16];
1112  uint32_t tmp;
1113 
1114  assert(flowtuple != NULL);
1115 
1116  tmp = flowtuple->src_ip;
1117  inet_ntop(AF_INET,&tmp, &ip_a[0], 16);
1118  tmp = CORSARO_FLOWTUPLE_SIXT_TO_IP(flowtuple);
1119  inet_ntop(AF_INET, &tmp, &ip_b[0], 16);
1120 
1121  fprintf(stdout, "%s|%s"
1122  "|%"PRIu16"|%"PRIu16
1123  "|%"PRIu8"|%"PRIu8"|0x%02"PRIx8
1124  "|%"PRIu16
1125  ",%"PRIu32"\n",
1126  ip_a, ip_b,
1127  ntohs(flowtuple->src_port),
1128  ntohs(flowtuple->dst_port),
1129  flowtuple->protocol,
1130  flowtuple->ttl,
1131  flowtuple->tcp_flags,
1132  ntohs(flowtuple->ip_len),
1133  ntohl(flowtuple->packet_cnt));
1134 }
1135 
1138  corsaro_file_t *file,
1139  corsaro_flowtuple_class_start_t *class)
1140 {
1141  return corsaro_file_printf(corsaro, file,
1142  "START %s %"PRIu32"\n",
1143  class_names[class->class_type],
1144  class->count);
1145 }
1146 
1148 void corsaro_flowtuple_class_start_print(corsaro_flowtuple_class_start_t *class)
1149 {
1150  fprintf(stdout, "START %s %"PRIu32"\n", class_names[class->class_type],
1151  class->count);
1152 }
1153 
1156  corsaro_file_t *file,
1157  corsaro_flowtuple_class_end_t *class)
1158 {
1159  return corsaro_file_printf(corsaro, file, "END %s\n",
1160  class_names[class->class_type]);
1161 }
1162 
1164 void corsaro_flowtuple_class_end_print(corsaro_flowtuple_class_end_t *class)
1165 {
1166  fprintf(stdout, "END %s\n", class_names[class->class_type]);
1167 }
1168 
1171  corsaro_in_record_type_t record_type,
1173 {
1174  switch(record_type)
1175  {
1177  return corsaro_flowtuple_class_start_fprint(corsaro, file,
1178  (corsaro_flowtuple_class_start_t *)record->buffer);
1179  break;
1180 
1182  return corsaro_flowtuple_class_end_fprint(corsaro, file,
1183  (corsaro_flowtuple_class_end_t *)record->buffer);
1184  break;
1185 
1187  return corsaro_flowtuple_fprint(corsaro, file,
1188  (corsaro_flowtuple_t *)record->buffer);
1189  break;
1190 
1191  default:
1192  corsaro_log(__func__, corsaro, "record_type %d not a flowtuple record",
1193  record_type);
1194  return -1;
1195  break;
1196  }
1197 
1198  return -1;
1199 }
1200 
1204 {
1205  switch(record_type)
1206  {
1209  (corsaro_flowtuple_class_start_t *)record->buffer);
1210  break;
1211 
1214  (corsaro_flowtuple_class_end_t *)record->buffer);
1215  break;
1216 
1218  corsaro_flowtuple_print((corsaro_flowtuple_t *)record->buffer);
1219  break;
1220 
1221  default:
1222  corsaro_log_file(__func__, NULL, "record_type %d not a flowtuple record",
1223  record_type);
1224  return -1;
1225  break;
1226  }
1227 
1228  return 0;
1229 }
1230 
1232 void inline corsaro_flowtuple_free(corsaro_flowtuple_t *t)
1233 {
1234  free(t);
1235 }
1236 
1238 int corsaro_flowtuple_add_inc(void *h, corsaro_flowtuple_t *t,
1239  uint32_t increment)
1240 {
1241  kh_sixt_t *hash = (kh_sixt_t *)h;
1242  int khret;
1243  khiter_t khiter;
1244  corsaro_flowtuple_t *new_6t = NULL;
1245 
1246  assert(hash != NULL);
1247 
1248  /* check if this is in the hash already */
1249  if((khiter = kh_get(sixt, hash, t)) == kh_end(hash))
1250  {
1251  /* create a new tuple struct */
1252  if((new_6t = malloc(sizeof(corsaro_flowtuple_t))) == NULL)
1253  {
1254  corsaro_log_file(__func__, NULL, "malloc failed");
1255  return -1;
1256  }
1257 
1258  /* fill it */
1259  memcpy(new_6t, t, sizeof(corsaro_flowtuple_t));
1260 
1261  /* add it to the hash */
1262  khiter = kh_put(sixt, hash, new_6t, &khret);
1263  /* set the count to one */
1264  /*kh_value(hash, khiter) = increment;*/
1265  new_6t->packet_cnt = htonl(increment);
1266  }
1267  else
1268  {
1269  /* simply increment the existing one */
1270  /*kh_value(hash, khiter)+=increment;*/
1271  new_6t = kh_key(hash, khiter);
1272 
1273  /* will this cause a wrap? */
1274  assert((UINT32_MAX - ntohl(new_6t->packet_cnt)) > increment);
1275 
1276  new_6t->packet_cnt = htonl(ntohl(new_6t->packet_cnt)+increment);
1277  }
1278  return 0;
1279 }
1280 
1281 /*
1282  * Hashes the flowtuple based on the following table
1283  *
1284  * With slash eight optimization:
1285  * --------------------------------
1286  * | SRC_IP * 59 |
1287  * ----------------------------------------
1288  * | | DST_IP << 8 | PROTO |
1289  * ----------------------------------------
1290  * | SRC_PORT <<16 | DST_PORT |
1291  * --------------------------------
1292  * | TTL |TCP_FLG| LEN |
1293  * --------------------------------
1294  *
1295  * Without slash eight optimization:
1296  * --------------------------------
1297  * | SRC_IP * 59 |
1298  * --------------------------------
1299  * | DST_IP |
1300  * --------------------------------
1301  * | SRC_PORT <<16 | DST_PORT |
1302  * --------------------------------
1303  * | TTL |TCP_FLG|PROTO| LEN |
1304  * --------------------------------
1305  */
1307 {
1308  khint32_t h = (khint32_t)ft->src_ip*59;
1309 #ifdef CORSARO_SLASH_EIGHT
1310  CORSARO_FLOWTUPLE_SHIFT_AND_XOR((ft->dst_ip.b<<24)|(ft->dst_ip.c<<16)|
1311  (ft->dst_ip.d<<8)|(ft->protocol));
1312 #else
1314 #endif
1317  CORSARO_FLOWTUPLE_SHIFT_AND_XOR((ft->ttl<<24)|(ft->tcp_flags<<16));
1318 #ifdef CORSARO_SLASH_EIGHT
1320 #else
1322 #endif
1323  return h;
1324 }
Structure representing the start or end of an interval.
Definition: corsaro_int.h:156
An opaque structure defining an corsaro input file.
Definition: corsaro_file.h:86
Plugins which write output should ignore this packet.
Definition: corsaro_int.h:207
int corsaro_flowtuple_end_interval(corsaro_t *corsaro, corsaro_interval_t *int_end)
Implements the end_interval function of the plugin API.
Header file dealing with the corsaro plugin manager.
static void usage(corsaro_plugin_t *plugin)
Print usage information to stderr.
int corsaro_flowtuple_process_packet(corsaro_t *corsaro, corsaro_packet_t *packet)
Implements the process_packet function of the plugin API.
int corsaro_flowtuple_process_flowtuple_class_end(corsaro_t *corsaro, corsaro_flowtuple_class_end_t *class)
Implements the process_flowtuple_class_end function of the plugin API.
The highest class value currently in use.
KHASH_INIT(sixt, corsaro_flowtuple_t *, char, 0, corsaro_flowtuple_hash_func, corsaro_flowtuple_hash_equal)
Initialize the hash functions and datatypes.
void bytes_htonl(uint8_t *bytes, uint32_t u32)
Convert a host ordered long to a network ordered byte array.
Definition: utils.c:57
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.
An opaque structure defining an corsaro output file.
Definition: corsaro_file.h:60
off_t corsaro_flowtuple_class_end_fprint(corsaro_t *corsaro, corsaro_file_t *file, corsaro_flowtuple_class_end_t *class)
Print a class end record to a file in ASCII format.
corsaro_plugin_t * corsaro_flowtuple_alloc(corsaro_t *corsaro)
Implements the alloc function of the plugin API.
This packet is a backscatter packet.
off_t corsaro_file_printf(struct corsaro *corsaro, corsaro_file_t *file, const char *format,...)
Print a string to an corsaro file.
Definition: corsaro_file.c:214
void corsaro_flowtuple_print(corsaro_flowtuple_t *flowtuple)
Print a FlowTuple to stdout in ASCII format.
A reusable opaque structure for corsaro to read an input record into.
Definition: corsaro_int.h:350
corsaro_plugin_manager_t * plugin_manager
A pointer to the corsaro plugin manager state.
Definition: corsaro_int.h:336
char ** argv
Array of plugin arguments This is populated by the plugin manager in corsaro_plugin_enable_plugin.
uint32_t corsaro_flowtuple_get_destination_ip(corsaro_flowtuple_t *flowtuple)
Convenience function to get the destination IP address from a FlowTuple.
ASCII IO mode.
Definition: corsaro.h:153
#define LT_PKT(corsaro_packet)
Convenience macro to get to the libtrace packet inside an corsaro packet.
Definition: corsaro_int.h:227
Binary IO mode.
Definition: corsaro.h:155
#define STATE(corsaro)
Extends the generic plugin state convenience macro in corsaro_plugin.h.
static int read_class_start(corsaro_in_t *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read a class start record.
off_t corsaro_flowtuple_read_global_data_record(struct corsaro_in *corsaro, enum corsaro_in_record_type *record_type, struct corsaro_in_record *record)
Implements the read_global_data_record function of the plugin API.
int corsaro_flowtuple_close_output(corsaro_t *corsaro)
Implements the close_output function of the plugin API.
corsaro_flowtuple_sort
Possible states for FlowTuple output sorting.
off_t corsaro_flowtuple_record_fprint(corsaro_t *corsaro, corsaro_file_t *file, corsaro_in_record_type_t record_type, corsaro_in_record_t *record)
Print a record to a file in ASCII format.
static int validate_class_end(corsaro_flowtuple_class_end_t *class)
Check that a class end record is valid.
Default FlowTuple output sorting behavior (enabled)
void corsaro_flowtuple_class_end_print(corsaro_flowtuple_class_end_t *class)
Print a class end record to stdout in ASCII format.
FlowTuple output sorting is enabled.
int corsaro_flowtuple_probe_filename(const char *fname)
Implements the probe_filename function of the plugin API.
#define CORSARO_FILE_MODE(file)
Accessor macro for getting the mode of a file.
Definition: corsaro_file.h:113
#define corsaro_flowtuple_hash_equal(alpha, bravo)
Tests two flowtuples for equality.
off_t corsaro_file_rpeek(corsaro_file_in_t *file, void *buffer, off_t len)
Reads from an corsaro input file into the provided buffer, but does not update the read pointer...
Definition: corsaro_file.c:395
void corsaro_file_close(struct corsaro *corsaro, corsaro_file_t *file)
Closes an corsaro output file and frees the writer structure.
Definition: corsaro_file.c:230
#define corsaro_flowtuple_lt(alpha, bravo)
Tests if one flowtuple is less than another.
Header file which exports corsaro_flowtuple plugin API.
static libtrace_packet_t * packet
A pointer to a libtrace packet.
Definition: corsaro_main.c:67
void corsaro_plugin_free_state(corsaro_plugin_manager_t *manager, corsaro_plugin_t *plugin)
Free the state for a plugin.
uint16_t ip_len
Length of the IP packet (from the IP header)
This packet is an ICMP Request packet.
off_t corsaro_flowtuple_read_record(struct corsaro_in *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Implements the read_record function of the plugin API.
int corsaro_flowtuple_process_flowtuple_class_start(corsaro_t *corsaro, corsaro_flowtuple_class_start_t *class)
Implements the process_flowtuple_class_start function of the plugin API.
uint32_t dst_ip
A Structure which represents the 3 useful bytes of the destination ip.
Header file for common utility functions.
A lightweight wrapper around a libtrace packet.
Definition: corsaro_int.h:211
corsaro_plugin_manager_t * plugin_manager
A pointer to the corsaro plugin manager state.
Definition: corsaro_int.h:273
int corsaro_flowtuple_process_flowtuple(corsaro_t *corsaro, corsaro_flowtuple_t *flowtuple, corsaro_packet_state_t *state)
Implements the process_flowtuple function of the plugin API.
KSORT_INIT(sixt, corsaro_flowtuple_t *, corsaro_flowtuple_lt)
Initialize the sorting functions and datatypes.
corsaro_in_record_type
Corsaro input record types.
Definition: corsaro.h:97
void corsaro_flowtuple_free(corsaro_flowtuple_t *t)
Free a FlowTuple record.
static int ascii_dump(corsaro_t *corsaro, corsaro_flowtuple_class_type_t dist)
Dump the given flowtuple to the plugin's outfile in ASCII format.
corsaro_file_t * corsaro_io_prepare_file(corsaro_t *corsaro, const char *plugin_name, corsaro_interval_t *interval)
Uses the current settings to open an corsaro file for the given plugin.
Definition: corsaro_io.c:688
off_t corsaro_io_read_interval_end(corsaro_in_t *corsaro, corsaro_file_in_t *file, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read the appropriate interval trailers from the file.
Definition: corsaro_io.c:1260
void corsaro_plugin_register_state(corsaro_plugin_manager_t *manager, corsaro_plugin_t *plugin, void *state)
Register the state for a plugin.
uint32_t corsaro_flowtuple_get_source_ip(corsaro_flowtuple_t *flowtuple)
Convenience function to get the source IP address from a FlowTuple.
The corsaro_flowtuple flowtuple record.
Definition: corsaro.h:134
void corsaro_file_rclose(corsaro_file_in_t *file)
Closes an corsaro input file and frees the reader structure.
Definition: corsaro_file.c:428
int corsaro_plugin_probe_filename(const char *fname, corsaro_plugin_t *plugin)
Check a filename to see if it contains a plugin's name.
static int sort_hash(corsaro_t *corsaro, kh_sixt_t *hash, corsaro_flowtuple_t ***sorted)
Given a st hash, malloc and return a sorted array of pointers.
off_t corsaro_io_write_interval_end(corsaro_t *corsaro, corsaro_file_t *file, corsaro_interval_t *int_end)
Write the appropriate interval trailers to the file.
Definition: corsaro_io.c:872
static int parse_args(corsaro_t *corsaro)
Parse the arguments given to the plugin.
int corsaro_flowtuple_probe_file(corsaro_in_t *corsaro, const char *fturi)
Check if an input file is a FlowTuple file.
The end of an interval.
Definition: corsaro.h:115
#define CORSARO_PLUGIN_GENERATE_TAIL
Convenience macro that defines all the 'remaining' blank fields in a corsaro plugin object...
void * malloc_zero(const size_t size)
Allocate memory and set it to zero.
Definition: utils.c:78
Header file dealing with the low-level file IO.
#define CORSARO_FLOWTUPLE_SIXT_TO_IP(flowtuple)
Convert the 3byte flowtuple dest ip to 32bits of network ordered uint32.
uint16_t dst_port
The destination port (or ICMP code)
int corsaro_flowtuple_add_inc(void *h, corsaro_flowtuple_t *t, uint32_t increment)
Either add the given flowtuple to the hash, or increment the current count.
enum corsaro_flowtuple_class_type corsaro_flowtuple_class_type_t
Possible classification types for a flowtuple.
FlowTuple output sorting is disabled.
static corsaro_in_record_t * record
A pointer to a corsaro record.
Definition: corsaro_main.c:76
int argc
Count of arguments in argv.
khint32_t corsaro_flowtuple_hash_func(struct corsaro_flowtuple *ft)
Hash the given flowtuple into a 32bit value.
void corsaro_log_in(const char *func, corsaro_in_t *corsaro, const char *format,...)
Write a formatted string to the logfile associated with an corsaro input object.
Definition: corsaro_log.c:121
void bytes_htons(uint8_t *bytes, uint16_t u16)
Convert a host ordered short to a network ordered byte array.
Definition: utils.c:50
off_t corsaro_io_read_interval_start(corsaro_in_t *corsaro, corsaro_file_in_t *file, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read the appropriate interval headers from the file.
Definition: corsaro_io.c:1232
int corsaro_is_rotate_interval(corsaro_t *corsaro)
Convenience function to determine if the output files should be rotated.
Definition: corsaro.c:1041
off_t corsaro_io_read_bytes(corsaro_in_t *corsaro, corsaro_in_record_t *record, off_t len)
Read the given number of bytes into the record.
Definition: corsaro_io.c:1317
#define CORSARO_FLOWTUPLE_BYTECNT
Used to give the length of the binary representation of a flowtuple.
The corsaro_flowtuple flowtuple classification type end record.
Definition: corsaro.h:131
corsaro_packet_state_t state
The corsaro state associated with this packet.
Definition: corsaro_int.h:214
uint8_t flags
Features of the packet that have been identified by earlier plugins.
Definition: corsaro_int.h:197
uint8_t * buffer
The buffer to read the record into.
Definition: corsaro_int.h:356
corsaro_interval_t interval_start
State for the current interval.
Definition: corsaro_int.h:292
int corsaro_flowtuple_init_input(corsaro_in_t *corsaro)
Implements the init_input function of the plugin API.
uint16_t src_port
The source port (or ICMP type)
Represents the eight important fields in the ip header that we will use to 'uniquely' identify a pack...
The packet is classified as backscatter.
Definition: corsaro_int.h:204
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
int corsaro_flowtuple_start_interval(corsaro_t *corsaro, corsaro_interval_t *int_start)
Implements the start_interval function of the plugin API.
int corsaro_flowtuple_record_print(corsaro_in_record_type_t record_type, corsaro_in_record_t *record)
Print a record to stdout in ASCII format.
off_t corsaro_file_write(struct corsaro *corsaro, corsaro_file_t *file, const void *buffer, off_t len)
Writes the contents of a buffer using an corsaro output file.
Definition: corsaro_file.c:142
Corsaro input state.
Definition: corsaro_int.h:323
The corsaro_flowtuple flowtuple classification type start record.
Definition: corsaro.h:128
The start of an interval.
Definition: corsaro.h:112
#define CORSARO_FLOWTUPLE_SHIFT_AND_XOR(value)
Convenience macro to help with the hashing function.
uint8_t ttl
The TTL.
#define CORSARO_FLOWTUPLE_MAGIC
The magic number for this plugin when not using /8 opts - "SIXU".
uint8_t tcp_flags
TCP Flags (excluding NS)
Corsaro state for a packet.
Definition: corsaro_int.h:194
#define STATE_IN(corsaro)
Extends the generic plugin state convenience macro in corsaro_plugin.h.
void corsaro_flowtuple_class_start_print(corsaro_flowtuple_class_start_t *class)
Print a class start record to stdout in ASCII format.
static int flowtuple_classify_packet(corsaro_t *corsaro, libtrace_packet_t *packet)
Determines the traffic class for a packet; possible options are CORSARO_FLOWTUPLE_CLASS_BACKSCATTER, CORSARO_FLOWTUPLE_CLASS_ICMPREQ, CLASS_OTHER.
static int binary_dump(corsaro_t *corsaro, corsaro_flowtuple_class_type_t dist)
Dump the given flowtuple to the plugin's outfile in binary format.
int corsaro_flowtuple_probe_magic(corsaro_in_t *corsaro, corsaro_file_in_t *file)
Implements the probe_magic function of the plugin API.
Header file dealing with the corsaro file IO.
#define OUTFILE_POINTERS
The number of output file pointers to support non-blocking close at the end of an interval...
The packet is not backscatter, not ICMP Request.
The null type used for wildcard matching.
Definition: corsaro.h:100
static int read_flowtuple(corsaro_in_t *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read a flowtuple record.
static int read_class_end(corsaro_in_t *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read a class end record.
Corsaro output state.
Definition: corsaro_int.h:230
off_t corsaro_flowtuple_fprint(corsaro_t *corsaro, corsaro_file_t *file, corsaro_flowtuple_t *flowtuple)
Print a flowtuple to a file in ASCII format.
#define CORSARO_IO_INTERVAL_HEADER_BYTE_LEN
Length of the interval header.
Definition: corsaro_io.h:48
static int validate_flowtuple(corsaro_flowtuple_t *flowtuple)
Attempt to validate a flowtuple record (no-op)
int corsaro_flowtuple_close_input(corsaro_in_t *corsaro)
Implements the close_input function of the plugin API.
corsaro_file_in_t * corsaro_file_ropen(const char *filename)
Creates a new corsaro file reader and opens the provided file for reading.
Definition: corsaro_file.c:256
#define PLUGIN_NAME
The name of this plugin.
off_t corsaro_io_write_interval_start(corsaro_t *corsaro, corsaro_file_t *file, corsaro_interval_t *int_start)
Write the appropriate interval headers to the file.
Definition: corsaro_io.c:856
void corsaro_log(const char *func, corsaro_t *corsaro, const char *format,...)
Write a formatted string to the logfile associated with an corsaro object.
Definition: corsaro_log.c:113
uint32_t src_ip
The source IP.
off_t corsaro_flowtuple_class_start_fprint(corsaro_t *corsaro, corsaro_file_t *file, corsaro_flowtuple_class_start_t *class)
Print a class start record to a file in ASCII format.
uint8_t protocol
The protocol.
int corsaro_flowtuple_init_output(corsaro_t *corsaro)
Implements the init_output function of the plugin API.
enum corsaro_in_record_type corsaro_in_record_type_t
Corsaro input record types.
An corsaro packet processing plugin.
enum corsaro_flowtuple_sort corsaro_flowtuple_sort_t
Possible states for FlowTuple output sorting.
static int validate_class_start(corsaro_flowtuple_class_start_t *class)
Check that a class start record is valid.
#define PLUGIN(corsaro)
Extends the generic plugin plugin convenience macro in corsaro_plugin.h.
static corsaro_plugin_t corsaro_flowtuple_plugin
Common plugin information across all instances.
corsaro_file_in_t * file
The corsaro input file to read data from.
Definition: corsaro_int.h:329
Header file dealing with the internal corsaro functions.
static const char * class_names[]
Array of string names for classes.