IEEE 802.15.4: Support the MPX IE defined by IEEE 802.15.9
authorRobert Sauter <sauter@locoslab.com>
Tue, 11 Jul 2017 09:32:22 +0000 (11:32 +0200)
committerAnders Broman <a.broman58@gmail.com>
Thu, 13 Jul 2017 04:08:43 +0000 (04:08 +0000)
Still open: Reassembly and support for KMP payload dissection besides EAPOL

Bug: 13883
Change-Id: I48a1e6af5c6fb5594fb4e6a5258db0d8ebaf4a70
Reviewed-on: https://code.wireshark.org/review/22597
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
epan/dissectors/packet-ieee802154.c
epan/dissectors/packet-ieee802154.h

index f0fbef7351cda72e8f41eea21776c7472429eb0c..428153b52feaeb78f4db8bc73f90fb0c744c53ae 100644 (file)
@@ -71,6 +71,8 @@
 #include <epan/to_str.h>
 #include <epan/show_exception.h>
 #include <epan/proto_data.h>
+#include <epan/etypes.h>
+#include <epan/oui.h>
 #include <wsutil/pint.h>
 
 /* Use libgcrypt for cipher libraries. */
@@ -273,7 +275,7 @@ static void dissect_ieee802154_common       (tvbuff_t *, packet_info *, proto_tr
 
 /* Information Elements */
 static void dissect_ieee802154_header_ie       (tvbuff_t *, packet_info *, proto_tree *, guint *, ieee802154_packet *);
-static int  dissect_ieee802154_payload_ie      (tvbuff_t *, packet_info *, proto_tree *, guint);
+static int  dissect_ieee802154_payload_ie      (tvbuff_t *, packet_info *, proto_tree *, guint, proto_tree *);
 static void dissect_802154_enhanced_beacon_filter(tvbuff_t *tvb, proto_tree *subtree, guint16 psie_remaining, gint *offset);
 static void dissect_802154_tsch_time_sync(tvbuff_t *, proto_tree *, int *, guint);
 static void dissect_802154_tsch_timeslot(tvbuff_t *, proto_tree *, guint, guint16, gint*);
@@ -407,6 +409,18 @@ static int hf_ieee802154_6top_slot_offset = -1;
 static int hf_ieee802154_6top_channel_offset = -1;
 static int hf_ieee802154_6top_total_num_cells = -1;
 
+static int hf_ieee802159_mpx = -1;
+static int hf_ieee802159_mpx_transaction_control = -1;
+static int hf_ieee802159_mpx_transfer_type = -1;
+static int hf_ieee802159_mpx_transaction_id = -1;
+static int hf_ieee802159_mpx_transaction_id_as_multiplex_id = -1;
+static int hf_ieee802159_mpx_fragment_number = -1;
+static int hf_ieee802159_mpx_total_frame_size = -1;
+static int hf_ieee802159_mpx_multiplex_id = -1;
+static int hf_ieee802159_mpx_kmp_id = -1;
+static int hf_ieee802159_mpx_kmp_vendor_oui = -1;
+static int hf_ieee802159_mpx_fragment = -1;
+
 static int proto_zboss = -1;
 static int hf_zboss_direction = -1;
 static int hf_zboss_page = -1;
@@ -530,6 +544,8 @@ static gint ett_ieee802154_p_ie_6top_cell_list = -1;
 static gint ett_ieee802154_p_ie_6top_cand_cell_list = -1;
 static gint ett_ieee802154_p_ie_6top_rel_cell_list = -1;
 static gint ett_ieee802154_p_ie_6top_cell = -1;
+static gint ett_ieee802159_mpx = -1;
+static gint ett_ieee802159_mpx_transaction_control = -1;
 
 static expert_field ei_ieee802154_invalid_addressing = EI_INIT;
 /* static expert_field ei_ieee802154_invalid_panid_compression = EI_INIT; */
@@ -548,6 +564,9 @@ static expert_field ei_ieee802154_6top_unsupported_command = EI_INIT;
 static expert_field ei_ieee802154_ie_unsupported_element_id = EI_INIT;
 static expert_field ei_ieee802154_ie_unknown_element_id = EI_INIT;
 static expert_field ei_ieee802154_ie_unknown_extra_content = EI_INIT;
+static expert_field ei_ieee802159_mpx_invalid_transfer_type = EI_INIT;
+static expert_field ei_ieee802159_mpx_unsupported_kmp = EI_INIT;
+static expert_field ei_ieee802159_mpx_unknown_kmp = EI_INIT;
 
 static int ieee802_15_4_short_address_type = -1;
 /*
@@ -567,6 +586,9 @@ static dissector_handle_t  ieee802154_handle;
 static dissector_handle_t  ieee802154_nonask_phy_handle;
 static dissector_handle_t  ieee802154_nofcs_handle;
 
+static dissector_table_t ethertype_table;  // for the MPX-IE
+static dissector_handle_t eapol_handle;  // for the MPX-IE
+
 /* Versions */
 static const value_string ieee802154_frame_versions[] = {
     { IEEE802154_VERSION_2003,     "IEEE Std 802.15.4-2003" },
@@ -710,6 +732,7 @@ static const value_string ieee802154_payload_ie_names[] = {
     { IEEE802154_PAYLOAD_IE_ESDU,                     "ESDU IE" },
     { IEEE802154_PAYLOAD_IE_MLME,                     "MLME IE" },
     { IEEE802154_PAYLOAD_IE_VENDOR,                   "Vendor Specific IE" },
+    { IEEE802154_PAYLOAD_IE_MPX,                      "MPX IE" },
     { IEEE802154_PAYLOAD_IE_IETF,                     "IETF IE" },
     { IEEE802154_PAYLOAD_IE_TERMINATION,              "Payload Termination IE" },
     { 0, NULL }
@@ -833,6 +856,33 @@ static const value_string ietf_6top_cell_options[] = {
     { 0, NULL}
 };
 
+static const value_string mpx_transfer_type_vals[] = {
+    { IEEE802159_MPX_FULL_FRAME, "Full Frame" },
+    { IEEE802159_MPX_FULL_FRAME_NO_MUXID, "Full frame with compressed Multiplex ID" },
+    { IEEE802159_MPX_NON_LAST_FRAGMENT, "Non-last Fragment" },
+    { IEEE802159_MPX_LAST_FRAGMENT, "Last Fragment" },
+    { IEEE802159_MPX_ABORT, "Abort" },
+    { 0, NULL }
+};
+
+static const value_string mpx_multiplex_id_vals[] = {
+    { IEEE802159_MPX_MULTIPLEX_ID_KMP, "KMP" },
+    { 0, NULL }
+};
+
+static const value_string mpx_kmp_id_vals[] = {
+    { IEEE802159_MPX_KMP_ID_IEEE8021X, "IEEE 802.1X/MKA" },
+    { IEEE802159_MPX_KMP_ID_HIP, "HIP" },
+    { IEEE802159_MPX_KMP_ID_IKEV2, "IKEv2" },
+    { IEEE802159_MPX_KMP_ID_PANA, "PANA" },
+    { IEEE802159_MPX_KMP_ID_DRAGONFLY, "Dragonfly" },
+    { IEEE802159_MPX_KMP_ID_IEEE80211_4WH, "IEEE 802.11/4WH" },
+    { IEEE802159_MPX_KMP_ID_IEEE80211_GKH, "IEEE 802.11/GKH" },
+    { IEEE802159_MPX_KMP_ID_ETSI_TS_102_887_2, "ETSI TS 102 887-2" },
+    { IEEE802159_MPX_KMP_ID_VENDOR_SPECIFIC, "Vendor-specific" },
+    { 0, NULL }
+};
+
 static const int * header_short_format_nested_ie[] = {
     &hf_ieee802154_psie_type_short,
     &hf_ieee802154_psie_id_short,
@@ -1850,7 +1900,7 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
 
     /* Presence of Payload IEs is defined by the termination of the Header IEs */
     if (packet->payload_ie_present) {
-        offset += dissect_ieee802154_payload_ie(payload_tvb, pinfo, ieee802154_tree, offset);
+        offset += dissect_ieee802154_payload_ie(payload_tvb, pinfo, ieee802154_tree, offset, tree);
     }
 
     if ((packet->version == IEEE802154_VERSION_2015) && (packet->frame_type == IEEE802154_FCF_CMD)) {
@@ -2930,6 +2980,134 @@ dissect_802154_enhanced_beacon_filter(tvbuff_t *tvb, proto_tree *tree, guint16 p
     }
 }
 
+/**
+ * Subdissector for MPX IEs (IEEE 802.15.9)
+ *
+ * @param tvb the tv buffer
+ * @param pinfo packet info
+ * @param tree the tree to append this item to
+ * @param top_level_tree the top level tree used for displaying payload content
+ */
+static guint
+dissect_mpx_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *top_level_tree)
+{
+    static const int * fields[] = {
+            &hf_ieee802159_mpx_transaction_id,
+            &hf_ieee802159_mpx_transfer_type,
+            NULL
+    };
+    static const int * fields_compressed_multiplex_id[] = {
+            &hf_ieee802159_mpx_transaction_id_as_multiplex_id,
+            &hf_ieee802159_mpx_transfer_type,
+            NULL
+    };
+
+    guint offset = 0;
+    guint8 transaction_control = tvb_get_guint8(tvb, offset);
+    guint8 transfer_type = (guint8) (transaction_control & IEEE802159_MPX_TRANSFER_TYPE_MASK);
+    guint8 transaction_id = (guint8) ((transaction_control & IEEE802159_MPX_TRANSACTION_ID_MASK) >> IEEE802159_MPX_TRANSACTION_ID_SHIFT);
+    gint32 multiplex_id = -1;
+    guint8 fragment_number;
+
+    if (transfer_type == IEEE802159_MPX_FULL_FRAME_NO_MUXID) {
+        proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee802159_mpx_transaction_control, ett_ieee802159_mpx_transaction_control,
+                               fields_compressed_multiplex_id, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
+        multiplex_id = transaction_id;
+    } else {
+        proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee802159_mpx_transaction_control, ett_ieee802159_mpx_transaction_control,
+                               fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS);
+    }
+    offset += 1;
+
+    switch (transfer_type) {  // cf. IEEE 802.15.9 Table 18 - Summary of different MPX IE formats
+        case IEEE802159_MPX_FULL_FRAME:
+            proto_tree_add_item(tree, hf_ieee802159_mpx_multiplex_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+            multiplex_id = tvb_get_letohs(tvb, offset);
+            offset += 2;
+            break;
+        case IEEE802159_MPX_FULL_FRAME_NO_MUXID:
+            break;  // nothing to do
+        case IEEE802159_MPX_NON_LAST_FRAGMENT:
+            fragment_number = tvb_get_guint8(tvb, offset);
+            proto_tree_add_item(tree, hf_ieee802159_mpx_fragment_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            offset += 1;
+            if (fragment_number == 0) {
+                proto_tree_add_item(tree, hf_ieee802159_mpx_total_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+                offset += 2;
+                multiplex_id = tvb_get_letohs(tvb, offset);
+                proto_tree_add_item(tree, hf_ieee802159_mpx_multiplex_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+                offset += 2;
+            }
+            break;
+        case IEEE802159_MPX_LAST_FRAGMENT:
+            proto_tree_add_item(tree, hf_ieee802159_mpx_fragment_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+            offset += 1;
+            break;
+        case IEEE802159_MPX_ABORT:
+            if (tvb_reported_length_remaining(tvb, offset) == 2) {
+                proto_tree_add_item(tree, hf_ieee802159_mpx_total_frame_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+                offset += 2;
+            }
+            return offset;
+        default:  // reserved values -> warning and return
+            expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_invalid_transfer_type);
+            return offset;
+    }
+
+    // TODO: reassembly
+
+    dissector_handle_t dissector = NULL;
+
+    if (multiplex_id == IEEE802159_MPX_MULTIPLEX_ID_KMP) {
+        guint8 kmp_id = tvb_get_guint8(tvb, offset);
+        proto_tree_add_item(tree, hf_ieee802159_mpx_kmp_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+        offset += 1;
+        switch (kmp_id) {
+            case IEEE802159_MPX_KMP_ID_IEEE8021X:
+                dissector = eapol_handle;
+                break;
+
+            // TODO
+            case IEEE802159_MPX_KMP_ID_HIP:
+            case IEEE802159_MPX_KMP_ID_IKEV2:
+            case IEEE802159_MPX_KMP_ID_PANA:
+            case IEEE802159_MPX_KMP_ID_DRAGONFLY:
+            case IEEE802159_MPX_KMP_ID_IEEE80211_4WH:
+            case IEEE802159_MPX_KMP_ID_IEEE80211_GKH:
+            case IEEE802159_MPX_KMP_ID_ETSI_TS_102_887_2:
+                expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unsupported_kmp);
+                break;
+
+            case IEEE802159_MPX_KMP_ID_VENDOR_SPECIFIC:
+                proto_tree_add_item(tree, hf_ieee802159_mpx_kmp_vendor_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
+                offset += 3;
+                break;
+
+            // Unknown
+            default:
+                expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_ieee802159_mpx_unknown_kmp);
+        }
+    }
+
+    if (transfer_type == IEEE802159_MPX_FULL_FRAME || transfer_type == IEEE802159_MPX_FULL_FRAME_NO_MUXID) {
+        tvbuff_t * payload = tvb_new_subset_remaining(tvb, offset);
+        if (multiplex_id > 1500) {
+            dissector = dissector_get_uint_handle(ethertype_table, (guint)multiplex_id);
+        }
+        if (dissector) {
+            call_dissector(dissector, payload, pinfo, top_level_tree);  // exceptions are caught in our caller
+        } else {
+            call_data_dissector(payload, pinfo, top_level_tree);
+        }
+    } else {
+        proto_tree_add_item(tree, hf_ieee802159_mpx_fragment, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA);
+    }
+    offset = tvb_reported_length(tvb);
+
+    return offset;
+}
+
+
 /**
  * Subdissector for Vendor Specific IEs (Information Elements)
  *
@@ -2975,9 +3153,10 @@ dissect_ieee802154_vendor_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
  * @param pinfo pointer to packet information fields (unused).
  * @param tree pointer to command subtree.
  * @param orig_offset offset into the tvbuff to begin dissection.
+ * @param top_level_tree the top level tree used for displaying payload content
  */
 static int
-dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint orig_offset)
+dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint orig_offset, proto_tree *top_level_tree)
 {
     // GCC emits a spurious -Wclobbered if offset is used as function parameter (even with volatile)
     volatile guint offset = orig_offset;
@@ -3035,6 +3214,14 @@ dissect_ieee802154_payload_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
                     consumed = dissect_ieee802154_vendor_ie(content, pinfo, subtree);
                     break;
 
+                case IEEE802154_PAYLOAD_IE_MPX:
+                    // IEEE 802.15.9
+                    subitem = proto_tree_add_item(ies_tree, hf_ieee802159_mpx, tvb, offset, length + 2, ENC_NA);
+                    subtree = proto_item_add_subtree(subitem, ett_ieee802159_mpx);
+                    proto_tree_add_bitmask(subtree, tvb, offset, hf_ieee802154_payload_ie_tlv, ett_ieee802154_payload_ie_tlv, fields, ENC_LITTLE_ENDIAN);
+                    consumed = dissect_mpx_ie(content, pinfo, subtree, top_level_tree);
+                    break;
+
                 case IEEE802154_PAYLOAD_IE_IETF:
                     // RFC 8137: IEEE 802.15.4 Information Element for the IETF
                     subitem = proto_tree_add_item(ies_tree, hf_ieee802154_pie_ietf, tvb, offset, length + 2, ENC_NA);
@@ -4541,6 +4728,63 @@ void proto_register_ieee802154(void)
         { "Total Number of Cells", "wpan.6top_total_num_cells", FT_UINT16, BASE_DEC, NULL, 0x0,
           NULL, HFILL }},
 
+        /* MPX IE (IEEE 802.15.9) */
+        { &hf_ieee802159_mpx,
+          { "MPX IE", "wpan.mpx", FT_NONE, BASE_NONE, NULL, 0x0,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_transaction_control,
+          { "Transaction Control", "wpan.mpx.transaction_control", FT_UINT8, BASE_HEX, NULL, 0x0,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_transfer_type,
+          { "Transfer Type", "wpan.mpx.transfer_type", FT_UINT8, BASE_HEX, VALS(mpx_transfer_type_vals), IEEE802159_MPX_TRANSFER_TYPE_MASK,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_transaction_id,
+          { "Transaction ID", "wpan.mpx.transaction_id", FT_UINT8, BASE_HEX, NULL, IEEE802159_MPX_TRANSACTION_ID_MASK,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_transaction_id_as_multiplex_id,
+          { "Multiplex ID", "wpan.mpx.multiplex_id", FT_UINT8, BASE_HEX, VALS(mpx_multiplex_id_vals), IEEE802159_MPX_TRANSACTION_ID_MASK,
+            "Transaction ID used as Multiplex ID", HFILL }
+        },
+
+        { &hf_ieee802159_mpx_fragment_number,
+          { "Fragment Number", "wpan.mpx.fragment_number", FT_UINT8, BASE_DEC, NULL, 0x0,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_total_frame_size,
+          { "Total Frame Size", "wpan.mpx.total_frame_size", FT_UINT16, BASE_DEC, NULL, 0x0,
+            "Total Upper-Layer Frame Size", HFILL }
+        },
+
+        { &hf_ieee802159_mpx_multiplex_id,
+          { "Multiplex ID", "wpan.mpx.multiplex_id", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_kmp_id,
+          { "KMP ID", "wpan.mpx.kmp.id", FT_UINT8, BASE_DEC, VALS(mpx_kmp_id_vals), 0x0,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_kmp_vendor_oui,
+          { "Vendor OUI", "wpan.mpx.kmp.vendor_oui", FT_UINT24, BASE_HEX, VALS(oui_vals), 0x0,
+            NULL, HFILL }
+        },
+
+        { &hf_ieee802159_mpx_fragment,
+          { "Upper-Layer Frame Fragment", "wpan.mpx.fragment", FT_BYTES, SEP_SPACE, NULL, 0x0,
+            NULL, HFILL }
+        },
+
+
         /* Command Frame Specific Fields */
 
         { &hf_ieee802154_cmd_id,
@@ -4785,6 +5029,8 @@ void proto_register_ieee802154(void)
         &ett_ieee802154_payload_ie_tlv,
         &ett_ieee802154_pie_termination,
         &ett_ieee802154_pie_vendor,
+        &ett_ieee802159_mpx,
+        &ett_ieee802159_mpx_transaction_control,
         &ett_ieee802154_pie_ietf,
         &ett_ieee802154_pie_unknown,
         &ett_ieee802154_tsch_timeslot,
@@ -4849,6 +5095,12 @@ void proto_register_ieee802154(void)
                 "Unknown IE element ID", EXPFILL }},
         { &ei_ieee802154_ie_unknown_extra_content, { "wpan.ie_unknown_extra_content", PI_PROTOCOL, PI_WARN,
                 "Unexpected extra content for IE", EXPFILL }},
+        { &ei_ieee802159_mpx_invalid_transfer_type, { "wpan.payload_ie.mpx.invalid_transfer_type", PI_PROTOCOL, PI_WARN,
+                "Invalid transfer type (cf. IEEE 802.15.9 Table 19)", EXPFILL }},
+        { &ei_ieee802159_mpx_unsupported_kmp, { "wpan.payload_ie.mpx.invalid_transfer_type", PI_PROTOCOL, PI_WARN,
+                "Unsupported KMP ID", EXPFILL }},
+        { &ei_ieee802159_mpx_unknown_kmp, { "wpan.payload_ie.mpx.invalid_transfer_type", PI_PROTOCOL, PI_WARN,
+                "Unknown KMP ID (cf. IEEE 802.15.9 Table 21)", EXPFILL }},
     };
 
     /* Preferences. */
@@ -5027,6 +5279,10 @@ void proto_reg_handoff_ieee802154(void)
 
     /* Register dissector handles. */
     dissector_add_uint("ethertype", ieee802154_ethertype, ieee802154_handle);
+
+    /* For the MPX-IE */
+    ethertype_table = find_dissector_table("ethertype");
+    eapol_handle = find_dissector("eapol");
 } /* proto_reg_handoff_ieee802154 */
 
 /*
index 7295512427ae181f0d8c7e6415bd166edd6b0700..a8eacc06459de43f42d38f3c378e1a2f0ec7174e 100644 (file)
@@ -255,7 +255,8 @@ typedef enum {
 #define IEEE802154_PAYLOAD_IE_ESDU           0x0 /* Encapsulated Service Data Unit */
 #define IEEE802154_PAYLOAD_IE_MLME           0x1 /* Media Access Control (MAC) subLayer Management Entity */
 #define IEEE802154_PAYLOAD_IE_VENDOR         0x2 /* Vendor Specific */
-/* Reserved 0x3-0x4 */
+#define IEEE802154_PAYLOAD_IE_MPX            0x3 /* MPX IE (802.15.9) */
+/* Reserved 0x4 */
 #define IEEE802154_PAYLOAD_IE_IETF           0x5 /* IETF IE, RFC 8137 */
 /* Reserved 0x6-0xe */
 #define IEEE802154_PAYLOAD_IE_TERMINATION    0xf
@@ -345,6 +346,29 @@ typedef enum {
 #define IETF_6TOP_CELL_OPTION_SHARED   0x04
 #define IETF_6TOP_CELL_OPTION_RESERVED 0xF8
 
+/* IEEE 802.15.9 MPX IE */
+#define IEEE802159_MPX_TRANSFER_TYPE_MASK      0x07
+#define IEEE802159_MPX_TRANSACTION_ID_MASK     0xf8
+#define IEEE802159_MPX_TRANSACTION_ID_SHIFT    0x03
+/* IEEE 802.15.9 Table 19 */
+#define IEEE802159_MPX_FULL_FRAME                 0
+#define IEEE802159_MPX_FULL_FRAME_NO_MUXID        1
+#define IEEE802159_MPX_NON_LAST_FRAGMENT          2
+#define IEEE802159_MPX_LAST_FRAGMENT              4
+#define IEEE802159_MPX_ABORT                      6
+/* IEEE 802.15.9 Table 20 */
+#define IEEE802159_MPX_MULTIPLEX_ID_KMP           1
+/* IEEE 802.15.9 Table 21 */
+#define IEEE802159_MPX_KMP_ID_IEEE8021X           1
+#define IEEE802159_MPX_KMP_ID_HIP                 2
+#define IEEE802159_MPX_KMP_ID_IKEV2               3
+#define IEEE802159_MPX_KMP_ID_PANA                4
+#define IEEE802159_MPX_KMP_ID_DRAGONFLY           5
+#define IEEE802159_MPX_KMP_ID_IEEE80211_4WH       6
+#define IEEE802159_MPX_KMP_ID_IEEE80211_GKH       7
+#define IEEE802159_MPX_KMP_ID_ETSI_TS_102_887_2   8
+#define IEEE802159_MPX_KMP_ID_VENDOR_SPECIFIC   255
+
 /*  Structure containing information regarding all necessary packet fields. */
 typedef struct {
     /* Frame control field. */