diff options
-rw-r--r-- | epan/dissectors/packet-ieee802154.c | 495 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee802154.h | 6 |
2 files changed, 273 insertions, 228 deletions
diff --git a/epan/dissectors/packet-ieee802154.c b/epan/dissectors/packet-ieee802154.c index bbb9d2d1de..1ac9e228db 100644 --- a/epan/dissectors/packet-ieee802154.c +++ b/epan/dissectors/packet-ieee802154.c @@ -317,15 +317,20 @@ static int hf_ieee802154_ie_present = -1; static int hf_ieee802154_src_addr_mode = -1; static int hf_ieee802154_version = -1; static int hf_ieee802154_dst_addr_mode = -1; -static int hf_ieee802154_header_ie = -1; +static int hf_ieee802154_header_ies = -1; +static int hf_ieee802154_header_ie_tlv = -1; static int hf_ieee802154_header_ie_type = -1; static int hf_ieee802154_header_ie_id = -1; static int hf_ieee802154_header_ie_length = -1; -static int hf_ieee802154_header_ie_tlv = -1; -static int hf_ieee802154_header_termination = -1; -static int hf_ieee802154_time_correction = -1; +static int hf_ieee802154_hie_unknown = -1; +static int hf_ieee802154_hie_unknown_content = -1; +static int hf_ieee802154_hie_unsupported = -1; +static int hf_ieee802154_hie_time_correction = -1; +static int hf_ieee802154_hie_ht1 = -1; +static int hf_ieee802154_hie_ht2 = -1; static int hf_ieee802154_nack = -1; -static int hf_ieee802154_time_correction_value = -1; +static int hf_ieee802154_hie_time_correction_time_sync_info = -1; +static int hf_ieee802154_hie_time_correction_value = -1; static int hf_ieee802154_payload_ie = -1; static int hf_ieee802154_mlme = -1; static int hf_ieee802154_payload_ie_tlv = -1; @@ -480,9 +485,14 @@ static gint ett_ieee802154_gts = -1; static gint ett_ieee802154_gts_direction = -1; static gint ett_ieee802154_gts_descriptors = -1; static gint ett_ieee802154_pendaddr = -1; -static gint ett_ieee802154_header = -1; +static gint ett_ieee802154_header_ies = -1; static gint ett_ieee802154_header_ie = -1; -static gint ett_ieee802154_h_ie_payload = -1; +static gint ett_ieee802154_header_ie_tlv = -1; +static gint ett_ieee802154_hie_unknown = -1; +static gint ett_ieee802154_hie_unsupported = -1; +static gint ett_ieee802154_hie_time_correction = -1; +static gint ett_ieee802154_hie_ht1 = -1; +static gint ett_ieee802154_hie_ht2 = -1; static gint ett_ieee802154_payload = -1; static gint ett_ieee802154_payload_ie = -1; static gint ett_ieee802154_mlme = -1; @@ -521,7 +531,9 @@ static expert_field ei_ieee802154_time_correction_error = EI_INIT; static expert_field ei_ieee802154_6top_unsupported_type = EI_INIT; static expert_field ei_ieee802154_6top_unsupported_return_code = EI_INIT; static expert_field ei_ieee802154_6top_unsupported_command = EI_INIT; -static expert_field ei_ieee802154_unsupported_element_id = 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 int ieee802_15_4_short_address_type = -1; /* @@ -648,33 +660,38 @@ static const value_string ieee802154_ie_types[] = { }; static const value_string ieee802154_psie_types[] = { - { 0, "Short" }, - { 1, "Long" }, + { 0, "Short" }, + { 1, "Long" }, { 0, NULL } }; static const value_string ieee802154_header_ie_names[] = { - { IEEE802154_HEADER_VENDOR_SPECIFIC, "Vendor Specific IE" }, - { IEEE802154_HEADER_IE_CSL, "CSL IE" }, - { IEEE802154_HEADER_IE_RIT, "RIT IE" }, - { IEEE802154_HEADER_IE_DSME_PAN, "DSME PAN descriptor IE" }, - { IEEE802154_HEADER_IE_RENDEZVOUS, "Rendezvous Time IE" }, - { IEEE802154_HEADER_IE_TIME_CORR, "Time Correction IE" }, - { IEEE802154_HEADER_IE_EXT_DSME_PAN, "Extended DSME PAN descriptor IE" }, - { IEEE802154_HEADER_IE_FSCD, "Fragment Sequence Context Description (FSCD) IE" }, - { IEEE802154_HEADER_IE_SMPL_SUPER_FRM, "Simplified Superframe Specification IE" }, - { IEEE802154_HEADER_IE_SMPL_GTS, "Simplified GTS Specification IE" }, - { IEEE802154_HEADER_IE_LECIM, "LECIM Capabilities IE" }, - { IEEE802154_HEADER_IE_TRLE, "TRLE Descriptor" }, - { IEEE802154_HEADER_IE_RCC_CAP, "RCC Capabilities IE" }, - { IEEE802154_HEADER_IE_RCCN, "RCCN Descriptor IE" }, - { IEEE802154_HEADER_IE_GLOBAL_TIME, "Global Time IE" }, - { IEEE802154_HEADER_IE_DA_IE, "DA IE" }, - { IEEE802154_HEADER_IE_EID_TERM1, "Header Termination 1" }, - { IEEE802154_HEADER_IE_EID_TERM2, "Header Termination 2" }, + { IEEE802154_HEADER_IE_VENDOR_SPECIFIC, "Vendor Specific IE" }, + { IEEE802154_HEADER_IE_CSL, "CSL IE" }, + { IEEE802154_HEADER_IE_RIT, "RIT IE" }, + { IEEE802154_HEADER_IE_DSME_PAN, "DSME PAN descriptor IE" }, + { IEEE802154_HEADER_IE_RENDEZVOUS, "Rendezvous Time IE" }, + { IEEE802154_HEADER_IE_TIME_CORR, "Time Correction IE" }, + { IEEE802154_HEADER_IE_EXT_DSME_PAN, "Extended DSME PAN descriptor IE" }, + { IEEE802154_HEADER_IE_FSCD, "Fragment Sequence Context Description (FSCD) IE" }, + { IEEE802154_HEADER_IE_SMPL_SUPER_FRM, "Simplified Superframe Specification IE" }, + { IEEE802154_HEADER_IE_SMPL_GTS, "Simplified GTS Specification IE" }, + { IEEE802154_HEADER_IE_LECIM, "LECIM Capabilities IE" }, + { IEEE802154_HEADER_IE_TRLE, "TRLE Descriptor" }, + { IEEE802154_HEADER_IE_RCC_CAP, "RCC Capabilities IE" }, + { IEEE802154_HEADER_IE_RCCN, "RCCN Descriptor IE" }, + { IEEE802154_HEADER_IE_GLOBAL_TIME, "Global Time IE" }, + { IEEE802154_HEADER_IE_DA_IE, "DA IE" }, + { IEEE802154_HEADER_IE_HT1, "Header Termination 1 IE" }, + { IEEE802154_HEADER_IE_HT2, "Header Termination 2 IE" }, { 0, NULL } }; +static const true_false_string hf_ieee802154_nack_tfs = { + "Negative Acknowledgement", + "Acknowledgement" +}; + static const value_string ieee802154_payload_ie_names[] = { { IEEE802154_PAYLOAD_IE_ESDU, "ESDU IE" }, { IEEE802154_PAYLOAD_IE_MLME, "MLME IE" }, @@ -1800,8 +1817,9 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g payload_tvb = tvb_new_subset_length_caplen(tvb, offset, captured_len, reported_len); } - /* presense of Payload IEs is defined by the termination of the Header IEs */ offset = 0; + + /* 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); } @@ -1955,53 +1973,6 @@ dissect_ieee802154_fcs: } /* dissect_ieee802154_common */ /** - *Subdissector command for the Header Information Element TSCH Time Correction - * - * This field is constructed by taking a signed 16-bit 2's compliment time - * correction in the range of - 2048 us to 2047 us, AND'ing it with 0xfff, and - * OR'ing again with 0x8000 to indicate a negative acknowledgment. - * - *@param tvb pointer to buffer containing raw packet. - *@param h_inf_elem_tree pointer to data tree wireshark uses to display packet. - *@param offset offset into the tvbuff to begin dissection. - */ -static void -dissect_802154_h_ie_time_correction(tvbuff_t *tvb, proto_tree *h_inf_elem_tree, guint offset, packet_info *pinfo) { - - guint16 raw_data; - proto_tree *time_correction_tree = NULL; - gboolean is_nack; - proto_item *time_correction_item = NULL; - proto_item *boolean_item = NULL; - proto_item *drift_item = NULL; - - raw_data = tvb_get_letohs(tvb, offset); - is_nack = (gboolean) ((raw_data & (guint16)0x8000) ? 1 : 0); - gint16 drift_us = 0; - - if(raw_data & 0x0800) { /* Negative integer */ - drift_us = (gint16) (raw_data | 0xf000); - } else { /* Positive integer */ - drift_us = (gint16) (raw_data & 0x0fff); - } - time_correction_item = proto_tree_add_bytes_format_value(h_inf_elem_tree, hf_ieee802154_time_correction, tvb, offset, 2, NULL, - "Time correction: %d us | Non-acknowledgement: %s", drift_us, (guint32) is_nack ? "True" : "False"); - time_correction_tree = proto_item_add_subtree(time_correction_item, ett_ieee802154_h_ie_payload); - - /* Valid time correct value */ - if(raw_data <= 0x8fff) { - drift_item = proto_tree_add_int(time_correction_tree, hf_ieee802154_time_correction_value, tvb, offset, 2, drift_us); - PROTO_ITEM_SET_GENERATED(drift_item); - boolean_item = proto_tree_add_boolean(time_correction_tree, hf_ieee802154_nack, tvb, offset, 2, (guint32) is_nack); - PROTO_ITEM_SET_GENERATED(boolean_item); - } - /* Incorrect value */ - else { - expert_add_info(pinfo, time_correction_item, &ei_ieee802154_time_correction_error); - } -} /* dissect_802154_h_ie_time_correction */ - -/** * Subdissector for the MLME Channel Hopping IE * * Reference: IEEE 802.15.4-2015 - 7.4.4.31 Channel hopping IE @@ -2453,168 +2424,207 @@ dissect_ieee802154_pendaddr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t } /* for */ } /* dissect_ieee802154_pendaddr */ +/* + * Header IEs + */ + /** - *Subdissector for Header IEs (Information Elements) - *Since the header is never encrypted and the payload may be encrypted, - *we dissect header and payload IEs separately. - *The termination of the Header IE tells us whether there are any - *payload IEs to follow, so it is always set by the termination. + * Create a tree for a Header IE including the TLV header * - *@param tvb pointer to buffer containing raw packet. - *@param pinfo pointer to packet information fields. - *@param tree pointer to command subtree. - *@param offset offset into the tvbuff to begin dissection. - *@param packet IEEE 802.15.4 packet information. + * @param tvb the tv buffer + * @param tree the tree to append this item to + * @param offset start of the IE (its TLV header) in tvb + * @param ie_length the content length of the Header IE + * @param hf field index + * @param ett tree index + * @param new_item pointer to store the item created for this Header IE + * @returns the tree created for the Header IE */ -static void -dissect_ieee802154_header_ie(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset, ieee802154_packet *packet) +static proto_tree* +create_header_ie_tree(tvbuff_t *tvb, proto_tree *tree, guint offset, guint ie_length, int hf, gint ett, proto_item** new_item) { + proto_item *subitem; proto_tree *subtree; - proto_item *header_item; - guint16 header_ie; - guint16 id; - guint16 length; - guint header_length; - - static const int * fields[] = { - &hf_ieee802154_header_ie_type, - &hf_ieee802154_header_ie_id, - &hf_ieee802154_header_ie_length, - NULL + static const int * tlv_fields[] = { + &hf_ieee802154_header_ie_type, + &hf_ieee802154_header_ie_id, + &hf_ieee802154_header_ie_length, + NULL }; - header_item = proto_tree_add_item(tree, hf_ieee802154_header_ie, tvb, *offset, -1, ENC_NA); - header_length = 0; - - do { - header_ie = tvb_get_letohs(tvb, *offset); - id = (guint16) ((header_ie & IEEE802154_HEADER_IE_ID_MASK) >> 7); - length = (guint16) (header_ie & IEEE802154_HEADER_IE_LENGTH_MASK); - header_length += 2 + length; - - /* until the Header IEs are finalized, just use the data dissector */ - if (length > 0) { - subtree = proto_item_add_subtree(header_item, ett_ieee802154_header); - proto_item_append_text(subtree, ", Element ID: %s, Length: %d", val_to_str_const(id, ieee802154_header_ie_names, "Unknown IE"), length); - proto_tree_add_bitmask(subtree, tvb, *offset, hf_ieee802154_header_ie_tlv, ett_ieee802154_header_ie, fields, ENC_LITTLE_ENDIAN); - *offset += 2; - - switch(id){ - - case IEEE802154_HEADER_IE_TIME_CORR: - // 7.4.2.7 Time Correction IE - dissect_802154_h_ie_time_correction(tvb, subtree, *offset, pinfo); - break; - - case IEEE802154_HEADER_VENDOR_SPECIFIC: - // 7.4.2.2 Vendor Specific Header IE - // TODO - - case IEEE802154_HEADER_IE_CSL: - // 7.4.2.3 CSL IE - // TODO - - case IEEE802154_HEADER_IE_RIT: - // 7.4.2.4 RIT IE - // TODO + subitem = proto_tree_add_item(tree, hf, tvb, offset, 2 + ie_length, ENC_NA); + subtree = proto_item_add_subtree(subitem, ett); - case IEEE802154_HEADER_IE_DSME_PAN: - // 7.4.2.5 DSME PAN descriptor IE - // TODO + proto_tree_add_bitmask_with_flags(subtree, tvb, offset, hf_ieee802154_header_ie_tlv, ett_ieee802154_header_ie_tlv, + tlv_fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); - case IEEE802154_HEADER_IE_RENDEZVOUS: - // 7.4.2.6 Rendezvous Time IE - - case IEEE802154_HEADER_IE_EXT_DSME_PAN: - // 7.4.2.8 Extended DSME PAN descriptor IE - // TODO - - case IEEE802154_HEADER_IE_FSCD: - // 7.4.2.9 Fragment Sequence Context Description (FSCD) IE - // TODO - - case IEEE802154_HEADER_IE_SMPL_SUPER_FRM: - // 7.4.2.10 Simplified Superframe Specification IE - // TODO - - case IEEE802154_HEADER_IE_SMPL_GTS: - // 7.4.2.11 Simplified GTS Specification IE - // TODO - - case IEEE802154_HEADER_IE_LECIM: - // 7.4.2.12 LECIM Capabilities IE - // TODO - - case IEEE802154_HEADER_IE_RCC_CAP: - // 7.4.2.13 RCC Capabilities IE - // TODO - - case IEEE802154_HEADER_IE_RCCN: - // 7.4.2.14 RCCN Descriptor IE - // TODO + *new_item = subitem; + return subtree; +} - case IEEE802154_HEADER_IE_GLOBAL_TIME: - // 7.4.2.15 Global Time IE - // TODO +/** + * Dissect the Time Correction Header IE (7.4.2.7) + * + * This field is constructed by taking a signed 16-bit 2's compliment time + * correction in the range of -2048 us to 2047 us, AND'ing it with 0xfff, and + * OR'ing again with 0x8000 to indicate a negative acknowledgment. + * + * @param tvb the tv buffer + * @param pinfo packet info used for expert info + * @param tree the tree to append this item to + * @param packet IEEE 802.15.4 packet information + * @param item the item for this Header IE + * @param ies_item the superordinate item for all Header IEs + * @returns the number of consumed bytes + */ +static guint16 +dissect_802154_hie_time_correction(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ieee802154_packet *packet _U_, + proto_item *item, proto_item *ies_item) +{ + static const int * fields[] = { + &hf_ieee802154_hie_time_correction_value, + &hf_ieee802154_nack, + NULL + }; + guint16 time_sync_value; + proto_tree_add_bitmask_with_flags(tree, tvb, 0, hf_ieee802154_hie_time_correction_time_sync_info, ett_ieee802154_header_ie, + fields, ENC_LITTLE_ENDIAN, BMT_NO_FLAGS); + time_sync_value = tvb_get_letohs(tvb, 0); + if (time_sync_value & ~(0x8fff)) { + expert_add_info(pinfo, item, &ei_ieee802154_time_correction_error); + } + if (time_sync_value & 0x8000) { + proto_item_append_text(ies_item, ": NACK"); + } + return 2; +} - case IEEE802154_HEADER_IE_DA_IE: - // 7.4.2.16 DA IE - // TODO +/** + * Subdissector for Header IEs (Information Elements) + * + * Since the header is never encrypted and the payload may be encrypted, + * we dissect header and payload IEs separately. + * The termination of the Header IE tells us whether there are any + * payload IEs to follow. + * + * @param tvb pointer to buffer containing raw packet. + * @param pinfo pointer to packet information fields. + * @param tree pointer to command subtree. + * @param offset offset into the tvbuff to begin dissection. + * @param packet IEEE 802.15.4 packet information. + */ +static void +dissect_ieee802154_header_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, ieee802154_packet *packet) +{ + proto_item *ies_item; + proto_tree *ies_tree; + proto_item *subitem; + proto_tree *volatile subtree; // may change in TRY block and is used in CATCH + tvbuff_t *content; + guint16 ie_header; + guint16 id; + guint16 length; + guint16 consumed; + const char *name; + volatile guint total_length = 0; // silence spurious -Wclobber warning - case IEEE802154_HEADER_IE_TRLE: - // ??????? - // TODO + ies_item = proto_tree_add_item(tree, hf_ieee802154_header_ies, tvb, *offset, -1, ENC_NA); + ies_tree = proto_item_add_subtree(ies_item, ett_ieee802154_header_ies); - default: - expert_add_info(pinfo, header_item, &ei_ieee802154_unsupported_element_id); + do { + ie_header = tvb_get_letohs(tvb, *offset); + id = (guint16) ((ie_header & IEEE802154_HEADER_IE_ID_MASK) >> 7); + length = (guint16) (ie_header & IEEE802154_HEADER_IE_LENGTH_MASK); + content = tvb_new_subset_length(tvb, *offset + 2, length); + name = try_val_to_str(id, ieee802154_header_ie_names); + total_length += 2 + length; + + subtree = NULL; // for checking in catch block if already created + + TRY { // primarily to catch out-of-bounds exceptions if a IE is expected to have more content + switch (id) { + case IEEE802154_HEADER_IE_HT1: + proto_item_append_text(ies_item, ", %s", name); + subtree = create_header_ie_tree(tvb, ies_tree, *offset, length, hf_ieee802154_hie_ht1, ett_ieee802154_hie_ht1, &subitem); + consumed = 0; break; - } - *offset += length; - } else { - // Header IE of empty length - switch(id){ - case IEEE802154_HEADER_IE_EID_TERM1: - //header_item = proto_tree_add_item(tree, hf_ieee802154_header_ie, tvb, *offset, 2 + length, ENC_NA); - subtree = proto_item_add_subtree(header_item, ett_ieee802154_header); - proto_item_append_text(subtree, ", Element ID: %s, Length: %d", val_to_str_const(id, ieee802154_header_ie_names, "Unknown IE"), length); - proto_tree_add_bitmask(subtree, tvb, *offset, hf_ieee802154_header_termination, ett_ieee802154_header_ie, fields, ENC_LITTLE_ENDIAN); - - *offset += 2; + case IEEE802154_HEADER_IE_HT2: + proto_item_append_text(ies_item, ", %s", name); + subtree = create_header_ie_tree(tvb, ies_tree, *offset, length, hf_ieee802154_hie_ht2, ett_ieee802154_hie_ht2, &subitem); + consumed = 0; + break; + case IEEE802154_HEADER_IE_TIME_CORR: // 7.4.2.7 Time Correction IE + proto_item_append_text(ies_item, ", %s", name); + subtree = create_header_ie_tree(tvb, ies_tree, *offset, length, hf_ieee802154_hie_time_correction, ett_ieee802154_hie_time_correction, &subitem); + consumed = dissect_802154_hie_time_correction(content, pinfo, subtree, packet, subitem, ies_item); break; - case IEEE802154_HEADER_IE_EID_TERM2: - //header_item = proto_tree_add_item(tree, hf_ieee802154_header_ie, tvb, *offset, 2 + length, ENC_NA); - subtree = proto_item_add_subtree(header_item, ett_ieee802154_header); - proto_item_append_text(subtree, ", Element ID: %s, Length: %d", val_to_str_const(id, ieee802154_header_ie_names, "Unknown IE"), length); - proto_tree_add_bitmask(subtree, tvb, *offset, hf_ieee802154_header_termination, ett_ieee802154_header_ie, fields, ENC_LITTLE_ENDIAN); - - *offset += 2; + // the IEs defined in 802.15.4-2015 that are not yet supported + case IEEE802154_HEADER_IE_CSL: // TODO: 7.4.2.3 CSL IE + case IEEE802154_HEADER_IE_RIT: // TODO: 7.4.2.4 RIT IE + case IEEE802154_HEADER_IE_DSME_PAN: // TODO: 7.4.2.5 DSME PAN descriptor IE + case IEEE802154_HEADER_IE_RENDEZVOUS: // TODO: 7.4.2.6 Rendezvous Time IE + case IEEE802154_HEADER_IE_EXT_DSME_PAN: // TODO: 7.4.2.8 Extended DSME PAN descriptor IE + case IEEE802154_HEADER_IE_FSCD: // TODO: 7.4.2.9 Fragment Sequence Context Description (FSCD) IE + case IEEE802154_HEADER_IE_SMPL_SUPER_FRM: // TODO: 7.4.2.10 Simplified Superframe Specification IE + case IEEE802154_HEADER_IE_SMPL_GTS: // TODO: 7.4.2.11 Simplified GTS Specification IE + case IEEE802154_HEADER_IE_LECIM: // TODO: 7.4.2.12 LECIM Capabilities IE + case IEEE802154_HEADER_IE_RCC_CAP: // TODO: 7.4.2.13 RCC Capabilities IE + case IEEE802154_HEADER_IE_RCCN: // TODO: 7.4.2.14 RCCN Descriptor IE + case IEEE802154_HEADER_IE_GLOBAL_TIME: // TODO: 7.4.2.15 Global Time IE + case IEEE802154_HEADER_IE_DA_IE: // TODO: 7.4.2.16 DA IE + case IEEE802154_HEADER_IE_TRLE: // TODO: F5.1.1 TRLE Descriptor IE + proto_item_append_text(ies_item, ", Unsupported: %s", name); + subtree = create_header_ie_tree(tvb, ies_tree, *offset, length, hf_ieee802154_hie_unsupported, ett_ieee802154_hie_unsupported, &subitem); + proto_item_append_text(subitem, ": %s", name); + if (length > 0) { + proto_tree_add_item(subtree, hf_ieee802154_hie_unknown_content, content, 0, length, ENC_NA); + } + expert_add_info(pinfo, subitem, &ei_ieee802154_ie_unsupported_element_id); + consumed = length; break; + // unknown IE default: - subtree = proto_item_add_subtree(header_item, ett_ieee802154_header); - proto_item_append_text(subtree, ", Element ID: %s, Length: %d", val_to_str_const(id, ieee802154_header_ie_names, "Unknown IE"), length); - proto_tree_add_bitmask(subtree, tvb, *offset, hf_ieee802154_header_ie_tlv, ett_ieee802154_header_ie, fields, ENC_LITTLE_ENDIAN); - *offset += 2; - expert_add_info(pinfo, header_item, &ei_ieee802154_unsupported_element_id); + proto_item_append_text(ies_item, ", Unknown IE 0x%02x", id); + subtree = create_header_ie_tree(tvb, ies_tree, *offset, length, hf_ieee802154_hie_unknown, ett_ieee802154_hie_unknown, &subitem); + proto_item_append_text(subitem, ": 0x%02x", id); + if (length > 0) { + proto_tree_add_item(subtree, hf_ieee802154_hie_unknown_content, content, 0, length, ENC_NA); + } + expert_add_info(pinfo, subitem, &ei_ieee802154_ie_unknown_element_id); + consumed = length; break; } + + if (consumed < length) { + proto_tree_add_item(subtree, hf_ieee802154_hie_unknown_content, content, consumed, length - consumed, ENC_NA); + expert_add_info(pinfo, subitem, &ei_ieee802154_ie_unknown_extra_content); + } } + CATCH_ALL { + if (subtree == NULL) { // if not done yet, create a tree for the exception + subtree = create_header_ie_tree(tvb, ies_tree, *offset, length, hf_ieee802154_hie_unknown, ett_ieee802154_hie_unknown, &subitem); + } + show_exception(tvb, pinfo, subtree, EXCEPT_CODE, GET_MESSAGE); + } + ENDTRY; + + *offset += 2 + length; } while ((tvb_reported_length_remaining(tvb, *offset) > IEEE802154_MIC_LENGTH(packet->security_level) + IEEE802154_FCS_LEN + 1) && - (id != IEEE802154_HEADER_IE_EID_TERM1) && - (id != IEEE802154_HEADER_IE_EID_TERM2)); + (id != IEEE802154_HEADER_IE_HT1) && + (id != IEEE802154_HEADER_IE_HT2)); // Once the dissection is over, the length of the header is known - proto_item_set_len(header_item, header_length); + proto_item_set_len(ies_item, total_length); - /* Presence of Payload IEs is determined by how the Header IEs are terminated */ - if (id == IEEE802154_HEADER_IE_EID_TERM1) { + // Presence of Payload IEs is determined by how the Header IEs are terminated + if (id == IEEE802154_HEADER_IE_HT1) { packet->payload_ie_present = TRUE; } else { packet->payload_ie_present = FALSE; } - } /* dissect_ieee802154_header_ie */ /** @@ -2775,7 +2785,7 @@ dissect_ieee802154_payload_mlme_sub_ie(tvbuff_t *tvb, packet_info *pinfo _U_, pr offset += 2; if (psie_remaining) { proto_tree_add_item(tree, hf_ieee802154_mlme_ie_data, tvb, offset, psie_remaining, ENC_NA); - expert_add_info(pinfo, tree, &ei_ieee802154_unsupported_element_id); + expert_add_info(pinfo, tree, &ei_ieee802154_ie_unsupported_element_id); offset += psie_remaining; } break; @@ -4065,7 +4075,7 @@ void proto_register_ieee802154(void) NULL, HFILL }}, { &hf_ieee802154_src64_origin, - { "Origin", "wpan.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0, + { "Origin", "wpan.src64.origin", FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_ieee802154_fcs, @@ -4086,10 +4096,13 @@ void proto_register_ieee802154(void) /* Header IE */ - { &hf_ieee802154_header_ie, - { "Header IE", "wpan.header_ie", FT_NONE, BASE_NONE, NULL, + { &hf_ieee802154_header_ies, + { "Header IEs", "wpan.header_ie", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { &hf_ieee802154_header_ie_tlv, + { "IE Header", "wpan.header_ie_tlv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + { &hf_ieee802154_header_ie_type, { "Type", "wpan.header_ie.type", FT_UINT16, BASE_DEC, VALS(ieee802154_ie_types), IEEE802154_HEADER_IE_TYPE_MASK, NULL, HFILL }}, @@ -4102,24 +4115,47 @@ void proto_register_ieee802154(void) { "Length", "wpan.header_ie.length", FT_UINT16, BASE_DEC, NULL, IEEE802154_HEADER_IE_LENGTH_MASK, NULL, HFILL }}, - { &hf_ieee802154_header_ie_tlv, - { "IE Header", "wpan.header_ie_tlv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, - { &hf_ieee802154_header_termination, - { "Header Termination", "wpan.header_ie_termination", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + /* Individual Header IEs */ + + { &hf_ieee802154_hie_unknown, + { "Unknown Header IE", "wpan.header_ie.unknown", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee802154_hie_unknown_content, + { "Unknown Content", "wpan.header_ie.unknown_content", FT_BYTES, SEP_SPACE, NULL, 0x0, + NULL, HFILL }}, + + + { &hf_ieee802154_hie_unsupported, + { "Unsupported Header IE", "wpan.header_ie.unsupported", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee802154_hie_ht1, + { "Header Termination 1 IE (Payload IEs follow)", "wpan.header_ie.ht1", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee802154_hie_ht2, + { "Header Termination 2 IE (Payload follows)", "wpan.header_ie.ht2", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + /* Time correction IE */ + { &hf_ieee802154_hie_time_correction, + { "Time Correction IE", "wpan.header_ie.time_correction", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, - { &hf_ieee802154_time_correction, - { "Time correction", "wpan.time_correction", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { &hf_ieee802154_hie_time_correction_time_sync_info, + { "Time Sync Info", "wpan.header_ie.time_correction.time_sync_info", FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, { &hf_ieee802154_nack, - { "Non-acknowledgement", "wpan.nack", FT_BOOLEAN, 16, NULL, 0x8000, + { "Nack", "wpan.nack", FT_BOOLEAN, 16, TFS(&hf_ieee802154_nack_tfs), 0x8000, NULL, HFILL }}, - { &hf_ieee802154_time_correction_value, - { "Time correction", "wpan.time_correction_value", FT_INT16, BASE_DEC, NULL, 0x0FFF, - NULL, HFILL }}, + { &hf_ieee802154_hie_time_correction_value, + { "Time Correction", "wpan.header_ie.time_correction.value", FT_INT16, BASE_DEC|BASE_UNIT_STRING, &units_microseconds, 0x0FFF, + "Time correction in microseconds", HFILL }}, /* Payload IEs */ @@ -4601,9 +4637,14 @@ void proto_register_ieee802154(void) &ett_ieee802154_gts_direction, &ett_ieee802154_gts_descriptors, &ett_ieee802154_pendaddr, - &ett_ieee802154_header, + &ett_ieee802154_header_ies, &ett_ieee802154_header_ie, - &ett_ieee802154_h_ie_payload, + &ett_ieee802154_header_ie_tlv, + &ett_ieee802154_hie_unknown, + &ett_ieee802154_hie_unsupported, + &ett_ieee802154_hie_time_correction, + &ett_ieee802154_hie_ht1, + &ett_ieee802154_hie_ht2, &ett_ieee802154_payload, &ett_ieee802154_payload_ie, &ett_ieee802154_tsch_timeslot, @@ -4662,8 +4703,12 @@ void proto_register_ieee802154(void) "Incorrect value. Reference: IEEE-802.15.4-2015. Table 7-8: Values of the Time Sync Info field for ACK with timing Information", EXPFILL}}, { &ei_ieee802154_6top_unsupported_return_code, { "wpan.6top_unsupported_code", PI_PROTOCOL, PI_WARN, "Unsupported 6Top return code", EXPFILL }}, - { &ei_ieee802154_unsupported_element_id, { "wpan.header_ie_unsupported_element_id", PI_PROTOCOL, PI_WARN, - "Unsupported Header IE element ID", EXPFILL }}, + { &ei_ieee802154_ie_unsupported_element_id, { "wpan.ie_unsupported_element_id", PI_PROTOCOL, PI_WARN, + "Unsupported IE element ID", EXPFILL }}, + { &ei_ieee802154_ie_unknown_element_id, { "wpan.ie_unknown_element_id", PI_PROTOCOL, PI_WARN, + "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 }}, }; /* Preferences. */ diff --git a/epan/dissectors/packet-ieee802154.h b/epan/dissectors/packet-ieee802154.h index 1ceb34ff2a..be2b8d51a0 100644 --- a/epan/dissectors/packet-ieee802154.h +++ b/epan/dissectors/packet-ieee802154.h @@ -227,7 +227,7 @@ typedef enum { } ieee802154_key_hash; /* Header IE Element ID */ -#define IEEE802154_HEADER_VENDOR_SPECIFIC 0x00 +#define IEEE802154_HEADER_IE_VENDOR_SPECIFIC 0x00 /* Reserved 0x01-0x19 */ #define IEEE802154_HEADER_IE_CSL 0x1a #define IEEE802154_HEADER_IE_RIT 0x1b @@ -247,8 +247,8 @@ typedef enum { /* Assigned to External Organization: 0x2a */ #define IEEE802154_HEADER_IE_DA_IE 0x2b /* Reserved 0x2c-0x7d */ -#define IEEE802154_HEADER_IE_EID_TERM1 0x7e -#define IEEE802154_HEADER_IE_EID_TERM2 0x7f +#define IEEE802154_HEADER_IE_HT1 0x7e +#define IEEE802154_HEADER_IE_HT2 0x7f /* Reserved 0x80-0xff */ /* Payload IE Group ID */ |