Re: IP cheksum and libnet_pblock_coalesce

Frédéric Raynal <[email protected]> Wed, 29 Sep 2004 17:17:17 +0200
Newsgroups gmane.comp.security.libnet
Message-ID <[email protected]>
On Tue, Sep 28, 2004 at 11:28:27AM +0800, Wu Yongwei wrote:
> 
> 
> >Hi,
> >
> >That is a known (but tricky) bug reported some times ago. David
> >Baroso proposed something like :
> >
> >sum += ((*(u_int8_t *)addr & 0xFF)<<8);
> >
> >The difficulty is to find something working on both big and little 
> >endian systems.
> 
> The expression above seems to work only on big-endian machines and 
> proves wrong in my test on x86 (contrary to Mr David Barroso's 
> statement). The third edition of UNIX Network Programming has something 
> like this (adapted):
> 
> u_int16_t last_byte = 0;
> ...
> if (nleft == 1) {
>     *(u_int8_t*)&last_byte = *(u_int8_t*)addr;
>     sum += last_byte;
> }
> 
> I feel this is good.
> 

Hi,

I like it ... but I feel there is a problem. Thus, I coded this small
example:

main()
{
	char i[] = "\x01\x02\x03";
	unsigned short last = 0, sum = 0x4455, *s = (unsigned
			short*)i;


	*(unsigned char*)&last = *(unsigned char*)s;    

	printf("last=0x%04x\n", last);
	sum += last;
	printf("sum=0x%04x\n", sum);

	sum = 0x4455;
	sum += (*(unsigned char*)s & 0xff)<<8;
	printf("sum=0x%04x\n", sum);
}


And here are the results:


On Mac OS X (big endian) :
last=0x0100
sum=0x4555
sum=0x4555

On x86 (little endian):
last=0x0001
sum=0x4456
sum=0x4555

And checksm must be big endian (network ordered) ...

I am not in position to perform tests here, so if some people could do
it, that will be very helpful.

	Fred Raynal