diff --git a/CHANGELOG b/CHANGELOG index 612a18aa..01d2f5e9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -62,6 +62,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/ip.c b/src/core/ipv4/ip.c index c79a4e98..95d2db40 100644 --- a/src/core/ipv4/ip.c +++ b/src/core/ipv4/ip.c @@ -223,6 +223,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(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + /* @todo: send ICMP_DUR_NET? */ goto return_noroute; } #if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF @@ -264,6 +265,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 ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { +#if IP_FRAG + ip_frag(p, netif, ip_current_dest_addr()); +#else /* IP_FRAG */ + /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */ +#endif /* IP_FRAG */ + } else { + /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */ + icmp_dest_unreach(p, ICMP_DUR_FRAG); + } + return; + } /* transmit pbuf on chosen interface */ netif->output(netif, p, ¤t_iphdr_dest); return;