Ignore:
Timestamp:
03/06/13 13:28:51 (8 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:
68b7f29
Parents:
af27241
Message:
  • Added checksumming functions for both the IP and transport layer. The functions will calculate the correct checksum for that packet and also return a pointer to the checksum field in the appropriate header so that the caller can either evaluate whether the checksum is correct, replace the existing checksum, or do whatever they want.
  • Also managed to fix a bunch of broken Revision svn tags
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/protocols_transport.c

    r05f2718 rc909fad  
    3535#include "libtrace.h"
    3636#include "protocols.h"
     37#include "checksum.h"
    3738#include <assert.h>
    3839#include <stdlib.h>
    3940#include <stdio.h> // fprintf
     41#include <string.h>
    4042
    4143/* This file contains all the protocol decoding functions for transport layer
     
    419421}
    420422
    421 
     423DLLEXPORT uint16_t *trace_checksum_transport(libtrace_packet_t *packet,
     424                uint16_t *csum) {
     425
     426        void *header = NULL;
     427        uint16_t ethertype;
     428        uint32_t remaining;
     429        uint32_t sum = 0;
     430        uint8_t proto = 0;
     431        uint16_t *csum_ptr = NULL;
     432        int plen = 0;
     433
     434        uint8_t safety[65536];
     435        uint8_t *ptr = safety;
     436
     437        header = trace_get_layer3(packet, &ethertype, &remaining);
     438
     439        if (header == NULL)
     440                return NULL;
     441       
     442        if (ethertype == TRACE_ETHERTYPE_IP) {
     443                libtrace_ip_t *ip = (libtrace_ip_t *)header;
     444
     445                if (remaining < sizeof(libtrace_ip_t))
     446                        return NULL;
     447
     448                sum = ipv4_pseudo_checksum(ip);
     449
     450        } else if (ethertype == TRACE_ETHERTYPE_IPV6) {
     451                libtrace_ip6_t *ip = (libtrace_ip6_t *)header;
     452               
     453                if (remaining < sizeof(libtrace_ip6_t))
     454                        return 0;
     455
     456                sum = ipv6_pseudo_checksum(ip);
     457       
     458        }
     459
     460        header = trace_get_transport(packet, &proto, &remaining);
     461
     462        if (proto == TRACE_IPPROTO_TCP) {
     463                libtrace_tcp_t *tcp = (libtrace_tcp_t *)header;
     464                header = trace_get_payload_from_tcp(tcp, &remaining);
     465               
     466                csum_ptr = &tcp->check;
     467
     468                memcpy(ptr, tcp, tcp->doff * 4);
     469
     470                tcp = (libtrace_tcp_t *)ptr;
     471                tcp->check = 0;
     472
     473                ptr += (tcp->doff * 4);
     474        }
     475       
     476        else if (proto == TRACE_IPPROTO_UDP) {
     477
     478                libtrace_udp_t *udp = (libtrace_udp_t *)header;
     479                header = trace_get_payload_from_udp(udp, &remaining);
     480               
     481                csum_ptr = &udp->check;
     482                memcpy(ptr, udp, sizeof(libtrace_udp_t));
     483
     484                udp = (libtrace_udp_t *)ptr;
     485                udp->check = 0;
     486
     487                ptr += sizeof(libtrace_udp_t);
     488        }
     489       
     490        else if (proto == TRACE_IPPROTO_ICMP) {
     491                /* ICMP doesn't use the pseudo header */
     492                sum = 0;
     493
     494                libtrace_icmp_t *icmp = (libtrace_icmp_t *)header;
     495                header = trace_get_payload_from_icmp(icmp, &remaining);
     496               
     497                csum_ptr = &icmp->checksum;
     498                memcpy(ptr, icmp, sizeof(libtrace_icmp_t));
     499
     500                icmp = (libtrace_icmp_t *)ptr;
     501                icmp->checksum = 0;
     502               
     503                ptr += sizeof(libtrace_icmp_t);
     504
     505        }
     506        else {
     507                return NULL;
     508        }
     509
     510        sum += add_checksum(safety, (uint16_t)(ptr - safety));
     511
     512        plen = trace_get_payload_length(packet);
     513        if (plen < 0)
     514                return NULL;
     515
     516        if (remaining < (uint32_t)plen)
     517                return NULL;
     518
     519        if (header == NULL)
     520                return NULL;
     521
     522        sum += add_checksum(header, (uint16_t)plen);
     523        *csum = ntohs(finish_checksum(sum));
     524        //assert(0);
     525       
     526        return csum_ptr;
     527}
Note: See TracChangeset for help on using the changeset viewer.