02 September 2010

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

No comments:

Post a Comment


Disclaimer: In no event shall the blog owner, be liable for any damages, including without limitation, special, indirect or consequential damages, or any damages, whatsoever resulting from access or use, or inability to access or use this Website or arising out of any materials, information, qualifications or recommendations on this Website.