Allow unicast NA messages without LLA option, in accordance to RFC2461

section 4.4, and as suggested by Phillip Toelke.

Change-Id: Ic9d9a6ad82ec201d25b9fc024936cfb1b41f1a7a
This commit is contained in:
Ivan Delamer 2012-01-27 14:54:39 -07:00
parent 13075460ea
commit 1d6347c9b0

View File

@ -127,8 +127,8 @@ nd6_input(struct pbuf *p, struct netif *inp)
struct na_header * na_hdr; struct na_header * na_hdr;
struct lladdr_option * lladdr_opt; struct lladdr_option * lladdr_opt;
/* Check that na header and link-layer address option fit in packet. */ /* Check that na header fits in packet. */
if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { if (p->len < (sizeof(struct na_header))) {
/* TODO debug message */ /* TODO debug message */
pbuf_free(p); pbuf_free(p);
ND6_STATS_INC(nd6.lenerr); ND6_STATS_INC(nd6.lenerr);
@ -137,7 +137,6 @@ nd6_input(struct pbuf *p, struct netif *inp)
} }
na_hdr = (struct na_header *)p->payload; na_hdr = (struct na_header *)p->payload;
lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
/* Unsolicited NA?*/ /* Unsolicited NA?*/
if (ip6_addr_ismulticast(ip6_current_dest_addr())) { if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
@ -145,6 +144,17 @@ nd6_input(struct pbuf *p, struct netif *inp)
* link-layer changed? * link-layer changed?
* part of DAD mechanism? */ * 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. */ /* Override ip6_current_dest_addr() so that we have an aligned copy. */
ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address)); 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; neighbor_cache[i].counter.reachable_time = reachable_time;
if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || if ((na_hdr->flags & ND6_FLAG_OVERRIDE) ||
(neighbor_cache[i].state == ND6_INCOMPLETE)) { (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); MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
} }
neighbor_cache[i].state = ND6_REACHABLE; neighbor_cache[i].state = ND6_REACHABLE;