mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-24 15:14:06 +00:00
Fixed lwip_standard_chksum() for unaligned memory access. Verified to work on c16x and BSD on P4.
This commit is contained in:
parent
33fbb06604
commit
43d448e73f
@ -60,37 +60,50 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef LWIP_CHKSUM
|
#ifndef LWIP_CHKSUM
|
||||||
#define LWIP_CHKSUM lwip_standard_chksum
|
#define LWIP_CHKSUM lwip_standard_chksum
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lwip checksum
|
||||||
|
*
|
||||||
|
* @param dataptr points to start of data to be summed at any boundary
|
||||||
|
* @param len length of data to be summed
|
||||||
|
* @return network order (!) lwip checksum (non-inverted Internet sum)
|
||||||
|
*
|
||||||
|
* @note accumulator size limits summable lenght to 64k
|
||||||
|
* @note host endianess is irrelevant (p3 RFC1071)
|
||||||
|
*/
|
||||||
static u16_t
|
static u16_t
|
||||||
lwip_standard_chksum(void *dataptr, int len)
|
lwip_standard_chksum(void *dataptr, u16_t len)
|
||||||
{
|
{
|
||||||
u32_t acc;
|
u32_t acc;
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %"S16_F")\n", (void *)dataptr, len));
|
u16_t src;
|
||||||
|
u8_t *octetptr;
|
||||||
|
|
||||||
/* iterate by two bytes at once */
|
acc = 0;
|
||||||
for(acc = 0; len > 1; len -= 2) {
|
/* dataptr may be at odd or even addresses */
|
||||||
/* WAS: acc = acc + *((u16_t *)dataptr)++; BUT THIS IS BROKEN FOR
|
octetptr = (u8_t*)dataptr;
|
||||||
* ARCHITECTURES WHICH DO NOT ALLOW UNALIGNED 16-BIT ACCESSES */
|
while (len > 1)
|
||||||
#if MEM_ALIGNMENT >= 2
|
{
|
||||||
acc += htons( ((u16_t)(((u8_t *)dataptr)[0])<<8) | ((u8_t *)dataptr)[1] );
|
/* first octet is most significant */
|
||||||
(void *)((u16_t *)dataptr + 1);
|
src = (*octetptr) << 8;
|
||||||
#else
|
octetptr++;
|
||||||
acc += *(u16_t *)dataptr;
|
/* second octet is least significant */
|
||||||
dataptr = (void *)((u16_t *)dataptr + 1);
|
src |= (*octetptr);
|
||||||
#endif
|
octetptr++;
|
||||||
|
acc += src;
|
||||||
|
len -= 2;
|
||||||
}
|
}
|
||||||
|
if (len > 0)
|
||||||
/* add up any last odd byte */
|
{
|
||||||
if (len == 1) {
|
/* accumulate remaining octet */
|
||||||
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
|
acc += (*octetptr);
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %"U16_F"\n", (u16_t)(*(u8_t *)dataptr)));
|
|
||||||
} else {
|
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
|
|
||||||
}
|
}
|
||||||
acc = (acc >> 16) + (acc & 0xffffUL);
|
/* add deferred carry bits */
|
||||||
|
acc = (acc >> 16) + (acc & 0x0000ffffUL);
|
||||||
if ((acc & 0xffff0000) != 0) {
|
if ((acc & 0xffff0000) != 0) {
|
||||||
acc = (acc >> 16) + (acc & 0xffffUL);
|
acc = (acc >> 16) + (acc & 0x0000ffffUL);
|
||||||
}
|
}
|
||||||
return (u16_t)acc;
|
/* caller must invert bits for Internet sum ! */
|
||||||
|
return htons((u16_t)acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user