]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/commitdiff
Allow unicast NA messages without LLA option, in accordance to RFC2461
authorIvan Delamer <delamer@inicotech.com>
Fri, 27 Jan 2012 21:54:39 +0000 (14:54 -0700)
committerIvan Delamer <delamer@inicotech.com>
Fri, 27 Jan 2012 21:54:39 +0000 (14:54 -0700)
section 4.4, and as suggested by Phillip Toelke.

Change-Id: Ic9d9a6ad82ec201d25b9fc024936cfb1b41f1a7a

src/core/ipv6/nd6.c

index 4ad052797268c67906077405cf33db703e91fcb8..ce36b4c128824c533f40d1c5b985c8ae06944ec0 100644 (file)
@@ -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;