source: tools/tracesplit/tracesplit.c @ f45e8af

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since f45e8af was f45e8af, checked in by Perry Lorier <perry@…>, 12 years ago
  • More debugging output on file rotation
  • Set rotation by time to always be based on the start time, even if the starttime is before the beginning of the trace, or after the beginning of the trace.
  • Property mode set to 100644
File size: 7.3 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          Set compression level\n"
44        ,argv0);
45        exit(1);
46}
47
48volatile int done=0;
49
50static void cleanup_signal(int sig)
51{
52        done=1;
53}
54
55int main(int argc, char *argv[])
56{
57        /* All these variables are getting silly */
58        struct libtrace_filter_t *filter=NULL;
59        struct libtrace_out_t *output = NULL;
60        struct libtrace_t *input;
61        struct libtrace_packet_t *packet = trace_create_packet();
62        struct sigaction sigact;
63        uint64_t count=UINT64_MAX;
64        uint64_t bytes=UINT64_MAX;
65        uint64_t starttime=0;
66        uint64_t endtime=UINT64_MAX;
67        uint64_t interval=UINT64_MAX;
68        double firsttime=0;
69        uint64_t pktcount=0;
70        uint64_t totbytes=0;
71        uint64_t totbyteslast=0;
72        uint64_t maxfiles = UINT64_MAX;
73        uint64_t filescreated = 0;
74        uint16_t snaplen = 0;
75        int verbose=0;
76        int compress_level=-1;
77       
78        if (argc<2) {
79                usage(argv[0]);
80                return 1;
81        }
82
83        /* Parse command line options */
84        while(1) {
85                int option_index;
86                struct option long_options[] = {
87                        { "filter",        1, 0, 'f' },
88                        { "count",         1, 0, 'c' },
89                        { "bytes",         1, 0, 'b' },
90                        { "starttime",     1, 0, 's' },
91                        { "endtime",       1, 0, 'e' },
92                        { "interval",      1, 0, 'i' },
93                        { "libtrace-help", 0, 0, 'H' },
94                        { "maxfiles",      1, 0, 'm' },
95                        { "snaplen",       1, 0, 'S' },
96                        { "verbose",       0, 0, 'v' },
97                        { "compress",      1, 0, 'z' },
98                        { NULL,            0, 0, 0   },
99                };
100
101                int c=getopt_long(argc, argv, "f:c:b:s:e:i:m:S:Hvz:",
102                                long_options, &option_index);
103
104                if (c==-1)
105                        break;
106
107                switch (c) {
108                        case 'f': filter=trace_create_filter(optarg);
109                                break;
110                        case 'c': count=atoi(optarg);
111                                break;
112                        case 'b': bytes=atoi(optarg);
113                                break;
114                        case 's': starttime=atoi(optarg); /* FIXME: use getdate */
115                                  break;
116                        case 'e': endtime=atoi(optarg);
117                                  break;
118                        case 'i': interval=atoi(optarg);
119                                  break;
120                        case 'm': maxfiles=atoi(optarg);
121                                  break;
122                        case 'S': snaplen=atoi(optarg);
123                                  break;
124                        case 'H':
125                                  trace_help();
126                                  exit(1);
127                                  break;
128                        case 'v':
129                                  verbose++;
130                                  break;
131                        case 'z':
132                                  compress_level=atoi(optarg);
133                                  if (compress_level<0 || compress_level>9) {
134                                        usage(argv[0]);
135                                        exit(1);
136                                  }
137                                  break;
138                        default:
139                                fprintf(stderr,"Unknown option: %c\n",c);
140                                usage(argv[0]);
141                                return 1;
142                }
143        }
144
145        if (optind+2>argc) {
146                fprintf(stderr,"missing inputuri or outputuri\n");
147                usage(argv[0]);
148        }
149
150        sigact.sa_handler = cleanup_signal;
151        sigemptyset(&sigact.sa_mask);
152        sigact.sa_flags = SA_RESTART;
153
154        sigaction(SIGINT, &sigact, NULL);
155        sigaction(SIGTERM, &sigact, NULL);
156
157        output=NULL;
158        input=trace_create(argv[optind]);
159        if (trace_is_err(input)) {
160                trace_perror(input,"%s",argv[optind]);
161                return 1;
162        }
163
164        if (trace_start(input)==-1) {
165                trace_perror(input,"%s",argv[optind]);
166                return 1;
167        }
168
169        signal(SIGINT,&cleanup_signal);
170        signal(SIGTERM,&cleanup_signal);
171
172        while(!done) {
173               
174                if (trace_read_packet(input,packet)<1) {
175                        break;
176                }
177
178                if (snaplen>0) {
179                        trace_set_capture_length(packet,snaplen);
180                }
181               
182                if (filter && !trace_apply_filter(filter,packet)) {
183                        continue;
184                }
185
186                if (trace_get_seconds(packet)<starttime) {
187                        continue;
188                }
189
190                if (trace_get_seconds(packet)>endtime) {
191                        break;
192                }
193
194                if (firsttime==0) {
195                        time_t now = trace_get_seconds(packet);
196                        if (starttime != 0) {
197                                firsttime=now-((now - starttime)%interval);
198                        }
199                        else {
200                                firsttime=now;
201                        }
202                }
203
204                if (output && trace_get_seconds(packet)>firsttime+interval) {
205                        trace_destroy_output(output);
206                        output=NULL;
207                        firsttime+=interval;
208                }
209
210                if (output && pktcount%count==0) {
211                        trace_destroy_output(output);
212                        output=NULL;
213                }
214
215                pktcount++;
216                totbytes+=trace_get_capture_length(packet);
217                if (output && totbytes-totbyteslast>=bytes) {
218                        trace_destroy_output(output);
219                        output=NULL;
220                        totbyteslast=totbytes;
221                }
222                if (!output) {
223                        char *buffer;
224                        bool need_ext=false;
225                        if (maxfiles <= filescreated) {
226                                break;
227                        }
228                        buffer=strdup(argv[optind+1]);
229                        if (interval!=UINT64_MAX && maxfiles>1) {
230                                buffer=strdupcat(buffer,"-");
231                                buffer=strdupcati(buffer,(uint64_t)firsttime);
232                                need_ext=true;
233                        }
234                        if (count!=UINT64_MAX && maxfiles>1) {
235                                buffer=strdupcat(buffer,"-");
236                                buffer=strdupcati(buffer,(uint64_t)pktcount);
237                                need_ext=true;
238                        }
239                        if (bytes!=UINT64_MAX && maxfiles>1) {
240                                static int filenum=0;
241                                buffer=strdupcat(buffer,"-");
242                                buffer=strdupcati(buffer,(uint64_t)++filenum);
243                                need_ext=true;
244                        }
245                        if (need_ext) {
246                                if (compress_level!=0)
247                                        buffer=strdupcat(buffer,".gz");
248                        }
249                        if (verbose>1) {
250                                fprintf(stderr,"%s:",buffer);
251                                if (count!=UINT64_MAX)
252                                        fprintf(stderr," count=%" PRIu64,pktcount);
253                                if (bytes!=UINT64_MAX)
254                                        fprintf(stderr," bytes=%" PRIu64,bytes);
255                                if (interval!=UINT64_MAX) {
256                                        time_t filetime = firsttime;
257                                        fprintf(stderr," time=%s",ctime(&filetime));
258                                }
259                                else {
260                                        fprintf(stderr,"\n");
261                                }
262                        }
263                        output=trace_create_output(buffer);
264                        if (trace_is_err_output(output)) {
265                                trace_perror_output(output,"%s",buffer);
266                                free(buffer);
267                                break;
268                        }
269                        if (compress_level!=-1) {
270                                if (trace_config_output(output,
271                                        TRACE_OPTION_OUTPUT_COMPRESS,
272                                        &compress_level)==-1) {
273                                        trace_perror_output(output,"Unable to set compression");
274                                }
275                        }
276                        trace_start_output(output);
277                        if (trace_is_err_output(output)) {
278                                trace_perror_output(output,"%s",buffer);
279                                free(buffer);
280                                break;
281                        }
282                        free(buffer);
283                        filescreated ++;
284                }
285
286                /* Some traces we have are padded (usually with 0x00), so
287                 * lets sort that out now and truncate them properly
288                 */
289
290                if (trace_get_capture_length(packet) 
291                        > trace_get_wire_length(packet)) {
292                        trace_set_capture_length(packet,trace_get_wire_length(packet));
293                }
294               
295                if (trace_write_packet(output,packet)==-1) {
296                        trace_perror_output(output,"write_packet");
297                        break;
298                }
299
300        }
301
302        if (trace_is_err(input)) {
303                trace_perror(input, "Reading packets");
304        }
305
306        if (verbose) {
307                uint64_t f;
308                f=trace_get_received_packets(input);
309                if (f!=UINT64_MAX)
310                        fprintf(stderr,"%" PRIu64 " packets on input\n",f);
311                f=trace_get_filtered_packets(input);
312                if (f!=UINT64_MAX)
313                        fprintf(stderr,"%" PRIu64 " packets filtered\n",f);
314                f=trace_get_dropped_packets(input);
315                if (f!=UINT64_MAX)
316                        fprintf(stderr,"%" PRIu64 " packets dropped\n",f);
317                f=trace_get_accepted_packets(input);
318                if (f!=UINT64_MAX)
319                        fprintf(stderr,"%" PRIu64 " packets accepted\n",f);
320        }
321       
322        trace_destroy(input);
323        if (output)
324                trace_destroy_output(output);
325
326        trace_destroy_packet(packet);
327
328        return 0;
329}
Note: See TracBrowser for help on using the repository browser.