From de8e810792c7fc4d400cbd33a1a88bfb256a94b8 Mon Sep 17 00:00:00 2001 From: sg Date: Wed, 19 Aug 2015 20:55:03 +0200 Subject: [PATCH] fixed bug #45120: Broadcast & multiple interfaces handling --- CHANGELOG | 8 ++++++-- src/core/ipv4/icmp.c | 28 ++++++++++++++++++++++++---- src/core/ipv4/ip4.c | 2 +- src/core/raw.c | 2 +- src/core/tcp_in.c | 2 +- src/core/udp.c | 4 +++- 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 45853b52..a82e825e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -249,11 +249,15 @@ HISTORY ++ Bugfixes: + 2015-08-19: Jens Nielsen + * icmp.c, ip4.c, tcp_in.c, udp.c, raw.c: fixed bug #45120: Broadcast & multiple + interfaces handling + 2015-08-19: Simon Goldschmidt (patch by "Sandra") - dns.c: fixed bug #45004: dns response without answer might be discarded + * dns.c: fixed bug #45004: dns response without answer might be discarded 2015-08-18: Chrysn - timers.c: patch #8704 fix sys_timeouts_sleeptime function + * timers.c: patch #8704 fix sys_timeouts_sleeptime function 2015-07-01: Erik Ekman * puf.c: fixed bug #45454 (pbuf_take_at() skips write and returns OK if offset diff --git a/src/core/ipv4/icmp.c b/src/core/ipv4/icmp.c index 19c9b0fd..5caba0a9 100644 --- a/src/core/ipv4/icmp.c +++ b/src/core/ipv4/icmp.c @@ -116,7 +116,7 @@ icmp_input(struct pbuf *p, struct netif *inp) #endif /* LWIP_MULTICAST_PING */ #if !LWIP_BROADCAST_PING /* broadcast destination address? */ - if (ip_addr_isbroadcast(ip_current_dest_addr(), inp)) { + if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif())) { accepted = 0; } #endif /* LWIP_BROADCAST_PING */ @@ -190,8 +190,28 @@ icmp_input(struct pbuf *p, struct netif *inp) LWIP_ASSERT("Can't move over header in packet", 0); } else { err_t ret; + ip4_addr_t* src; iphdr = (struct ip_hdr*)p->payload; - ip4_addr_copy(iphdr->src, inp->ip_addr); + +#if LWIP_MULTICAST_PING || LWIP_BROADCAST_PING + if (0 +#if LWIP_MULTICAST_PING + || ip_addr_ismulticast(ip_current_dest_addr()) +#endif +#if LWIP_BROADCAST_PING + || ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) +#endif + ) { + /* For multicast and broadcast, use address of receiving interface + * as source address */ + src = &inp->ip_addr; + } + else +#endif + { + src = ip_current_dest_addr(); + } + ip4_addr_copy(iphdr->src, *src); ip4_addr_copy(iphdr->dest, *ip4_current_src_addr()); ICMPH_TYPE_SET(iecho, ICMP_ER); #if CHECKSUM_GEN_ICMP @@ -218,8 +238,8 @@ icmp_input(struct pbuf *p, struct netif *inp) /* increase number of echo replies attempted to send */ snmp_inc_icmpoutechoreps(); - /* send an ICMP packet, src addr is the dest addr of the current packet */ - ret = ip4_output_if(p, ip4_current_dest_addr(), IP_HDRINCL, + /* send an ICMP packet */ + ret = ip4_output_if(p, src, IP_HDRINCL, ICMP_TTL, 0, IP_PROTO_ICMP, inp); if (ret != ERR_OK) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index a1a120b6..b57bd91f 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -660,7 +660,7 @@ ip4_input(struct pbuf *p, struct netif *inp) default: #if LWIP_ICMP /* send ICMP destination protocol unreachable unless is was a broadcast */ - if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp) && + if (!ip_addr_isbroadcast(ip_current_dest_addr(), netif) && !ip_addr_ismulticast(ip_current_dest_addr())) { pbuf_header_force(p, iphdr_hlen); /* Move to ip header, no check necessary. */ p->payload = iphdr; diff --git a/src/core/raw.c b/src/core/raw.c index ee816419..44a00393 100644 --- a/src/core/raw.c +++ b/src/core/raw.c @@ -111,7 +111,7 @@ raw_input(struct pbuf *p, struct netif *inp) ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr()))) { #if IP_SOF_BROADCAST_RECV /* broadcast filter? */ - if ((ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp)) + if ((ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif())) #if LWIP_IPV6 || PCB_ISIPV6(pcb) #endif /* LWIP_IPV6 */ diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 3cbfb084..a2acdbdd 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -136,7 +136,7 @@ tcp_input(struct pbuf *p, struct netif *inp) /* Don't even process incoming broadcasts/multicasts. */ if ( #if LWIP_IPV4 - (!ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp)) || + (!ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif())) || #endif /* LWIP_IPV4 */ ip_addr_ismulticast(ip_current_dest_addr())) { TCP_STATS_INC(tcp.proterr); diff --git a/src/core/udp.c b/src/core/udp.c index 09d20b46..d5d35088 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -161,6 +161,8 @@ udp_input(struct pbuf *p, struct netif *inp) u8_t broadcast; u8_t for_us; + LWIP_UNUSED_ARG(inp); + PERF_START; UDP_STATS_INC(udp.recv); @@ -180,7 +182,7 @@ udp_input(struct pbuf *p, struct netif *inp) udphdr = (struct udp_hdr *)p->payload; /* is broadcast packet ? */ - broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), inp); + broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()); LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));