Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!brl-adm!brl-sem!ron From: ron@brl-sem.ARPA (Ron Natalie ) Newsgroups: comp.dcom.lans Subject: Re: Internet Protocol header checksum implementation problem Message-ID: <714@brl-sem.ARPA> Date: Wed, 8-Apr-87 23:36:14 EST Article-I.D.: brl-sem.714 Posted: Wed Apr 8 23:36:14 1987 Date-Received: Mon, 13-Apr-87 03:58:16 EST References: <328@dcl-csvax.comp.lancs.ac.uk> Distribution: world Organization: Electronic Brain Research Lab Lines: 35 In article <328@dcl-csvax.comp.lancs.ac.uk>, david@comp.lancs.ac.uk (David Coffield) writes: > > To calculate the checksum I take each 16-bits within the header > ( starting with the version/IHL octet and ending with the octet immediately > preceding the data portion of the Internet packet). To each of these > I take the 16-bit one's complement and add them all up giving an > unsigned 16-bit value. This is then one's complemented to give me > the header checksum which is placed in the internet header checksum field > (as per the IP spec). You read the spec wrong. The checksum is the ones complement of the ones complement sum of all the values. The ones complement sum is not the twos complement sum of all the numbers ones complemented. When a ones complement number reaches the value 0xFFFF (-0) it must be incremented to 0 (+0) before adding another number to it. In assembler this is easy (if you don't already have ones complement instructions already), if the carry bit it set after an addition, add one to the result. A crude C function would look like this.... (assuming, 16 bit shorts, and > 16 bit longs, I know, silly assumption, but I'm just doing this for illustration) unsigned short header[N]; long tmpsum; int i; short sum; for(i = 0, tmpsum = 0; i < N; i++) { tmpsum += header[i]; if(tmpsum & 0x10000L) tmpsum = (tmpsum & 0xFFFF) + 1; } sum = ~tmpsum; -Ron