sde1000/NanodeUIP — Issue #10: [PATCH] Packet slicer: DHCP with <400-byte uip buffer
Author: maniacbug
Created: 2012-01-08 22:30:28+00:00
State: open

From 5f386f339e69a3ce7e62cd06ae8e412abf3cae67 Mon Sep 17 00:00:00 2001
From: maniacbug
Date: Sun, 8 Jan 2012 14:24:33 -0800
Subject: [PATCH] Packet slicer.

Allows processing of (and ignores checksums on) packets which are smaller than the packet header believes. This is very useful in highly-constrained memory environments. The most likely case of a sliced packet is the network later truncated it because the packet is larger than the UIP buffer.

A good example of where this helps is DHCP. The official minimum size of a DHCP packet is 590, but we don't want to have a UIP buffer of 590, we'd rather have 400. Fortunately, only the bottom 330 bytes have any data, so we can safely ignore the sliced off part. This allows DHCP without wasting RAM on otherwise unneeded UIP buffer space.
---
uip.cpp | 15 ++++++++++++---
1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/uip.cpp b/uip.cpp
index 8e577a9..5618d50 100644
--- a/uip.cpp
+++ b/uip.cpp
@@ -690,6 +690,8 @@ void
uip_process(u8_t flag)
{
register struct uip_conn *uip_connr = uip_conn;
+ /* Whether this packet was sliced (truncated) by the network layer */
+ uint8_t packet_sliced = 0;

#if UIP_UDP
if(flag == UIP_UDP_SEND_CONN) {
@@ -876,7 +878,8 @@ uip_process(u8_t flag)
#endif /* UIP_CONF_IPV6 */
} else {
UIP_LOG("ip: packet shorter than reported in IP header.");
- goto drop;
+ packet_sliced = 1;
+ UIP_LOG("Assuming it was sliced by the network layer.");
}

#if !UIP_CONF_IPV6
@@ -950,7 +953,10 @@ uip_process(u8_t flag)
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.chkerr);
UIP_LOG("ip: bad checksum.");
- goto drop;
+ if (packet_sliced)
+ UIP_LOG("Ignoring because packet was sliced.");
+ else
+ goto drop;
}
#endif /* UIP_CONF_IPV6 */

@@ -1100,7 +1106,10 @@ uip_process(u8_t flag)
UIP_STAT(++uip_stat.udp.drop);
UIP_STAT(++uip_stat.udp.chkerr);
UIP_LOG("udp: bad checksum.");
- goto drop;
+ if (packet_sliced)
+ UIP_LOG("Ignoring because packet was sliced.");
+ else
+ goto drop;
}
#else /* UIP_UDP_CHECKSUMS */
uip_len = uip_len - UIP_IPUDPH_LEN;
--
1.7.5.4