From c6605766e75dbe4d3c46a0f43a6bb86064e253c7 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Thu, 1 Mar 2012 19:10:52 +0100 Subject: [PATCH 1/9] Fixed unused variable warnings produced with the last commit --- src/api/api_lib.c | 7 +++---- src/include/lwip/tcpip.h | 6 +++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/api/api_lib.c b/src/api/api_lib.c index b2670d02..244c4ecb 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -329,7 +329,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn) /* Let the stack know that we have accepted the connection. */ msg.msg.conn = conn; /* don't care for the return value of do_recv */ - TCPIP_APIMSG(&msg, do_recv, err); + TCPIP_APIMSG_NOERR(&msg, do_recv); #endif /* TCP_LISTEN_BACKLOG */ *new_conn = newconn; @@ -400,7 +400,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf) msg.msg.msg.r.len = 1; } /* don't care for the return value of do_recv */ - TCPIP_APIMSG(&msg, do_recv, err); + TCPIP_APIMSG_NOERR(&msg, do_recv); } /* If we are closed, we indicate that we no longer wish to use the socket */ @@ -532,14 +532,13 @@ netconn_recved(struct netconn *conn, u32_t length) if ((conn != NULL) && (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (netconn_get_noautorecved(conn))) { struct api_msg msg; - err_t err; /* Let the stack know that we have taken the data. */ /* TODO: Speedup: Don't block and wait for the answer here (to prevent multiple thread-switches). */ msg.msg.conn = conn; msg.msg.msg.r.len = length; /* don't care for the return value of do_recv */ - TCPIP_APIMSG(&msg, do_recv, err); + TCPIP_APIMSG_NOERR(&msg, do_recv); } #else /* LWIP_TCP */ LWIP_UNUSED_ARG(conn); diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index d0509f56..04567f2c 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -64,11 +64,14 @@ extern sys_mutex_t lock_tcpip_core; #else #define TCIP_APIMSG_SET_ERR(m, e) #endif -#define TCPIP_APIMSG(m,f,e) do { \ +#define TCPIP_APIMSG_NOERR(m,f) do { \ TCIP_APIMSG_SET_ERR(m, ERR_VAL); \ LOCK_TCPIP_CORE(); \ f(&((m)->msg)); \ UNLOCK_TCPIP_CORE(); \ +} while(0) +#define TCPIP_APIMSG(m,f,e) do { \ + TCPIP_APIMSG_NOERR(m,f); \ (e) = (m)->msg.err; \ } while(0) #define TCPIP_APIMSG_ACK(m) @@ -77,6 +80,7 @@ extern sys_mutex_t lock_tcpip_core; #else /* LWIP_TCPIP_CORE_LOCKING */ #define LOCK_TCPIP_CORE() #define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG_NOERR(m,f) do { (m)->function = f; tcpip_apimsg(m); } while(0) #define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0) #define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed) #define TCPIP_NETIFAPI(m) tcpip_netifapi(m) From 193ccaa3b4ac52243ad6f83ba6a5e492c2c4c777 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Thu, 1 Mar 2012 19:21:17 +0100 Subject: [PATCH 2/9] IGMP stats: added missing tab (by Gisle Vanem) --- src/core/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/stats.c b/src/core/stats.c index 5bdd5a23..06fbe0f2 100644 --- a/src/core/stats.c +++ b/src/core/stats.c @@ -99,8 +99,8 @@ stats_display_igmp(struct stats_igmp *igmp, const char *name) LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); - LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n", igmp->rx_group)); - LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n", igmp->rx_general)); + LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group)); + LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general)); LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); From bcabe63971360206c1ce9adeebdad94ac8e3091d Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 2 Mar 2012 08:53:51 -0700 Subject: [PATCH 3/9] Set ip_data.current_netif earlier to allow ICMPv6 packets in ip6_fwd. Then set to "accepted" netif, not inp. --- src/core/ipv6/ip6.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index 55b02c47..a051c0b3 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -395,6 +395,9 @@ ip6_input(struct pbuf *p, struct netif *inp) /* current header pointer. */ ip_data.current_ip6_header = ip6hdr; + /* In netif, used in case we need to send ICMPv6 packets back. */ + ip_data.current_netif = inp; + /* match packet against an interface, i.e. is this packet for us? */ if (ip6_addr_ismulticast(ip6_current_dest_addr())) { /* Always joined to multicast if-local and link-local all-nodes group. */ @@ -477,7 +480,7 @@ netif_found: } /* current netif pointer. */ - ip_data.current_netif = inp; + ip_data.current_netif = netif; /* Save next header type. */ nexth = IP6H_NEXTH(ip6hdr); From c52189557e8c401269ef25e3294b1200f8fb3f18 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 2 Mar 2012 08:59:34 -0700 Subject: [PATCH 4/9] Fixed error in calculating some IPv6 option header lengths. --- src/core/ipv6/ip6.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index a051c0b3..b5529d08 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -501,7 +501,7 @@ netif_found: nexth = *((u8_t *)p->payload); /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload) + 1); + hlen = 8 * (1 + *((u8_t *)p->payload + 1)); ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ @@ -524,7 +524,7 @@ netif_found: nexth = *((u8_t *)p->payload); /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload) + 1); + hlen = 8 * (1 + *((u8_t *)p->payload + 1)); ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ @@ -547,7 +547,7 @@ netif_found: nexth = *((u8_t *)p->payload); /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload) + 1); + hlen = 8 * (1 + *((u8_t *)p->payload + 1)); ip_data.current_ip_header_tot_len += hlen; /* Skip over this header. */ From 5c199483cd1cb863e7f27b8ce451a6325d7dfe8d Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 2 Mar 2012 09:06:57 -0700 Subject: [PATCH 5/9] Support IP_HDRINCL in ip6_output() and ip6_output_hinted(), previously only supported in ip6_output_if(). --- src/core/ipv6/ip6.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index b5529d08..ef018888 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -827,12 +827,23 @@ ip6_output(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, u8_t hl, u8_t tc, u8_t nexth) { struct netif *netif; + ip6_addr_t src_addr, dest_addr; /* pbufs passed to IPv6 must have a ref-count of 1 as their payload pointer gets altered as the packet is passed down the stack */ LWIP_ASSERT("p->ref == 1", p->ref == 1); - if ((netif = ip6_route(src, dest)) == NULL) { + if (dest != IP_HDRINCL) { + netif = ip6_route(src, dest); + } else { + /* IP header included in p, read addresses. */ + ip6hdr = (struct ip6_hdr *)p->payload; + ip6_addr_copy(src_addr, ip6hdr->src); + ip6_addr_copy(dest_addr, ip6hdr->dest); + netif = ip6_route(&src_addr, &dest_addr); + } + + if (netif == NULL) { LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", IP6_ADDR_BLOCK1(dest), IP6_ADDR_BLOCK2(dest), @@ -881,7 +892,17 @@ ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, gets altered as the packet is passed down the stack */ LWIP_ASSERT("p->ref == 1", p->ref == 1); - if ((netif = ip6_route(src, dest)) == NULL) { + if (dest != IP_HDRINCL) { + netif = ip6_route(src, dest); + } else { + /* IP header included in p, read addresses. */ + ip6hdr = (struct ip6_hdr *)p->payload; + ip6_addr_copy(src_addr, ip6hdr->src); + ip6_addr_copy(dest_addr, ip6hdr->dest); + netif = ip6_route(&src_addr, &dest_addr); + } + + if (netif == NULL) { LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", IP6_ADDR_BLOCK1(dest), IP6_ADDR_BLOCK2(dest), From 34531a8160412823e509d43719c750d09c7e3c58 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 2 Mar 2012 09:16:33 -0700 Subject: [PATCH 6/9] Check that pbuf_header succeeds in IPv6 reassembly. --- src/core/ipv6/ip6_frag.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c index f33f4fb9..1e6304ee 100644 --- a/src/core/ipv6/ip6_frag.c +++ b/src/core/ipv6/ip6_frag.c @@ -149,8 +149,12 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr) p = ipr->p; ipr->p = iprh->next_pbuf; /* Then, move back to the original header (we are now pointing to Fragment header). */ - pbuf_header(p, (u8_t*)p->payload - (u8_t*)ipr->iphdr); - icmp6_time_exceeded(p, ICMP6_TE_FRAG); + if (pbuf_header(p, (u8_t*)p->payload - (u8_t*)ipr->iphdr)) { + LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0); + } + else { + icmp6_time_exceeded(p, ICMP6_TE_FRAG); + } clen = pbuf_clen(p); LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); pbufs_freed += clen; @@ -490,9 +494,6 @@ ip6_reass(struct pbuf *p) frag_hdr->_fragment_offset = 0; frag_hdr->_identification = 0; - /* Move pbuf back to IPv6 header. */ - pbuf_header(p, (u8_t*)p->payload - (u8_t*)ipr->iphdr); - /* release the sources allocate for the fragment queue entry */ if (reassdatagrams == ipr) { /* it was the first in the list */ @@ -504,9 +505,16 @@ ip6_reass(struct pbuf *p) } memp_free(MEMP_IP6_REASSDATA, ipr); - /* and adjust the number of pbufs currently queued for reassembly. */ + /* adjust the number of pbufs currently queued for reassembly. */ ip6_reass_pbufcount -= pbuf_clen(p); + /* Move pbuf back to IPv6 header. */ + if (pbuf_header(p, (u8_t*)p->payload - (u8_t*)ipr->iphdr)) { + LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0); + pbuf_free(p); + return NULL; + } + /* Return the pbuf chain */ return p; } From 8c9542220413ce5cdc761759839275715b87ab01 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 2 Mar 2012 09:18:54 -0700 Subject: [PATCH 7/9] Early exit when checking if ip6 reassembled packet is valid. --- src/core/ipv6/ip6_frag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c index 1e6304ee..a43fd614 100644 --- a/src/core/ipv6/ip6_frag.c +++ b/src/core/ipv6/ip6_frag.c @@ -443,7 +443,7 @@ ip6_reass(struct pbuf *p) /* Final validity test: no gaps between current and last fragment. */ iprh_prev = iprh; q = iprh->next_pbuf; - while (q != NULL) { + while ((q != NULL) && valid) { iprh = (struct ip6_reass_helper*)q->payload; if (iprh_prev->end != iprh->start) { valid = 0; From 22e7b674ede969aa84fdfe0638a2dc7b974c951d Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 2 Mar 2012 09:27:14 -0700 Subject: [PATCH 8/9] Check arguments in nd6, and some other minor fixes nearby. --- src/core/ipv6/nd6.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index 60467535..9465db00 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -375,9 +375,7 @@ nd6_input(struct pbuf *p, struct netif *inp) /* If we are sending RS messages, stop. */ #if LWIP_IPV6_SEND_ROUTER_SOLICIT - if (inp->rs_count > 0) { - inp->rs_count = 0; - } + inp->rs_count = 0; #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ /* Get the matching default router entry. */ @@ -885,7 +883,7 @@ nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags) /* Set fields. */ na_hdr = (struct na_header *)p->payload; - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); na_hdr->type = ICMP6_TYPE_NA; na_hdr->code = 0; @@ -1133,6 +1131,10 @@ nd6_new_neighbor_cache_entry(void) static void nd6_free_neighbor_cache_entry(s8_t i) { + if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { + return; + } + #if LWIP_ND6_QUEUEING /* Free any queued packets. */ if (neighbor_cache[i].q != NULL) { @@ -1463,14 +1465,14 @@ nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif) } /* Copy dest address to destination cache. */ - ip6_addr_set(&(destination_cache[i].destination_addr), ip6addr); + ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr); /* Now find the next hop. is it a neighbor? */ if (ip6_addr_islinklocal(ip6addr) || nd6_is_prefix_in_netif(ip6addr, netif)) { /* Destination in local link. */ - destination_cache[i].pmtu = netif->mtu; - ip6_addr_copy(destination_cache[i].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); + destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; + ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); } else { /* We need to select a router. */ @@ -1549,6 +1551,10 @@ nd6_queue_packet(s8_t neighbor_index, struct pbuf * q) int copy_needed = 0; struct nd6_q_entry *new_entry, *r; + if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) { + return ERR_ARG; + } + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but * to copy the whole queue into a new PBUF_RAM (see bug #11400) * PBUF_ROMs can be left as they are, since ROM must not get changed. */ @@ -1656,6 +1662,10 @@ nd6_send_q(s8_t i) struct ip6_hdr *ip6hdr; struct nd6_q_entry *q; + if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { + return; + } + while (neighbor_cache[i].q != NULL) { /* remember first in queue */ q = neighbor_cache[i].q; From 773dcae2f9f6f676a3b7f20813778d9b957f9c31 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 2 Mar 2012 09:35:42 -0700 Subject: [PATCH 9/9] Missing declarations in supporting IP_HDRINCL. --- src/core/ipv6/ip6.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index ef018888..fcae57c6 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -827,6 +827,7 @@ ip6_output(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, u8_t hl, u8_t tc, u8_t nexth) { struct netif *netif; + struct ip6_hdr *ip6hdr; ip6_addr_t src_addr, dest_addr; /* pbufs passed to IPv6 must have a ref-count of 1 as their payload pointer @@ -886,6 +887,8 @@ ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint) { struct netif *netif; + struct ip6_hdr *ip6hdr; + ip6_addr_t src_addr, dest_addr; err_t err; /* pbufs passed to IP must have a ref-count of 1 as their payload pointer