[U-Boot] [PATCH]Fix checksum to handle odd-length packet
Greg Ren
gren at ubicom.com
Wed Dec 2 23:23:45 CET 2009
Hi all:
I am new to u-boot and got assignment to debug some networking issue. I
traced the checksum failure and was able to fix it with the patch below.
This change fixes:
1. The checksum generation failure for odd-length packet.
2. Do not ignore the LSB of checksum value - (Again, I am new to this.
Maybe someone can educate me about the idea of ignoring one bit of
checksum)
The patch is a git commit log from my local git reposite.
Thanks for your time and advice.
% git show cffd5fb03e0c3f116cce9f3ff825c5445a1eca3f
commit cffd5fb03e0c3f116cce9f3ff825c5445a1eca3f
Author: gren <gren at ubicom.com>
Date: Wed Dec 2 13:07:53 2009 -0800
Fix issue with checksum failure of odd-length packets
diff --git a/net/net.c b/net/net.c
old mode 100644
new mode 100755
index 5637cf5..5bbee04
--- a/net/net.c
+++ b/net/net.c
@@ -703,14 +703,14 @@ int PingSend(void)
ip->ip_sum = 0;
NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network
byte order */
NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */
- ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);
+ ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP);
s = &ip->udp_src; /* XXX ICMP starts here */
s[0] = htons(0x0800); /* echo-request, code */
s[1] = 0; /* checksum */
s[2] = 0; /* identifier */
s[3] = htons(PingSeqNo++); /* sequence number */
- s[1] = ~NetCksum((uchar *)s, 8/2);
+ s[1] = ~NetCksum((uchar *)s, 8);
/* size of the waiting packet */
NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) +
IP_HDR_SIZE_NO_UDP + 8;
@@ -1363,7 +1363,7 @@ NetReceive(volatile uchar * inpkt, int len)
if ((ip->ip_hl_v & 0x0f) > 0x05) {
return;
}
- if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) {
+ if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP)) {
puts ("checksum bad\n");
return;
}
@@ -1420,12 +1420,12 @@ NetReceive(volatile uchar * inpkt, int len)
ip->ip_off = 0;
NetCopyIP((void*)&ip->ip_dst,
&ip->ip_src);
NetCopyIP((void*)&ip->ip_src,
&NetOurIP);
- ip->ip_sum = ~NetCksum((uchar *)ip,
IP_HDR_SIZE_NO_UDP >> 1);
+ ip->ip_sum = ~NetCksum((uchar *)ip,
IP_HDR_SIZE_NO_UDP);
icmph->type = ICMP_ECHO_REPLY;
icmph->checksum = 0;
icmph->checksum = ~NetCksum((uchar
*)icmph,
- (len -
IP_HDR_SIZE_NO_UDP) >> 1);
+ (len -
IP_HDR_SIZE_NO_UDP));
(void) eth_send((uchar *)et,
ETHER_HDR_SIZE + len);
return;
#endif
@@ -1577,7 +1577,7 @@ static int net_check_prereq (proto_t protocol)
int
NetCksumOk(uchar * ptr, int len)
{
- return !((NetCksum(ptr, len) + 1) & 0xfffe);
+ return (NetCksum(ptr, len) == 0xffff);
}
@@ -1588,8 +1588,13 @@ NetCksum(uchar * ptr, int len)
ushort *p = (ushort *)ptr;
xsum = 0;
- while (len-- > 0)
+ while (len > 1) {
xsum += *p++;
+ len -= 2;
+ }
+ if (len == 1) {
+ xsum += (*p & 0xff00);
+ }
xsum = (xsum & 0xffff) + (xsum >> 16);
xsum = (xsum & 0xffff) + (xsum >> 16);
return (xsum & 0xffff);
@@ -1663,7 +1668,7 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int
dport, int sport, int len)
ip->udp_dst = htons(dport);
ip->udp_len = htons(8 + len);
ip->udp_xsum = 0;
- ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);
+ ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP);
}
void copy_filename (char *dst, char *src, int size)
Regards
Greg Ren
SW Engineer
Phone: (408)649-2703
195 Baypointe Pkwy. San Jose CA 95134
More information about the U-Boot
mailing list