removed nd llao option struct since not naturally aligned - replaced struct fields access with array based access

This commit is contained in:
joxe 2010-05-19 12:21:45 +00:00
parent 86879f66ac
commit 5c30aed814
2 changed files with 55 additions and 62 deletions

View File

@ -119,13 +119,12 @@ void uip_log(char *msg);
/** @} */ /** @} */
/** Pointer to ND option */ /** Pointer to ND option */
#define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) #define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
#define UIP_ND6_OPT_LLAO ((uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
#define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) #define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
#define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) #define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
/** @} */ /** @} */
static u8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/ static uint8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/
static uip_nd6_opt_llao *nd6_opt_llao; /** Pointer to llao option in uip_buf */ static uint8_t *nd6_opt_llao; /** Pointer to llao option in uip_buf */
#if !UIP_CONF_ROUTER // TBD see if we move it to ra_input #if !UIP_CONF_ROUTER // TBD see if we move it to ra_input
static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */ static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */
@ -136,6 +135,18 @@ static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/
static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */ static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */
static uip_ds6_addr_t *addr; /** Pointer to an interface address */ static uip_ds6_addr_t *addr; /** Pointer to an interface address */
/*------------------------------------------------------------------*/
/* create a llao */
static void
create_llao(uint8_t *llao, uint8_t type) {
llao[UIP_ND6_OPT_TYPE_OFFSET] = type;
llao[UIP_ND6_OPT_LEN_OFFSET] = UIP_ND6_OPT_LLAO_LEN >> 3;
memcpy(&llao[UIP_ND6_OPT_DATA_OFFSET], &uip_lladdr, UIP_LLADDR_LEN);
/* padding on some */
memset(&llao[UIP_ND6_OPT_DATA_OFFSET + UIP_LLADDR_LEN], 0,
UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN);
}
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
@ -174,9 +185,7 @@ uip_nd6_ns_input(void)
#endif /* UIP_CONF_IPV6_CHECKS */ #endif /* UIP_CONF_IPV6_CHECKS */
switch (UIP_ND6_OPT_HDR_BUF->type) { switch (UIP_ND6_OPT_HDR_BUF->type) {
case UIP_ND6_OPT_SLLAO: case UIP_ND6_OPT_SLLAO:
nd6_opt_llao = nd6_opt_llao = &uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset];
(struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len +
nd6_opt_offset];
#if UIP_CONF_IPV6_CHECKS #if UIP_CONF_IPV6_CHECKS
/* There must be NO option in a DAD NS */ /* There must be NO option in a DAD NS */
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
@ -187,10 +196,13 @@ uip_nd6_ns_input(void)
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
if(nbr == NULL) { if(nbr == NULL) {
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
&nd6_opt_llao->addr, 0, NBR_STALE); (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
0, NBR_STALE);
} else { } else {
if(memcmp(&nd6_opt_llao->addr, &nbr->lladdr, UIP_LLADDR_LEN) != 0) { if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); &nbr->lladdr, UIP_LLADDR_LEN) != 0) {
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN);
nbr->state = NBR_STALE; nbr->state = NBR_STALE;
} else { } else {
if(nbr->state == NBR_INCOMPLETE) { if(nbr->state == NBR_INCOMPLETE) {
@ -284,15 +296,8 @@ create_na:
UIP_ND6_NA_BUF->flagsreserved = flags; UIP_ND6_NA_BUF->flagsreserved = flags;
memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &addr->ipaddr, sizeof(uip_ipaddr_t)); memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &addr->ipaddr, sizeof(uip_ipaddr_t));
nd6_opt_llao = create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN],
(struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_OPT_TLLAO);
UIP_ND6_NA_LEN];
nd6_opt_llao->type = UIP_ND6_OPT_TLLAO;
nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3;
memcpy(&(nd6_opt_llao->addr), &uip_lladdr, UIP_LLADDR_LEN);
/* padding on some */
memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0,
UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN);
UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = 0;
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
@ -350,15 +355,10 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
} }
UIP_IP_BUF->len[1] = UIP_IP_BUF->len[1] =
UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN;
nd6_opt_llao =
(struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NS_LEN],
UIP_ND6_NS_LEN]; UIP_ND6_OPT_SLLAO);
nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; /* type of the option */
nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3;
memcpy(&nd6_opt_llao->addr, &uip_lladdr, UIP_LLADDR_LEN);
/* padding on some */
memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0,
UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN);
uip_len = uip_len =
UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN;
} else { } else {
@ -429,7 +429,7 @@ uip_nd6_na_input(void)
#endif /*UIP_CONF_IPV6_CHECKS */ #endif /*UIP_CONF_IPV6_CHECKS */
switch (UIP_ND6_OPT_HDR_BUF->type) { switch (UIP_ND6_OPT_HDR_BUF->type) {
case UIP_ND6_OPT_TLLAO: case UIP_ND6_OPT_TLLAO:
nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
break; break;
default: default:
PRINTF("ND option not supported in NA\n"); PRINTF("ND option not supported in NA\n");
@ -452,14 +452,15 @@ uip_nd6_na_input(void)
} }
if(nd6_opt_llao != 0) { if(nd6_opt_llao != 0) {
is_llchange = is_llchange =
memcmp((void *)&nd6_opt_llao->addr, (void *)(&nbr->lladdr), memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (void *)(&nbr->lladdr),
UIP_LLADDR_LEN); UIP_LLADDR_LEN);
} }
if(nbr->state == NBR_INCOMPLETE) { if(nbr->state == NBR_INCOMPLETE) {
if(nd6_opt_llao == NULL) { if(nd6_opt_llao == NULL) {
goto discard; goto discard;
} }
memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN);
if(is_solicited) { if(is_solicited) {
nbr->state = NBR_REACHABLE; nbr->state = NBR_REACHABLE;
nbr->nscount = 0; nbr->nscount = 0;
@ -481,7 +482,8 @@ uip_nd6_na_input(void)
if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange) if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange)
|| nd6_opt_llao == 0) { || nd6_opt_llao == 0) {
if(nd6_opt_llao != 0) { if(nd6_opt_llao != 0) {
memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN);
} }
if(is_solicited) { if(is_solicited) {
nbr->state = NBR_REACHABLE; nbr->state = NBR_REACHABLE;
@ -560,7 +562,7 @@ uip_nd6_rs_input(void)
#endif /*UIP_CONF_IPV6_CHECKS */ #endif /*UIP_CONF_IPV6_CHECKS */
switch (UIP_ND6_OPT_HDR_BUF->type) { switch (UIP_ND6_OPT_HDR_BUF->type) {
case UIP_ND6_OPT_SLLAO: case UIP_ND6_OPT_SLLAO:
nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; nd6_opt_llao = UIP_ND6_OPT_HDR_BUF;
break; break;
default: default:
PRINTF("ND option not supported in RS\n"); PRINTF("ND option not supported in RS\n");
@ -579,11 +581,13 @@ uip_nd6_rs_input(void)
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
/* we need to add the neighbor */ /* we need to add the neighbor */
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
&nd6_opt_llao->addr, 0, NBR_STALE); &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
} else { } else {
/* If LL address changed, set neighbor state to stale */ /* If LL address changed, set neighbor state to stale */
if(memcmp(&nd6_opt_llao->addr, &nbr->lladdr, UIP_LLADDR_LEN) != 0) { if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); &nbr->lladdr, UIP_LLADDR_LEN) != 0) {
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN);
nbr->state = NBR_STALE; nbr->state = NBR_STALE;
} }
nbr->isrouter = 0; nbr->isrouter = 0;
@ -656,13 +660,7 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
} }
/* Source link-layer option */ /* Source link-layer option */
nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO);
nd6_opt_llao->type = UIP_ND6_OPT_SLLAO;
nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3;
memcpy(&(nd6_opt_llao->addr), &uip_lladdr, UIP_LLADDR_LEN);
/* padding if needed */
memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0,
UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN);
uip_len += UIP_ND6_OPT_LLAO_LEN; uip_len += UIP_ND6_OPT_LLAO_LEN;
nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN; nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN;
@ -717,15 +715,9 @@ uip_nd6_rs_output(void)
uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN;
UIP_IP_BUF->len[1] = UIP_IP_BUF->len[1] =
UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN;
nd6_opt_llao =
(struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_RS_LEN],
UIP_ND6_RS_LEN]; UIP_ND6_OPT_SLLAO);
nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; /* type of the option */
nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3;
memcpy(&nd6_opt_llao->addr, &uip_lladdr, UIP_LLADDR_LEN);
/* padding on some link layers */
memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0,
UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN);
} }
UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = 0;
@ -787,17 +779,20 @@ uip_nd6_ra_input(void)
switch (UIP_ND6_OPT_HDR_BUF->type) { switch (UIP_ND6_OPT_HDR_BUF->type) {
case UIP_ND6_OPT_SLLAO: case UIP_ND6_OPT_SLLAO:
PRINTF("Processing SLLAO option in RA\n"); PRINTF("Processing SLLAO option in RA\n");
nd6_opt_llao = (uip_nd6_opt_llao *) UIP_ND6_OPT_HDR_BUF; nd6_opt_llao = UIP_ND6_OPT_HDR_BUF;
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
if(nbr == NULL) { if(nbr == NULL) {
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
&nd6_opt_llao->addr, 1, NBR_STALE); &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
1, NBR_STALE);
} else { } else {
if(nbr->state == NBR_INCOMPLETE) { if(nbr->state == NBR_INCOMPLETE) {
nbr->state = NBR_STALE; nbr->state = NBR_STALE;
} }
if(memcmp(&nd6_opt_llao->addr, &nbr->lladdr, UIP_LLADDR_LEN) != 0) { if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); &nbr->lladdr, UIP_LLADDR_LEN) != 0) {
memcpy(&nbr->lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN);
nbr->state = NBR_STALE; nbr->state = NBR_STALE;
} }
nbr->isrouter = 1; nbr->isrouter = 1;

View File

@ -132,6 +132,11 @@
#define UIP_ND6_OPT_MTU 5 #define UIP_ND6_OPT_MTU 5
/** @} */ /** @} */
/** \name ND6 option types */
/** @{ */
#define UIP_ND6_OPT_TYPE_OFFSET 0
#define UIP_ND6_OPT_LEN_OFFSET 1
#define UIP_ND6_OPT_DATA_OFFSET 2
/** \name ND6 message length (excluding options) */ /** \name ND6 message length (excluding options) */
/** @{ */ /** @{ */
@ -344,13 +349,6 @@ typedef struct uip_nd6_opt_mtu {
uint32_t mtu; uint32_t mtu;
} uip_nd6_opt_mtu; } uip_nd6_opt_mtu;
/** \brief ND option: both TLLAO and SLLAO */
typedef struct uip_nd6_opt_llao {
uint8_t type;
uint8_t len;
uip_lladdr_t addr;
} uip_nd6_opt_llao;
/** \struct Redirected header option */ /** \struct Redirected header option */
typedef struct uip_nd6_opt_redirected_hdr { typedef struct uip_nd6_opt_redirected_hdr {
uint8_t type; uint8_t type;