Skip to Content
[CAIDA - Cooperative Association for Internet Data Analysis logo]
The Cooperative Association for Internet Data Analysis
corsaro_main.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 
28 #include <getopt.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "libtrace.h"
35 
36 #include "utils.h"
37 
38 #include "corsaro.h"
39 #include "corsaro_log.h"
40 
49 volatile sig_atomic_t corsaro_shutdown = 0;
50 
51 static libtrace_t *trace = NULL;
52 static libtrace_packet_t *packet = NULL;
53 static libtrace_filter_t *filter = NULL;
54 static corsaro_t *corsaro = NULL;
55 
56 static void catch_sigint(int sig)
57 {
58  fprintf(stderr, "caught SIGINT, shutting down at the next opportunity\n");
59  corsaro_shutdown = 1;
60  signal(sig, catch_sigint);
61 }
62 
63 static void clean()
64 {
65 
66  if(packet != NULL)
67  {
68  trace_destroy_packet(packet);
69  packet = NULL;
70  }
71 
72  if(corsaro != NULL)
73  {
74  corsaro_finalize_output(corsaro);
75  }
76 }
77 
78 static int init_trace(char *tracefile)
79 {
80  trace = trace_create(tracefile);
81 
82  if (trace_is_err(trace)) {
83  trace_perror(trace,"Opening trace file");
84  clean();
85  return -1;
86  }
87 
88  if (trace_start(trace) == -1) {
89  trace_perror(trace,"Starting trace");
90  clean();
91  return -1;
92  }
93 
94  return 0;
95 }
96 
97 static void close_trace()
98 {
99  if(trace != NULL)
100  {
101  trace_destroy(trace);
102  trace = NULL;
103  }
104 }
105 
106 static void usage(const char *name)
107 {
108  fprintf(stderr,
109  "usage: %s -o outfile [-i interval] [-m mode] [-n name]\n"
110  " [-p plugin] [-f filter] trace_uri [trace_uri...]\n"
111  " -o <outfile> use <outfile> as a template for file names.\n"
112  " %%P will be replaced with the plugin name\n"
113  " -i <interval> distribution interval in seconds (default: %d)\n"
114  " -m <mode> output in 'ascii' or 'binary'. (default: ascii)\n"
115  " -n <name> monitor name (default: "
116  STR(CORSARO_MONITOR_NAME)")\n"
117  " -p <plugin> enable the given plugin, -p can be used \n"
118  " multiple times (default: all)\n"
119  " -f <filter> BPF filter to apply to packets\n",
121 }
122 
123 int main(int argc, char *argv[])
124 {
125  int opt;
126  char *tmpl = NULL;
127  char *name = NULL;
128  char *bpf_filter = NULL;
129  int i = -1000;
130  int mode = CORSARO_FILE_MODE_DEFAULT;
131  char *plugins[CORSARO_PLUGIN_ID_MAX];
132  int plugin_cnt = 0;
133  int tracefile_cnt = 0;
134  char *traceuri = "Multiple Traces";
135 
136  signal(SIGINT, catch_sigint);
137 
138  while((opt = getopt(argc, argv, "f:i:m:n:o:p:v?")) >= 0)
139  {
140  switch(opt)
141  {
142  case 'i':
143  i = atoi(optarg);
144  break;
145 
146  case 'm':
147  if(strcmp(optarg, "ascii") == 0)
148  {
149  /* ascii output format */
151  }
152  else if(strcmp(optarg, "binary") == 0)
153  {
155  }
156  else
157  {
158  fprintf(stderr,
159  "ERROR: mode parameter must be 'ascii' or 'binary'\n");
160  usage(argv[0]);
161  exit(-1);
162  }
163  break;
164 
165  case 'n':
166  name = strdup(optarg);
167  break;
168 
169  case 'o':
170  /*
171  if(strstr(optarg, CORSARO_PLUGIN_OUTPUT_PATTERN) == NULL)
172  {
173  fprintf(stderr,
174  "ERROR: template string must contain %s",
175  CORSARO_PLUGIN_OUTPUT_PATTERN);
176  usage(argv[0]);
177  exit(-1);
178  } */
179  tmpl = strdup(optarg);
180  break;
181 
182  case 'p':
183  plugins[plugin_cnt++] = strdup(optarg);
184  break;
185 
186  case 'f':
187  bpf_filter = strdup(optarg);
188  break;
189 
190  case '?':
191  case 'v':
192  fprintf(stderr, "corsaro version %d.%d.%d\n", CORSARO_MAJOR_VERSION,
193  CORSARO_MID_VERSION, CORSARO_MINOR_VERSION);
194  usage(argv[0]);
195  exit(0);
196  break;
197 
198  default:
199  usage(argv[0]);
200  exit(-1);
201  }
202  }
203 
204  if(optind > argc - 1)
205  {
206  usage(argv[0]);
207  exit(-1);
208  }
209 
210  tracefile_cnt = argc-optind;
211 
212  /* create a packet buffer */
213  if ((packet = trace_create_packet()) == NULL) {
214  perror("Creating libtrace packet");
215  clean();
216  return -1;
217  }
218 
219  /* argv[optind] is the pcap file */
220  /* only init the trace now if only one trace file */
221  if(tracefile_cnt == 1)
222  {
223  if(init_trace(argv[optind]) != 0)
224  {
225  fprintf(stderr, "failed to init trace");
226  clean();
227  return -1;
228  }
229  traceuri = argv[optind];
230  }
231 
232  /* create the bpf filter if specified */
233  if(bpf_filter != NULL)
234  {
235  filter = trace_create_filter(bpf_filter);
236  }
237 
238  if((corsaro = corsaro_alloc_output(tmpl, mode)) == NULL)
239  {
240  usage(argv[0]);
241  clean();
242  return -1;
243  }
244 
245  /* keep a record of what this file was called */
246  if(corsaro_set_traceuri(corsaro, traceuri) != 0)
247  {
248  corsaro_log(__func__, corsaro, "failed to set trace uri");
249  clean();
250  return -1;
251  }
252 
253  if(name != NULL && corsaro_set_monitorname(corsaro, name) != 0)
254  {
255  corsaro_log(__func__, corsaro, "failed to set monitor name");
256  clean();
257  return -1;
258  }
259 
260  if(i > -1000)
261  {
262  corsaro_set_interval(corsaro, i);
263  }
264 
265  for(i=0;i<plugin_cnt;i++)
266  {
267  if(corsaro_enable_plugin(corsaro, plugins[i]) != 0)
268  {
269  corsaro_log(__func__, corsaro, "failed to enable %s",
270  plugins[i]);
271  clean();
272  return -1;
273  }
274  }
275 
276  if(corsaro_start_output(corsaro) != 0)
277  {
278  corsaro_log(__func__, corsaro, "failed to start corsaro");
279  clean();
280  return -1;
281  }
282 
283  for(i = optind; i < argc; i++)
284  {
285  if(trace == NULL)
286  {
287  corsaro_log(__func__, corsaro, "processing %s", argv[i]);
288  init_trace(argv[i]);
289  }
290 
291  while (corsaro_shutdown == 0 && trace_read_packet(trace,packet)>0) {
292  if((filter == NULL || trace_apply_filter(filter, packet) > 0) &&
293  corsaro_per_packet(corsaro, packet) != 0)
294  {
295  corsaro_log(__func__, corsaro, "corsaro_per_packet failed");
296  clean();
297  return -1;
298  }
299  }
300 
301  if (trace_is_err(trace)) {
302  trace_perror(trace,"Reading packets");
303  corsaro_log(__func__, corsaro, "libtrace had an error reading packets");
304  clean();
305  return 1;
306  }
307 
308  close_trace();
309  }
310 
311  for(i=0;i<plugin_cnt;i++)
312  {
313  if(plugins[i] != NULL)
314  free(plugins[i]);
315  }
316 
317  if(tmpl != NULL)
318  free(tmpl);
319 
320  return corsaro_finalize_output(corsaro);
321 }