From d95bcab05328b3cbd03704b9f9c730dea71f61a3 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Thu, 22 Mar 2012 19:35:04 +0100 Subject: [PATCH] fixed bug #35927: missing refragmentaion in ip_forward --- CHANGELOG | 3 +++ src/core/ipv4/ip4.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 7265d967..34bbd40c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -76,6 +76,9 @@ HISTORY ++ Bugfixes: + 2012-03-22: Simon Goldschmidt + * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward + 2012-03-20: Simon Goldschmidt (patch by Mason) * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index eb2e9fac..e6be1203 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -211,6 +211,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); + /* @todo: send ICMP_DUR_NET? */ goto return_noroute; } #if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF @@ -252,6 +253,20 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) snmp_inc_ipforwdatagrams(); PERF_STOP("ip_forward"); + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { +#if IP_FRAG + if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { + ip_frag(p, netif, ip_current_dest_addr()); + } else { + /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */ + icmp_dest_unreach(p, ICMP_DUR_FRAG); + } + return; +#else /* IP_FRAG */ + /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */ +#endif /* IP_FRAG */ + } /* transmit pbuf on chosen interface */ netif->output(netif, p, ip_current_dest_addr()); return;