From 639f7dc020d04d8bcf86ca660927af8daf015dad Mon Sep 17 00:00:00 2001
From: Yonezawa-T2 <Yonezawa-T2@mail.dnp.co.jp>
Date: Thu, 19 Nov 2015 18:13:33 +0900
Subject: [PATCH] gnrc_ndp: fixed ND Option handling for 6LoWPAN

The forms of the Source/Target Link-layer Address option for 6LoWPAN are defined
in RFC 4944 Section 8:
https://tools.ietf.org/html/rfc4944#section-8
The address is 16 bit if length is 1, 64 bit if length is 2.
---
 .../ndp/internal/gnrc_ndp_internal.c          | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c b/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c
index d9f51cbc7f..73cd396602 100644
--- a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c
+++ b/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c
@@ -598,6 +598,24 @@ int gnrc_ndp_internal_sl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, uin
         pkt = pkt->next;
     }
 
+#ifdef MODULE_GNRC_SIXLOWPAN_ND
+    if ((sl2a_len == 2) || (sl2a_len == 8)) {
+        /* The link-layer seems to be IEEE 802.15.4.
+         * Determining address length from the option length:
+         * https://tools.ietf.org/html/rfc4944#section-8 */
+        if (sl2a_opt->len == 1) {
+            sl2a_len = 2;
+        }
+        else if (sl2a_opt->len == 2) {
+            sl2a_len = 8;
+        }
+        else {
+            DEBUG("ndp: invalid source link-layer address option received\n");
+            return -EINVAL;
+        }
+    }
+#endif
+
     DEBUG("ndp: received SL2A (link-layer address: %s)\n",
           gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), sl2a, sl2a_len));
 
@@ -644,6 +662,23 @@ int gnrc_ndp_internal_tl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6,
                 }
                 pkt = pkt->next;
             }
+#ifdef MODULE_GNRC_SIXLOWPAN_ND
+            if ((tl2a_len == 2) || (tl2a_len == 8)) {
+                /* The link-layer seems to be IEEE 802.15.4.
+                 * Determining address length from the option length:
+                 * https://tools.ietf.org/html/rfc4944#section-8 */
+                if (tl2a_opt->len == 1) {
+                    tl2a_len = 2;
+                }
+                else if (tl2a_opt->len == 2) {
+                    tl2a_len = 8;
+                }
+                else {
+                    DEBUG("ndp: invalid target link-layer address option received\n");
+                    return -EINVAL;
+                }
+            }
+#endif
 
             if (tl2a_len == 0) {  /* in case there was no source address in l2 */
                 tl2a_len = (tl2a_opt->len / 8) - sizeof(ndp_opt_t);
-- 
GitLab