diff --git a/epan/dissectors/packet-acn.c b/epan/dissectors/packet-acn.c index d637385f12..f6290c2c4e 100644 --- a/epan/dissectors/packet-acn.c +++ b/epan/dissectors/packet-acn.c @@ -85,6 +85,7 @@ void proto_reg_handoff_acn(void); #define ACN_PROTOCOL_ID_BROKER 0x00000009 #define ACN_PROTOCOL_ID_LLRP 0x0000000A #define ACN_PROTOCOL_ID_EPT 0x0000000B +#define ACN_PROTOCOL_ID_DMX_3 0x50430001 #define ACN_ADDR_NULL 0 #define ACN_ADDR_IPV4 1 @@ -595,6 +596,12 @@ static int hf_acn_dmx_count = -1; static int hf_acn_dmx_2_start_code = -1; static int hf_acn_dmx_data = -1; +static int hf_acn_postamble_key_fingerprint = -1; +static int hf_acn_postamble_seq_type = -1; +static int hf_acn_postamble_seq_hi = -1; +static int hf_acn_postamble_seq_low = -1; +static int hf_acn_postamble_message_digest = -1; + /* static int hf_acn_dmx_dmp_vector = -1; */ /* Try heuristic ACN decode */ @@ -752,6 +759,7 @@ static const value_string acn_protocol_id_vals[] = { { ACN_PROTOCOL_ID_BROKER, "Broker Protocol" }, { ACN_PROTOCOL_ID_LLRP, "Low Level Recovery Protocol" }, { ACN_PROTOCOL_ID_EPT, "Extensible Packet Transport Protocol" }, + { ACN_PROTOCOL_ID_DMX_3, "Pathway Connectivity Secure DMX Protocol" }, { 0, NULL }, }; @@ -2816,6 +2824,13 @@ static const value_string magic_ip_configuration_vals[] = { { 0, NULL } }; +static const value_string security_seq_type_vals[] = { + { 0, "Time (ms since epoch)" }, + { 1, "Volatile" }, + { 2, "Non-volatile" }, + { 0, NULL } +}; + static const value_string rdmnet_llrp_vector_vals[] = { { RDMNET_LLRP_VECTOR_PROBE_REQUEST, "LLRP probe request" }, { RDMNET_LLRP_VECTOR_PROBE_REPLY, "LLRP probe reply" }, @@ -3240,6 +3255,7 @@ is_acn(tvbuff_t *tvb) if (is_acn_or_rdmnet_over_udp(tvb, &protocol_id)) { if ((protocol_id == ACN_PROTOCOL_ID_DMX) || (protocol_id == ACN_PROTOCOL_ID_DMX_2) || + (protocol_id == ACN_PROTOCOL_ID_DMX_3) || (protocol_id == ACN_PROTOCOL_ID_SDT)) return TRUE; } @@ -5435,7 +5451,7 @@ dissect_acn_dmx_data_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, switch (vector) { case ACN_DMP_VECTOR_SET_PROPERTY: dmx_start_code = tvb_get_ntohs(tvb, data_offset); - if (protocol_id == ACN_PROTOCOL_ID_DMX_2) { + if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) { proto_tree_add_item(pdu_tree, hf_acn_dmx_2_first_property_address, tvb, data_offset, 2, ENC_BIG_ENDIAN); } else { proto_tree_add_item(pdu_tree, hf_acn_dmx_start_code, tvb, data_offset, 2, ENC_BIG_ENDIAN); @@ -5447,7 +5463,7 @@ dissect_acn_dmx_data_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, proto_tree_add_item(pdu_tree, hf_acn_dmx_count, tvb, data_offset, 2, ENC_BIG_ENDIAN); data_offset += 2; - if (protocol_id == ACN_PROTOCOL_ID_DMX_2) { + if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) { dmx_2_start_code = (guint8)tvb_get_ntohs(tvb, data_offset - 1); proto_tree_add_item(pdu_tree, hf_acn_dmx_2_start_code, tvb, data_offset, 1, ENC_BIG_ENDIAN); data_offset += 1; @@ -5485,7 +5501,7 @@ dissect_acn_dmx_data_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, leading_char = ' '; } /* add a snippet to info (this may be slow) */ - if (protocol_id == ACN_PROTOCOL_ID_DMX_2) { + if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) { info_start_code = dmx_2_start_code; } else { @@ -5628,7 +5644,7 @@ dissect_acn_dmx_base_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, /* process based on vector */ switch (vector) { case ACN_DMP_VECTOR_SET_PROPERTY: - if (protocol_id == ACN_PROTOCOL_ID_DMX_2) { + if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) { proto_tree_add_item(pdu_tree, hf_acn_dmx_source_name, tvb, data_offset, 64, ENC_UTF_8|ENC_NA); data_offset += 64; } else { @@ -5640,7 +5656,7 @@ dissect_acn_dmx_base_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, proto_tree_add_item(pdu_tree, hf_acn_dmx_priority, tvb, data_offset, 1, ENC_BIG_ENDIAN); data_offset += 1; - if (protocol_id == ACN_PROTOCOL_ID_DMX_2) { + if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) { proto_tree_add_item(pdu_tree, hf_acn_dmx_2_reserved, tvb, data_offset, 2, ENC_BIG_ENDIAN); data_offset += 2; } @@ -5649,7 +5665,7 @@ dissect_acn_dmx_base_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, proto_tree_add_item(pdu_tree, hf_acn_dmx_sequence_number, tvb, data_offset, 1, ENC_BIG_ENDIAN); data_offset += 1; - if (protocol_id == ACN_PROTOCOL_ID_DMX_2) { + if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) { option_flags = tvb_get_guint8(tvb, data_offset); pi = proto_tree_add_uint(pdu_tree, hf_acn_dmx_2_options, tvb, data_offset, 1, option_flags); flag_tree = proto_item_add_subtree(pi, ett_acn_dmx_2_options); @@ -7024,6 +7040,7 @@ dissect_acn_root_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of switch (protocol_id) { case ACN_PROTOCOL_ID_DMX: case ACN_PROTOCOL_ID_DMX_2: + case ACN_PROTOCOL_ID_DMX_3: if (global_acn_dmx_enable) { end_offset = dissect_acn_root_pdu_header(tvb, pinfo, pdu_tree, ti, ": Root DMX", &offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, 1, &pdu_flvh_length, 1); @@ -7101,6 +7118,7 @@ dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) guint32 old_offset; guint32 end_offset; acn_pdu_offsets pdu_offsets = {0,0,0,0,0}; + guint16 postamble_size; /* if (!is_acn(tvb)) { */ /* return 0; */ @@ -7116,17 +7134,31 @@ dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* add preamble, postamble and ACN Packet ID */ proto_tree_add_item(acn_tree, hf_acn_preamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN); data_offset += 2; + postamble_size = tvb_get_guint16(tvb, data_offset, ENC_BIG_ENDIAN); proto_tree_add_item(acn_tree, hf_acn_postamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN); data_offset += 2; proto_tree_add_item(acn_tree, hf_acn_packet_identifier, tvb, data_offset, 12, ENC_UTF_8 | ENC_NA); data_offset += 12; - /* one past the last byte */ + /* one past the last data byte, not including the postamble */ end_offset = data_offset + tvb_reported_length_remaining(tvb, data_offset); - while (data_offset < end_offset) { + while (data_offset < end_offset - postamble_size) { old_offset = data_offset; data_offset = dissect_acn_root_pdu(tvb, pinfo, acn_tree, data_offset, &pdu_offsets, 1); - if (data_offset == old_offset) break; + if (data_offset == old_offset) return tvb_reported_length(tvb); + } + /* one past the last postamble byte */ + while (data_offset < end_offset) { + proto_tree_add_item(acn_tree, hf_acn_postamble_key_fingerprint, tvb, data_offset, 4, ENC_NA); + data_offset += 4; + proto_tree_add_item(acn_tree, hf_acn_postamble_seq_type, tvb, data_offset, 1, ENC_NA); + data_offset += 1; + proto_tree_add_item(acn_tree, hf_acn_postamble_seq_hi, tvb, data_offset, 3, ENC_BIG_ENDIAN); + data_offset += 3; + proto_tree_add_item(acn_tree, hf_acn_postamble_seq_low, tvb, data_offset, 4, ENC_BIG_ENDIAN); + data_offset += 4; + proto_tree_add_item(acn_tree, hf_acn_postamble_message_digest, tvb, data_offset, 16, ENC_NA); + data_offset += 16; } return tvb_reported_length(tvb); } @@ -7959,6 +7991,42 @@ proto_register_acn(void) FT_GUID, BASE_NONE, NULL, 0x0, "Reply DCID", HFILL } }, + + /* Key Fingerprint */ + { &hf_acn_postamble_key_fingerprint, + { "Key Fingerprint", "acn.security.key_fingerprint", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Security Key Fingerprint", HFILL } + }, + + /* Sequence type */ + { &hf_acn_postamble_seq_type, + { "Sequence Type", "acn.security.seq_type", + FT_UINT8, BASE_DEC, VALS(security_seq_type_vals), 0x0, + "Security Sequence Type", HFILL } + }, + + /* Sequence High */ + { &hf_acn_postamble_seq_hi, + { "Sequence High", "acn.security.seq_hi", + FT_UINT24, BASE_HEX, NULL, 0x0, + "Security Sequence High", HFILL } + }, + + /* Sequence Low */ + { &hf_acn_postamble_seq_low, + { "Sequence Low", "acn.security.seq_low", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Security Sequence Low", HFILL } + }, + + /* Message Digest */ + { &hf_acn_postamble_message_digest, + { "Message Digest", "acn.security.digest", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Security Message Digest", HFILL } + }, + }; static hf_register_info rdmnet_hf[] = {