Ignore:
Timestamp:
03/06/13 13:31:48 (9 years ago)
Author:
Shane Alcock <salcock@…>
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:
ec0b927
Parents:
c909fad
Message:
  • Updated tracereplay to use the new libtrace checksumming functions - tracereplay was kinda broken anyway in that it wouldn't do anything with the TCP/UDP checksums because of a broken call to trace_get_payload_from_ip (bad remaining value).
  • As an added benefit, tracereplay show now correctly update the checksums for IPv6 and ICMPv4 packets
File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/tracereplay/tracereplay.c

    r1ca17db r68b7f29  
    2727int broadcast = 0;
    2828
    29 /* This function assumes that the relevant fields have been zeroed out.
    30    RFC 1071 describes the method and provides a code example*/
    31 static uint16_t checksum(void * buffer, uint16_t length) {
    32         uint32_t sum = 0;
    33         uint16_t * buff = (uint16_t *) buffer;
    34         uint16_t count = length;
    35 
    36         while(count > 1 ) {
    37                 sum += *buff++;
    38                 count = count -2;
    39         }
    40 
    41         if(count > 0) {
    42                 sum += *buff;
    43         }
    44 
    45         while (sum>>16)
    46                 sum = (sum & 0xffff) + (sum >> 16);
    47 
    48         return ~sum;
    49 }
    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  */
    56 
    57 static void udp_tcp_checksum(libtrace_ip_t *ip, uint32_t length) {
    58 
    59         uint32_t sum = 0;
    60         uint16_t protocol = ip->ip_p;
    61         uint16_t temp = 0;
    62         uint16_t * check = NULL;
    63         uint16_t tsum = 0;
    64         void * transportheader = NULL;
    65         uint32_t rem;
    66 
    67         sum += (uint16_t) ~checksum(&ip->ip_src.s_addr,sizeof(uint32_t));
    68         sum += (uint16_t) ~checksum(&ip->ip_dst.s_addr,sizeof(uint32_t));
    69 
    70 
    71         /*this will be in host order whereas everything else is in network order*/
    72         temp = htons(protocol);
    73         sum += (uint16_t) ~checksum(&temp,sizeof(uint16_t));
    74 
    75         /*this will be in host order whereas everything else is in network order*/
    76         temp = htons(length);
    77         sum += (uint16_t) ~checksum(&temp,sizeof(uint16_t));
    78 
    79         transportheader = trace_get_payload_from_ip(ip,NULL,&rem);
    80 
    81         if (transportheader == NULL)
     29static void replace_ip_checksum(libtrace_packet_t *packet) {
     30
     31        uint16_t *ip_csm_ptr = NULL;
     32        uint16_t calc_csum;
     33
     34        ip_csm_ptr = trace_checksum_layer3(packet, &calc_csum);
     35
     36        if (ip_csm_ptr == NULL)
    8237                return;
    83 
    84         /* UDP */
    85         if(protocol == 17 ) {
    86                 libtrace_udp_t * udp_header = transportheader;
    87 
    88                 if (rem < sizeof(libtrace_udp_t))
    89                         return;
    90                 check = &udp_header -> check;
    91                 *check = 0;
    92                 tsum = checksum(transportheader, length);
    93         }
    94         /* TCP */
    95         else if(protocol == 6) {
    96                 libtrace_tcp_t * tcp_header = transportheader;
    97 
    98                 if (rem < sizeof(libtrace_tcp_t))
    99                         return;
    100                 tcp_header -> check = 0;
    101                 check = &tcp_header -> check;
    102                 *check = 0;
    103                 tsum = checksum(transportheader,length);
    104         }
    105 
    106         sum += (uint16_t) ~tsum;
    107 
    108         while (sum>>16)
    109                 sum = (sum & 0xffff) + (sum >> 16);
    110 
    111         if(check != NULL) {
    112                 *check = (uint16_t)~sum;
    113         }
    114 
    115 
     38        *ip_csm_ptr = htons(calc_csum);
     39
     40}
     41
     42static void replace_transport_checksum(libtrace_packet_t *packet) {
     43
     44        uint16_t *csm_ptr = NULL;
     45        uint16_t calc_csum;
     46       
     47        csm_ptr = trace_checksum_transport(packet, &calc_csum);
     48
     49        if (csm_ptr == NULL)
     50                return;
     51        *csm_ptr = htons(calc_csum);
    11652
    11753}
     
    16197        }
    16298
    163 
    164 
    165         header = trace_get_ip(new_packet);
    166         if(header != NULL) {
    167                 /* update ip checksum */
    168                 wire_length -= sizeof(uint32_t)*header->ip_hl;
    169                 header -> ip_sum = 0;
    170                 sum = checksum(header,header->ip_hl*sizeof(uint32_t));
    171                 header -> ip_sum = sum;
    172                 /* update transport layer checksums */
    173                 udp_tcp_checksum(header,ntohs(header->ip_len)-sizeof(uint32_t)*header->ip_hl);
    174         }
     99        replace_ip_checksum(new_packet);
     100        replace_transport_checksum(new_packet);
    175101
    176102        return new_packet;
Note: See TracChangeset for help on using the changeset viewer.