source: tools/tracesplit/tracesplit.c @ 4423dc7

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

Add support to various tools for outputting the number of dropped packets
they've seen

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