IP header checksum calculation

/* IP Header in Little Endian /
#pragma pack(1)
typedef struct iphdr 
{
    u_char    ip_hl:4,        / header length /
            ip_v:4;            / version /
    u_char    ip_tos;            / type of service /
    short    ip_len;            / total length /
    u_short    ip_id;            / identification /
    short    ip_off;            / fragment offset field /
#define    IP_DF 0x4000        / dont fragment flag /
#define    IP_MF 0x2000        / more fragments flag /
    u_char    ip_ttl;            / time to live /
    u_char    ip_p;            / protocol /
    u_short    ip_sum;            / checksum /
    struct    in_addr ip_src,ip_dst;    / source and dest address */
} iphdr, *iphdr_ptr;
#pragma pack()

uint16 CalcIPChecksum(iphdr header)
{
    // clear existent IP header
    header->ip_sum = 0x0;

    // calc the checksum
    unsigned int nbytes = sizeof(iphdr);
    unsigned short *buf = reinterpret_cast( header );
    unsigned int sum = 0;
    for (; nbytes > 1; nbytes -= 2)
    {
        sum += *buf++;
    }
    if (nbytes == 1)
    {
        sum += *(unsigned char*) buf;
    }
    sum  = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);

    return ~sum;
}

Read more at faqs.com, RFC791 - Internet Protocol

Posted at BinaryCell

Comments

Popular Posts