From 1d6347c9b0f8dda56faa860654137f1902a87206 Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Fri, 27 Jan 2012 14:54:39 -0700 Subject: [PATCH] Allow unicast NA messages without LLA option, in accordance to RFC2461 section 4.4, and as suggested by Phillip Toelke. Change-Id: Ic9d9a6ad82ec201d25b9fc024936cfb1b41f1a7a --- src/core/ipv6/nd6.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index 4ad05279..ce36b4c1 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -127,8 +127,8 @@ nd6_input(struct pbuf *p, struct netif *inp) struct na_header * na_hdr; struct lladdr_option * lladdr_opt; - /* Check that na header and link-layer address option fit in packet. */ - if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { + /* Check that na header fits in packet. */ + if (p->len < (sizeof(struct na_header))) { /* TODO debug message */ pbuf_free(p); ND6_STATS_INC(nd6.lenerr); @@ -137,7 +137,6 @@ nd6_input(struct pbuf *p, struct netif *inp) } na_hdr = (struct na_header *)p->payload; - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); /* Unsolicited NA?*/ if (ip6_addr_ismulticast(ip6_current_dest_addr())) { @@ -145,6 +144,17 @@ nd6_input(struct pbuf *p, struct netif *inp) * link-layer changed? * part of DAD mechanism? */ + /* Check that link-layer address option also fits in packet. */ + if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); + /* Override ip6_current_dest_addr() so that we have an aligned copy. */ ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address)); @@ -211,6 +221,17 @@ nd6_input(struct pbuf *p, struct netif *inp) neighbor_cache[i].counter.reachable_time = reachable_time; if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || (neighbor_cache[i].state == ND6_INCOMPLETE)) { + /* Check that link-layer address option also fits in packet. */ + if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); + MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); } neighbor_cache[i].state = ND6_REACHABLE;