source: tools/tracereplay/tracereplay.c @ 2b9a4c7

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 2b9a4c7 was 2b9a4c7, checked in by Yuwei Wang <yww4@…>, 12 years ago

using getopt for commandline arguements. add -f for filter support

  • Property mode set to 100644
File size: 4.4 KB
RevLine 
[550be94]1
2
3
4/* This is a simple example program that demonstrates how to use the libtrace
5 * event framework. The event framework is ideal for reading from devices and
6 * interfaces in a non-blocking manner, and for reading from a trace in
7 * "tracetime" as opposed to as fast as possible.
8 */
9
10
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <assert.h>
15#include <sys/types.h>
16#include <unistd.h>
17#include <string.h>
18#include <libtrace.h>
[2b9a4c7]19#include <getopt.h>
[550be94]20
21static libtrace_packet_t * per_packet(libtrace_packet_t *packet) {
22 
23  uint32_t remaining;
24  libtrace_linktype_t linktype;
25  void * pkt_buffer = trace_get_packet_buffer(packet,&linktype,&remaining);
[9b8ece6]26  libtrace_packet_t *new_packet = trace_create_packet();
[550be94]27
28  size_t wire_length = trace_get_wire_length(packet);
29
30  trace_construct_packet(new_packet,linktype,pkt_buffer,wire_length);
31
32  return new_packet;
33 
34}
35
36static uint32_t event_read_packet(libtrace_t *trace, libtrace_packet_t *packet) 
37{
38        libtrace_eventobj_t obj;
39        fd_set rfds;
40        struct timeval sleep_tv;
41       
42        FD_ZERO(&rfds);
43       
44        for (;;) {
45                obj = trace_event(trace, packet);
46
47                switch(obj.type) {
48                       
49                        /* Device has no packets at present - lets wait until
50                         * it does get something */
51                        case TRACE_EVENT_IOWAIT:
52                                FD_ZERO(&rfds);
53                                FD_SET(obj.fd, &rfds);
54                                select(obj.fd + 1, &rfds, NULL, NULL, 0);
55                                continue;
56                               
57                        /* Replaying a trace in tracetime and the next packet
58                         * is not due yet */
59                        case TRACE_EVENT_SLEEP:
60                                /* select offers good precision for sleeping */
61                                sleep_tv.tv_sec = (int)obj.seconds;
62                                sleep_tv.tv_usec = (int) ((obj.seconds - sleep_tv.tv_sec) * 1000000.0);
63                                select(0, NULL, NULL, NULL, &sleep_tv);
64                                continue;
65                               
66                        /* We've got a packet! */
67                        case TRACE_EVENT_PACKET:
68                                /* Check for error first */
69                                if (obj.size == -1)
70                                        return -1;
71                                return 1;
72                               
73                        /* End of trace has been reached */
74                        case TRACE_EVENT_TERMINATE:
75                                return -1;
76                               
77                        /* An event we don't know about has occured */
78                        default:
79                                fprintf(stderr, "Unknown event type occured\n");
80                                return -1;
81                }
82        }
83}
[2b9a4c7]84
85static void usage(char * argv) {
86        fprintf(stderr, "usage: %s [options] libtraceuri outputuri...\n", argv);
87        fprintf(stderr, " --filter bpfexpr\n");
88        fprintf(stderr, " -f bpfexpr\n");
89        fprintf(stderr, "\t\tApply a bpf filter expression\n");
90}
91
[550be94]92int main(int argc, char *argv[]) {
93       
94        libtrace_t *trace;
95        libtrace_out_t *output;
96        libtrace_packet_t *packet;
[2b9a4c7]97        libtrace_filter_t *filter=NULL;
[550be94]98        int psize = 0;
99        char *uri = 0;
[2b9a4c7]100
101        while(1) {
102                int option_index;
103                struct option long_options[] = {
104                        { "filter",     1, 0, 'f'},
105                        { "help",       0, 0, 'h'},
106                        { NULL,         0, 0, 0}
107                };
108
109                int c = getopt_long(argc, argv, "f:",
110                                long_options, &option_index);
111
112                if(c == -1)
113                        break;
114
115                switch (c) {
116                        case 'f':
117                                filter = trace_create_filter(optarg);
118                                break;
119                        case 'h':
120                                usage(argv[0]);
121                                return 1;
122                        default:
123                                fprintf(stderr, "Unknown option: %c\n", c);
124                }
125        }
126
127        if(optind>=argc) {
128                fprintf(stderr, "Missing input uri\n");
129                usage(argv[0]);
130                return 1;
131        }
132        if(optind+1>=argc) {
133                fprintf(stderr, "Missing output uri\n");
134                usage(argv[0]);
135                return 1;
[550be94]136        }
137
[2b9a4c7]138        uri = strdup(argv[optind]);
139
[550be94]140        /* Create the trace */
141        trace = trace_create(uri);
142        if (trace_is_err(trace)) {
143                trace_perror(trace, "trace_create");
144                return 1;
145        }
[2b9a4c7]146
147        /* apply filter */
148        if(filter) {
149                if(trace_config(trace, TRACE_OPTION_FILTER, filter)) {
150                        trace_perror(trace, "ignoring: ");
151                }
152        }
153
[550be94]154        /* Starting the trace */
155        if (trace_start(trace) != 0) {
156                trace_perror(trace, "trace_start");
157                return 1;
158        }
159
160        /* Creating output trace */
[2b9a4c7]161        output = trace_create_output(argv[optind+1]);
[550be94]162       
163        if (trace_is_err_output(output)) {
[2b9a4c7]164                trace_perror_output(output, "Opening output trace: ");
[550be94]165                return 1;
166        }
167        if (trace_start_output(output)) {
[2b9a4c7]168                trace_perror_output(output, "Starting output trace: ");
[550be94]169                trace_destroy_output(output);
170                trace_destroy(trace);
171                return 1;
172        }
173
174        packet = trace_create_packet();
175
176        for (;;) {
177                if ((psize = event_read_packet(trace, packet)) <= 0) {
178                        break;
179                }
180
181                /* Got a packet - let's do something with it */
182                libtrace_packet_t * new = per_packet(packet);
183
184                if (trace_write_packet(output, new) < 0) {
185                        trace_perror_output(output, "Writing packet");
186                        trace_destroy(trace);
187                        trace_destroy_output(output);
188                        trace_destroy_packet(packet);
189                        return 1;
190                }
191                trace_destroy_packet(new);
192        }
193        free(uri);
194        trace_destroy(trace);
[2b9a4c7]195        trace_destroy_filter(filter);
[550be94]196        trace_destroy_output(output);
197        trace_destroy_packet(packet);
198        return 0;
199
200}
Note: See TracBrowser for help on using the repository browser.