Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}