source: tools/tracesplit/tracesplit.c @ 34d1d98

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 34d1d98 was 34d1d98, checked in by Perry Lorier <perry@…>, 13 years ago
  • Create a .gz extension only if we're compressing files
  • Add extensions if we build up the uri ourselves
  • 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        if (optind+2<argc) {
144                fprintf(stderr,"missing inputuri or outputuri\n");
145                usage(argv[0]);
146        }
147
148        sigact.sa_handler = cleanup_signal;
149        sigemptyset(&sigact.sa_mask);
150        sigact.sa_flags = SA_RESTART;
151
152        sigaction(SIGINT, &sigact, NULL);
153        sigaction(SIGTERM, &sigact, NULL);
154
155        output=NULL;
156        input=trace_create(argv[optind]);
157        if (trace_is_err(input)) {
158                trace_perror(input,"%s",argv[optind]);
159                return 1;
160        }
161
162        if (trace_start(input)==-1) {
163                trace_perror(input,"%s",argv[optind]);
164                return 1;
165        }
166
167        signal(SIGINT,&cleanup_signal);
168        signal(SIGTERM,&cleanup_signal);
169
170        while(!done) {
171               
172                if (trace_read_packet(input,packet)<1) {
173                        break;
174                }
175
176                if (snaplen>0) {
177                        trace_set_capture_length(packet,snaplen);
178                }
179               
180                if (filter && !trace_apply_filter(filter,packet)) {
181                        continue;
182                }
183
184                if (trace_get_seconds(packet)<starttime) {
185                        continue;
186                }
187
188                if (trace_get_seconds(packet)>endtime) {
189                        break;
190                }
191
192                if (firsttime==0) {
193                        firsttime=trace_get_seconds(packet);
194                }
195
196                if (output && trace_get_seconds(packet)>firsttime+interval) {
197                        trace_destroy_output(output);
198                        output=NULL;
199                        firsttime+=interval;
200                }
201
202                if (output && pktcount%count==0) {
203                        trace_destroy_output(output);
204                        output=NULL;
205                }
206
207                pktcount++;
208                totbytes+=trace_get_capture_length(packet);
209                if (output && totbytes-totbyteslast>=bytes) {
210                        trace_destroy_output(output);
211                        output=NULL;
212                        totbyteslast=totbytes;
213                }
214                if (!output) {
215                        char *buffer;
216                        bool need_ext=false;
217                        if (maxfiles <= filescreated) {
218                                break;
219                        }
220                        buffer=strdup(argv[optind+1]);
221                        if (interval!=UINT64_MAX && maxfiles>1) {
222                                buffer=strdupcat(buffer,"-");
223                                buffer=strdupcati(buffer,(uint64_t)firsttime);
224                                need_ext=true;
225                        }
226                        if (count!=UINT64_MAX && maxfiles>1) {
227                                buffer=strdupcat(buffer,"-");
228                                buffer=strdupcati(buffer,(uint64_t)pktcount);
229                                need_ext=true;
230                        }
231                        if (bytes!=UINT64_MAX && maxfiles>1) {
232                                static int filenum=0;
233                                buffer=strdupcat(buffer,"-");
234                                buffer=strdupcati(buffer,(uint64_t)++filenum);
235                                need_ext=true;
236                        }
237                        if (need_ext) {
238                                if (compress_level!=0)
239                                        buffer=strdupcat(buffer,".gz");
240                        }
241                        output=trace_create_output(buffer);
242                        if (trace_is_err_output(output)) {
243                                trace_perror_output(output,"%s",buffer);
244                                free(buffer);
245                                break;
246                        }
247                        if (compress_level!=-1) {
248                                if (trace_config_output(output,
249                                        TRACE_OPTION_OUTPUT_COMPRESS,
250                                        &compress_level)==-1) {
251                                        trace_perror_output(output,"Unable to set compression");
252                                }
253                        }
254                        trace_start_output(output);
255                        if (trace_is_err_output(output)) {
256                                trace_perror_output(output,"%s",buffer);
257                                free(buffer);
258                                break;
259                        }
260                        if (verbose) {
261                                fprintf(stderr,"%s\n",buffer);
262                        }
263                        free(buffer);
264                        filescreated ++;
265                }
266
267                /* Some traces we have are padded (usually with 0x00), so
268                 * lets sort that out now and truncate them properly
269                 */
270
271                if (trace_get_capture_length(packet) 
272                        > trace_get_wire_length(packet)) {
273                        trace_set_capture_length(packet,trace_get_wire_length(packet));
274                }
275               
276                if (trace_write_packet(output,packet)==-1) {
277                        trace_perror_output(output,"write_packet");
278                        break;
279                }
280
281        }
282
283        if (trace_is_err(input)) {
284                trace_perror(input, "Reading packets");
285        }
286
287        if (verbose) {
288                uint64_t f;
289                f=trace_get_received_packets(input);
290                if (f!=UINT64_MAX)
291                        fprintf(stderr,"%" PRIu64 " packets on input\n",f);
292                f=trace_get_filtered_packets(input);
293                if (f!=UINT64_MAX)
294                        fprintf(stderr,"%" PRIu64 " packets filtered\n",f);
295                f=trace_get_dropped_packets(input);
296                if (f!=UINT64_MAX)
297                        fprintf(stderr,"%" PRIu64 " packets dropped\n",f);
298                f=trace_get_accepted_packets(input);
299                if (f!=UINT64_MAX)
300                        fprintf(stderr,"%" PRIu64 " packets accepted\n",f);
301        }
302       
303        trace_destroy(input);
304        if (output)
305                trace_destroy_output(output);
306
307        trace_destroy_packet(packet);
308
309        return 0;
310}
Note: See TracBrowser for help on using the repository browser.