i'm trying to calculate the checksum of an ip address header(without options), following the algorithm: divide the header in 16 bit words, sum all the words, apply NOT operator on the result to obtain the checksum, but i still got wrong results, sniffing the packets with wireshark i can see that they are wrong, for example, this is my method:
void compute_ip_checksum(struct ip_hdr* ip){
unsigned short* begin = (unsigned short*)ip;
unsigned short* end = begin + (IP_NOPT_HEADER_LENGTH / 2);
unsigned short checksum = 0;
ip->checksum = 0;
for (; begin != end; begin++){
checksum += *begin;
}
ip->checksum = htons(~checksum);
}
the ip header i build is:
ip.version_and_length = (IPV4 << 4) | (IP_NOPT_HEADER_LENGTH/4);
ip.type_of_service = 0;
ip.total_length = htons(IP_NOPT_HEADER_LENGTH + TCP_NOPT_HEADER_LENGTH);
ip.frag_id = 0;
ip.flags_and_frag_offset = htons(DONT_FRAGMENT << 13);
ip.time_to_live = 128;
ip.protocol = TCP_PAYLOAD;
ip.src_ip = inet_addr("1.1.1.1");
ip.dst_ip = inet_addr("1.1.1.2");
Since i'm converting all the values to the network byte order, i'm not doing any conversions in the checksum sum, only after the NOT operation, cause i'm almost sure that my windows is LITTLEENDIAN, and if thats the case the result will be put in this byteorder. the result of my functions is: 0x7a17 and the wireshark result is 0x7917 for this header. Can someone explain what is wrong here? my references are: RFC 791 and How to Calculate IpHeader Checksum