mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-25 00:14:02 +00:00
Unaligned 16-bit access fix for the standard checksum routine by Peter Jolasson.
This commit is contained in:
parent
e11d57c883
commit
f05d392920
@ -51,7 +51,8 @@
|
|||||||
/* This is a reference implementation of the checksum algorithm
|
/* This is a reference implementation of the checksum algorithm
|
||||||
|
|
||||||
- it may not work on all architectures, and all processors, particularly
|
- it may not work on all architectures, and all processors, particularly
|
||||||
if they have issues with alignment and 16 bit access.
|
if they have issues with alignment and 16 bit access (although this should
|
||||||
|
be fixed since inet.c 1.22).
|
||||||
|
|
||||||
- in this case you will need to port it to your architecture and
|
- in this case you will need to port it to your architecture and
|
||||||
#define LWIP_CHKSUM <your_checksum_routine>
|
#define LWIP_CHKSUM <your_checksum_routine>
|
||||||
@ -63,15 +64,22 @@ static u16_t
|
|||||||
lwip_standard_chksum(void *dataptr, int len)
|
lwip_standard_chksum(void *dataptr, int len)
|
||||||
{
|
{
|
||||||
u32_t acc;
|
u32_t acc;
|
||||||
|
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", (void *)dataptr, len));
|
LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", (void *)dataptr, len));
|
||||||
|
|
||||||
|
/* iterate by two bytes at once */
|
||||||
for(acc = 0; len > 1; len -= 2) {
|
for(acc = 0; len > 1; len -= 2) {
|
||||||
/* acc = acc + *((u16_t *)dataptr)++;*/
|
/* WAS: acc = acc + *((u16_t *)dataptr)++; BUT THIS IS BROKEN FOR
|
||||||
|
* ARCHITECTURES WHICH DO NOT ALLOW UNALIGNED 16-BIT ACCESSES */
|
||||||
|
#if MEM_ALIGNMENT >= 2
|
||||||
|
acc += htons( ((u16_t)(((u8_t *)dataptr)[0])<<8) | ((u8_t *)dataptr)[1] );
|
||||||
|
dataptr += 2;
|
||||||
|
#else
|
||||||
acc += *(u16_t *)dataptr;
|
acc += *(u16_t *)dataptr;
|
||||||
dataptr = (void *)((u16_t *)dataptr + 1);
|
dataptr = (void *)((u16_t *)dataptr + 1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add up any odd byte */
|
/* add up any last odd byte */
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
|
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", (unsigned int)(*(u8_t *)dataptr)));
|
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", (unsigned int)(*(u8_t *)dataptr)));
|
||||||
@ -79,13 +87,12 @@ lwip_standard_chksum(void *dataptr, int len)
|
|||||||
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
|
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
|
||||||
}
|
}
|
||||||
acc = (acc >> 16) + (acc & 0xffffUL);
|
acc = (acc >> 16) + (acc & 0xffffUL);
|
||||||
|
|
||||||
if ((acc & 0xffff0000) != 0) {
|
if ((acc & 0xffff0000) != 0) {
|
||||||
acc = (acc >> 16) + (acc & 0xffffUL);
|
acc = (acc >> 16) + (acc & 0xffffUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (u16_t)acc;
|
return (u16_t)acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* inet_chksum_pseudo:
|
/* inet_chksum_pseudo:
|
||||||
|
Loading…
Reference in New Issue
Block a user