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