Commit 4561ea0a authored by Stancu Florin's avatar Stancu Florin Committed by Christopher Friedt
Browse files

net: ieee802154: software dest address filtering



Checks PAN ID for matching self address / broadcast, then the short /
extended address based on the used address mode.

Only when IEEE802154_HW_FILTER is not advertised by driver.

Signed-off-by: default avatarStancu Florin <niflostancu@gmail.com>
parent 55e3c732
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -119,6 +119,66 @@ static inline void set_pkt_ll_addr(struct net_linkaddr *addr, bool comp,
	addr->type = NET_LINK_IEEE802154;
}

/**
 * Filters the destination address of the frame (used when IEEE802154_HW_FILTER
 * is not available).
 */
static bool ieeee802154_check_dst_addr(struct net_if *iface,
				      struct ieee802154_mhr *mhr)
{
	struct ieee802154_context *ctx = net_if_l2_data(iface);
	struct ieee802154_address_field_plain *dst_plain = &mhr->dst_addr->plain;

	/*
	 * Apply filtering requirements from chapter 6.7.2 of the IEEE
	 * 802.15.4-2015 standard:
	 */

	if (mhr->fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_NONE) {
		/* TODO: apply d.4 and d.5 when PAN coordinator is implemented */
		/* also, macImplicitBroadcast is not implemented */
		return false;
	}

	/*
	 * c. If a destination PAN ID is included in the frame, it shall match
	 * macPanId or shall be the broadcastPAN ID
	 */
	if (!(dst_plain->pan_id == IEEE802154_BROADCAST_PAN_ID ||
			dst_plain->pan_id == ctx->pan_id)) {
		LOG_DBG("Frame PAN ID does not match!");
		return false;
	}

	if (mhr->fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_SHORT) {
		/*
		 * d.1. A short destination address is included in the frame,
		 * and it matches either macShortAddress orthe broadcast
		 * address.
		 */
		if (!(dst_plain->addr.short_addr == IEEE802154_BROADCAST_ADDRESS ||
				dst_plain->addr.short_addr == ctx->short_addr)) {
			LOG_DBG("Frame dst address (short) does not match!");
			return false;
		}

	} else if (mhr->fs->fc.dst_addr_mode == IEEE802154_ADDR_MODE_EXTENDED) {
		/*
		 * An extended destination address is included in the frame and
		 * matches either macExtendedAddress or, if macGroupRxMode is
		 * set to TRUE, an 64-bit extended unique identifier (EUI-64)
		 * group address.
		 */
		if (memcmp(dst_plain->addr.ext_addr, ctx->ext_addr,
					IEEE802154_EXT_ADDR_LENGTH) != 0) {
			LOG_DBG("Frame dst address (ext) does not match!");
			return false;
		}
	}

	return true;
}

#ifdef CONFIG_NET_6LO
static inline
enum net_verdict ieee802154_manage_recv_packet(struct net_if *iface,
@@ -166,6 +226,8 @@ out:
static enum net_verdict ieee802154_recv(struct net_if *iface,
					struct net_pkt *pkt)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->api;
	struct ieee802154_mpdu mpdu;
	size_t hdr_len;

@@ -174,6 +236,12 @@ static enum net_verdict ieee802154_recv(struct net_if *iface,
		return NET_DROP;
	}

	/* validate LL destination address (when IEEE802154_HW_FILTER not available) */
	if (!(radio->get_capabilities(net_if_get_device(iface)) & IEEE802154_HW_FILTER) &&
			!ieeee802154_check_dst_addr(iface, &mpdu.mhr)) {
		return NET_DROP;
	}

	if (mpdu.mhr.fs->fc.frame_type == IEEE802154_FRAME_TYPE_ACK) {
		return NET_DROP;
	}