|
|
|
@ -45,11 +45,11 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN];
|
|
|
|
|
|
|
|
|
|
/* random helper function */ |
|
|
|
|
void ng_ndp_nbr_sol_handle(kernel_pid_t iface, ng_pktsnip_t *pkt, |
|
|
|
|
ipv6_hdr_t *ipv6, ng_ndp_nbr_sol_t *nbr_sol, |
|
|
|
|
ipv6_hdr_t *ipv6, ndp_nbr_sol_t *nbr_sol, |
|
|
|
|
size_t icmpv6_size) |
|
|
|
|
{ |
|
|
|
|
uint16_t opt_offset = 0; |
|
|
|
|
uint8_t *buf = ((uint8_t *)nbr_sol) + sizeof(ng_ndp_nbr_sol_t); |
|
|
|
|
uint8_t *buf = ((uint8_t *)nbr_sol) + sizeof(ndp_nbr_sol_t); |
|
|
|
|
ipv6_addr_t *tgt; |
|
|
|
|
int sicmpv6_size = (int)icmpv6_size; |
|
|
|
|
|
|
|
|
@ -62,7 +62,7 @@ void ng_ndp_nbr_sol_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
|
|
|
|
|
|
|
|
|
/* check validity */ |
|
|
|
|
if ((ipv6->hl != 255) || (nbr_sol->code != 0) || |
|
|
|
|
(icmpv6_size < sizeof(ng_ndp_nbr_sol_t)) || |
|
|
|
|
(icmpv6_size < sizeof(ndp_nbr_sol_t)) || |
|
|
|
|
ipv6_addr_is_multicast(&nbr_sol->tgt) || |
|
|
|
|
(ipv6_addr_is_unspecified(&ipv6->src) && |
|
|
|
|
ipv6_addr_is_solicited_node(&ipv6->dst))) { |
|
|
|
@ -78,13 +78,13 @@ void ng_ndp_nbr_sol_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sicmpv6_size -= sizeof(ng_ndp_nbr_sol_t); |
|
|
|
|
sicmpv6_size -= sizeof(ndp_nbr_sol_t); |
|
|
|
|
|
|
|
|
|
while (sicmpv6_size > 0) { |
|
|
|
|
ng_ndp_opt_t *opt = (ng_ndp_opt_t *)(buf + opt_offset); |
|
|
|
|
ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); |
|
|
|
|
|
|
|
|
|
switch (opt->type) { |
|
|
|
|
case NG_NDP_OPT_SL2A: |
|
|
|
|
case NDP_OPT_SL2A: |
|
|
|
|
if (!ng_ndp_internal_sl2a_opt_handle(iface, pkt, ipv6, nbr_sol->type, opt)) { |
|
|
|
|
/* invalid source link-layer address option */ |
|
|
|
|
return; |
|
|
|
@ -114,11 +114,11 @@ static inline bool _pkt_has_l2addr(ng_netif_hdr_t *netif_hdr)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ng_ndp_nbr_adv_handle(kernel_pid_t iface, ng_pktsnip_t *pkt, |
|
|
|
|
ipv6_hdr_t *ipv6, ng_ndp_nbr_adv_t *nbr_adv, |
|
|
|
|
ipv6_hdr_t *ipv6, ndp_nbr_adv_t *nbr_adv, |
|
|
|
|
size_t icmpv6_size) |
|
|
|
|
{ |
|
|
|
|
uint16_t opt_offset = 0; |
|
|
|
|
uint8_t *buf = ((uint8_t *)nbr_adv) + sizeof(ng_ndp_nbr_adv_t); |
|
|
|
|
uint8_t *buf = ((uint8_t *)nbr_adv) + sizeof(ndp_nbr_adv_t); |
|
|
|
|
int l2tgt_len = 0; |
|
|
|
|
uint8_t l2tgt[NG_IPV6_NC_L2_ADDR_MAX]; |
|
|
|
|
int sicmpv6_size = (int)icmpv6_size; |
|
|
|
@ -135,7 +135,7 @@ void ng_ndp_nbr_adv_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
|
|
|
|
|
|
|
|
|
/* check validity */ |
|
|
|
|
if ((ipv6->hl != 255) || (nbr_adv->code != 0) || |
|
|
|
|
(icmpv6_size < sizeof(ng_ndp_nbr_adv_t)) || |
|
|
|
|
(icmpv6_size < sizeof(ndp_nbr_adv_t)) || |
|
|
|
|
ipv6_addr_is_multicast(&nbr_adv->tgt)) { |
|
|
|
|
DEBUG("ndp: neighbor advertisement was invalid.\n"); |
|
|
|
|
/* ipv6 releases */ |
|
|
|
@ -149,13 +149,13 @@ void ng_ndp_nbr_adv_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sicmpv6_size -= sizeof(ng_ndp_nbr_adv_t); |
|
|
|
|
sicmpv6_size -= sizeof(ndp_nbr_adv_t); |
|
|
|
|
|
|
|
|
|
while (sicmpv6_size > 0) { |
|
|
|
|
ng_ndp_opt_t *opt = (ng_ndp_opt_t *)(buf + opt_offset); |
|
|
|
|
ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); |
|
|
|
|
|
|
|
|
|
switch (opt->type) { |
|
|
|
|
case NG_NDP_OPT_TL2A: |
|
|
|
|
case NDP_OPT_TL2A: |
|
|
|
|
if ((l2tgt_len = ng_ndp_internal_tl2a_opt_handle(pkt, ipv6, nbr_adv->type, opt, l2tgt)) < 0) { |
|
|
|
|
/* invalid target link-layer address option */ |
|
|
|
|
return; |
|
|
|
@ -191,14 +191,14 @@ void ng_ndp_nbr_adv_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
|
|
|
|
nc_entry->l2_addr_len = l2tgt_len; |
|
|
|
|
memcpy(nc_entry->l2_addr, l2tgt, l2tgt_len); |
|
|
|
|
|
|
|
|
|
if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_S) { |
|
|
|
|
if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_S) { |
|
|
|
|
ng_ndp_internal_set_state(nc_entry, NG_IPV6_NC_STATE_REACHABLE); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
ng_ndp_internal_set_state(nc_entry, NG_IPV6_NC_STATE_STALE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_R) { |
|
|
|
|
if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_R) { |
|
|
|
|
nc_entry->flags |= NG_IPV6_NC_IS_ROUTER; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
@ -226,7 +226,7 @@ void ng_ndp_nbr_adv_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
|
|
|
|
(memcmp(nc_entry->l2_addr, l2tgt, l2tgt_len) == 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_O) || !l2tgt_changed || |
|
|
|
|
if ((nbr_adv->flags & NDP_NBR_ADV_FLAGS_O) || !l2tgt_changed || |
|
|
|
|
(l2tgt_len == 0)) { |
|
|
|
|
if (l2tgt_len != 0) { |
|
|
|
|
nc_entry->iface = iface; |
|
|
|
@ -234,14 +234,14 @@ void ng_ndp_nbr_adv_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
|
|
|
|
|
memcpy(nc_entry->l2_addr, l2tgt, l2tgt_len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_S) { |
|
|
|
|
if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_S) { |
|
|
|
|
ng_ndp_internal_set_state(nc_entry, NG_IPV6_NC_STATE_REACHABLE); |
|
|
|
|
} |
|
|
|
|
else if (l2tgt_changed && (l2tgt_len != 0)) { |
|
|
|
|
ng_ndp_internal_set_state(nc_entry, NG_IPV6_NC_STATE_STALE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_R) { |
|
|
|
|
if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_R) { |
|
|
|
|
nc_entry->flags |= NG_IPV6_NC_IS_ROUTER; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
@ -365,10 +365,10 @@ ng_pktsnip_t *ng_ndp_nbr_sol_build(ipv6_addr_t *tgt, ng_pktsnip_t *options)
|
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pkt = ng_icmpv6_build(options, ICMPV6_NBR_SOL, 0, sizeof(ng_ndp_nbr_sol_t)); |
|
|
|
|
pkt = ng_icmpv6_build(options, ICMPV6_NBR_SOL, 0, sizeof(ndp_nbr_sol_t)); |
|
|
|
|
|
|
|
|
|
if (pkt != NULL) { |
|
|
|
|
ng_ndp_nbr_sol_t *nbr_sol = pkt->data; |
|
|
|
|
ndp_nbr_sol_t *nbr_sol = pkt->data; |
|
|
|
|
nbr_sol->resv.u32 = 0; |
|
|
|
|
nbr_sol->tgt.u64[0].u64 = tgt->u64[0].u64; |
|
|
|
|
nbr_sol->tgt.u64[1].u64 = tgt->u64[1].u64; |
|
|
|
@ -389,11 +389,11 @@ ng_pktsnip_t *ng_ndp_nbr_adv_build(uint8_t flags, ipv6_addr_t *tgt,
|
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pkt = ng_icmpv6_build(options, ICMPV6_NBR_ADV, 0, sizeof(ng_ndp_nbr_adv_t)); |
|
|
|
|
pkt = ng_icmpv6_build(options, ICMPV6_NBR_ADV, 0, sizeof(ndp_nbr_adv_t)); |
|
|
|
|
|
|
|
|
|
if (pkt != NULL) { |
|
|
|
|
ng_ndp_nbr_adv_t *nbr_adv = pkt->data; |
|
|
|
|
nbr_adv->flags = (flags & NG_NDP_NBR_ADV_FLAGS_MASK); |
|
|
|
|
ndp_nbr_adv_t *nbr_adv = pkt->data; |
|
|
|
|
nbr_adv->flags = (flags & NDP_NBR_ADV_FLAGS_MASK); |
|
|
|
|
nbr_adv->resv[0] = nbr_adv->resv[1] = nbr_adv->resv[2] = 0; |
|
|
|
|
nbr_adv->tgt.u64[0].u64 = tgt->u64[0].u64; |
|
|
|
|
nbr_adv->tgt.u64[1].u64 = tgt->u64[1].u64; |
|
|
|
@ -410,7 +410,7 @@ static inline size_t _ceil8(uint8_t length)
|
|
|
|
|
|
|
|
|
|
ng_pktsnip_t *ng_ndp_opt_build(uint8_t type, size_t size, ng_pktsnip_t *next) |
|
|
|
|
{ |
|
|
|
|
ng_ndp_opt_t *opt; |
|
|
|
|
ndp_opt_t *opt; |
|
|
|
|
ng_pktsnip_t *pkt = ng_pktbuf_add(next, NULL, _ceil8(size), NG_NETTYPE_UNDEF); |
|
|
|
|
|
|
|
|
|
if (pkt == NULL) { |
|
|
|
@ -429,13 +429,13 @@ ng_pktsnip_t *ng_ndp_opt_build(uint8_t type, size_t size, ng_pktsnip_t *next)
|
|
|
|
|
static inline ng_pktsnip_t *_opt_l2a_build(uint8_t type, const uint8_t *l2addr, |
|
|
|
|
uint8_t l2addr_len, ng_pktsnip_t *next) |
|
|
|
|
{ |
|
|
|
|
ng_pktsnip_t *pkt = ng_ndp_opt_build(type, sizeof(ng_ndp_opt_t) + l2addr_len, |
|
|
|
|
ng_pktsnip_t *pkt = ng_ndp_opt_build(type, sizeof(ndp_opt_t) + l2addr_len, |
|
|
|
|
next); |
|
|
|
|
|
|
|
|
|
if (pkt != NULL) { |
|
|
|
|
ng_ndp_opt_t *l2a_opt = pkt->data; |
|
|
|
|
ndp_opt_t *l2a_opt = pkt->data; |
|
|
|
|
|
|
|
|
|
memset(l2a_opt + 1, 0, pkt->size - sizeof(ng_ndp_opt_t)); |
|
|
|
|
memset(l2a_opt + 1, 0, pkt->size - sizeof(ndp_opt_t)); |
|
|
|
|
memcpy(l2a_opt + 1, l2addr, l2addr_len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -448,7 +448,7 @@ ng_pktsnip_t *ng_ndp_opt_sl2a_build(const uint8_t *l2addr, uint8_t l2addr_len,
|
|
|
|
|
DEBUG("ndp: building source link-layer address option (l2addr: %s)\n", |
|
|
|
|
ng_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr, l2addr_len)); |
|
|
|
|
|
|
|
|
|
return _opt_l2a_build(NG_NDP_OPT_SL2A, l2addr, l2addr_len, next); |
|
|
|
|
return _opt_l2a_build(NDP_OPT_SL2A, l2addr, l2addr_len, next); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ng_pktsnip_t *ng_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len, |
|
|
|
@ -457,7 +457,7 @@ ng_pktsnip_t *ng_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len,
|
|
|
|
|
DEBUG("ndp: building target link-layer address option (l2addr: %s)\n", |
|
|
|
|
ng_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr, l2addr_len)); |
|
|
|
|
|
|
|
|
|
return _opt_l2a_build(NG_NDP_OPT_TL2A, l2addr, l2addr_len, next); |
|
|
|
|
return _opt_l2a_build(NDP_OPT_TL2A, l2addr, l2addr_len, next); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|