diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index a86de7021..d611d10c1 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -132,6 +132,16 @@ static uip_ipaddr_t ipaddr; static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ #endif +#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER +/*------------------------------------------------------------------*/ +/* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */ +static void +extract_lladdr_aligned(uip_lladdr_t *dest) { + if(dest != NULL && nd6_opt_llao != NULL) { + memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); + } +} +#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */ /*------------------------------------------------------------------*/ /* create a llao */ static void @@ -191,15 +201,14 @@ ns_input(void) #endif /*UIP_CONF_IPV6_CHECKS */ nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - 0, NBR_STALE); + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - UIP_LLADDR_LEN); + lladdr, UIP_LLADDR_LEN) != 0) { + memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); nbr->state = NBR_STALE; } else { if(nbr->state == NBR_INCOMPLETE) { @@ -621,18 +630,18 @@ rs_input(void) goto discard; } else { #endif /*UIP_CONF_IPV6_CHECKS */ + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { /* we need to add the neighbor */ - uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); } else { /* If LL address changed, set neighbor state to stale */ if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_rm(nbr); - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE); nbr->reachable = nbr_data.reachable; nbr->sendns = nbr_data.sendns; nbr->nscount = nbr_data.nscount; @@ -859,9 +868,9 @@ ra_input(void) nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF; nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { - nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, - (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], - 1, NBR_STALE); + uip_lladdr_t lladdr_aligned; + extract_lladdr_aligned(&lladdr_aligned); + nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE); } else { uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); if(nbr->state == NBR_INCOMPLETE) {