source: tools/tracesplit/tracesplit.c @ ba91618

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ba91618 was ba91618, checked in by Shane Alcock <salcock@…>, 11 years ago
  • Updated manpages for traceanon and tracemerge to reflect new -Z option.
  • Attempted to add some consistency in the naming of long options for -z and -Z across tools
  • Property mode set to 100644
File size: 9.0 KB
Line 
1#include <libtrace.h>
2#include <stdio.h>
3#include <stdlib.h>
4#ifdef HAVE_INTTYPES_H
5#  include <inttypes.h>
6#endif
7#include <lt_inttypes.h>
8#include <stdbool.h>
9#include <getopt.h>
10#include <string.h>
11#include <assert.h>
12#include <signal.h>
13#include <time.h>
14
15static char *strdupcat(char *str,char *app)
16{
17        str=realloc(str,strlen(str)+strlen(app)+1);
18        strcat(str,app);
19        return str;
20}
21
22static char *strdupcati(char *str,uint64_t i)
23{
24        char buffer[64];
25        snprintf(buffer,sizeof(buffer),"%" PRIu64,i);
26        return strdupcat(str,buffer);
27}
28
29static int usage(char *argv0)
30{
31        printf("Usage:\n"
32        "%s flags inputuri outputuri\n"
33        "-f --filter=bpf        only output packets that match filter\n"
34        "-c --count=n           split every n packets\n"
35        "-b --bytes=n           Split every n bytes received\n"
36        "-i --interval=n        Split every n seconds\n"
37        "-s --starttime=time    Start at time\n"
38        "-e --endtime=time      End at time\n"
39        "-m --maxfiles=n        Create a maximum of n trace files\n"
40        "-H --libtrace-help     Print libtrace runtime documentation\n"
41        "-S --snaplen           Snap packets at the specified length\n"
42        "-v --verbose           Output statistics\n"
43        "-z --compress-level    Set compression level\n"
44        "-Z --compress-type     Set compression type\n"
45        ,argv0);
46        exit(1);
47}
48
49volatile int done=0;
50
51static void cleanup_signal(int sig)
52{
53        (void)sig;
54        done=1;
55}
56
57int main(int argc, char *argv[])
58{
59        /* All these variables are getting silly */
60        struct libtrace_filter_t *filter=NULL;
61        struct libtrace_out_t *output = NULL;
62        struct libtrace_t *input;
63        struct libtrace_packet_t *packet = trace_create_packet();
64        struct sigaction sigact;
65        uint64_t count=UINT64_MAX;
66        uint64_t bytes=UINT64_MAX;
67        uint64_t starttime=0;
68        uint64_t endtime=UINT64_MAX;
69        uint64_t interval=UINT64_MAX;
70        double firsttime=0;
71        uint64_t pktcount=0;
72        uint64_t totbytes=0;
73        uint64_t totbyteslast=0;
74        uint64_t maxfiles = UINT64_MAX;
75        uint64_t filescreated = 0;
76        uint16_t snaplen = 0;
77        int verbose=0;
78        int compress_level=-1;
79        char *compress_type_str=NULL;
80        trace_option_compresstype_t compress_type = TRACE_OPTION_COMPRESSTYPE_NONE;
81
82        if (argc<2) {
83                usage(argv[0]);
84                return 1;
85        }
86
87        /* Parse command line options */
88        while(1) {
89                int option_index;
90                struct option long_options[] = {
91                        { "filter",        1, 0, 'f' },
92                        { "count",         1, 0, 'c' },
93                        { "bytes",         1, 0, 'b' },
94                        { "starttime",     1, 0, 's' },
95                        { "endtime",       1, 0, 'e' },
96                        { "interval",      1, 0, 'i' },
97                        { "libtrace-help", 0, 0, 'H' },
98                        { "maxfiles",      1, 0, 'm' },
99                        { "snaplen",       1, 0, 'S' },
100                        { "verbose",       0, 0, 'v' },
101                        { "compress-level", 1, 0, 'z' },
102                        { "compress-type", 1, 0, 'Z' },
103                        { NULL,            0, 0, 0   },
104                };
105
106                int c=getopt_long(argc, argv, "f:c:b:s:e:i:m:S:Hvz:Z:",
107                                long_options, &option_index);
108
109                if (c==-1)
110                        break;
111
112                switch (c) {
113                        case 'f': filter=trace_create_filter(optarg);
114                                break;
115                        case 'c': count=atoi(optarg);
116                                break;
117                        case 'b': bytes=atoi(optarg);
118                                break;
119                        case 's': starttime=atoi(optarg); /* FIXME: use getdate */
120                                  break;
121                        case 'e': endtime=atoi(optarg);
122                                  break;
123                        case 'i': interval=atoi(optarg);
124                                  break;
125                        case 'm': maxfiles=atoi(optarg);
126                                  break;
127                        case 'S': snaplen=atoi(optarg);
128                                  break;
129                        case 'H':
130                                  trace_help();
131                                  exit(1);
132                                  break;
133                        case 'v':
134                                  verbose++;
135                                  break;
136                        case 'z':
137                                  compress_level=atoi(optarg);
138                                  if (compress_level<0 || compress_level>9) {
139                                        usage(argv[0]);
140                                        exit(1);
141                                  }
142                                  break;
143                        case 'Z':
144                                  compress_type_str=optarg;
145                                  break;       
146                        default:
147                                fprintf(stderr,"Unknown option: %c\n",c);
148                                usage(argv[0]);
149                                return 1;
150                }
151        }
152
153        if (compress_type_str == NULL && compress_level >= 0) {
154                fprintf(stderr, "Compression level set, but no compression type was defined, setting to gzip\n");
155                compress_type = TRACE_OPTION_COMPRESSTYPE_ZLIB;
156        }
157
158        else if (compress_type_str == NULL) {
159                /* If a level or type is not specified, use the "none"
160                 * compression module */
161                compress_type = TRACE_OPTION_COMPRESSTYPE_NONE;
162        }
163
164        /* I decided to be fairly generous in what I accept for the
165         * compression type string */
166        else if (strncmp(compress_type_str, "gz", 2) == 0 ||
167                        strncmp(compress_type_str, "zlib", 4) == 0) {
168                compress_type = TRACE_OPTION_COMPRESSTYPE_ZLIB;
169        } else if (strncmp(compress_type_str, "bz", 2) == 0) {
170                compress_type = TRACE_OPTION_COMPRESSTYPE_BZ2;
171        } else if (strncmp(compress_type_str, "lzo", 3) == 0) {
172                compress_type = TRACE_OPTION_COMPRESSTYPE_LZO;
173        } else if (strncmp(compress_type_str, "no", 2) == 0) {
174                compress_type = TRACE_OPTION_COMPRESSTYPE_NONE;
175        } else {
176                fprintf(stderr, "Unknown compression type: %s\n", 
177                        compress_type_str);
178                return 1;
179        }
180
181        if (optind+2>argc) {
182                fprintf(stderr,"missing inputuri or outputuri\n");
183                usage(argv[0]);
184        }
185
186        sigact.sa_handler = cleanup_signal;
187        sigemptyset(&sigact.sa_mask);
188        sigact.sa_flags = SA_RESTART;
189
190        sigaction(SIGINT, &sigact, NULL);
191        sigaction(SIGTERM, &sigact, NULL);
192
193        output=NULL;
194        input=trace_create(argv[optind]);
195        if (trace_is_err(input)) {
196                trace_perror(input,"%s",argv[optind]);
197                return 1;
198        }
199
200        if (trace_start(input)==-1) {
201                trace_perror(input,"%s",argv[optind]);
202                return 1;
203        }
204
205        signal(SIGINT,&cleanup_signal);
206        signal(SIGTERM,&cleanup_signal);
207
208        while(!done) {
209               
210                if (trace_read_packet(input,packet)<1) {
211                        break;
212                }
213
214                if (trace_get_link_type(packet) == ~0U) {
215                        fprintf(stderr, "Halted due to being unable to determine linktype - input trace may be corrupt.\n");
216                        break;
217                }
218
219                if (snaplen>0) {
220                        trace_set_capture_length(packet,snaplen);
221                }
222               
223                if (filter && !trace_apply_filter(filter,packet)) {
224                        continue;
225                }
226
227                if (trace_get_seconds(packet)<starttime) {
228                        continue;
229                }
230
231                if (trace_get_seconds(packet)>endtime) {
232                        break;
233                }
234
235                if (firsttime==0) {
236                        time_t now = trace_get_seconds(packet);
237                        if (starttime != 0) {
238                                firsttime=now-((now - starttime)%interval);
239                        }
240                        else {
241                                firsttime=now;
242                        }
243                }
244
245                if (output && trace_get_seconds(packet)>firsttime+interval) {
246                        trace_destroy_output(output);
247                        output=NULL;
248                        firsttime+=interval;
249                }
250
251                if (output && pktcount%count==0) {
252                        trace_destroy_output(output);
253                        output=NULL;
254                }
255
256                pktcount++;
257                totbytes+=trace_get_capture_length(packet);
258                if (output && totbytes-totbyteslast>=bytes) {
259                        trace_destroy_output(output);
260                        output=NULL;
261                        totbyteslast=totbytes;
262                }
263                if (!output) {
264                        char *buffer;
265                        bool need_ext=false;
266                        if (maxfiles <= filescreated) {
267                                break;
268                        }
269                        buffer=strdup(argv[optind+1]);
270                        if (interval!=UINT64_MAX && maxfiles>1) {
271                                buffer=strdupcat(buffer,"-");
272                                buffer=strdupcati(buffer,(uint64_t)firsttime);
273                                need_ext=true;
274                        }
275                        if (count!=UINT64_MAX && maxfiles>1) {
276                                buffer=strdupcat(buffer,"-");
277                                buffer=strdupcati(buffer,(uint64_t)pktcount);
278                                need_ext=true;
279                        }
280                        if (bytes!=UINT64_MAX && maxfiles>1) {
281                                static int filenum=0;
282                                buffer=strdupcat(buffer,"-");
283                                buffer=strdupcati(buffer,(uint64_t)++filenum);
284                                need_ext=true;
285                        }
286                        if (need_ext) {
287                                if (compress_level!=0)
288                                        buffer=strdupcat(buffer,".gz");
289                        }
290                        if (verbose>1) {
291                                fprintf(stderr,"%s:",buffer);
292                                if (count!=UINT64_MAX)
293                                        fprintf(stderr," count=%" PRIu64,pktcount);
294                                if (bytes!=UINT64_MAX)
295                                        fprintf(stderr," bytes=%" PRIu64,bytes);
296                                if (interval!=UINT64_MAX) {
297                                        time_t filetime = firsttime;
298                                        fprintf(stderr," time=%s",ctime(&filetime));
299                                }
300                                else {
301                                        fprintf(stderr,"\n");
302                                }
303                        }
304                        output=trace_create_output(buffer);
305                        if (trace_is_err_output(output)) {
306                                trace_perror_output(output,"%s",buffer);
307                                free(buffer);
308                                break;
309                        }
310                        if (compress_level!=-1) {
311                                if (trace_config_output(output,
312                                        TRACE_OPTION_OUTPUT_COMPRESS,
313                                        &compress_level)==-1) {
314                                        trace_perror_output(output,"Unable to set compression level");
315                                }
316                        }
317
318                        if (trace_config_output(output,
319                                TRACE_OPTION_OUTPUT_COMPRESSTYPE,
320                                &compress_type) == -1) {
321                                        trace_perror_output(output, "Unable to set compression type");
322                        }
323
324                        trace_start_output(output);
325                        if (trace_is_err_output(output)) {
326                                trace_perror_output(output,"%s",buffer);
327                                free(buffer);
328                                break;
329                        }
330                        free(buffer);
331                        filescreated ++;
332                }
333
334                /* Some traces we have are padded (usually with 0x00), so
335                 * lets sort that out now and truncate them properly
336                 */
337
338                if (trace_get_capture_length(packet) 
339                        > trace_get_wire_length(packet)) {
340                        trace_set_capture_length(packet,trace_get_wire_length(packet));
341                }
342               
343                if (trace_write_packet(output,packet)==-1) {
344                        trace_perror_output(output,"write_packet");
345                        break;
346                }
347
348        }
349
350        if (trace_is_err(input)) {
351                trace_perror(input, "Reading packets");
352        }
353
354        if (verbose) {
355                uint64_t f;
356                f=trace_get_received_packets(input);
357                if (f!=UINT64_MAX)
358                        fprintf(stderr,"%" PRIu64 " packets on input\n",f);
359                f=trace_get_filtered_packets(input);
360                if (f!=UINT64_MAX)
361                        fprintf(stderr,"%" PRIu64 " packets filtered\n",f);
362                f=trace_get_dropped_packets(input);
363                if (f!=UINT64_MAX)
364                        fprintf(stderr,"%" PRIu64 " packets dropped\n",f);
365                f=trace_get_accepted_packets(input);
366                if (f!=UINT64_MAX)
367                        fprintf(stderr,"%" PRIu64 " packets accepted\n",f);
368        }
369       
370        trace_destroy(input);
371        if (output)
372                trace_destroy_output(output);
373
374        trace_destroy_packet(packet);
375
376        return 0;
377}
Note: See TracBrowser for help on using the repository browser.