]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/ieee802154/header_ops.c
ieee802154: add definitions for link-layer security and header functions
[mirror_ubuntu-bionic-kernel.git] / net / ieee802154 / header_ops.c
index bed42a48408c6cc71cf4a47ba5bd897603cfaf7b..c09294e39ca60326d5b40c8431bf202ce5559225 100644 (file)
@@ -195,15 +195,16 @@ ieee802154_hdr_get_sechdr(const u8 *buf, struct ieee802154_sechdr *hdr)
        return pos;
 }
 
+static int ieee802154_sechdr_lengths[4] = {
+       [IEEE802154_SCF_KEY_IMPLICIT] = 5,
+       [IEEE802154_SCF_KEY_INDEX] = 6,
+       [IEEE802154_SCF_KEY_SHORT_INDEX] = 10,
+       [IEEE802154_SCF_KEY_HW_INDEX] = 14,
+};
+
 static int ieee802154_hdr_sechdr_len(u8 sc)
 {
-       switch (IEEE802154_SCF_KEY_ID_MODE(sc)) {
-       case IEEE802154_SCF_KEY_IMPLICIT: return 5;
-       case IEEE802154_SCF_KEY_INDEX: return 6;
-       case IEEE802154_SCF_KEY_SHORT_INDEX: return 10;
-       case IEEE802154_SCF_KEY_HW_INDEX: return 14;
-       default: return -EINVAL;
-       }
+       return ieee802154_sechdr_lengths[IEEE802154_SCF_KEY_ID_MODE(sc)];
 }
 
 static int ieee802154_hdr_minlen(const struct ieee802154_hdr *hdr)
@@ -285,3 +286,40 @@ ieee802154_hdr_peek_addrs(const struct sk_buff *skb, struct ieee802154_hdr *hdr)
        return pos;
 }
 EXPORT_SYMBOL_GPL(ieee802154_hdr_peek_addrs);
+
+int
+ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr)
+{
+       const u8 *buf = skb_mac_header(skb);
+       int pos;
+
+       pos = ieee802154_hdr_peek_addrs(skb, hdr);
+       if (pos < 0)
+               return -EINVAL;
+
+       if (hdr->fc.security_enabled) {
+               u8 key_id_mode = IEEE802154_SCF_KEY_ID_MODE(*(buf + pos));
+               int want = pos + ieee802154_sechdr_lengths[key_id_mode];
+
+               if (buf + want > skb_tail_pointer(skb))
+                       return -EINVAL;
+
+               pos += ieee802154_hdr_get_sechdr(buf + pos, &hdr->sec);
+       }
+
+       return pos;
+}
+EXPORT_SYMBOL_GPL(ieee802154_hdr_peek);
+
+int ieee802154_max_payload(const struct ieee802154_hdr *hdr)
+{
+       int hlen = ieee802154_hdr_minlen(hdr);
+
+       if (hdr->fc.security_enabled) {
+               hlen += ieee802154_sechdr_lengths[hdr->sec.key_id_mode] - 1;
+               hlen += ieee802154_sechdr_authtag_len(&hdr->sec);
+       }
+
+       return IEEE802154_MTU - hlen - IEEE802154_MFR_SIZE;
+}
+EXPORT_SYMBOL_GPL(ieee802154_max_payload);