source: tools/tracesplit/tracesplit.c @ fafc1ff

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

Cleanup when we receive a signal to abort.

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