diff --git "a/nd6-3c40d93-left.c" "b/lwip\\src\\core\\ipv6\\nd6.c"
index 7c65df3..aeeff4e 100644
--- "a/nd6-3c40d93-left.c"
+++ "b/lwip\\src\\core\\ipv6\\nd6.c"
@@ -148,7 +148,8 @@ nd6_input(struct pbuf *p, struct netif *inp)
        * 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))) {
+      lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
+      if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
         /* TODO debug message */
         pbuf_free(p);
         ND6_STATS_INC(nd6.lenerr);
@@ -156,8 +157,6 @@ nd6_input(struct pbuf *p, struct netif *inp)
         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));
 
@@ -225,7 +224,8 @@ nd6_input(struct pbuf *p, struct netif *inp)
       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))) {
+        lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header));
+        if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
           /* TODO debug message */
           pbuf_free(p);
           ND6_STATS_INC(nd6.lenerr);
@@ -265,9 +265,11 @@ nd6_input(struct pbuf *p, struct netif *inp)
     ns_hdr = (struct ns_header *)p->payload;
 
     /* Check if there is a link-layer address provided. Only point to it if in this buffer. */
-    lladdr_opt = NULL;
-    if (p->len >= (sizeof(struct ns_header) + sizeof(struct lladdr_option))) {
+    lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header));
+    if (p->len >= (sizeof(struct ns_header) + (lladdr_opt->length >> 3))) {
       lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header));
+    } else {
+      lladdr_opt = NULL;
     }
 
     /* Check if the target address is configured on the receiving netif. */
@@ -515,9 +517,12 @@ nd6_input(struct pbuf *p, struct netif *inp)
 
     redir_hdr = (struct redirect_header *)p->payload;
 
-    lladdr_opt = NULL;
-    if (p->len >= (sizeof(struct redirect_header) + sizeof(struct lladdr_option))) {
+    lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header));
+    if (p->len >= (sizeof(struct redirect_header) + (lladdr_opt->length << 3))) {
+
       lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header));
+    } else {
+      lladdr_opt = NULL;
     }
 
     /* Copy original destination address to current source address, to have an aligned copy. */
@@ -798,6 +803,7 @@ nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
 {
   struct ns_header * ns_hdr;
   struct lladdr_option * lladdr_opt;
+  u16_t lladdr_option_len;
   struct pbuf * p;
   ip6_addr_t * src_addr;
 
@@ -809,8 +815,9 @@ nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
   }
 
   /* Allocate a packet. */
-  p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + sizeof(struct lladdr_option), PBUF_RAM);
-  if ((p == NULL) || (p->len < (sizeof(struct ns_header) + sizeof(struct lladdr_option)))) {
+  lladdr_option_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
+  p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + (lladdr_option_len << 3), PBUF_RAM);
+  if ((p == NULL) || (p->len < (sizeof(struct ns_header) +(lladdr_option_len << 3)))) {
     /* We couldn't allocate a suitable pbuf for the ns. drop it. */
     if (p != NULL) {
       pbuf_free(p);
@@ -829,6 +836,7 @@ nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
   ns_hdr->reserved = 0;
   ip6_addr_set(&(ns_hdr->target_address), target_addr);
 
+  memset(lladdr_opt, 0, lladdr_option_len << 3);
   lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR;
   lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
   SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len);
@@ -863,6 +871,7 @@ nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
 {
   struct na_header * na_hdr;
   struct lladdr_option * lladdr_opt;
+  u16_t lladdr_option_len;
   struct pbuf * p;
   ip6_addr_t * src_addr;
   ip6_addr_t * dest_addr;
@@ -873,8 +882,9 @@ nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
   src_addr = target_addr;
 
   /* Allocate a packet. */
-  p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + sizeof(struct lladdr_option), PBUF_RAM);
-  if ((p == NULL) || (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option)))) {
+  lladdr_option_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
+  p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + (lladdr_option_len << 3), PBUF_RAM);
+  if ((p == NULL) || (p->len < (sizeof(struct na_header) + (lladdr_option_len << 3)))) {
     /* We couldn't allocate a suitable pbuf for the ns. drop it. */
     if (p != NULL) {
       pbuf_free(p);
@@ -896,8 +906,9 @@ nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags)
   na_hdr->reserved[2] = 0;
   ip6_addr_set(&(na_hdr->target_address), target_addr);
 
+  memset(lladdr_opt, 0, lladdr_option_len << 3);
   lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR;
-  lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
+  lladdr_opt->length = lladdr_option_len;
   SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len);
 
   /* Generate the solicited node address for the target address. */
@@ -936,6 +947,7 @@ nd6_send_rs(struct netif * netif)
 {
   struct rs_header * rs_hdr;
   struct lladdr_option * lladdr_opt;
+  u16_t lladdr_option_len;
   struct pbuf * p;
   ip6_addr_t * src_addr;
   u16_t packet_len;
@@ -953,8 +965,9 @@ nd6_send_rs(struct netif * netif)
 
   /* Allocate a packet. */
   packet_len = sizeof(struct rs_header);
+  lladdr_option_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
   if (src_addr != IP6_ADDR_ANY) {
-    packet_len += sizeof(struct lladdr_option);
+    packet_len += (lladdr_option_len << 3);
   }
   p = pbuf_alloc(PBUF_IP, packet_len, PBUF_RAM);
   if ((p == NULL) || (p->len < packet_len)) {
@@ -977,6 +990,7 @@ nd6_send_rs(struct netif * netif)
   if (src_addr != IP6_ADDR_ANY) {
     /* Include our hw address. */
     lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct rs_header));
+    memset(lladdr_opt, 0, lladdr_option_len << 3);
     lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR;
     lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0);
     SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len);
@@ -1029,8 +1043,12 @@ nd6_new_neighbor_cache_entry(void)
   s8_t i;
   s8_t j;
   u32_t time;
-
-
+  
+#if LWIP_RPL
+  #include "netif/rpl/rplopt.h"
+  RPL_IPV6_NEIGHBOR_CALLBACK(ip6_current_src_addr());
+#endif
+  
   /* First, try to find an empty entry. */
   for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
     if (neighbor_cache[i].state == ND6_NO_ENTRY) {
@@ -1136,7 +1154,11 @@ nd6_free_neighbor_cache_entry(s8_t i)
   if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) {
     return;
   }
-
+#if LWIP_RPL
+  #include "netif/rpl/rplopt.h"
+  RPL_IPV6_NEIGHBOR_CALLBACK(&neighbor_cache[i].next_hop_address);
+#endif
+  
   /* Free any queued packets. */
   if (neighbor_cache[i].q != NULL) {
     nd6_free_q(neighbor_cache[i].q);
@@ -1744,6 +1766,39 @@ nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif)
   return 1280; /* Minimum MTU */
 }
 
+/**
+ * @todo: please fix the function name and add correct documentation!
+ */
+void
+nd6_neighbor_cach_add(u8_t *hwaddr, ip6_addr_t * ip6addr,
+                      u8_t state, struct netif * netif)
+{
+   s8_t i;
+
+   i = nd6_find_neighbor_cache_entry(ip6addr);
+   if(i < 0) {
+      /* Add their IPv6 address and link-layer address to neighbor cache.
+       * We will need it at least to send a unicast NA message, but most
+       * likely we will also be communicating with this node soon. */
+     i = nd6_new_neighbor_cache_entry();
+     if (i < 0) {
+     /* We couldn't assign a cache entry for this neighbor.
+      * we won't be able to reply. drop it. */
+       ND6_STATS_INC(nd6.memerr);
+       return;
+     }
+   }
+   neighbor_cache[i].netif = netif;
+   MEMCPY(neighbor_cache[i].lladdr, hwaddr, netif->hwaddr_len);
+   ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6addr);
+   if(state == ND6_INCOMPLETE) {
+     neighbor_cache[i].state = ND6_INCOMPLETE;
+     neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
+   } else {
+     neighbor_cache[i].state = ND6_REACHABLE;
+     neighbor_cache[i].counter.reachable_time = LWIP_ND6_REACHABLE_TIME;
+   }
+}
 
 #if LWIP_ND6_TCP_REACHABILITY_HINTS
 /**
