uint16_t ieee802154_compute_header_size(struct net_if *iface, struct in6_addr *dst) { uint16_t hdr_len = sizeof(struct ieee802154_fcf_seq); /** if dst is NULL, we'll consider it as a brodcast header */ if (!dst || net_is_ipv6_addr_mcast(dst) || net_is_ipv6_addr_unspecified(dst)) { /* 4 dst pan/addr + 8 src addr */ hdr_len += IEEE802154_PAN_ID_LENGTH + IEEE802154_SHORT_ADDR_LENGTH + IEEE802154_EXT_ADDR_LENGTH; } else { struct net_nbr *nbr; nbr = net_ipv6_nbr_lookup(iface, dst); if (nbr) { /* ToDo: handle short addresses */ /* dst pan/addr + src addr */ hdr_len += IEEE802154_PAN_ID_LENGTH + (IEEE802154_EXT_ADDR_LENGTH * 2); } else { /* src pan/addr only */ hdr_len += IEEE802154_PAN_ID_LENGTH + IEEE802154_EXT_ADDR_LENGTH; } } /* Todo: handle security aux header */ NET_DBG("Computed size of %u", hdr_len); return hdr_len; }
static inline enum ieee802154_addressing_mode get_dst_addr_mode(struct net_if *iface, struct in6_addr *dst, struct net_nbr **nbr, bool *broadcast) { if (net_is_ipv6_addr_mcast(dst) || net_is_ipv6_addr_unspecified(dst)) { *broadcast = true; *nbr = NULL; return IEEE802154_ADDR_MODE_SHORT; } *broadcast = false; /* ToDo: Prefer short addr, when _associated_ to a PAN * if associated: * - Check if dst is known nb and has short addr * - if so, return short. */ *nbr = net_ipv6_nbr_lookup(iface, dst); if (!*nbr) { return IEEE802154_ADDR_MODE_NONE; } return IEEE802154_ADDR_MODE_EXTENDED; }
u16_t ieee802154_compute_header_size(struct net_if *iface, struct in6_addr *dst) { u16_t hdr_len = sizeof(struct ieee802154_fcf_seq); #ifdef CONFIG_NET_L2_IEEE802154_SECURITY struct ieee802154_security_ctx *sec_ctx = &((struct ieee802154_context *)net_if_l2_data(iface))->sec_ctx; #endif /** if dst is NULL, we'll consider it as a brodcast header */ if (!dst || net_is_ipv6_addr_mcast(dst) || net_is_ipv6_addr_unspecified(dst)) { NET_DBG("Broadcast destination"); /* 4 dst pan/addr + 8 src addr */ hdr_len += IEEE802154_PAN_ID_LENGTH + IEEE802154_SHORT_ADDR_LENGTH + IEEE802154_EXT_ADDR_LENGTH; if (IS_ENABLED(CONFIG_NET_L2_IEEE802154_SECURITY)) { NET_DBG("Broadcast packet do not have security"); goto done; } } else { struct net_nbr *nbr; nbr = net_ipv6_nbr_lookup(iface, dst); if (nbr) { /* ToDo: handle short addresses */ /* dst pan/addr + src addr */ hdr_len += IEEE802154_PAN_ID_LENGTH + (IEEE802154_EXT_ADDR_LENGTH * 2); } else { /* src pan/addr only */ hdr_len += IEEE802154_PAN_ID_LENGTH + IEEE802154_EXT_ADDR_LENGTH; } } #ifdef CONFIG_NET_L2_IEEE802154_SECURITY if (sec_ctx->level == IEEE802154_SECURITY_LEVEL_NONE) { goto done; } /* Compute aux-sec hdr size and add it to hdr_len */ hdr_len += IEEE802154_SECURITY_CF_LENGTH + IEEE802154_SECURITY_FRAME_COUNTER_LENGTH; switch (sec_ctx->key_mode) { case IEEE802154_KEY_ID_MODE_IMPLICIT: /* The only mode supported for now, * generate_aux_securiy_hdr() will fail on other modes */ break; case IEEE802154_KEY_ID_MODE_INDEX: hdr_len += IEEE8021254_KEY_ID_FIELD_INDEX_LENGTH; break; case IEEE802154_KEY_ID_MODE_SRC_4_INDEX: hdr_len += IEEE8021254_KEY_ID_FIELD_SRC_4_INDEX_LENGTH; break; case IEEE802154_KEY_ID_MODE_SRC_8_INDEX: hdr_len += IEEE8021254_KEY_ID_FIELD_SRC_8_INDEX_LENGTH; } /* This is a _HACK_: as net pkt do not let the possibility to * reserve tailroom - here for authentication tag - it reserves * it in headroom so the payload won't occupy all the left space * and then when it will come to finalize the data frame it will * reduce the reserve space by the tag size, move the payload * backward accordingly, and only then: * run the encryption/authentication which will fill the tag * space in the end. */ if (sec_ctx->level < IEEE802154_SECURITY_LEVEL_ENC) { hdr_len += level_2_tag_size[sec_ctx->level]; } else { hdr_len += level_2_tag_size[sec_ctx->level - 4]; } #endif /* CONFIG_NET_L2_IEEE802154_SECURITY */ done: NET_DBG("Computed size of %u", hdr_len); return hdr_len; }