Skip to Content
[CAIDA - Center for Applied Internet Data Analysis logo]
The Center for Applied Internet Data Analysis
corsaro.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 <assert.h>
30 #include <inttypes.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "libtrace.h"
35 
36 #include "corsaro_file.h"
37 #include "corsaro_io.h"
38 #include "corsaro_log.h"
39 #include "utils.h"
40 
41 #ifdef WITH_PLUGIN_SIXT
42 #include "corsaro_flowtuple.h"
43 #endif
44 
55 {
56  corsaro_packet_t *pkt;
57 
58  if((pkt = malloc_zero(sizeof(corsaro_packet_t))) == NULL)
59  {
60  corsaro_log(__func__, corsaro, "could not malloc corsaro_packet");
61  return NULL;
62  }
63  /* this corsaro packet still needs a libtrace packet to be loaded... */
64  return pkt;
65 }
66 
69 {
70  assert(packet != NULL);
71 
72  /* This is dangerous to do field-by-field, new plugins may not be responsible
73  and reset their own fields. Therefore we will do this by force */
74  memset(&packet->state, 0, sizeof(corsaro_packet_state_t));
75 }
76 
79 {
80  /* we will assume that somebody else is taking care of the libtrace packet */
81  if(packet != NULL)
82  {
83  free(packet);
84  }
85 }
86 
89 {
90  corsaro_plugin_t *p = NULL;
91 
92  if(corsaro == NULL)
93  {
94  /* nothing to be done... */
95  return;
96  }
97 
98  /* free up the plugins first, they may try and use some of our info before
99  closing */
100  if(corsaro->plugin_manager != NULL)
101  {
102  while((p = corsaro_plugin_next(corsaro->plugin_manager, p)) != NULL)
103  {
104  p->close_output(corsaro);
105  }
106 
108  corsaro->plugin_manager = NULL;
109  }
110 
111  if(corsaro->uridata != NULL)
112  {
113  free(corsaro->uridata);
114  corsaro->uridata = NULL;
115  }
116 
117  if(corsaro->monitorname != NULL)
118  {
119  free(corsaro->monitorname);
120  corsaro->monitorname = NULL;
121  }
122 
123  if(corsaro->template != NULL)
124  {
125  free(corsaro->template);
126  corsaro->template = NULL;
127  }
128 
129  if(corsaro->packet != NULL)
130  {
131  corsaro_packet_free(corsaro->packet);
132  corsaro->packet = NULL;
133  }
134 
135  if(corsaro->global_file != NULL)
136  {
137  corsaro_file_close(corsaro, corsaro->global_file);
138  corsaro->global_file = NULL;
139  }
140 
141  /* close this as late as possible */
142  corsaro_log_close(corsaro);
143 
144  free(corsaro);
145 
146  return;
147 }
148 
151  uint32_t number,
152  uint32_t time)
153 {
154  interval->corsaro_magic = CORSARO_MAGIC;
155  interval->magic = CORSARO_MAGIC_INTERVAL;
156  interval->number = number;
157  interval->time = time;
158 }
159 
162 {
163  assert(corsaro != NULL);
164 
165  if(corsaro->meta_output_rotate < 0)
166  {
167  return corsaro_is_rotate_interval(corsaro);
168  }
169  else if(corsaro->meta_output_rotate > 0 &&
170  (corsaro->interval_start.number+1) %
171  corsaro->meta_output_rotate == 0)
172  {
173  return 1;
174  }
175  else
176  {
177  return 0;
178  }
179 }
180 
182 static corsaro_t *corsaro_init(char *template, corsaro_file_mode_t mode)
183 {
184  corsaro_t *e;
185 
186  if((e = malloc_zero(sizeof(corsaro_t))) == NULL)
187  {
188  corsaro_log(__func__, NULL, "could not malloc corsaro_t");
189  return NULL;
190  }
191 
192  /* what time is it? */
194 
195  /* uridata doesn't *need* to be set */
196 
197  /* set a default monitorname for when im bad and directly retrieve it
198  from the structure */
199  e->monitorname = strdup(STR(CORSARO_MONITOR_NAME));
200 
201  /* template does, however */
202  /* check that it is valid */
203  if(corsaro_io_validate_template(e, template) == 0)
204  {
205  corsaro_log(__func__, e, "invalid template %s", template);
206  goto err;
207  }
208  if((e->template = strdup(template)) == NULL)
209  {
210  corsaro_log(__func__, e,
211  "could not duplicate template string (no memory?)");
212  goto err;
213  }
214 
215  /* as does the mode */
216  e->output_mode = mode;
217 
218  /* check if compression should be used based on the file name */
220 
221  /* use the default compression level for now */
223 
224  /* lets get us a wrapper packet ready */
225  if((e->packet = corsaro_packet_alloc(e)) == NULL)
226  {
227  corsaro_log(__func__, e, "could not create corsaro packet");
228  goto err;
229  }
230 
231  /* ask the plugin manager to get us some plugins */
232  /* this will init all compiled plugins but not start them, this gives
233  us a chance to wait for the user to choose a subset to enable
234  with corsaro_enable_plugin and then we'll re-init */
235  if((e->plugin_manager = corsaro_plugin_manager_init(e->logfile)) == NULL)
236  {
237  corsaro_log(__func__, e, "could not initialize plugin manager");
238  goto err;
239  }
240 
241  /* set the default interval alignment value */
242  e->interval_align = CORSARO_INTERVAL_ALIGN_DEFAULT;
243 
244  /* interval doesn't need to be actively set, use the default for now */
246 
247  /* default for meta rotate should be to follow output_rotate */
248  e->meta_output_rotate = -1;
249 
250  /* initialize the current interval */
252 
253  /* set the libtrace related values to unknown for now */
254  e->accepted_pkts = UINT64_MAX;
255  e->dropped_pkts = UINT64_MAX;
256 
257  /* the rest are zero, as they should be. */
258 
259  /* ready to rock and roll! */
260 
261  return e;
262 
263  err:
264  /* 02/26/13 - ak comments because it is up to the user to call
265  corsaro_finalize_output to free the memory */
266  /*corsaro_free(e);*/
267  return NULL;
268 }
269 
271 static int start_interval(corsaro_t *corsaro, struct timeval int_start)
272 {
273  corsaro_plugin_t *tmp = NULL;
274 
275  /* record this so we know when the interval started */
276  /* the interval number is already incremented by end_interval */
277  corsaro->interval_start.time = int_start.tv_sec;
278 
279  /* the following is to support file rotation */
280  /* initialize the log file */
281  if(corsaro->logfile_disabled == 0 && corsaro->logfile == NULL)
282  {
283  /* if this is the first interval, let them know we are switching to
284  logging to a file */
285  if(corsaro->interval_start.number == 0)
286  {
287  /* there is a replica of this message in the other place that
288  * corsaro_log_init is called */
289  corsaro_log(
290  __func__, corsaro, "now logging to file"
291 #ifdef DEBUG
292  " (and stderr)"
293 #endif
294  );
295  }
296 
297  if(corsaro_log_init(corsaro) != 0)
298  {
299  corsaro_log(__func__, corsaro, "could not initialize log file");
300  corsaro_free(corsaro);
301  return -1;
302  }
303  }
304 
305  /* initialize the global output file */
306  if(corsaro->global_file_disabled == 0 && corsaro->global_file == NULL)
307  {
308  if((corsaro->global_file =
309  corsaro_io_prepare_file(corsaro,
311  &corsaro->interval_start)) == NULL)
312  {
313  corsaro_log(__func__, corsaro, "could not open global output file");
314  corsaro_free(corsaro);
315  return -1;
316  }
317 
318  /* write headers to the global file */
319  if(corsaro_io_write_header(corsaro, corsaro->global_file, NULL) <= 0)
320  {
321  corsaro_log(__func__, corsaro, "could not write global headers");
322  corsaro_free(corsaro);
323  return -1;
324  }
325  }
326 
327  /* ask each plugin to start a new interval */
328  /* plugins should rotate their files now too */
329  while((tmp = corsaro_plugin_next(corsaro->plugin_manager, tmp)) != NULL)
330  {
331  if(tmp->start_interval(corsaro, &corsaro->interval_start) != 0)
332  {
333  corsaro_log(__func__, corsaro, "%s failed to start interval at %ld",
334  tmp->name, int_start.tv_sec);
335  return -1;
336  }
337  }
338  return 0;
339 }
340 
342 static int end_interval(corsaro_t *corsaro, struct timeval int_end)
343 {
344  corsaro_plugin_t *tmp = NULL;
345 
346  corsaro_interval_t interval_end;
347 
348  populate_interval(&interval_end, corsaro->interval_start.number,
349  int_end.tv_sec);
350 
351  /* write the global interval start header */
352  if(corsaro->global_file != NULL &&
354  &corsaro->interval_start) <= 0)
355  {
356  corsaro_log(__func__, corsaro,
357  "could not write global interval start headers at %ld",
358  corsaro->interval_start.time);
359  return -1;
360  }
361  /* ask each plugin to end the current interval */
362  while((tmp = corsaro_plugin_next(corsaro->plugin_manager, tmp)) != NULL)
363  {
364  if(tmp->end_interval(corsaro, &interval_end) != 0)
365  {
366  corsaro_log(__func__, corsaro, "%s failed to end interval at %ld",
367  tmp->name, int_end.tv_sec);
368  return -1;
369  }
370  }
371  /* write the global interval end header */
372  if(corsaro->global_file != NULL &&
373  corsaro_io_write_interval_end(corsaro, corsaro->global_file,
374  &interval_end) <= 0)
375  {
376  corsaro_log(__func__, corsaro,
377  "could not write global interval end headers at %ld",
378  interval_end.time);
379  return -1;
380  }
381 
382  /* if we are rotating, now is the time to close our output files */
383  if(is_meta_rotate_interval(corsaro))
384  {
385  if(corsaro->global_file != NULL)
386  {
387  /* write headers to the global file */
388  if(corsaro_io_write_trailer(corsaro,
389  corsaro->global_file, NULL) <= 0)
390  {
391  corsaro_log(__func__, corsaro,
392  "could not write global trailers");
393  corsaro_free(corsaro);
394  return -1;
395  }
396  corsaro_file_close(corsaro, corsaro->global_file);
397  corsaro->global_file = NULL;
398  }
399 
400  /* we should also update the long-term counters at this point */
401  if(corsaro->trace != NULL)
402  {
403  corsaro->accepted_pkts = trace_get_accepted_packets(corsaro->trace);
404  corsaro->dropped_pkts = trace_get_dropped_packets(corsaro->trace);
405  }
406 
407  /* this MUST be the last thing closed in case any of the other things want
408  to log their end-of-interval activities (e.g. the pkt cnt from writing
409  the trailers */
410  if(corsaro->logfile != NULL)
411  {
412  corsaro_log_close(corsaro);
413  }
414  }
415 
416  corsaro->interval_end_needed = 0;
417  return 0;
418 }
419 
422 {
423  if(corsaro == NULL)
424  {
425  /* nothing to be done */
426 
427  corsaro_log_in(__func__, corsaro,
428  "WARNING: corsaro_in_free called on NULL object; "
429  "this could indicate a double-free");
430  return;
431  }
432 
433  /* free the uridata */
434  free(corsaro->uridata);
435  corsaro->uridata = NULL;
436 
437  /* close the plugin */
438  if(corsaro->plugin != NULL)
439  {
440  corsaro->plugin->close_input(corsaro);
441  }
442  /*
443  while((p = corsaro_plugin_next(corsaro->plugin_manager, p)) != NULL)
444  {
445  p->close_input(corsaro);
446  }
447  */
448 
449  /* free the plugin manager */
450  if(corsaro->plugin_manager != NULL)
451  {
453  corsaro->plugin_manager = NULL;
454  }
455 
456  /* close the input file */
457  if(corsaro->file != NULL)
458  {
459  corsaro_file_rclose(corsaro->file);
460  corsaro->file = NULL;
461  }
462 
463  corsaro->started = 0;
464 
465  free(corsaro);
466 }
467 
469 static corsaro_in_t *corsaro_in_init(const char *corsarouri)
470 {
471  corsaro_in_t *e;
472 
473  if((e = malloc_zero(sizeof(corsaro_in_t))) == NULL)
474  {
475  corsaro_log_in(__func__, NULL, "could not malloc corsaro_t");
476  return NULL;
477  }
478 
479  if((e->uridata = strdup(corsarouri)) == NULL)
480  {
481  corsaro_log_in(__func__, e,
482  "could not duplicate uri string (no memory?)");
483  goto err;
484  }
485 
486  /* set to null until we know if this is a global file or a plugin */
488 
489  /* initialize the logging */
490  if(corsaro_log_in_init(e) != 0)
491  {
492  corsaro_log_in(__func__, e, "could not initialize log file");
493  goto err;
494  }
495 
496  /* ask the plugin manager to get us some plugins */
497  if((e->plugin_manager = corsaro_plugin_manager_init(NULL)) == 0)
498  {
499  corsaro_log_in(__func__, e, "could not initialize plugins");
500  goto err;
501  }
502 
503  /* do not init plugins here, we will init only the one needed */
504 
505  /* delay opening the input file until we 'start' */
506 
507  return e;
508 
509  err:
510  corsaro_in_free(e);
511  return NULL;
512 }
513 
516 {
517  corsaro_plugin_t *tmp = NULL;
518  while((tmp = corsaro_plugin_next(corsaro->plugin_manager, tmp)) != NULL)
519  {
520  if(tmp->process_packet(corsaro, packet) < 0)
521  {
522  corsaro_log(__func__, corsaro, "%s failed to process packet",
523  tmp->name);
524  return -1;
525  }
526  }
527  return 0;
528 }
529 
530 #ifdef WITH_PLUGIN_SIXT
531 
532 static int per_flowtuple(corsaro_t *corsaro, corsaro_flowtuple_t *tuple)
533 {
534  /* ensure that the state is clear */
536 
537  corsaro_plugin_t *tmp = NULL;
538  while((tmp = corsaro_plugin_next(corsaro->plugin_manager, tmp)) != NULL)
539  {
540  if(tmp->process_flowtuple != NULL &&
541  tmp->process_flowtuple(corsaro, tuple, &corsaro->packet->state) < 0)
542  {
543  corsaro_log(__func__, corsaro, "%s failed to process flowtuple",
544  tmp->name);
545  return -1;
546  }
547  }
548 
549  corsaro->packet_cnt += ntohl(tuple->packet_cnt);
550 
551  return 0;
552 }
553 
555 static int per_flowtuple_class_start(corsaro_t *corsaro,
556  corsaro_flowtuple_class_start_t *class)
557 {
558  corsaro_plugin_t *tmp = NULL;
559  while((tmp = corsaro_plugin_next(corsaro->plugin_manager, tmp)) != NULL)
560  {
561  if(tmp->process_flowtuple_class_start != NULL &&
562  tmp->process_flowtuple_class_start(corsaro, class) < 0)
563  {
564  corsaro_log(__func__, corsaro,
565  "%s failed to process flowtuple class start",
566  tmp->name);
567  return -1;
568  }
569  }
570 
571  return 0;
572 }
573 
575 static int per_flowtuple_class_end(corsaro_t *corsaro,
576  corsaro_flowtuple_class_end_t *class)
577 {
578  corsaro_plugin_t *tmp = NULL;
579  while((tmp = corsaro_plugin_next(corsaro->plugin_manager, tmp)) != NULL)
580  {
581  if(tmp->process_flowtuple_class_end != NULL &&
582  tmp->process_flowtuple_class_end(corsaro, class) < 0)
583  {
584  corsaro_log(__func__, corsaro,
585  "%s failed to process flowtuple class end",
586  tmp->name);
587  return -1;
588  }
589  }
590 
591  return 0;
592 }
593 #endif
594 
596 static int per_interval_start(corsaro_t *corsaro,
598 {
599  struct timeval ts;
600  ts.tv_usec = 0;
601  ts.tv_sec = interval->time;
602 
603  /* if this is the first interval start, mark the first time */
604  if(corsaro->packet_cnt == 0)
605  {
606  corsaro->first_ts = ts;
607  }
608 
609  corsaro->interval_start.number = interval->number;
610  if(start_interval(corsaro, ts) != 0)
611  {
612  corsaro_log(__func__, corsaro, "could not start interval at %ld",
613  interval->time);
614  return -1;
615  }
616  return 0;
617 }
618 
620 static int per_interval_end(corsaro_t *corsaro,
622 {
623  struct timeval ts;
624  ts.tv_sec = interval->time;
625  corsaro->interval_start.number = interval->number;
626  corsaro->last_ts = ts;
627  if(end_interval(corsaro, ts) != 0)
628  {
629  corsaro_log(__func__, corsaro, "could not end interval at %ld",
630  interval->time);
631  /* we don't free in case the client wants to try to carry on */
632  return -1;
633  }
634  return 0;
635 }
636 
638 static int check_global_filename(char *fname)
639 {
640  if(strstr(fname, CORSARO_IO_GLOBAL_NAME) != NULL)
641  {
642  return 1;
643  }
644  return 0;
645 }
646 
649 {
650  char buffer[1024];
651  int len;
652 
653  len = corsaro_file_rpeek(file, buffer, sizeof(buffer));
654 
655  /* an corsaro global file will have 'EDGRHEAD' as the first 8 bytes */
656  if(len < 8)
657  {
658  return 0;
659  }
660 
661  /* lets make this easy and just do a string compare */
662  buffer[8] = '\0';
663 
664  if(strncmp(&buffer[0], "EDGRHEAD", 8) == 0)
665  {
666  return 1;
667  }
668  return 0;
669 }
670 
673 {
674  char buffer[1024];
675  int len;
676 
677  /* we need to peek and see if there is any plugin data */
678  len = corsaro_file_rpeek(corsaro->file, buffer,
679  sizeof(buffer));
680  if(len < sizeof(corsaro_plugin_data_t)
681  && len < sizeof(corsaro_interval_t))
682  {
683  corsaro_log_in(__func__, corsaro,
684  "invalid corsaro global file");
685  return -1;
686  }
687 
688  /* a plugin data record will have 'EDGRDATA' */
689  /* an interval start record will have 'EDGRINTR' */
690  /* either way, use strncmp */
691  buffer[8] = '\0';
692  if(strncmp(buffer, "EDGRDATA", 8) == 0)
693  {
694  return 1;
695  }
696  else if(strncmp(buffer, "EDGRINTR", 8) == 0)
697  {
698  return 0;
699 
700  }
701  else
702  {
703  return -1;
704  }
705 }
706 
709 {
710  char buffer[1024];
711  int len;
712 
713  /* we need to peek and see if there is any plugin data */
714  len = corsaro_file_rpeek(corsaro->file, buffer,
715  sizeof(buffer));
716  if(len < sizeof(corsaro_trailer_t)
717  && len < sizeof(corsaro_interval_t))
718  {
719  corsaro_log_in(__func__, corsaro,
720  "invalid corsaro global file");
721  return -1;
722  }
723 
724  /* a plugin data record will have 'EDGRFOOT' */
725  /* an interval start record will have 'EDGRINTR' */
726  /* either way, use strncmp */
727  buffer[8] = '\0';
728  if(strncmp(buffer, "EDGRFOOT", 8) == 0)
729  {
730  return 1;
731  }
732  else if(strncmp(buffer, "EDGRINTR", 8) == 0)
733  {
734  return 0;
735  }
736  else
737  {
738  return -1;
739  }
740 }
741 
743 static off_t read_record(corsaro_in_t *corsaro,
744  corsaro_in_record_type_t *record_type,
746 {
747  off_t bytes_read = -1;
748  int rc;
749 
750  /* this code is adapted from corsaro_flowtuple.c */
751  switch(corsaro->expected_type)
752  {
754  /* ask the io subsystem to read it for us */
755  bytes_read = corsaro_io_read_header(corsaro, corsaro->file, record_type,
756  record);
757  if(bytes_read > 0)
758  {
760  }
761  break;
762 
764  /* ask the io subsystem to read it for us */
765  bytes_read = corsaro_io_read_interval_start(corsaro, corsaro->file,
766  record_type, record);
767  if(bytes_read == sizeof(corsaro_interval_t))
768  {
769  rc = is_plugin_data_or_interval(corsaro);
770  if(rc == 1)
771  {
773  }
774  else if(rc == 0)
775  {
777  }
778  else
779  {
780  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
781  }
782  }
783  break;
784 
786  /* ask the io subsystem to read it for us */
787  bytes_read = corsaro_io_read_plugin_start(corsaro, corsaro->file,
788  record_type, record);
789  if(bytes_read == sizeof(corsaro_plugin_data_t))
790  {
791  /* which plugin is this? */
792  if((corsaro->plugin = corsaro_plugin_get_by_magic(
793  corsaro->plugin_manager,
794  ((corsaro_plugin_data_t*)record->buffer)->plugin_magic)
795  )
796  == NULL)
797  {
798  corsaro_log_in(__func__, corsaro, "invalid plugin magic detected");
799  corsaro_log_in(__func__, corsaro, "is corsaro built with all "
800  "necessary plugins?");
801  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
802  }
803  else
804  {
805  /* we'll pass these over to the plugin */
807  }
808  }
809  else
810  {
811  corsaro_log_in(__func__, corsaro,
812  "failed to read plugin data start");
813  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
814  }
815  break;
816 
818  /* pass this over to the plugin */
819  assert(corsaro->plugin != NULL);
820  bytes_read = corsaro->plugin->read_global_data_record(corsaro, record_type, record);
821 
822  if(bytes_read >= 0)
823  {
825  }
826  break;
827 
829  /* ask the io subsystem to read it for us */
830  bytes_read = corsaro_io_read_plugin_end(corsaro, corsaro->file,
831  record_type, record);
832  if(bytes_read == sizeof(corsaro_plugin_data_t))
833  {
834  /* check if there is more plugin data */
835  rc = is_plugin_data_or_interval(corsaro);
836  if(rc == 1)
837  {
839  }
840  else if(rc == 0)
841  {
843  }
844  else
845  {
846  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
847  }
848  }
849  break;
850 
852  /* ask the io subsystem to read it for us */
853  bytes_read = corsaro_io_read_interval_end(corsaro, corsaro->file,
854  record_type, record);
855  if(bytes_read == sizeof(corsaro_interval_t))
856  {
857  /* check for an interval start, or for a trailer */
858  rc = is_trailer_or_interval(corsaro);
859  if(rc == 0)
860  {
862  }
863  else if(rc == 1)
864  {
866  }
867  else
868  {
869  *record_type = CORSARO_IN_RECORD_TYPE_NULL;
870  }
871  }
872  break;
873 
875  /* ask the io subsystem to read it for us */
876  bytes_read = corsaro_io_read_trailer(corsaro, corsaro->file, record_type,
877  record);
878  if(bytes_read == sizeof(corsaro_trailer_t))
879  {
881  }
882  break;
883 
884  default:
885  corsaro_log_in(__func__, corsaro, "invalid expected record type");
886  }
887 
888  return bytes_read;
889 }
890 
891 /* == PUBLIC CORSARO API FUNCS BELOW HERE == */
892 
894 {
896 
897  /* quick sanity check that folks aren't trying to write to stdout */
898  if(template == NULL || strcmp(template, "-") == 0)
899  {
900  corsaro_log(__func__, NULL, "writing to stdout not supported");
901  return NULL;
902  }
903 
904  /* initialize the corsaro object */
905  if((corsaro = corsaro_init(template, mode)) == NULL)
906  {
907  corsaro_log(__func__, NULL, "could not initialize corsaro object");
908  return NULL;
909  }
910 
911  /* 10/17/13 AK moves logging init to corsaro_start_output so that the user may
912  call corsaro_disable_logfile after alloc */
913 
914  return corsaro;
915 }
916 
918 {
919  corsaro_plugin_t *p = NULL;
920 
921  assert(corsaro != NULL);
922 
923  /* only initialize the log file if there are no time format fields in the file
924  name (otherwise they will get a log file with a zero timestamp. */
925  /* Note that if indeed it does have a timestamp, the initialization error
926  messages will not be logged to a file. In fact nothing will be logged until
927  the first packet is received. */
928  assert(corsaro->logfile == NULL);
929  if(corsaro->logfile_disabled == 0 &&
930  corsaro_io_template_has_timestamp(corsaro) == 0)
931  {
932  corsaro_log(
933  __func__, corsaro, "now logging to file"
934 #ifdef DEBUG
935  " (and stderr)"
936 #endif
937  );
938 
939  if(corsaro_log_init(corsaro) != 0)
940  {
941  return -1;
942  }
943  }
944 
945  /* ask the plugin manager to start up */
946  /* this allows it to remove disabled plugins */
948  {
949  corsaro_log(__func__, corsaro, "could not start plugin manager");
950  /* corsaro_free(corsaro); */
951  return -1;
952  }
953 
954  /* now, ask each plugin to open its output file */
955  /* we need to do this here so that the corsaro object is fully set up
956  that is, the traceuri etc is set */
957  while((p = corsaro_plugin_next(corsaro->plugin_manager, p)) != NULL)
958  {
959  if(p->init_output(corsaro) != 0)
960  {
961  /* 02/25/13 - ak comments debug message */
962  /*
963  corsaro_log(__func__, corsaro, "plugin could not init output");
964  */
965  /* corsaro_free(corsaro); */
966  return -1;
967  }
968  }
969 
970  corsaro->started = 1;
971 
972  return 0;
973 }
974 
977 {
978  assert(corsaro != NULL);
979  /* you cant set interval alignment once corsaro has started */
980  assert(corsaro->started == 0);
981 
982  corsaro_log(__func__, corsaro, "setting interval alignment to %d",
983  align);
984 
985  corsaro->interval_align = align;
986 }
987 
988 void corsaro_set_interval(corsaro_t *corsaro, unsigned int i)
989 {
990  assert(corsaro != NULL);
991  /* you can't set the interval once corsaro has been started */
992  assert(corsaro->started == 0);
993 
994  corsaro_log(__func__, corsaro, "setting interval length to %d",
995  i);
996 
997  corsaro->interval = i;
998 }
999 
1001  int intervals)
1002 {
1003  assert(corsaro != NULL);
1004  /* you can't enable rotation once corsaro has been started */
1005  assert(corsaro->started == 0);
1006 
1007  corsaro_log(__func__, corsaro,
1008  "setting output rotation after %d interval(s)",
1009  intervals);
1010 
1011  /* if they have asked to rotate, but did not put a timestamp in the template,
1012  * we will end up clobbering files. warn them. */
1013  if(corsaro_io_template_has_timestamp(corsaro) == 0)
1014  {
1015  /* we skip the log and write directly out so that it is clear even if they
1016  * have debugging turned off */
1017  fprintf(stderr, "WARNING: using output rotation without any timestamp "
1018  "specifiers in the template.\n");
1019  fprintf(stderr,
1020  "WARNING: output files will be overwritten upon rotation\n");
1021  /* @todo consider making this a fatal error */
1022  }
1023 
1024  corsaro->output_rotate = intervals;
1025 }
1026 
1028  int intervals)
1029 {
1030  assert(corsaro != NULL);
1031  /* you can't enable rotation once corsaro has been started */
1032  assert(corsaro->started == 0);
1033 
1034  corsaro_log(__func__, corsaro,
1035  "setting meta output rotation after %d intervals(s)",
1036  intervals);
1037 
1038  corsaro->meta_output_rotate = intervals;
1039 }
1040 
1042 {
1043  assert(corsaro != NULL);
1044 
1045  if(corsaro->output_rotate == 0)
1046  {
1047  return 0;
1048  }
1049  else if((corsaro->interval_start.number+1) % corsaro->output_rotate == 0)
1050  {
1051  return 1;
1052  }
1053  else
1054  {
1055  return 0;
1056  }
1057 }
1058 
1059 int corsaro_set_trace(corsaro_t *corsaro, libtrace_t *trace)
1060 {
1061  assert(corsaro != NULL);
1062 
1063  /* this function can actually be called once corsaro is started */
1064  if(corsaro->trace != NULL)
1065  {
1066  corsaro_log(__func__, corsaro, "updating trace pointer");
1067  }
1068  else
1069  {
1070  corsaro_log(__func__, corsaro, "setting trace pointer");
1071  }
1072 
1073  /* reset the counters */
1074  corsaro->accepted_pkts = 0;
1075  corsaro->dropped_pkts = 0;
1076 
1077  corsaro->trace = trace;
1078  return 0;
1079 }
1080 
1081 int corsaro_set_traceuri(corsaro_t *corsaro, char *uri)
1082 {
1083  assert(corsaro != NULL);
1084 
1085  if(corsaro->started != 0)
1086  {
1087  corsaro_log(__func__, corsaro,
1088  "trace uri can only be set before "
1089  "corsaro_start_output is called");
1090  return -1;
1091  }
1092 
1093  if(corsaro->uridata != NULL)
1094  {
1095  corsaro_log(__func__, corsaro, "updating trace uri from %s to %s",
1096  corsaro->uridata, uri);
1097  }
1098  else
1099  {
1100  corsaro_log(__func__, corsaro, "setting trace uri to %s",
1101  uri);
1102  }
1103 
1104  if((corsaro->uridata = strdup(uri)) == NULL)
1105  {
1106  corsaro_log(__func__, corsaro,
1107  "could not duplicate uri string (no memory?)");
1108  return -1;
1109  }
1110  return 0;
1111 }
1112 
1114 {
1115  assert(corsaro != NULL);
1116  corsaro->logfile_disabled = 1;
1117 }
1118 
1120 {
1121  assert(corsaro != NULL);
1122  corsaro->global_file_disabled = 1;
1123 }
1124 
1125 int corsaro_enable_plugin(corsaro_t *corsaro, const char *plugin_name,
1126  const char *plugin_args)
1127 {
1128  assert(corsaro != NULL);
1129  assert(corsaro->plugin_manager != NULL);
1130 
1131  return corsaro_plugin_enable_plugin(corsaro->plugin_manager, plugin_name,
1132  plugin_args);
1133 }
1134 
1135 int corsaro_get_plugin_names(char ***plugin_names)
1136 {
1137  /* we make this work by creating a plugin manager, walking the list of
1138  * plugins, and dumping their names.
1139  */
1140  /* @todo add a 'usage' method to the plugin API so we can explicitly dump
1141  the usage for each plugin */
1142 
1143  int i = 0;
1144  char **names = NULL;
1145  corsaro_plugin_t *tmp = NULL;
1146  corsaro_plugin_manager_t *tmp_manager = NULL;
1147  if((tmp_manager = corsaro_plugin_manager_init(NULL)) == NULL)
1148  {
1149  return -1;
1150  }
1151 
1152  /* initialize the array of char pointers */
1153  if((names = malloc(sizeof(char *) * tmp_manager->plugins_cnt)) == NULL)
1154  {
1155  return -1;
1156  }
1157 
1158  while((tmp = corsaro_plugin_next(tmp_manager, tmp)) != NULL)
1159  {
1160  names[i] = strndup(tmp->name, strlen(tmp->name));
1161  i++;
1162  }
1163 
1164  corsaro_plugin_manager_free(tmp_manager);
1165 
1166  *plugin_names = names;
1167  return i;
1168 }
1169 
1170 void corsaro_free_plugin_names(char **plugin_names, int plugin_cnt)
1171 {
1172  int i;
1173  if(plugin_names == NULL)
1174  {
1175  return;
1176  }
1177  for(i = 0; i < plugin_cnt; i++)
1178  {
1179  if(plugin_names[i] != NULL)
1180  {
1181  free(plugin_names[i]);
1182  }
1183  plugin_names[i] = NULL;
1184  }
1185  free(plugin_names);
1186 }
1187 
1189 {
1190  return corsaro->accepted_pkts == UINT64_MAX ?
1191  UINT64_MAX :
1192  trace_get_accepted_packets(corsaro->trace) - corsaro->accepted_pkts;
1193 }
1194 
1196 {
1197  return corsaro->dropped_pkts == UINT64_MAX ?
1198  UINT64_MAX :
1199  trace_get_dropped_packets(corsaro->trace) - corsaro->dropped_pkts;
1200 }
1201 
1202 const char *corsaro_get_traceuri(corsaro_t *corsaro)
1203 {
1204  return corsaro->uridata;
1205 }
1206 
1207 int corsaro_set_monitorname(corsaro_t *corsaro, char *name)
1208 {
1209  assert(corsaro != NULL);
1210 
1211  if(corsaro->started != 0)
1212  {
1213  corsaro_log(__func__, corsaro,
1214  "monitor name can only be set before "
1215  "corsaro_start_output is called");
1216  return -1;
1217  }
1218 
1219  if(corsaro->monitorname != NULL)
1220  {
1221  corsaro_log(__func__, corsaro,
1222  "updating monitor name from %s to %s",
1223  corsaro->monitorname, name);
1224  }
1225  else
1226  {
1227  corsaro_log(__func__, corsaro, "setting monitor name to %s",
1228  name);
1229  }
1230 
1231  if((corsaro->monitorname = strdup(name)) == NULL)
1232  {
1233  corsaro_log(__func__, corsaro,
1234  "could not duplicate monitor name string (no memory?)");
1235  return -1;
1236  }
1237  corsaro_log(__func__, corsaro, "%s", corsaro->monitorname);
1238  return 0;
1239 }
1240 
1241 const char *corsaro_get_monitorname(corsaro_t *corsaro)
1242 {
1243  return corsaro->monitorname;
1244 }
1245 
1246 int corsaro_per_packet(corsaro_t *corsaro, libtrace_packet_t *ltpacket)
1247 {
1248  struct timeval ts;
1249  struct timeval report;
1250 
1251  assert(corsaro != NULL);
1252  assert(corsaro->started == 1 && "corsaro_start_output must be called before"
1253  "packets can be processed");
1254 
1255  /* poke this ltpacket into our corsaro packet */
1256  corsaro->packet->ltpacket = ltpacket;
1257 
1258  /* ensure that the state is clear */
1260 
1261  /* this is now the latest packet we have seen */
1262  corsaro->last_ts = ts = trace_get_timeval(ltpacket);
1263 
1264  /* it also means we need to dump an interval end record */
1265  corsaro->interval_end_needed = 1;
1266 
1267  /* if this is the first acket we record, keep the timestamp */
1268  if(corsaro->packet_cnt == 0)
1269  {
1270  corsaro->first_ts = ts;
1271  if(start_interval(corsaro, ts) != 0)
1272  {
1273  corsaro_log(__func__, corsaro, "could not start interval at %ld",
1274  ts.tv_sec);
1275  return -1;
1276  }
1277 
1278  corsaro->next_report = ts.tv_sec + corsaro->interval;
1279 
1280  /* if we are aligning our intervals, truncate the end down */
1281  if(corsaro->interval_align == CORSARO_INTERVAL_ALIGN_YES)
1282  {
1283  corsaro->next_report = (corsaro->next_report/corsaro->interval)
1284  *corsaro->interval;
1285  }
1286  }
1287 
1288  /* using an interval value of less than zero disables intervals
1289  such that only one distribution will be generated upon completion */
1290  while(corsaro->interval >= 0 && (uint32_t)ts.tv_sec >= corsaro->next_report)
1291  {
1292  /* we want to mark the end of the interval such that all pkt times are <=
1293  the time of the end of the interval.
1294  because we deal in second granularity, we simply subtract one from the
1295  time */
1296  report.tv_sec = corsaro->next_report-1;
1297 
1298  if(end_interval(corsaro, report) != 0)
1299  {
1300  corsaro_log(__func__, corsaro, "could not end interval at %ld",
1301  ts.tv_sec);
1302  /* we don't free in case the client wants to try to carry on */
1303  return -1;
1304  }
1305 
1306  corsaro->interval_start.number++;
1307 
1308  /* we now add the second back on to the time to get the start time */
1309  report.tv_sec = corsaro->next_report;
1310  if(start_interval(corsaro, report) != 0)
1311  {
1312  corsaro_log(__func__, corsaro, "could not start interval at %ld",
1313  ts.tv_sec);
1314  /* we don't free in case the client wants to try to carry on */
1315  return -1;
1316  }
1317  corsaro->next_report += corsaro->interval;
1318  }
1319 
1320  /* count this packet for our overall packet count */
1321  corsaro->packet_cnt++;
1322 
1323  /* ask each plugin to process this packet */
1324  return process_packet(corsaro, corsaro->packet);
1325 }
1326 
1330 {
1331  corsaro_interval_t *interval = NULL;
1332 
1333 #ifdef WITH_PLUGIN_SIXT
1334  corsaro_flowtuple_t *flowtuple = NULL;
1335  corsaro_flowtuple_class_start_t *class_start = NULL;
1336  corsaro_flowtuple_class_end_t *class_end = NULL;
1337 #endif
1338 
1339  /* we want trigger interval start/end events based on the incoming
1340  interval start and end */
1342  {
1343  interval = (corsaro_interval_t *)
1345 
1346  return per_interval_start(corsaro, interval);
1347  }
1349  {
1350  interval = (corsaro_interval_t *)
1352 
1353  return per_interval_end(corsaro, interval);
1354  }
1355 #ifdef WITH_PLUGIN_SIXT
1357  {
1358  flowtuple = (corsaro_flowtuple_t *)
1360 
1361  return per_flowtuple(corsaro, flowtuple);
1362  }
1364  {
1365  class_start = (corsaro_flowtuple_class_start_t *)
1367 
1368  return per_flowtuple_class_start(corsaro, class_start);
1369  }
1371  {
1372  class_end = (corsaro_flowtuple_class_end_t *)
1374 
1375  return per_flowtuple_class_end(corsaro, class_end);
1376  }
1377 #endif
1378 
1379  return 0;
1380 }
1381 
1383 {
1384  if(corsaro == NULL)
1385  {
1386  return 0;
1387  }
1388  if(corsaro->started != 0)
1389  {
1390  if(corsaro->interval_end_needed != 0 &&
1391  end_interval(corsaro, corsaro->last_ts) != 0)
1392  {
1393  corsaro_log(__func__, corsaro, "could not end interval at %ld",
1394  corsaro->last_ts.tv_sec);
1395  corsaro_free(corsaro);
1396  return -1;
1397  }
1398  if(corsaro->global_file != NULL &&
1399  corsaro_io_write_trailer(corsaro, corsaro->global_file, NULL) <= 0)
1400  {
1401  corsaro_log(__func__, corsaro,
1402  "could not write global trailers");
1403  corsaro_free(corsaro);
1404  return -1;
1405  }
1406  }
1407 
1408  corsaro_free(corsaro);
1409  return 0;
1410 }
1411 
1412 /* ===== corsaro_in API functions ===== */
1413 
1414 corsaro_in_t *corsaro_alloc_input(const char *corsarouri)
1415 {
1417 
1418  /* initialize the corsaro object */
1419  if((corsaro = corsaro_in_init(corsarouri)) == NULL)
1420  {
1421  corsaro_log_in(__func__, NULL, "could not initialize corsaro_in object");
1422  return NULL;
1423  }
1424 
1425  return corsaro;
1426 }
1427 
1429 {
1430  corsaro_plugin_t *p = NULL;
1431 
1432  assert(corsaro != NULL);
1433  assert(corsaro->started == 0);
1434  assert(corsaro->plugin == NULL);
1435 
1436  /* open the file! */
1437  if((corsaro->file = corsaro_file_ropen(corsaro->uridata)) == NULL)
1438  {
1439  corsaro_log_in(__func__, corsaro, "could not open input file %s",
1440  corsaro->uridata);
1441  /* ak comments the following, leave it up to the caller to free
1442  the state object */
1443  /*corsaro_in_free(corsaro);*/
1444  return -1;
1445  }
1446 
1447  /* determine the plugin which created this file */
1448  while((p = corsaro_plugin_next(corsaro->plugin_manager, p)) != NULL &&
1449  corsaro->plugin == NULL)
1450  {
1451  if(p->probe_filename(corsaro->uridata) == 1)
1452  {
1453  corsaro_log_in(__func__, corsaro,
1454  "%s plugin selected to read %s (using file name)",
1455  p->name, corsaro->uridata);
1456  corsaro->plugin = p;
1457  }
1458  }
1459 
1460  /* if the previous method for detection failed, lets try peeking into
1461  the file */
1462  p = NULL;
1463  while(corsaro->plugin == NULL &&
1464  (p = corsaro_plugin_next(corsaro->plugin_manager, p)) != NULL)
1465  {
1466  if(p->probe_magic(corsaro, corsaro->file) == 1)
1467  {
1468  corsaro_log_in(__func__, corsaro,
1469  "%s plugin selected to read %s (using magic)",
1470  p->name, corsaro->uridata);
1471  corsaro->plugin = p;
1472  }
1473  }
1474 
1475  /* if corsaro->plugin is still NULL, see if this is the global output */
1476  if(corsaro->plugin == NULL)
1477  {
1478  if(check_global_filename(corsaro->uridata) != 1 &&
1479  check_global_magic(corsaro, corsaro->file) != 1)
1480  {
1481  /* we have no idea what this file was created by */
1482  corsaro_log_in(__func__, corsaro,
1483  "unable to find plugin to decode %s\n"
1484  " - is this a corsaro file?\n"
1485  " - is corsaro compiled with all needed plugins?",
1486  corsaro->uridata);
1487  return -1;
1488  }
1489  else
1490  {
1491  /* this the corsaro global output */
1492  /* we initially expect an corsaro header record in a global file */
1494  corsaro_log_in(__func__, corsaro, "corsaro_global selected to read %s",
1495  corsaro->uridata);
1496  }
1497  }
1498  else
1499  {
1500  /* start up the plugin we detected */
1501  if(corsaro->plugin->init_input(corsaro) != 0)
1502  {
1503  corsaro_log_in(__func__, corsaro, "could not initialize %s",
1504  corsaro->plugin->name);
1505  return -1;
1506  }
1507  }
1508 
1509  corsaro->started = 1;
1510 
1511  return 0;
1512 }
1513 
1515 {
1516  corsaro_in_record_t *record = NULL;
1517 
1518  if((record = malloc(sizeof(corsaro_in_record_t))) == NULL)
1519  {
1520  corsaro_log_in(__func__, corsaro, "could not malloc corsaro_in_record_t");
1521  return NULL;
1522  }
1523 
1524  record->corsaro = corsaro;
1525 
1526  /* pre-allocate some memory for the buffer */
1527  if((record->buffer = malloc(sizeof(uint8_t)*
1529  {
1530  corsaro_log_in(__func__, corsaro, "could not malloc record buffer");
1531  corsaro_in_free_record(record);
1532  return NULL;
1533  }
1534 
1536 
1537  record->type = -1;
1538 
1539  return record;
1540 }
1541 
1543 {
1544  if(record == NULL)
1545  {
1546  corsaro_log_file(__func__, NULL, "possible double free of record pointer");
1547  return;
1548  }
1549 
1550  if(record->buffer != NULL)
1551  {
1552  free(record->buffer);
1553  record->buffer = NULL;
1554  }
1555  record->buffer_len = -1;
1556 
1557  record->type = -1;
1558 
1559  free(record);
1560 }
1561 
1563  corsaro_in_record_type_t *record_type,
1565 {
1566  /* the first check makes sure we don't have a plugin that we have assigned
1567  the file to, the second ensures that if there is a plugin, we will
1568  only directly use it when we're not in global mode */
1569  if(corsaro->plugin != NULL
1571  {
1572  return corsaro->plugin->read_record(corsaro, record_type, record);
1573  }
1574  else
1575  {
1576  /* this is the global plugin, handle it ourselves */
1577  return read_record(corsaro, record_type, record);
1578  }
1579 
1580  return -1;
1581 }
1582 
1584 {
1585  return record->buffer;
1586 }
1587 
1589 {
1590  corsaro_in_free(corsaro);
1591  return 0;
1592 }
Structure representing the start or end of an interval.
Definition: corsaro_int.h:156
The start of a plugin data section.
Definition: corsaro.h:118
An opaque structure defining an corsaro input file.
Definition: corsaro_file.h:86
void corsaro_in_free_record(corsaro_in_record_t *record)
Free an corsaro record object.
Definition: corsaro.c:1542
corsaro_plugin_t * plugin
Pointer to the plugin to be used to read this file.
Definition: corsaro_int.h:339
int corsaro_finalize_output(corsaro_t *corsaro)
Write the final interval and free resources allocated by corsaro.
Definition: corsaro.c:1382
void corsaro_disable_globalfile(corsaro_t *corsaro)
Accessor function to disable the global metadata file.
Definition: corsaro.c:1119
int corsaro_per_record(corsaro_t *corsaro, corsaro_in_record_type_t type, corsaro_in_record_t *record)
Perform corsaro processing on a given corsaro record.
Definition: corsaro.c:1327
int interval
The number of seconds after which plugins will be asked to dump data.
Definition: corsaro_int.h:280
off_t corsaro_io_read_plugin_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 plugin header from the file.
Definition: corsaro_io.c:1288
const char * name
The name of this plugin used in the ascii output and eventually to allow plugins to be enabled and di...
int compress_level
The compression level (ignored if not compressing)
Definition: corsaro_int.h:254
corsaro_in_t * corsaro_alloc_input(const char *corsarouri)
Allocate an corsaro object for reading an corsaro file.
Definition: corsaro.c:1414
static int per_interval_start(corsaro_t *corsaro, corsaro_interval_t *interval)
Process an interval start record.
Definition: corsaro.c:596
uint64_t dropped_pkts
The total number of packets that have been dropped by libtrace (before the current interval) ...
Definition: corsaro_int.h:315
int corsaro_get_plugin_names(char ***plugin_names)
Return an array of the names of plugins which are compiled into corsaro.
Definition: corsaro.c:1135
Header file dealing with the corsaro logging sub-system.
Structure representing the start or end of a plugin data block.
Definition: corsaro_int.h:172
const char * corsaro_get_monitorname(corsaro_t *corsaro)
Accessor function to get the monitor name string.
Definition: corsaro.c:1241
uint64_t packet_cnt
The total number of packets that have been processed.
Definition: corsaro_int.h:307
static void corsaro_free(corsaro_t *corsaro)
Cleanup and free the given corsaro instance.
Definition: corsaro.c:88
#define CORSARO_FILE_COMPRESS_LEVEL_DEFAULT
The default compression level.
Definition: corsaro_file.h:51
struct timeval init_time
The local wall time that corsaro was started at.
Definition: corsaro_int.h:233
A reusable opaque structure for corsaro to read an input record into.
Definition: corsaro_int.h:350
int interval_end_needed
Whether there are un-dumped packets in the current interval.
Definition: corsaro_int.h:304
corsaro_interval_align_t interval_align
The first interval end will be rounded down to the nearest integer multiple of the interval length if...
Definition: corsaro_int.h:277
corsaro_file_mode_t output_mode
The default output mode for new files.
Definition: corsaro_int.h:248
void corsaro_free_plugin_names(char **plugin_names, int plugin_cnt)
Free the array of plugin names returned by corsaro_get_plugin_names.
Definition: corsaro.c:1170
static int end_interval(corsaro_t *corsaro, struct timeval int_end)
End the current interval.
Definition: corsaro.c:342
corsaro_plugin_manager_t * plugin_manager
A pointer to the corsaro plugin manager state.
Definition: corsaro_int.h:336
int(* close_input)(struct corsaro_in *corsaro)
Concludes an input file and cleans up the plugin data.
int corsaro_start_output(corsaro_t *corsaro)
Initialize an corsaro object that has already been allocated.
Definition: corsaro.c:917
static int check_global_filename(char *fname)
Check if the filename is a global output file.
Definition: corsaro.c:638
size_t buffer_len
The length of the buffer.
Definition: corsaro_int.h:359
int(* close_output)(struct corsaro *corsaro)
Concludes an output file and cleans up the plugin data.
int started
Has this corsaro_in object been started yet?
Definition: corsaro_int.h:342
uint32_t magic
The interval magic number.
Definition: corsaro_int.h:161
int corsaro_plugin_enable_plugin(corsaro_plugin_manager_t *manager, const char *plugin_name, const char *plugin_args)
Attempt to enable a plugin by its name.
off_t corsaro_io_read_plugin_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 plugin trailer from the file.
Definition: corsaro_io.c:1303
#define CORSARO_IN_RECORD_DEFAULT_BUFFER_LEN
The initial buffer size in the record object.
Definition: corsaro_int.h:347
off_t corsaro_io_read_trailer(corsaro_in_t *corsaro, corsaro_file_in_t *file, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read the corsaro trailers from the file.
Definition: corsaro_io.c:1206
int corsaro_set_trace(corsaro_t *corsaro, libtrace_t *trace)
Accessor function to set the trace pointer.
Definition: corsaro.c:1059
uint64_t accepted_pkts
The total number of packets that have been accepted by libtrace (before the current interval) ...
Definition: corsaro_int.h:311
corsaro_plugin_t * corsaro_plugin_next(corsaro_plugin_manager_t *manager, corsaro_plugin_t *plugin)
Retrieve the next plugin in the list.
corsaro_packet_t * packet
A pointer to the wrapper packet passed to the plugins.
Definition: corsaro_int.h:269
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
uint16_t plugins_cnt
The number of active plugins.
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
uint32_t corsaro_magic
The global corsaro magic number.
Definition: corsaro_int.h:159
struct timeval last_ts
The time of the most recent packet seen by corsaro.
Definition: corsaro_int.h:301
Header file which exports corsaro_flowtuple plugin API.
libtrace_packet_t * ltpacket
A pointer to the underlying libtrace packet.
Definition: corsaro_int.h:223
static libtrace_packet_t * packet
A pointer to a libtrace packet.
Definition: corsaro_main.c:67
corsaro_plugin_t * corsaro_plugin_get_by_magic(corsaro_plugin_manager_t *manager, uint32_t id)
Attempt to retrieve a plugin by magic number (not by using magic)
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 int check_global_magic(corsaro_in_t *corsaro, corsaro_file_in_t *file)
Check for the global output magic number in the given file.
Definition: corsaro.c:648
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
void corsaro_plugin_manager_free(corsaro_plugin_manager_t *manager)
Free the plugin manager and all in-use plugins.
int logfile_disabled
Has the user asked us not to log to a file?
Definition: corsaro_int.h:266
Holds the metadata for the plugin manager.
void corsaro_log_close(corsaro_t *corsaro)
Close the log file for an corsaro output object.
Definition: corsaro_log.c:163
Overall corsaro magic number - "EDGR".
Definition: corsaro_int.h:73
Structure representing a corsaro file trailer.
Definition: corsaro_int.h:116
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
int corsaro_plugin_manager_start(corsaro_plugin_manager_t *manager)
Start the plugin manager.
corsaro_in_record_type_t expected_type
The next expected record type when reading the corsaro_global file.
Definition: corsaro_int.h:332
enum corsaro_interval_align corsaro_interval_align_t
Settings for interval alignment.
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
void corsaro_set_output_rotation(corsaro_t *corsaro, int intervals)
Accessor function to set the rotation frequency of output files.
Definition: corsaro.c:1000
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
#define STR(a)
Stringify a macro value.
Definition: utils.h:57
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
uint64_t corsaro_get_accepted_packets(corsaro_t *corsaro)
Accessor function to get the number of accepted packets in this interval.
Definition: corsaro.c:1188
void * malloc_zero(const size_t size)
Allocate memory and set it to zero.
Definition: utils.c:78
static corsaro_in_t * corsaro_in_init(const char *corsarouri)
Initialize a new corsaro_in instance.
Definition: corsaro.c:469
Header file dealing with the low-level file IO.
off_t corsaro_io_write_header(corsaro_t *corsaro, corsaro_file_t *file, corsaro_header_t *header)
Write the corsaro headers to the file.
Definition: corsaro_io.c:787
static int interval
The amount of time to wait until we dump the hash.
static int start_interval(corsaro_t *corsaro, struct timeval int_start)
Start a new interval.
Definition: corsaro.c:271
int(* init_output)(struct corsaro *corsaro)
Initialises an output file using the plugin.
static corsaro_in_record_t * record
A pointer to a corsaro record.
Definition: corsaro_main.c:76
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
int meta_output_rotate
The meta output files will be rotated after n intervals if >=0 a value of 0 indicates no rotation...
Definition: corsaro_int.h:289
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_io_template_has_timestamp(corsaro_t *corsaro)
Determines whether there are any time-related patterns in the file template.
Definition: corsaro_io.c:758
The overall corsaro trailer (currently only in global)
Definition: corsaro.h:109
int corsaro_is_rotate_interval(corsaro_t *corsaro)
Convenience function to determine if the output files should be rotated.
Definition: corsaro.c:1041
corsaro_plugin_manager_t * corsaro_plugin_manager_init()
Initialize the plugin manager and all in-use plugins.
int(* probe_filename)(const char *fname)
Given a filename, return if this is the most likely plugin.
int corsaro_log_init(corsaro_t *corsaro)
Initialize the logging sub-system for an corsaro output object.
Definition: corsaro_log.c:141
int corsaro_io_validate_template(corsaro_t *corsaro, char *template)
Validates a output file template for needed features.
Definition: corsaro_io.c:735
The corsaro_flowtuple flowtuple classification type end record.
Definition: corsaro.h:131
static corsaro_t * corsaro
A pointer to the instance of corsaro that we will drive.
Definition: corsaro_main.c:80
corsaro_packet_state_t state
The corsaro state associated with this packet.
Definition: corsaro_int.h:214
static libtrace_t * trace
A pointer to a libtrace object.
Definition: corsaro_main.c:65
corsaro_in_record_t * corsaro_in_alloc_record(corsaro_in_t *corsaro)
Allocate a reusable corsaro record object.
Definition: corsaro.c:1514
int(* start_interval)(struct corsaro *corsaro, struct corsaro_interval *int_start)
Starts a new interval.
#define CORSARO_INTERVAL_DEFAULT
The interval after which we will end an interval.
Definition: corsaro_int.h:185
int corsaro_per_packet(corsaro_t *corsaro, libtrace_packet_t *ltpacket)
Perform corsaro processing on a given libtrace packet.
Definition: corsaro.c:1246
uint8_t * buffer
The buffer to read the record into.
Definition: corsaro_int.h:356
int output_rotate
The output files will be rotated after n intervals if >0.
Definition: corsaro_int.h:283
corsaro_interval_t interval_start
State for the current interval.
Definition: corsaro_int.h:292
corsaro interval magic number - "INTR"
Definition: corsaro_int.h:77
int global_file_disabled
Has the user asked us not to create a global output file?
Definition: corsaro_int.h:260
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
uint32_t time
The time this interval started/ended.
Definition: corsaro_int.h:165
int(* end_interval)(struct corsaro *corsaro, struct corsaro_interval *int_end)
Ends an interval.
char * monitorname
The name of the monitor that corsaro is running on.
Definition: corsaro_int.h:242
void corsaro_set_interval_alignment(corsaro_t *corsaro, corsaro_interval_align_t align)
Accessor function to enable/disable the alignment of the initial interval.
Definition: corsaro.c:975
The end of a plugin data section.
Definition: corsaro.h:121
Corsaro input state.
Definition: corsaro_int.h:323
The corsaro_flowtuple flowtuple classification type start record.
Definition: corsaro.h:128
int corsaro_set_monitorname(corsaro_t *corsaro, char *name)
Accessor function to set the monitor name.
Definition: corsaro.c:1207
The start of an interval.
Definition: corsaro.h:112
The overall corsaro header (currently only in global)
Definition: corsaro.h:106
char * uridata
The uri that was used to open the trace file.
Definition: corsaro_int.h:239
char * uridata
The uri of the file to read data from.
Definition: corsaro_int.h:326
const char * corsaro_get_traceuri(corsaro_t *corsaro)
Accessor function to get the trace uri string.
Definition: corsaro.c:1202
int(* process_packet)(struct corsaro *corsaro, struct corsaro_packet *packet)
Process a packet.
corsaro_file_compress_t compress
The compression type (based on the file name)
Definition: corsaro_int.h:251
Corsaro state for a packet.
Definition: corsaro_int.h:194
static off_t read_record(corsaro_in_t *corsaro, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read a global file record.
Definition: corsaro.c:743
Header file dealing with the corsaro file IO.
corsaro_in_t * corsaro
The corsaro input object the record is associated with.
Definition: corsaro_int.h:353
off_t(* read_global_data_record)(struct corsaro_in *corsaro, enum corsaro_in_record_type *record_type, struct corsaro_in_record *record)
Reads a plugin global data block from an input file.
static void corsaro_packet_state_reset(corsaro_packet_t *packet)
Reset the state for a the given corsaro packet wrapper.
Definition: corsaro.c:68
static int is_trailer_or_interval(corsaro_in_t *corsaro)
Check if the next record is a trailer or an interval.
Definition: corsaro.c:708
static int per_interval_end(corsaro_t *corsaro, corsaro_interval_t *interval)
Process an interval end record.
Definition: corsaro.c:620
corsaro_t * corsaro_alloc_output(char *template, corsaro_file_mode_t mode)
Allocate an corsaro object.
Definition: corsaro.c:893
struct timeval first_ts
The time of the the first packet seen by corsaro.
Definition: corsaro_int.h:298
The null type used for wildcard matching.
Definition: corsaro.h:100
void * corsaro_in_get_record_data(corsaro_in_record_t *record)
Get a pointer data in a record.
Definition: corsaro.c:1583
Internal type for directing read requests.
Definition: corsaro.h:103
#define CORSARO_IO_GLOBAL_NAME
The name to use for the global 'plugin' file.
Definition: corsaro_io.h:66
static int process_packet(corsaro_t *corsaro, corsaro_packet_t *packet)
Process the given corsaro packet.
Definition: corsaro.c:515
void corsaro_set_interval(corsaro_t *corsaro, unsigned int i)
Accessor function to set the interval length.
Definition: corsaro.c:988
corsaro_file_t * logfile
The file to write log output to.
Definition: corsaro_int.h:263
void gettimeofday_wrap(struct timeval *tv)
Convenience function to get the current time of day.
Definition: utils.c:71
uint64_t corsaro_get_dropped_packets(corsaro_t *corsaro)
Accessor function to get the number of dropped packets in this interval.
Definition: corsaro.c:1195
Corsaro output state.
Definition: corsaro_int.h:230
corsaro_file_t * global_file
The corsaro output file to write global output to.
Definition: corsaro_int.h:257
int(* init_input)(struct corsaro_in *corsaro)
Initialises an input file using the plugin.
corsaro_file_compress_t corsaro_file_detect_compression(char *filename)
Attempts to detect the type of compression for a file based on the suffix.
Definition: corsaro_file.c:54
libtrace_t * trace
The libtrace trace pointer for the trace that we are being fed.
Definition: corsaro_int.h:236
int corsaro_log_in_init(corsaro_in_t *corsaro)
Initialize the logging sub-system for an corsaro input object.
Definition: corsaro_log.c:156
corsaro_in_record_type_t type
The type of the record currently in the buffer.
Definition: corsaro_int.h:362
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
int corsaro_enable_plugin(corsaro_t *corsaro, const char *plugin_name, const char *plugin_args)
Attempt to enable a plugin using the given plugin name.
Definition: corsaro.c:1125
int started
Has this corsaro object been started yet?
Definition: corsaro_int.h:318
off_t corsaro_io_write_trailer(corsaro_t *corsaro, corsaro_file_t *file, corsaro_trailer_t *trailer)
Write the corsaro trailers to the file.
Definition: corsaro_io.c:822
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
int corsaro_set_traceuri(corsaro_t *corsaro, char *uri)
Accessor function to set the trace uri string.
Definition: corsaro.c:1081
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
static void populate_interval(corsaro_interval_t *interval, uint32_t number, uint32_t time)
Fill the given interval object with the default values.
Definition: corsaro.c:150
enum corsaro_file_mode corsaro_file_mode_t
Enum of supported file modes.
static void corsaro_in_free(corsaro_in_t *corsaro)
Cleanup and free a corsaro_in instance.
Definition: corsaro.c:421
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
char * template
The template used to create corsaro output files.
Definition: corsaro_int.h:245
static int is_plugin_data_or_interval(corsaro_in_t *corsaro)
Check if the next record is plugin data or an interval.
Definition: corsaro.c:672
void corsaro_set_meta_output_rotation(corsaro_t *corsaro, int intervals)
Accessor function to set the rotation frequency of meta output files.
Definition: corsaro.c:1027
static void corsaro_packet_free(corsaro_packet_t *packet)
Free the given corsaro packet wrapper.
Definition: corsaro.c:78
off_t corsaro_io_read_header(corsaro_in_t *corsaro, corsaro_file_in_t *file, corsaro_in_record_type_t *record_type, corsaro_in_record_t *record)
Read an corsaro header from the file.
Definition: corsaro_io.c:1106
static int is_meta_rotate_interval(corsaro_t *corsaro)
Check if the meta output files should be rotated.
Definition: corsaro.c:161
enum corsaro_in_record_type corsaro_in_record_type_t
Corsaro input record types.
static corsaro_t * corsaro_init(char *template, corsaro_file_mode_t mode)
Initialize a new corsaro object.
Definition: corsaro.c:182
uint32_t next_report
The time that this interval will be dumped at.
Definition: corsaro_int.h:295
An corsaro packet processing plugin.
static corsaro_packet_t * corsaro_packet_alloc(corsaro_t *corsaro)
Allocate a corsaro packet wrapper structure.
Definition: corsaro.c:54
int(* probe_magic)(struct corsaro_in *corsaro, corsaro_file_in_t *file)
Given a file, looks at next 4 bytes to determine if this is the right plugin.
off_t(* read_record)(struct corsaro_in *corsaro, enum corsaro_in_record_type *record_type, struct corsaro_in_record *record)
Reads the next block of plugin data from an input file.
void corsaro_disable_logfile(corsaro_t *corsaro)
Accessor function to disable logging to a file.
Definition: corsaro.c:1113
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.