Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1da67b8 authored by Alexander Aring's avatar Alexander Aring Committed by Marcel Holtmann
Browse files

ieee802154: header_ops: fix frame control setting



Sometimes upper-layer protocols wants to generate a new mac header by
filling "struct ieee802154_hdr" only. These upper-layers sets for the
address settings the source and dest fields, but not the fc fields for
indicate the source and dest address mode. This patch changes the
"ieee802154_hdr_push" function so the fc address fields are set
according the source and dest fields of "struct ieee802154_hdr".

Signed-off-by: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent cdd38b21
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ struct ieee802154_hdr {
 * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
 * version, if SECEN is set.
 */
int ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr);
int ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr);

/* pulls the entire 802.15.4 header off of the skb, including the security
 * header, and performs pan id decompression
+9 −9
Original line number Diff line number Diff line
@@ -83,35 +83,35 @@ ieee802154_hdr_push_sechdr(u8 *buf, const struct ieee802154_sechdr *hdr)
}

int
ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr)
{
	u8 buf[MAC802154_FRAME_HARD_HEADER_LEN];
	int pos = 2;
	int rc;
	struct ieee802154_hdr_fc fc = hdr->fc;
	struct ieee802154_hdr_fc *fc = &hdr->fc;

	buf[pos++] = hdr->seq;

	fc.dest_addr_mode = hdr->dest.mode;
	fc->dest_addr_mode = hdr->dest.mode;

	rc = ieee802154_hdr_push_addr(buf + pos, &hdr->dest, false);
	if (rc < 0)
		return -EINVAL;
	pos += rc;

	fc.source_addr_mode = hdr->source.mode;
	fc->source_addr_mode = hdr->source.mode;

	if (hdr->source.pan_id == hdr->dest.pan_id &&
	    hdr->dest.mode != IEEE802154_ADDR_NONE)
		fc.intra_pan = true;
		fc->intra_pan = true;

	rc = ieee802154_hdr_push_addr(buf + pos, &hdr->source, fc.intra_pan);
	rc = ieee802154_hdr_push_addr(buf + pos, &hdr->source, fc->intra_pan);
	if (rc < 0)
		return -EINVAL;
	pos += rc;

	if (fc.security_enabled) {
		fc.version = 1;
	if (fc->security_enabled) {
		fc->version = 1;

		rc = ieee802154_hdr_push_sechdr(buf + pos, &hdr->sec);
		if (rc < 0)
@@ -120,7 +120,7 @@ ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
		pos += rc;
	}

	memcpy(buf, &fc, 2);
	memcpy(buf, fc, 2);

	memcpy(skb_push(skb, pos), buf, pos);