source: tools/tracereplay/tracereplay.c @ ff7d949

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ff7d949 was ff7d949, checked in by Andreas Löf <andreas.lof@…>, 12 years ago

checksums working

  • Property mode set to 100644
File size: 5.7 KB
Line 
1
2/*
3
4  Tracereplay is a simple utility that takes a trace and replays it to a
5  specified interface.
6  It pads packets with zeroes to reach the original length of the packet
7  and recalculates crc checksums in ip/tcp/udp headers.
8
9  Authors: Andreas Loef and Yuwei Wang
10
11
12 */
13
14
15
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <assert.h>
20#include <sys/types.h>
21#include <unistd.h>
22#include <string.h>
23#include <libtrace.h>
24#include <getopt.h>
25#include <arpa/inet.h>
26
27#define FCS_SIZE 4
28
29/* This function assumes that the relevant fields have been zeroed out. RFC 1071*/
30static uint16_t checksum(void * buffer, uint16_t length) {
31  uint32_t sum = 0;
32  uint16_t * buff = (uint16_t *) buffer;
33  uint16_t count = length;
34
35  while(count > 1 ) {
36    sum += *buff++;
37    count = count -2;
38  }
39
40  if(count > 0) {
41    sum += buff;
42  }
43 
44  while (sum>>16)
45    sum = (sum & 0xffff) + (sum >> 16);
46
47  return ~sum;
48}
49
50static uint16_t udp_tcp_checksum(libtrace_packet_t *packet) {
51
52  uint32_t sum;
53
54
55
56}
57
58
59static libtrace_packet_t * per_packet(libtrace_packet_t *packet) {
60 
61  uint32_t remaining;
62  libtrace_linktype_t linktype;
63  void * pkt_buffer = trace_get_packet_buffer(packet,&linktype,&remaining);
64  libtrace_packet_t *new_packet = trace_create_packet();
65
66  size_t wire_length = trace_get_wire_length(packet);
67
68  libtrace_ip_t * header;
69
70  if(linktype == TRACE_TYPE_ETH || linktype == TRACE_TYPE_80211) {
71    wire_length -= FCS_SIZE;
72  }
73
74  trace_construct_packet(new_packet,linktype,pkt_buffer,wire_length);
75 
76
77  header = trace_get_ip(new_packet);
78  if(header != NULL) {
79    header -> ip_sum = 0;
80    header -> ip_sum = checksum(header,header->ip_hl*sizeof(uint32_t));
81  }
82
83  return new_packet;
84 
85}
86
87
88
89static uint32_t event_read_packet(libtrace_t *trace, libtrace_packet_t *packet) 
90{
91        libtrace_eventobj_t obj;
92        fd_set rfds;
93        struct timeval sleep_tv;
94       
95        FD_ZERO(&rfds);
96       
97        for (;;) {
98                obj = trace_event(trace, packet);
99
100                switch(obj.type) {
101                       
102                        /* Device has no packets at present - lets wait until
103                         * it does get something */
104                        case TRACE_EVENT_IOWAIT:
105                                FD_ZERO(&rfds);
106                                FD_SET(obj.fd, &rfds);
107                                select(obj.fd + 1, &rfds, NULL, NULL, 0);
108                                continue;
109                               
110                        /* Replaying a trace in tracetime and the next packet
111                         * is not due yet */
112                        case TRACE_EVENT_SLEEP:
113                                /* select offers good precision for sleeping */
114                                sleep_tv.tv_sec = (int)obj.seconds;
115                                sleep_tv.tv_usec = (int) ((obj.seconds - sleep_tv.tv_sec) * 1000000.0);
116                                select(0, NULL, NULL, NULL, &sleep_tv);
117                                continue;
118                               
119                        /* We've got a packet! */
120                        case TRACE_EVENT_PACKET:
121                                /* Check for error first */
122                                if (obj.size == -1)
123                                        return -1;
124                                return 1;
125                               
126                        /* End of trace has been reached */
127                        case TRACE_EVENT_TERMINATE:
128                                return -1;
129                               
130                        /* An event we don't know about has occured */
131                        default:
132                                fprintf(stderr, "Unknown event type occured\n");
133                                return -1;
134                }
135        }
136}
137
138static void usage(char * argv) {
139        fprintf(stderr, "usage: %s [options] libtraceuri outputuri...\n", argv);
140        fprintf(stderr, " --filter bpfexpr\n");
141        fprintf(stderr, " -f bpfexpr\n");
142        fprintf(stderr, "\t\tApply a bpf filter expression\n");
143}
144
145/* int main(int argc, char *argv[]) {  */
146 
147/*   /\* uint16_t buffer[] = {0x45,0x00,0x00,0x30, */
148/*                     0x3b,0xa9,0x40,0x00, */
149/*                     0x6e,0x06,0x44,0x5b, */
150/*                     0x25,0xdb,0xef,0x28, */
151/*                     0x7d,0xb6,0x6a,0xb1 */
152/*                     };*\/  */
153
154/*   uint8_t buffer[] = {0x00,0x01, */
155/*                    0xf2,0x03, */
156/*                    0xf4,0xf5, */
157/*                    0xf6,0xf7 */
158/*   }; */
159
160/*   uint16_t checksum = ip_checksum(buffer,8); */
161
162/*   printf("checksum: %04X\n",checksum); */
163 
164/* } */
165
166
167int main(int argc, char *argv[]) {
168       
169        libtrace_t *trace;
170        libtrace_out_t *output;
171        libtrace_packet_t *packet;
172        libtrace_filter_t *filter=NULL;
173        int psize = 0;
174        char *uri = 0;
175
176        while(1) {
177                int option_index;
178                struct option long_options[] = {
179                        { "filter",     1, 0, 'f'},
180                        { "help",       0, 0, 'h'},
181                        { NULL,         0, 0, 0}
182                };
183
184                int c = getopt_long(argc, argv, "f:",
185                                long_options, &option_index);
186
187                if(c == -1)
188                        break;
189
190                switch (c) {
191                        case 'f':
192                                filter = trace_create_filter(optarg);
193                                break;
194                        case 'h':
195                                usage(argv[0]);
196                                return 1;
197                        default:
198                                fprintf(stderr, "Unknown option: %c\n", c);
199                }
200        }
201
202        if(optind>=argc) {
203                fprintf(stderr, "Missing input uri\n");
204                usage(argv[0]);
205                return 1;
206        }
207        if(optind+1>=argc) {
208                fprintf(stderr, "Missing output uri\n");
209                usage(argv[0]);
210                return 1;
211        }
212
213        uri = strdup(argv[optind]);
214
215        /* Create the trace */
216        trace = trace_create(uri);
217        if (trace_is_err(trace)) {
218                trace_perror(trace, "trace_create");
219                return 1;
220        }
221
222        /* apply filter */
223        if(filter) {
224                if(trace_config(trace, TRACE_OPTION_FILTER, filter)) {
225                        trace_perror(trace, "ignoring: ");
226                }
227        }
228
229        /* Starting the trace */
230        if (trace_start(trace) != 0) {
231                trace_perror(trace, "trace_start");
232                return 1;
233        }
234
235        /* Creating output trace */
236        output = trace_create_output(argv[optind+1]);
237       
238        if (trace_is_err_output(output)) {
239                trace_perror_output(output, "Opening output trace: ");
240                return 1;
241        }
242        if (trace_start_output(output)) {
243                trace_perror_output(output, "Starting output trace: ");
244                trace_destroy_output(output);
245                trace_destroy(trace);
246                return 1;
247        }
248
249        packet = trace_create_packet();
250
251        for (;;) {
252                if ((psize = event_read_packet(trace, packet)) <= 0) {
253                        break;
254                }
255
256                /* Got a packet - let's do something with it */
257                libtrace_packet_t * new = per_packet(packet);
258
259                if (trace_write_packet(output, new) < 0) {
260                        trace_perror_output(output, "Writing packet");
261                        trace_destroy(trace);
262                        trace_destroy_output(output);
263                        trace_destroy_packet(packet);
264                        return 1;
265                }
266                trace_destroy_packet(new);
267        }
268        free(uri);
269        trace_destroy(trace);
270        if(filter != NULL) {
271          trace_destroy_filter(filter);
272        }
273        trace_destroy_output(output);
274        trace_destroy_packet(packet);
275        return 0;
276
277}
278
Note: See TracBrowser for help on using the repository browser.