source: tools/tracesplit/tracesplit.c @ a8f2692

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

Tidy up a bazillion tiny warnings

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