net/lwip : add routine to parse Neighbor Advertisement message
This commit is patch to introduce dns client API testcases
- as per RFC4861, 7.2.5.  Receipt of Neighbor Advertisements
accordingly neighbor cache entry state, entry information should be
updated
@@ -258,7 +258,7 @@ void nd6_input(struct pbuf *p, struct netif *inp)
}
/* Update cache entry. */
- if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || (neighbor_cache[i].state == ND6_INCOMPLETE)) {
+ if ((neighbor_cache[i].state == ND6_INCOMPLETE)) {
/* Check that link-layer address option also fits in packet. */
if (p->len < (sizeof(struct na_header) + 2)) {
/* @todo debug message */
@@ -269,7 +269,46 @@ void nd6_input(struct pbuf *p, struct netif *inp)
}
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);
+ ND6_STATS_INC(nd6.drop);
+ return;
+ }
+
+ MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+
+ if ((na_hdr->flags & ND6_FLAG_SOLICITED)) {
+ neighbor_cache[i].state = ND6_REACHABLE;
+ } else {
+ neighbor_cache[i].state = ND6_STALE;
+ }
+ if ((na_hdr->flags & ND6_FLAG_ROUTER)) {
+ neighbor_cache[i].isrouter = 1;
+ } else {
+ /* @todo
+ * IsRouter flag in the cache MUST be set based on the Router flag
+ * in the received advertisement
+ * Node MUST remove that router from the Default Router List
+ * and update Destincation Cache entries for all destinations using that
+ * neighbor router as specified in Section 7.3.3
+ */
+ }
+ } else {
+ /* neighbor cache entry state is not ND6_INCOMPLETE */
+ if ((na_hdr->flags & ND6_FLAG_OVERRIDE)) {
+ /* Check that link-layer address option also fits in packet. */
+ if (p->len < (sizeof(struct na_header) + 2)) {
+ /* @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));
if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) {
/* @todo debug message */
pbuf_free(p);
@@ -279,14 +318,24 @@ void nd6_input(struct pbuf *p, struct netif *inp)
}
MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len);
+
+ if ((na_hdr->flags & ND6_FLAG_SOLICITED)) {
+ neighbor_cache[i].state = ND6_REACHABLE;
+ } else {
+ neighbor_cache[i].state = ND6_STALE;
+ }
+ } else {
+ if (neighbor_cache[i].state == ND6_REACHABLE) {
+ neighbor_cache[i].state = ND6_STALE;
+ }
+ }
}
neighbor_cache[i].netif = inp;
- neighbor_cache[i].state = ND6_REACHABLE;
neighbor_cache[i].counter.reachable_time = reachable_time;
/* Send queued packets, if any. */
- if (neighbor_cache[i].q != NULL) {
+ if (neighbor_cache[i].state == ND6_REACHABLE && neighbor_cache[i].q != NULL) {
nd6_send_q(i);
}
}
