From 40e162e58dff93bb941340d832bca8e6ce368600 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 20 Dec 2018 11:25:26 -0800 Subject: Fix UDP checksum verification error. From RFC 768, if UDP packet checksum computation yields a result of zero, change it to hex 0xFFFF. The current udhcpc checksum verification would yield false positive for this case. A better way is to compute the checksum with the original checksum field and the result should be zero for good udp packet. Signed-off-by: Yangchun Fu --- toys/pending/dhcp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/toys/pending/dhcp.c b/toys/pending/dhcp.c index b99bb4c0..25f9b913 100644 --- a/toys/pending/dhcp.c +++ b/toys/pending/dhcp.c @@ -650,7 +650,6 @@ static int mode_app(void) static int read_raw(void) { dhcp_raw_t packet; - uint16_t check; int bytes = 0; memset(&packet, 0, sizeof(packet)); @@ -676,18 +675,19 @@ static int read_raw(void) dbg("\tUnrelated/bogus packet, ignoring\n"); return -2; } - // verify IP checksum - check = packet.iph.check; - packet.iph.check = 0; - if (check != dhcp_checksum(&packet.iph, sizeof(packet.iph))) { + // Verify IP checksum. + if (dhcp_checksum(&packet.iph, sizeof(packet.iph)) != 0) { dbg("\tBad IP header checksum, ignoring\n"); return -2; } + // Verify UDP checksum. From RFC 768, the UDP checksum is done over the IPv4 + // pseudo header, the UDP header and the UDP data. The IPv4 pseudo header + // includes saddr, daddr, protocol, and UDP length. The IP header has to be + // modified for this. memset(&packet.iph, 0, ((size_t) &((struct iphdr *)0)->protocol)); + packet.iph.check = 0; packet.iph.tot_len = packet.udph.len; - check = packet.udph.check; - packet.udph.check = 0; - if (check && check != dhcp_checksum(&packet, bytes)) { + if (packet.udph.check != 0 && dhcp_checksum(&packet, bytes) != 0) { dbg("\tPacket with bad UDP checksum received, ignoring\n"); return -2; } -- cgit v1.2.3