source: tools/tracesplit/tracesplit.c @ 0539f11

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 0539f11 was 0539f11, checked in by Perry Lorier <perry@…>, 13 years ago

Complain about missing arguments.

  • Property mode set to 100644
File size: 6.9 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
14static char *strdupcat(char *str,char *app)
15{
16        str=realloc(str,strlen(str)+strlen(app)+1);
17        strcat(str,app);
18        return str;
19}
20
21static char *strdupcati(char *str,uint64_t i)
22{
23        char buffer[64];
24        snprintf(buffer,sizeof(buffer),"%" PRIu64,i);
25        return strdupcat(str,buffer);
26}
27
28static int usage(char *argv0)
29{
30        printf("Usage:\n"
31        "%s flags inputuri outputuri\n"
32        "-f --filter=bpf        only output packets that match filter\n"
33        "-c --count=n           split every n packets\n"
34        "-b --bytes=n           Split every n bytes received\n"
35        "-i --interval=n        Split every n seconds\n"
36        "-s --starttime=time    Start at time\n"
37        "-e --endtime=time      End at time\n"
38        "-m --maxfiles=n        Create a maximum of n trace files\n"
39        "-H --libtrace-help     Print libtrace runtime documentation\n"
40        "-S --snaplen           Snap packets at the specified length\n"
41        "-v --verbose           Output statistics\n"
42        "-z --compress          Set compression level\n"
43        ,argv0);
44        exit(1);
45}
46
47volatile int done=0;
48
49static void cleanup_signal(int sig)
50{
51        done=1;
52}
53
54int main(int argc, char *argv[])
55{
56        /* All these variables are getting silly */
57        struct libtrace_filter_t *filter=NULL;
58        struct libtrace_out_t *output = NULL;
59        struct libtrace_t *input;
60        struct libtrace_packet_t *packet = trace_create_packet();
61        struct sigaction sigact;
62        uint64_t count=UINT64_MAX;
63        uint64_t bytes=UINT64_MAX;
64        uint64_t starttime=0;
65        uint64_t endtime=UINT64_MAX;
66        uint64_t interval=UINT64_MAX;
67        double firsttime=0;
68        uint64_t pktcount=0;
69        uint64_t totbytes=0;
70        uint64_t totbyteslast=0;
71        uint64_t maxfiles = UINT64_MAX;
72        uint64_t filescreated = 0;
73        uint16_t snaplen = 0;
74        int verbose=0;
75        int compress_level=-1;
76       
77        if (argc<2) {
78                usage(argv[0]);
79                return 1;
80        }
81
82        /* Parse command line options */
83        while(1) {
84                int option_index;
85                struct option long_options[] = {
86                        { "filter",        1, 0, 'f' },
87                        { "count",         1, 0, 'c' },
88                        { "bytes",         1, 0, 'b' },
89                        { "starttime",     1, 0, 's' },
90                        { "endtime",       1, 0, 'e' },
91                        { "interval",      1, 0, 'i' },
92                        { "libtrace-help", 0, 0, 'H' },
93                        { "maxfiles",      1, 0, 'm' },
94                        { "snaplen",       1, 0, 'S' },
95                        { "verbose",       0, 0, 'v' },
96                        { "compress",      1, 0, 'z' },
97                        { NULL,            0, 0, 0   },
98                };
99
100                int c=getopt_long(argc, argv, "f:c:b:s:e:i:m:S:Hvz:",
101                                long_options, &option_index);
102
103                if (c==-1)
104                        break;
105
106                switch (c) {
107                        case 'f': filter=trace_create_filter(optarg);
108                                break;
109                        case 'c': count=atoi(optarg);
110                                break;
111                        case 'b': bytes=atoi(optarg);
112                                break;
113                        case 's': starttime=atoi(optarg); /* FIXME: use getdate */
114                                  break;
115                        case 'e': endtime=atoi(optarg);
116                                  break;
117                        case 'i': interval=atoi(optarg);
118                                  break;
119                        case 'm': maxfiles=atoi(optarg);
120                                  break;
121                        case 'S': snaplen=atoi(optarg);
122                                  break;
123                        case 'H':
124                                  trace_help();
125                                  exit(1);
126                                  break;
127                        case 'v':
128                                  verbose++;
129                                  break;
130                        case 'z':
131                                  compress_level=atoi(optarg);
132                                  if (compress_level<0 || compress_level>9) {
133                                        usage(argv[0]);
134                                        exit(1);
135                                  }
136                                  break;
137                        default:
138                                fprintf(stderr,"Unknown option: %c\n",c);
139                                usage(argv[0]);
140                                return 1;
141                }
142        }
143
144        if (optind+2>argc) {
145                fprintf(stderr,"missing inputuri or outputuri\n");
146                usage(argv[0]);
147        }
148
149        sigact.sa_handler = cleanup_signal;
150        sigemptyset(&sigact.sa_mask);
151        sigact.sa_flags = SA_RESTART;
152
153        sigaction(SIGINT, &sigact, NULL);
154        sigaction(SIGTERM, &sigact, NULL);
155
156        output=NULL;
157        input=trace_create(argv[optind]);
158        if (trace_is_err(input)) {
159                trace_perror(input,"%s",argv[optind]);
160                return 1;
161        }
162
163        if (trace_start(input)==-1) {
164                trace_perror(input,"%s",argv[optind]);
165                return 1;
166        }
167
168        signal(SIGINT,&cleanup_signal);
169        signal(SIGTERM,&cleanup_signal);
170
171        while(!done) {
172               
173                if (trace_read_packet(input,packet)<1) {
174                        break;
175                }
176
177                if (snaplen>0) {
178                        trace_set_capture_length(packet,snaplen);
179                }
180               
181                if (filter && !trace_apply_filter(filter,packet)) {
182                        continue;
183                }
184
185                if (trace_get_seconds(packet)<starttime) {
186                        continue;
187                }
188
189                if (trace_get_seconds(packet)>endtime) {
190                        break;
191                }
192
193                if (firsttime==0) {
194                        firsttime=trace_get_seconds(packet);
195                }
196
197                if (output && trace_get_seconds(packet)>firsttime+interval) {
198                        trace_destroy_output(output);
199                        output=NULL;
200                        firsttime+=interval;
201                }
202
203                if (output && pktcount%count==0) {
204                        trace_destroy_output(output);
205                        output=NULL;
206                }
207
208                pktcount++;
209                totbytes+=trace_get_capture_length(packet);
210                if (output && totbytes-totbyteslast>=bytes) {
211                        trace_destroy_output(output);
212                        output=NULL;
213                        totbyteslast=totbytes;
214                }
215                if (!output) {
216                        char *buffer;
217                        bool need_ext=false;
218                        if (maxfiles <= filescreated) {
219                                break;
220                        }
221                        buffer=strdup(argv[optind+1]);
222                        if (interval!=UINT64_MAX && maxfiles>1) {
223                                buffer=strdupcat(buffer,"-");
224                                buffer=strdupcati(buffer,(uint64_t)firsttime);
225                                need_ext=true;
226                        }
227                        if (count!=UINT64_MAX && maxfiles>1) {
228                                buffer=strdupcat(buffer,"-");
229                                buffer=strdupcati(buffer,(uint64_t)pktcount);
230                                need_ext=true;
231                        }
232                        if (bytes!=UINT64_MAX && maxfiles>1) {
233                                static int filenum=0;
234                                buffer=strdupcat(buffer,"-");
235                                buffer=strdupcati(buffer,(uint64_t)++filenum);
236                                need_ext=true;
237                        }
238                        if (need_ext) {
239                                if (compress_level!=0)
240                                        buffer=strdupcat(buffer,".gz");
241                        }
242                        output=trace_create_output(buffer);
243                        if (trace_is_err_output(output)) {
244                                trace_perror_output(output,"%s",buffer);
245                                free(buffer);
246                                break;
247                        }
248                        if (compress_level!=-1) {
249                                if (trace_config_output(output,
250                                        TRACE_OPTION_OUTPUT_COMPRESS,
251                                        &compress_level)==-1) {
252                                        trace_perror_output(output,"Unable to set compression");
253                                }
254                        }
255                        trace_start_output(output);
256                        if (trace_is_err_output(output)) {
257                                trace_perror_output(output,"%s",buffer);
258                                free(buffer);
259                                break;
260                        }
261                        if (verbose) {
262                                fprintf(stderr,"%s\n",buffer);
263                        }
264                        free(buffer);
265                        filescreated ++;
266                }
267
268                /* Some traces we have are padded (usually with 0x00), so
269                 * lets sort that out now and truncate them properly
270                 */
271
272                if (trace_get_capture_length(packet) 
273                        > trace_get_wire_length(packet)) {
274                        trace_set_capture_length(packet,trace_get_wire_length(packet));
275                }
276               
277                if (trace_write_packet(output,packet)==-1) {
278                        trace_perror_output(output,"write_packet");
279                        break;
280                }
281
282        }
283
284        if (trace_is_err(input)) {
285                trace_perror(input, "Reading packets");
286        }
287
288        if (verbose) {
289                uint64_t f;
290                f=trace_get_received_packets(input);
291                if (f!=UINT64_MAX)
292                        fprintf(stderr,"%" PRIu64 " packets on input\n",f);
293                f=trace_get_filtered_packets(input);
294                if (f!=UINT64_MAX)
295                        fprintf(stderr,"%" PRIu64 " packets filtered\n",f);
296                f=trace_get_dropped_packets(input);
297                if (f!=UINT64_MAX)
298                        fprintf(stderr,"%" PRIu64 " packets dropped\n",f);
299                f=trace_get_accepted_packets(input);
300                if (f!=UINT64_MAX)
301                        fprintf(stderr,"%" PRIu64 " packets accepted\n",f);
302        }
303       
304        trace_destroy(input);
305        if (output)
306                trace_destroy_output(output);
307
308        trace_destroy_packet(packet);
309
310        return 0;
311}
Note: See TracBrowser for help on using the repository browser.