Changeset 6d9bd23 for tools/tracereplay


Ignore:
Timestamp:
11/26/09 17:11:40 (11 years ago)
Author:
Andreas Löf <andreas.lof@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
0f2e206
Parents:
58e2f74
Message:

added options for setting the destination ethernet address to broadcast.
added option to set snaplength

tidied up code and added some comments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/tracereplay/tracereplay.c

    r58e2f74 r6d9bd23  
    1111
    1212 */
    13 
    14 
    1513
    1614
     
    2725#define FCS_SIZE 4
    2826
    29 
    30 
    31 
    32 /* This function assumes that the relevant fields have been zeroed out. RFC 1071*/
     27int broadcast;
     28
     29/* This function assumes that the relevant fields have been zeroed out.
     30   RFC 1071 describes the method and provides a code example*/
    3331static uint16_t checksum(void * buffer, uint16_t length) {
    3432  uint32_t sum = 0;
     
    5048  return ~sum;
    5149}
     50
     51/*
     52  This function calculates and fills in the correct checksum on
     53  a transport protocol header.
     54  Currently only UDP and TCP are supported.
     55*/
    5256
    5357static void udp_tcp_checksum(libtrace_ip_t *ip, uint32_t length) {
     
    5862  uint16_t * check = NULL;
    5963  uint16_t tsum = 0;
    60 
     64  void * transportheader = NULL;
    6165
    6266  sum += (uint16_t) ~checksum(&ip->ip_src.s_addr,sizeof(uint32_t));
     
    7276  sum += (uint16_t) ~checksum(&temp,sizeof(uint16_t));
    7377
    74   void * transportheader = trace_get_payload_from_ip(ip,NULL,NULL);
    75 
     78  transportheader = trace_get_payload_from_ip(ip,NULL,NULL);
     79
     80  /* UDP */
    7681  if(protocol == 17 ) {
    7782    libtrace_udp_t * udp_header = transportheader;
     
    8085    tsum = checksum(transportheader, length);
    8186  }
     87  /* TCP */
    8288  else if(protocol == 6) {
    8389    libtrace_tcp_t * tcp_header = transportheader;
     
    101107}
    102108
    103 
     109/*
     110  Create a copy of the packet that can be written to the output URI.
     111  if the packet is IPv4 the checksum will be recalculated to account for
     112  cryptopan. Same for TCP and UDP. No other protocols are supported at the
     113  moment.
     114 */
    104115static libtrace_packet_t * per_packet(libtrace_packet_t *packet) {
    105116  uint32_t remaining = 0; 
    106117  libtrace_linktype_t linktype = 0;
    107   void * pkt_buffer = trace_get_packet_buffer(packet,&linktype,&remaining);
    108   remaining = 0;
    109118  libtrace_ip_t * header = NULL;
    110119  uint16_t sum = 0;
    111   libtrace_packet_t *new_packet = trace_create_packet();
    112  
    113   size_t wire_length = trace_get_wire_length(packet);
    114 
     120  libtrace_packet_t *new_packet;
     121  size_t wire_length;
     122  void * pkt_buffer;
     123  void * l2_header;
     124  libtrace_ether_t * ether_header;
     125  int i;
     126
     127  pkt_buffer = trace_get_packet_buffer(packet,&linktype,&remaining);
     128  remaining = 0;
     129  new_packet = trace_create_packet();
     130 
     131  wire_length = trace_get_wire_length(packet);
     132
     133  /* if it's ehternet we don't want to add space for the FCS that will
     134     be appended. */
    115135  if(linktype == TRACE_TYPE_ETH || linktype == TRACE_TYPE_80211) {
    116136    wire_length -= FCS_SIZE;
     
    118138
    119139  trace_construct_packet(new_packet,linktype,pkt_buffer,wire_length);
    120  
    121 
     140
     141
     142  if(broadcast) {
     143    l2_header = trace_get_layer2(new_packet,&linktype,&remaining);
     144    if(linktype == TRACE_TYPE_ETH){
     145      ether_header = (libtrace_ether_t *) l2_header;
     146      for(i = 0; i < 6; i++) {
     147        ether_header -> ether_dhost[i] = 0xFF;
     148      }
     149    }
     150   
     151  }
     152
     153 
     154 
    122155  header = trace_get_ip(new_packet);
    123156  if(header != NULL) {
     157    /* update ip checksum */
    124158    wire_length -= sizeof(uint32_t)*header->ip_hl;
    125159    header -> ip_sum = 0;
    126160    sum = checksum(header,header->ip_hl*sizeof(uint32_t));
    127161    header -> ip_sum = sum;
     162    /* update transport layer checksums */
    128163    udp_tcp_checksum(header,ntohs(header->ip_len)-sizeof(uint32_t)*header->ip_hl);
    129164  }
     
    185220
    186221static void usage(char * argv) {
    187         fprintf(stderr, "usage: %s [options] libtraceuri outputuri...\n", argv);
     222        fprintf(stderr, "usage: %s [options] inputuri outputuri...\n", argv);
    188223        fprintf(stderr, " --filter bpfexpr\n");
    189224        fprintf(stderr, " -f bpfexpr\n");
    190225        fprintf(stderr, "\t\tApply a bpf filter expression\n");
     226        fprintf(stderr, " -s snaplength\n");
     227        fprintf(stderr, " --snaplength snaplength\n");
     228        fprintf(stderr, "\t\tTruncate the packets read from inputuri to <snaplength>\n");
     229        fprintf(stderr, " -b\n");
     230        fprintf(stderr, " --broadcast\n");
     231        fprintf(stderr, "\t\tSend ethernet frames to broadcast address\n");
     232
    191233}
    192234
     
    199241        int psize = 0;
    200242        char *uri = 0;
     243        libtrace_packet_t * new;
     244        int snaplen = 0;
     245       
    201246
    202247        while(1) {
     
    205250                        { "filter",     1, 0, 'f'},
    206251                        { "help",       0, 0, 'h'},
     252                        { "snaplen",    1, 0, 's'},
     253                        { "broadcast",  0, 0, 'b'},
    207254                        { NULL,         0, 0, 0}
    208255                };
    209256
    210                 int c = getopt_long(argc, argv, "f:",
     257                int c = getopt_long(argc, argv, "bhs:f:",
    211258                                long_options, &option_index);
    212259
     
    215262
    216263                switch (c) {
    217                         case 'f':
    218                                 filter = trace_create_filter(optarg);
    219                                 break;
    220                         case 'h':
    221                                 usage(argv[0]);
    222                                 return 1;
    223                         default:
    224                                 fprintf(stderr, "Unknown option: %c\n", c);
     264                case 'f':
     265                  filter = trace_create_filter(optarg);
     266                  break;
     267                case 's':
     268                  snaplen = atoi(optarg);
     269                  break;
     270
     271                case 'b':
     272                  broadcast = 1;
     273                  break;
     274                 
     275                case 'h':
     276                 
     277                  usage(argv[0]);
     278                  return 1;
     279                default:
     280                  fprintf(stderr, "Unknown option: %c\n", c);
    225281                }
    226282        }
     
    246302        }
    247303
     304        /*apply snaplength */
     305        if(snaplen) {
     306          if(trace_config(trace,TRACE_OPTION_SNAPLEN,&snaplen)) {
     307            trace_perror(trace,"error setting snaplength, proceeding anyway");
     308          }
     309        }
     310
    248311        /* apply filter */
    249312        if(filter) {
     
    281344
    282345                /* Got a packet - let's do something with it */
    283                 libtrace_packet_t * new = per_packet(packet);
     346                new = per_packet(packet);
    284347
    285348                if (trace_write_packet(output, new) < 0) {
Note: See TracChangeset for help on using the changeset viewer.