diff --git a/epan/dissectors/Makefile.am b/epan/dissectors/Makefile.am index d8c894b92e..7163b4c225 100644 --- a/epan/dissectors/Makefile.am +++ b/epan/dissectors/Makefile.am @@ -1443,6 +1443,7 @@ DISSECTOR_SRC = \ packet-xmpp-utils.c \ packet-xmpp.c \ packet-xot.c \ + packet-xra.c \ packet-xtp.c \ packet-xyplex.c \ packet-yami.c \ diff --git a/epan/dissectors/packet-xra.c b/epan/dissectors/packet-xra.c new file mode 100644 index 0000000000..5a2aca5642 --- /dev/null +++ b/epan/dissectors/packet-xra.c @@ -0,0 +1,1211 @@ +/* packet-xra.c + * Routines for Excentis DOCSIS31 XRA31 sniffer dissection + * Copyright 2017, Bruno Verstuyft + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +/* Initialize the protocol and registered fields */ +static dissector_handle_t docsis_handle; +static dissector_handle_t xra_handle; + + +static int proto_xra = -1; + +static int proto_plc = -1; +static int proto_ncp = -1; +static int proto_segment = -1; +static int proto_init_ranging = -1; + + +static gint ett_xra = -1; +static gint ett_xra_tlv = -1; +static gint ett_xra_tlv_cw_info = -1; +static gint ett_xra_tlv_ms_info = -1; +static gint ett_xra_tlv_burst_info = -1; +static gint ett_plc = -1; +static gint ett_plc_mb = -1; +static gint ett_ncp = -1; +static gint ett_ncp_mb = -1; +static gint ett_init_ranging = -1; + +static gint hf_xra_version = -1; +static gint hf_xra_direction = -1; +static gint hf_xra_packettype = -1; +static gint hf_xra_tlvlength = -1; +static gint hf_xra_tlv = -1; +/* + * XRA TLV + */ +static gint hf_xra_tlv_ds_channel_id = -1; +static gint hf_xra_tlv_us_channel_id = -1; +static gint hf_xra_tlv_profile_id = -1; +static gint hf_xra_tlv_sid = -1; +static gint hf_xra_tlv_iuc = -1; +static gint hf_xra_tlv_burstid = -1; +static gint hf_xra_tlv_ms_info = -1; +static gint hf_xra_tlv_burst_info = -1; +static gint hf_xra_tlv_ucd_ccc_parity = -1; +static gint hf_xra_tlv_grant_size = -1; +static gint hf_xra_tlv_segment_header_present = -1; +static gint hf_xra_tlv_ncp_trunc = -1; +static gint hf_xra_tlv_ncp_symbolid = -1; +/* + *Ranging TLV + */ +static gint hf_xra_tlv_ranging_start_minislot_id_abs = -1; +static gint hf_xra_tlv_ranging_start_minislot_id_rel = -1; +static gint hf_xra_tlv_ranging_stop_minislot_id_rel = -1; +static gint hf_xra_tlv_ranging_number_ofdma_frames = -1; +static gint hf_xra_tlv_ranging_mer = -1; +static gint hf_xra_tlv_ranging_timing_adjust = -1; + +static gint hf_xra_unknown = -1; + +/* + * Codeword Info TLV + */ +static gint hf_xra_tlv_cw_info = -1; +static gint hf_xra_tlv_cw_info_nr_of_info_bytes = -1; +static gint hf_xra_tlv_cw_info_bch_decoding_successful = -1; +static gint hf_xra_tlv_cw_info_profile_parity = -1; +static gint hf_xra_tlv_cw_info_bch_number_of_corrected_bits = -1; +static gint hf_xra_tlv_cw_info_ldpc_nr_of_code_bits = -1; +static gint hf_xra_tlv_cw_info_ldpc_decoding_successful = -1; +static gint hf_xra_tlv_cw_info_ldpc_number_of_corrected_bits = -1; +static gint hf_xra_tlv_cw_info_ldpc_number_of_iterations = -1; + +/* + * Burst Info TLV + */ +static gint hf_xra_tlv_burst_info_burst_id_reference = -1; + +/* + * PLC specific + */ +static gint hf_plc_mb = -1; + +/* + * NCP specific + */ +static gint hf_ncp_mb = -1; +static gint hf_ncp_mb_profileid = -1; +static gint hf_ncp_mb_z = -1; +static gint hf_ncp_mb_c = -1; +static gint hf_ncp_mb_n = -1; +static gint hf_ncp_mb_l = -1; +static gint hf_ncp_mb_t = -1; +static gint hf_ncp_mb_u = -1; +static gint hf_ncp_mb_r = -1; +static gint hf_ncp_mb_subcarrier_start_pointer = -1; +static gint hf_ncp_crc = -1; + +/* + * Init Ranging Specific + */ +static gint hf_xra_init_ranging_mac = -1; +static gint hf_xra_init_ranging_ds_channel_id = -1; +static gint hf_xra_init_ranging_crc = -1; + +/* + *PLC MB + */ +static gint hf_plc_em_mb = -1; +static gint hf_plc_trigger_mb = -1; + +/* + * PLC Timestamp MB specific + */ +static gint hf_plc_mb_ts_reserved = -1; +static gint hf_plc_mb_ts_timestamp = -1; +static gint hf_plc_mb_ts_crc24d = -1; + +/* + * PLC Message Channel MB specific + */ +static gint hf_plc_mb_mc_reserved = -1; +static gint hf_plc_mb_mc_pspf_present = -1; +static gint hf_plc_mb_mc_psp = -1; + +/* + * OFDMA SEGMENT + */ +static gint hf_docsis_segment_pfi = -1; +static gint hf_docsis_segment_reserved = -1; +static gint hf_docsis_segment_pointerfield = -1; +static gint hf_docsis_segment_sequencenumber = -1; +static gint hf_docsis_segment_sidclusterid = -1; +static gint hf_docsis_segment_request = -1; +static gint hf_docsis_segment_hcs = -1; +static gint hf_docsis_segment_data = -1; + + +static int dissect_xra(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_); +static int dissect_xra_tlv(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_, guint16 tlvLength, guint* segmentHeaderPresent); +static int dissect_plc(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_); +static int dissect_ncp(tvbuff_t * tvb, proto_tree * tree, void* data _U_); +static int dissect_init_ranging(tvbuff_t * tvb, proto_tree * tree, void* data _U_); +static int dissect_ofdma_segment(tvbuff_t * tvb, proto_tree * tree, void* data _U_); + + + +#define XRA_DIRECTION_DOWNSTREAM 0 +#define XRA_DIRECTION_UPSTREAM 1 + +#define XRA_PACKETTYPE_DS_SCQAM_DOCSIS_MACFRAME 1 +#define XRA_PACKETTYPE_OFDM_DOCSIS 8 +#define XRA_PACKETTYPE_OFDM_NCP 9 +#define XRA_PACKETTYPE_OFDM_PLC 10 + +#define XRA_PACKETTYPE_TDMA_BURST 65 +#define XRA_PACKETTYPE_OFDMA_DATA_BURST 72 +#define XRA_PACKETTTYPE_OFDMA_INITIAL_RANGING 73 +#define XRA_PACKETTTYPE_OFDMA_FINE_RANGING 74 +#define XRA_PACKETTYPE_OFDMA_REQ 75 +#define XRA_PACKETTYPE_OFDMA_PROBING_SEQUENCE 76 +#define XRA_PACKETTYPE_US_DOCSIS_MACFRAME 80 + +/*TLVs*/ +#define XRA_DS_CHANNEL_ID 1 +#define XRA_DS_FREQUENCY 2 +#define XRA_MODULATION 3 +#define XRA_ANNEX 4 +#define XRA_PROFILE_ID 5 +#define XRA_CODEWORD_INFO 6 +#define XRA_NCP_TRUNC 7 +#define XRA_NCP_SYMBOLID 8 +#define XRA_MER 9 +#define XRA_US_CHANNEL_ID 10 +#define XRA_SID 11 +#define XRA_IUC 12 +#define XRA_BURST_ID 13 +#define XRA_BURST_INFO 14 +#define XRA_MINISLOT_INFO 15 +#define XRA_UCD_CCC_PARITY 16 +#define XRA_GRANT_SIZE 17 +#define XRA_SEGMENT_HEADER_PRESENT 18 +#define XRA_NUMBER_OFDMA_FRAMES 19 +#define XRA_ESTIMATED_TIMING_ADJUST 20 +#define XRA_ESTIMATED_POWER_LEVEL 21 +#define XRA_SUBSLOT_ID 22 + +#define XRA_CONFIGURATION_INFO 254 +#define XRA_EXTENSION_TYPE 255 + + +/*Codeword Info Sub-Tlvs*/ +#define XRA_TLV_CW_INFO_PROFILE_PARITY 1 +#define XRA_TLV_CW_INFO_NR_OF_INFO_BYTES 2 +#define XRA_TLV_CW_INFO_BCH_DECODING_SUCCESFUL 3 +#define XRA_TLV_CW_INFO_BCH_NUMBER_OF_CORRECTED_BITS 4 +#define XRA_TLV_CW_INFO_LDPC_NUMBER_OF_CODE_BITS 5 +#define XRA_TLV_CW_INFO_LDPC_DECODING_SUCCESSFUL 6 +#define XRA_TLV_CW_INFO_LDPC_NUMBER_OF_CORRECTED_BITS 7 +#define XRA_TLV_CW_INFO_LDPC_NUMBER_OF_ITERATIONS 8 + +/*Burst Info Sub-Tlv*/ +#define XRA_BURST_INFO_BURST_ID_REFERENCE 1 + +/*Minislot Info Sub-TLVs*/ +#define XRA_TLV_MINISLOT_INFO_START_MINISLOT_ID 1 +#define XRA_TLV_MINISLOT_INFO_REL_START_MINISLOT 2 +#define XRA_TLV_MINISLOT_INFO_REL_STOP_MINISLOT 3 + + + +/*PLC Message Block Types*/ +#define PLC_TIMESTAMP_MB 1 +#define PLC_ENERGY_MANAGEMENT_MB 2 +#define PLC_MESSAGE_CHANNEL_MB 3 +#define PLC_TRIGGER_MB 4 + + + + +static const value_string direction_vals[] = { + {XRA_DIRECTION_DOWNSTREAM, "Downstream"}, + {XRA_DIRECTION_UPSTREAM, "Upstream"}, + {0, NULL} +}; + +static const value_string packettype[] = { + {XRA_PACKETTYPE_DS_SCQAM_DOCSIS_MACFRAME, "SC-QAM DOCSIS Macframe"}, + {XRA_PACKETTYPE_OFDM_DOCSIS, "OFDM DOCSIS"}, + {XRA_PACKETTYPE_OFDM_NCP, "OFDM NCP"}, + {XRA_PACKETTYPE_OFDM_PLC, "OFDM PLC"}, + {XRA_PACKETTYPE_TDMA_BURST, "TDMA Burst"}, + {XRA_PACKETTYPE_OFDMA_DATA_BURST, "OFDMA Data Burst"}, + {XRA_PACKETTTYPE_OFDMA_INITIAL_RANGING, "OFDMA Initial Ranging"}, + {XRA_PACKETTTYPE_OFDMA_FINE_RANGING, "OFDMA Fine Ranging"}, + {XRA_PACKETTYPE_OFDMA_REQ, "OFDMA REQ"}, + {XRA_PACKETTYPE_OFDMA_PROBING_SEQUENCE, "OFDMA Probing Sequence"}, + {XRA_PACKETTYPE_US_DOCSIS_MACFRAME, "US DOCSIS Macframe"}, + {0, NULL} +}; + +static const value_string profile_id[] = { + {0, "Profile A"}, + {1, "Profile B"}, + {2, "Profile C"}, + {4, "Profile D"}, + {5, "Profile E"}, + {6, "Profile F"}, + {7, "Profile G"}, + {8, "Profile H"}, + {9, "Profile I"}, + {10, "Profile J"}, + {11, "Profile K"}, + {12, "Profile L"}, + {13, "Profile M"}, + {14, "Profile N"}, + {15, "Profile O"}, + {16, "Profile P"}, + {0, NULL} +}; + +static const value_string message_block_type[] = { + {PLC_TIMESTAMP_MB, "Timestamp Message Block"}, + {PLC_ENERGY_MANAGEMENT_MB, "Energy Management Message Block"}, + {PLC_MESSAGE_CHANNEL_MB, "Message Channel Message Block"}, + {PLC_TRIGGER_MB, "Trigger Message Block"}, + {0, NULL} +}; + +static const value_string packet_start_pointer_field[] = { + {0, "Not Present"}, + {1, "Present"}, + {0, NULL} +}; + +static const true_false_string zero_bit_loading = { + "subcarriers are all zero-bit-loaded", + "subcarriers follow profile" +}; + +static const true_false_string data_profile_update = { + "use odd profile", + "use even profile" +}; + +static const true_false_string ncp_profile_select = { + "use even profile", + "use odd profile" +}; + +static const true_false_string last_ncp_block = { + "this is the last NCP in the chain and is followed by an NCP CRC message block", + "this NCP is followed by another NCP" +}; + +static const true_false_string codeword_tagging = { + "this codeword is included in the codeword counts reported by the CM in the OPT-RSP message", + "this codeword is not included in the codeword counts reported by the CM in the OPT-RSP message" +}; + +static void +mer_fourth_db(char *buf, guint32 value) +{ + g_snprintf(buf, ITEM_LABEL_LENGTH, "%f dB", value/4.0); +} + +static int +dissect_xra(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_) { + proto_item *it; + proto_tree *xra_tree; + + it = proto_tree_add_protocol_format (tree, proto_xra, tvb, 0, -1,"XRA (Excentis XRA header)"); + + xra_tree = proto_item_add_subtree (it, ett_xra); + + tvbuff_t *docsis_tvb; + tvbuff_t *plc_tvb; + tvbuff_t *ncp_tvb; + tvbuff_t *xra_tlv_tvb; + tvbuff_t *segment_tvb; + tvbuff_t *init_ranging_tvb; + + guint direction, packet_type, tlv_length; + + proto_tree_add_item (xra_tree, hf_xra_version, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item_ret_uint (xra_tree, hf_xra_direction, tvb, 1, 1, ENC_BIG_ENDIAN, &direction); + proto_tree_add_item_ret_uint (xra_tree, hf_xra_packettype, tvb, 1, 1, ENC_BIG_ENDIAN, &packet_type); + proto_tree_add_item_ret_uint (xra_tree, hf_xra_tlvlength, tvb, 2, 2, ENC_BIG_ENDIAN, &tlv_length); + + col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(packet_type, packettype, "Unknown XRA packet type: %u")); + + /*Dissecting TLVs*/ + guint segment_header_present = 0; + xra_tlv_tvb = tvb_new_subset_length(tvb, 4, tlv_length); + dissect_xra_tlv(xra_tlv_tvb, pinfo, xra_tree, data, tlv_length, &segment_header_present); + + guint16 xra_length = 4 + tlv_length; + /*Dissecting contents*/ + switch(packet_type) { + case XRA_PACKETTYPE_OFDM_DOCSIS: + /*Calling docsis dissector*/ + docsis_tvb = tvb_new_subset_length(tvb, xra_length, tvb_captured_length_remaining(tvb, xra_length)); + if (docsis_handle) { + call_dissector (docsis_handle, docsis_tvb, pinfo, tree); + } + break; + case XRA_PACKETTYPE_OFDM_PLC: + plc_tvb = tvb_new_subset_length(tvb, xra_length, tvb_captured_length_remaining(tvb, xra_length)); + return dissect_plc(plc_tvb , pinfo, tree, data); + case XRA_PACKETTYPE_OFDM_NCP: + ncp_tvb = tvb_new_subset_length(tvb, xra_length, tvb_captured_length_remaining(tvb, xra_length)); + return dissect_ncp(ncp_tvb, tree, data); + case XRA_PACKETTYPE_OFDMA_DATA_BURST: + if(segment_header_present) { + col_append_str(pinfo->cinfo, COL_INFO, ": Segment"); + segment_tvb = tvb_new_subset_length(tvb, xra_length, tvb_captured_length_remaining(tvb, xra_length)); + return dissect_ofdma_segment(segment_tvb, tree, data); + } + break; + case XRA_PACKETTYPE_US_DOCSIS_MACFRAME: + /*Calling docsis dissector*/ + docsis_tvb = tvb_new_subset_length(tvb, xra_length, tvb_captured_length_remaining(tvb, xra_length)); + if (docsis_handle) { + call_dissector (docsis_handle, docsis_tvb, pinfo, tree); + } + break; + case XRA_PACKETTTYPE_OFDMA_FINE_RANGING: + /*Calling docsis dissector*/ + docsis_tvb = tvb_new_subset_length(tvb, xra_length, tvb_captured_length_remaining(tvb, xra_length)); + if (docsis_handle) { + call_dissector (docsis_handle, docsis_tvb, pinfo, tree); + } + break; + case XRA_PACKETTTYPE_OFDMA_INITIAL_RANGING: + init_ranging_tvb = tvb_new_subset_length(tvb, xra_length, tvb_captured_length_remaining(tvb, xra_length)); + return dissect_init_ranging(init_ranging_tvb, tree, data); + default: + proto_tree_add_item (xra_tree, hf_xra_unknown, tvb, 1, 1, ENC_NA); + break; + } + + return tvb_captured_length(tvb); +} + +static int +dissect_xra_tlv_cw_info(tvbuff_t * tvb, proto_tree * tree, void* data _U_, guint16 tlv_length) { + proto_item *it; + proto_tree *xra_tlv_cw_info_tree; + + it = proto_tree_add_item (tree, hf_xra_tlv_cw_info, tvb, 0, tlv_length, ENC_NA); + xra_tlv_cw_info_tree = proto_item_add_subtree (it, ett_xra_tlv_cw_info); + + guint16 tlv_index =0; + while (tlv_index < tlv_length) { + guint8 type = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + guint8 length = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + switch (type) { + case XRA_TLV_CW_INFO_NR_OF_INFO_BYTES: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_nr_of_info_bytes, tvb, tlv_index, length, ENC_NA); + break; + case XRA_TLV_CW_INFO_BCH_DECODING_SUCCESFUL: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_bch_decoding_successful, tvb, tlv_index, length, ENC_NA); + break; + case XRA_TLV_CW_INFO_PROFILE_PARITY: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_profile_parity, tvb, tlv_index, length, ENC_NA); + break; + case XRA_TLV_CW_INFO_BCH_NUMBER_OF_CORRECTED_BITS: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_bch_number_of_corrected_bits, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_TLV_CW_INFO_LDPC_NUMBER_OF_CODE_BITS: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_ldpc_nr_of_code_bits, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_TLV_CW_INFO_LDPC_DECODING_SUCCESSFUL: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_ldpc_decoding_successful, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_TLV_CW_INFO_LDPC_NUMBER_OF_CORRECTED_BITS: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_ldpc_number_of_corrected_bits, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_TLV_CW_INFO_LDPC_NUMBER_OF_ITERATIONS: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_tlv_cw_info_ldpc_number_of_iterations, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + default: + proto_tree_add_item (xra_tlv_cw_info_tree, hf_xra_unknown, tvb, tlv_index, length, ENC_NA); + break; + } + tlv_index+=length; + } + + return tvb_captured_length(tvb); +} + +static int +dissect_xra_tlv_ms_info(tvbuff_t * tvb, proto_tree * tree, void* data _U_, guint16 tlv_length) { + proto_item *it; + proto_tree *xra_tlv_ms_info_tree; + + it = proto_tree_add_item (tree, hf_xra_tlv_ms_info, tvb, 0, tlv_length, ENC_NA); + xra_tlv_ms_info_tree = proto_item_add_subtree (it, ett_xra_tlv_ms_info); + + guint16 tlv_index =0; + while (tlv_index < tlv_length) { + guint8 type = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + guint8 length = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + switch (type) { + case XRA_TLV_MINISLOT_INFO_START_MINISLOT_ID: + proto_tree_add_item (xra_tlv_ms_info_tree, hf_xra_tlv_ranging_start_minislot_id_abs, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_TLV_MINISLOT_INFO_REL_START_MINISLOT: + proto_tree_add_item (xra_tlv_ms_info_tree, hf_xra_tlv_ranging_start_minislot_id_rel, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_TLV_MINISLOT_INFO_REL_STOP_MINISLOT: + proto_tree_add_item (xra_tlv_ms_info_tree, hf_xra_tlv_ranging_stop_minislot_id_rel, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + default: + proto_tree_add_item (xra_tlv_ms_info_tree, hf_xra_unknown, tvb, tlv_index, length, ENC_NA); + break; + } + tlv_index+=length; + } + + return tvb_captured_length(tvb); +} + +static int +dissect_xra_tlv_burst_info(tvbuff_t * tvb, proto_tree * tree, void* data _U_, guint16 tlv_length) { + proto_item *it; + proto_tree *xra_tlv_burst_info_tree; + + it = proto_tree_add_item (tree, hf_xra_tlv_burst_info, tvb, 0, tlv_length, ENC_NA); + xra_tlv_burst_info_tree = proto_item_add_subtree (it, ett_xra_tlv_burst_info); + + guint16 tlv_index =0; + while (tlv_index < tlv_length) { + guint8 type = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + guint8 length = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + switch (type) { + case XRA_BURST_INFO_BURST_ID_REFERENCE: + proto_tree_add_item (xra_tlv_burst_info_tree, hf_xra_tlv_burst_info_burst_id_reference, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + default: + proto_tree_add_item (xra_tlv_burst_info_tree, hf_xra_unknown, tvb, tlv_index, length, ENC_NA); + break; + } + tlv_index+=length; + } + + return tvb_captured_length(tvb); +} + +static int +dissect_xra_tlv(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_, guint16 tlv_length, guint* segment_header_present) { + proto_item *it; + proto_tree *xra_tlv_tree; + guint symbol_id; + + it = proto_tree_add_item (tree, hf_xra_tlv, tvb, 0, tlv_length, ENC_NA); + xra_tlv_tree = proto_item_add_subtree (it, ett_xra_tlv); + + guint32 tlv_index =0; + tvbuff_t *xra_tlv_cw_info_tvb, *xra_tlv_ms_info_tvb, *xra_tlv_burst_info_tvb; + + while (tlv_index < tlv_length) { + guint8 type = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + guint8 length = tvb_get_guint8 (tvb, tlv_index); + ++tlv_index; + switch (type) { + case XRA_DS_CHANNEL_ID: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_ds_channel_id, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_PROFILE_ID: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_profile_id, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_CODEWORD_INFO: + xra_tlv_cw_info_tvb = tvb_new_subset_length(tvb, tlv_index, length); + dissect_xra_tlv_cw_info(xra_tlv_cw_info_tvb, xra_tlv_tree, data, length); + break; + case XRA_NCP_TRUNC: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_ncp_trunc, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_NCP_SYMBOLID: + proto_tree_add_item_ret_uint (xra_tlv_tree, hf_xra_tlv_ncp_symbolid, tvb, tlv_index, length, FALSE, &symbol_id); + col_append_fstr(pinfo->cinfo, COL_INFO, ": (SymbolId: %u):", symbol_id); + break; + case XRA_MER: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_ranging_mer, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_US_CHANNEL_ID: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_us_channel_id, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_SID: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_sid, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_IUC: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_iuc, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_BURST_ID: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_burstid, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_BURST_INFO: + xra_tlv_burst_info_tvb = tvb_new_subset_length(tvb, tlv_index, length); + dissect_xra_tlv_burst_info(xra_tlv_burst_info_tvb, xra_tlv_tree, data, length); + break; + case XRA_MINISLOT_INFO: + xra_tlv_ms_info_tvb = tvb_new_subset_length(tvb, tlv_index, length); + dissect_xra_tlv_ms_info(xra_tlv_ms_info_tvb, xra_tlv_tree, data, length); + break; + case XRA_UCD_CCC_PARITY: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_ucd_ccc_parity, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_GRANT_SIZE: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_grant_size, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_SEGMENT_HEADER_PRESENT: + proto_tree_add_item_ret_uint (xra_tlv_tree, hf_xra_tlv_segment_header_present, tvb, tlv_index, length, FALSE, segment_header_present); + break; + case XRA_NUMBER_OFDMA_FRAMES: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_ranging_number_ofdma_frames, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + case XRA_ESTIMATED_TIMING_ADJUST: + proto_tree_add_item (xra_tlv_tree, hf_xra_tlv_ranging_timing_adjust, tvb, tlv_index, length, ENC_BIG_ENDIAN); + break; + default: + proto_tree_add_item (xra_tlv_tree, hf_xra_unknown, tvb, tlv_index, length, ENC_NA); + break; + } + tlv_index+=length; + } + + return tvb_captured_length(tvb); +} + +void +dissect_timestamp_mb(tvbuff_t * tvb, proto_tree* tree) { + proto_tree_add_item (tree, hf_plc_mb_ts_reserved, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (tree, hf_plc_mb_ts_timestamp, tvb, 1, 8, ENC_BIG_ENDIAN); + proto_tree_add_item (tree, hf_plc_mb_ts_crc24d, tvb, 9, 3, ENC_NA); +} + +void +dissect_message_channel_mb(tvbuff_t * tvb, packet_info * pinfo, proto_tree* tree, guint16 remaining_length) { + proto_tree_add_item (tree, hf_plc_mb_mc_reserved, tvb, 0, 1, ENC_BIG_ENDIAN); + + guint packet_start_pointer_field_present, packet_start_pointer; + + proto_tree_add_item_ret_uint (tree, hf_plc_mb_mc_pspf_present, tvb, 0, 1, FALSE, &packet_start_pointer_field_present); + proto_tree_add_item_ret_uint (tree, hf_plc_mb_mc_psp, tvb, 1, 2, FALSE, &packet_start_pointer); + + /*If not present, this contains stuff from other packet. We can't do much in this case*/ + if(packet_start_pointer_field_present) { + guint16 docsis_start = 3 + packet_start_pointer; + if(docsis_start +6 < remaining_length) { + /*DOCSIS header in packet*/ + guint8 fc = tvb_get_guint8(tvb,docsis_start + 0); + if (fc == 0xFF) { + return; + } + guint16 docsis_length = 256*tvb_get_guint8(tvb,docsis_start + 2) + tvb_get_guint8(tvb,docsis_start + 3); + if (docsis_start + 6 + docsis_length <= remaining_length) { + /*DOCSIS packet included in packet*/ + tvbuff_t *docsis_tvb; + + docsis_tvb = tvb_new_subset_length(tvb, docsis_start, docsis_length + 6); + if (docsis_handle) { + call_dissector (docsis_handle, docsis_tvb, pinfo, tree); + } + } + } + } +} + +static int +dissect_message_block(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint8 mb_type, guint16 mb_length) { + proto_tree * mb_tree; + proto_item *mb_item; + + mb_item = proto_tree_add_item (tree, hf_plc_mb, tvb, 0, 1, ENC_BIG_ENDIAN); + + mb_tree = proto_item_add_subtree (mb_item, ett_plc_mb); + + switch (mb_type) { + case PLC_TIMESTAMP_MB: + dissect_timestamp_mb(tvb, mb_tree); + break; + case PLC_ENERGY_MANAGEMENT_MB: + proto_tree_add_item (mb_tree, hf_plc_em_mb, tvb, 0, mb_length, ENC_NA); + break; + case PLC_MESSAGE_CHANNEL_MB: + dissect_message_channel_mb(tvb, pinfo, mb_tree, mb_length); + break; + case PLC_TRIGGER_MB: + proto_tree_add_item (mb_tree, hf_plc_trigger_mb, tvb, 0, mb_length, ENC_NA); + break; + /*Future Use Message Block*/ + default: + break; + } + return tvb_captured_length(tvb); +} + +static int +dissect_ncp_message_block(tvbuff_t * tvb, proto_tree * tree) { + proto_tree * mb_tree; + proto_item *mb_item; + + mb_item = proto_tree_add_item (tree, hf_ncp_mb, tvb, 0, 3, ENC_NA); + mb_tree = proto_item_add_subtree (mb_item, ett_ncp_mb); + + proto_tree_add_item (mb_tree, hf_ncp_mb_profileid, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_z, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_c, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_n, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_l, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_t, tvb, 1, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_u, tvb, 1, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_r, tvb, 1, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (mb_tree, hf_ncp_mb_subcarrier_start_pointer, tvb, 1, 2, ENC_BIG_ENDIAN); + + return tvb_captured_length(tvb); +} + +static int +dissect_plc(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_) { + + guint16 offset = 0; + proto_tree *plc_tree; + proto_item *plc_item; + tvbuff_t *mb_tvb; + + plc_item = proto_tree_add_protocol_format (tree, proto_plc, tvb, 0, -1,"DOCSIS PLC"); + plc_tree = proto_item_add_subtree (plc_item, ett_plc); + + + while (tvb_reported_length_remaining(tvb, offset) > 0) { + guint8 mb_type = tvb_get_guint8 (tvb, offset) >>4; + guint8 mb_nibble2 = tvb_get_guint8 (tvb, offset) & 0x0F; + guint8 mb_byte2 = tvb_get_guint8 (tvb, offset+1); + guint8 last_mb = 0; + + /*Do not initialize with 0, otherwise an infinite loop results in case mbLength is not initialized.*/ + guint16 mb_length = 1000; + + if(mb_type == 0xFF) { + break; + } + switch (mb_type) { + case PLC_TIMESTAMP_MB: + mb_length =12; + col_append_str(pinfo->cinfo, COL_INFO, ": TS-MB, "); + break; + case PLC_ENERGY_MANAGEMENT_MB: + mb_length = 4 + mb_nibble2*6; + col_append_str(pinfo->cinfo, COL_INFO, "EM-MB, "); + break; + case PLC_MESSAGE_CHANNEL_MB: + last_mb = 1; + mb_length = tvb_captured_length_remaining(tvb, offset); + col_append_str(pinfo->cinfo, COL_INFO, "MC-MB"); + break; + case PLC_TRIGGER_MB: + mb_length = 9; + col_append_str(pinfo->cinfo, COL_INFO, "TRG-MB, "); + break; + /*Future Use Message Block*/ + default: + mb_length = 5 + 256*(mb_nibble2 &0x01) + mb_byte2; + col_append_str(pinfo->cinfo, COL_INFO, "FUT-MB, "); + break; + } + mb_tvb = tvb_new_subset_length(tvb, offset, tvb_captured_length_remaining(tvb, offset)); + dissect_message_block(mb_tvb,pinfo, plc_tree, mb_type, mb_length); + + if (last_mb) { + break; + } + + offset+= mb_length; + } + + return tvb_captured_length(tvb); +} + +static int +dissect_ncp(tvbuff_t * tvb, proto_tree * tree, void* data _U_) { + guint16 offset = 0; + proto_tree *ncp_tree; + proto_item *ncp_item; + tvbuff_t *ncp_mb_tvb; + + ncp_item = proto_tree_add_protocol_format (tree, proto_ncp, tvb, 0, -1,"DOCSIS NCP"); + ncp_tree = proto_item_add_subtree (ncp_item, ett_ncp); + + + while (tvb_captured_length_remaining(tvb, offset) > 3) { + ncp_mb_tvb = tvb_new_subset_length(tvb, offset, 3); + dissect_ncp_message_block(ncp_mb_tvb, ncp_tree); + + offset+= 3; + } + proto_tree_add_item (ncp_tree, hf_ncp_crc, tvb, offset, 3, ENC_NA); + + return tvb_captured_length(tvb); +} + +static int +dissect_init_ranging(tvbuff_t * tvb, proto_tree * tree, void* data _U_) { + + proto_tree *init_ranging_tree; + proto_item *init_ranging_item; + + init_ranging_item = proto_tree_add_protocol_format (tree, proto_init_ranging, tvb, 0, -1,"OFDMA Initial Ranging Request"); + init_ranging_tree = proto_item_add_subtree (init_ranging_item, ett_init_ranging); + + proto_tree_add_item (init_ranging_tree, hf_xra_init_ranging_mac, tvb, 0, 6, ENC_NA); + proto_tree_add_item (init_ranging_tree, hf_xra_init_ranging_ds_channel_id, tvb, 6, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (init_ranging_tree, hf_xra_init_ranging_crc, tvb, 7, 3, ENC_NA); + + return tvb_captured_length(tvb); +} + +static int +dissect_ofdma_segment(tvbuff_t * tvb, proto_tree * tree, void* data _U_) { + proto_tree *segment_tree; + proto_item *segment_item; + + + segment_item = proto_tree_add_protocol_format (tree, proto_segment, tvb, 0, -1,"DOCSIS Segment"); + segment_tree = proto_item_add_subtree (segment_item, ett_plc); + + proto_tree_add_item (segment_tree, hf_docsis_segment_pfi, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (segment_tree, hf_docsis_segment_reserved, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (segment_tree, hf_docsis_segment_pointerfield, tvb, 0, 2, ENC_BIG_ENDIAN); + proto_tree_add_item (segment_tree, hf_docsis_segment_sequencenumber, tvb, 2, 2, ENC_BIG_ENDIAN); + proto_tree_add_item (segment_tree, hf_docsis_segment_sidclusterid, tvb, 3, 1, ENC_BIG_ENDIAN); + proto_tree_add_item (segment_tree, hf_docsis_segment_request, tvb, 4, 2, ENC_BIG_ENDIAN); + proto_tree_add_item (segment_tree, hf_docsis_segment_hcs, tvb, 6, 2, ENC_BIG_ENDIAN); + proto_tree_add_item (segment_tree, hf_docsis_segment_data, tvb, 8, tvb_captured_length_remaining(tvb, 8), ENC_NA); + + return tvb_captured_length(tvb); +} + +void +proto_register_xra (void) +{ + static hf_register_info hf[] = { + {&hf_xra_version, + {"Version", "xra.version", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Xra Version", HFILL} + }, + {&hf_xra_direction, + {"Direction", "xra.direction", + FT_UINT8, BASE_DEC, VALS(direction_vals), 0xC0, + NULL, HFILL} + }, + {&hf_xra_packettype, + {"DS Packet Type", "xra.packettype", + FT_UINT8, BASE_DEC, VALS(packettype), 0x0, + NULL, HFILL} + }, + {&hf_xra_tlvlength, + {"TLV length", "xra.tlvlength", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv, + {"XRA TLV", "xra.tlv", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + /*XRA TLV*/ + {&hf_xra_tlv_ds_channel_id, + {"DS Channel ID", "xra.tlv.ds_channel_id", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_us_channel_id, + {"US Channel ID", "xra.tlv.us_channel_id", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_profile_id, + {"Profile", "xra.tlv.profile_id", + FT_UINT8, BASE_DEC, VALS(profile_id), 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_sid, + {"SID", "xra.tlv.sid", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_iuc, + {"IUC", "xra.tlv.iuc", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_burstid, + {"Burst ID", "xra.tlv.burstid", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ms_info, + {"Minislot Info", "xra.tlv.ms_info", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ucd_ccc_parity, + {"UCD CCC Parity", "xra.tlv.ucd_ccc_parity", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_grant_size, + {"Grant Size (bits)", "xra.tlv.grant_size", + FT_UINT32, BASE_DEC, NULL, 0x00FFFFFF, + NULL, HFILL} + }, + {&hf_xra_tlv_segment_header_present, + {"Segment Header Present", "xra.tlv.segment_header_present", + FT_UINT8, BASE_DEC, NULL,0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ncp_trunc, + {"Truncated due to uncorrectables", "xra.tlv.ncp.trunc", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ncp_symbolid, + {"SymbolId", "xra.tlv.ncp.symbolid", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + /*Ranging*/ + {&hf_xra_tlv_ranging_start_minislot_id_abs, + {"Start Minislot ID (absolute)", "xra.tlv.ranging.start_minislot_id_abs", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ranging_start_minislot_id_rel, + {"Start Minislot ID (relative)", "xra.tlv.ranging.start_minislot_id_rel", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ranging_stop_minislot_id_rel, + {"Stop Minislot ID (relative)", "xra.tlv.ranging.stop_minislot_id_rel", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ranging_number_ofdma_frames, + {"Number of OFDMA frames", "xra.tlv.ranging.number_ofdma_frames", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ranging_mer, + {"MER", "xra.tlv.ranging.mer", + FT_UINT8, BASE_CUSTOM, CF_FUNC(mer_fourth_db), 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_ranging_timing_adjust, + {"Timing Adjust (in 1/204.8 MHz units)", "xra.tlv.ranging.timing_adjust", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + /*Codeword Info DS*/ + {&hf_xra_tlv_cw_info, + {"Codeword Info", "xra.tlv.cw_info", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_nr_of_info_bytes, + {"Number of info bytes", "xra.tlv.cw_info.nr_of_info_bytes", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_bch_decoding_successful, + {"BCH decoding successful", "xra.tlv.cw_info.bch_decoding_successful", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_profile_parity, + {"Codeword parity", "xra.tlv.cw_info.profile_parity", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_bch_number_of_corrected_bits, + {"BCH Number of corrected bits", "xra.tlv.cw_info.bch_number_of_corrected_bits", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_ldpc_nr_of_code_bits, + {"Number of code bits", "xra.tlv.cw_info.ldpc_nr_of_code_bits", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_ldpc_decoding_successful, + {"LDPC decoding successful", "xra.tlv.cw_info.ldpc_decoding_successful", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_ldpc_number_of_iterations, + {"LDPC Number of iterations", "xra.tlv.cw_info.ldpc_number_of_iterations", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_cw_info_ldpc_number_of_corrected_bits, + {"LDPC Number of corrected info bits", "xra.tlv.cw_info.ldpc_number_of_corrected_bits", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_unknown, + {"Unknown", "xra.unknown", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + /*Burst Info */ + {&hf_xra_tlv_burst_info, + {"Burst Info", "xra.tlv.burst_info", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + {&hf_xra_tlv_burst_info_burst_id_reference, + {"Burst ID reference", "xra.tlv.burst_info.burst_id_reference", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + /*PLC specific*/ + {&hf_plc_mb, + {"PLC Message Block", "docsis_plc.mb_type", + FT_UINT8, BASE_DEC,VALS(message_block_type) , 0xF0, + NULL, HFILL} + }, + /*NCP specfific*/ + {&hf_ncp_mb, + {"NCP Message Block", "docsis_ncp.mb", + FT_BYTES, BASE_NONE,NULL , 0x0, + NULL, HFILL} + }, + {&hf_ncp_mb_profileid, + {"NCP MB Profile ID", "docsis_ncp.mb.profileid", + FT_UINT8, BASE_DEC,NULL , 0xF0, + NULL, HFILL} + }, + {&hf_ncp_mb_z, + {"NCP MB Zero Bit Loading", "docsis_ncp.mb.z", + FT_BOOLEAN, 8, TFS(&zero_bit_loading) , 0x08, + NULL, HFILL} + }, + {&hf_ncp_mb_c, + {"NCP MB Data Profile Update", "docsis_ncp.mb.z", + FT_BOOLEAN, 8, TFS(&data_profile_update) , 0x04, + NULL, HFILL} + }, + {&hf_ncp_mb_n, + {"NCP MB NCP Profile Selected", "docsis_ncp.mb.n", + FT_BOOLEAN, 8, TFS(&ncp_profile_select) , 0x02, + NULL, HFILL} + }, + {&hf_ncp_mb_l, + {"NCP MB Last NCP Block", "docsis_ncp.mb.l", + FT_BOOLEAN, 8, TFS(&last_ncp_block) , 0x01, + NULL, HFILL} + }, + {&hf_ncp_mb_t, + {"NCP MB Codeword Tagging", "docsis_ncp.mb.t", + FT_BOOLEAN, 8, TFS(&codeword_tagging) , 0x80, + NULL, HFILL} + }, + {&hf_ncp_mb_u, + {"NCP MB NCP Profile Update Indicator", "docsis_ncp.mb.u", + FT_BOOLEAN, 8, NULL , 0x40, + NULL, HFILL} + }, + {&hf_ncp_mb_r, + {"NCP MB Reserved", "docsis_ncp.mb.r", + FT_BOOLEAN, 8, NULL , 0x20, + NULL, HFILL} + }, + {&hf_ncp_mb_subcarrier_start_pointer, + {"NCP MB Subcarrier Start Pointer", "docsis_ncp.mb.subcarrier_start_pointer", + FT_UINT16, BASE_DEC, NULL , 0x1FFF, + NULL, HFILL} + }, + {&hf_ncp_crc, + {"NCP CRC", "docsis_ncp.crc", + FT_BYTES, BASE_NONE, NULL , 0x0, + NULL, HFILL} + }, + /*Init Ranging Specific*/ + {&hf_xra_init_ranging_mac, + {"MAC Address", "xra.init_ranging.mac", + FT_ETHER, BASE_NONE, NULL , 0x0, + NULL, HFILL} + }, + {&hf_xra_init_ranging_ds_channel_id, + {"DS Channel ID", "xra.init_ranging.ds_channel_id", + FT_UINT8, BASE_DEC, NULL , 0x0, + NULL, HFILL} + }, + {&hf_xra_init_ranging_crc, + {"CRC", "xra.init_ranging.crc", + FT_BYTES, BASE_NONE, NULL , 0x0, + NULL, HFILL} + }, + /*PLC MB*/ + {&hf_plc_em_mb, + {"PLC EM MB", "docsis_plc.em_mb", + FT_BYTES, BASE_NONE, NULL , 0x0, + NULL, HFILL} + }, + {&hf_plc_trigger_mb, + {"PLC Trigger MB", "docsis_plc.trigger_mb", + FT_BYTES, BASE_NONE, NULL , 0x0, + NULL, HFILL} + }, + /*Timestamp MB*/ + {&hf_plc_mb_ts_reserved, + {"Reserved", "docsis_plc.mb_ts_reserved", + FT_UINT8, BASE_DEC,0 , 0x0F, + NULL, HFILL} + }, + {&hf_plc_mb_ts_timestamp, + {"Timestamp", "docsis_plc.mb_ts_timestamp", + FT_UINT64, BASE_DEC,0 , 0x0, + NULL, HFILL} + }, + {&hf_plc_mb_ts_crc24d, + {"CRC-24-D", "docsis_plc.mb_ts_crc24d", + FT_BYTES, BASE_NONE, 0 , 0x0, + NULL, HFILL} + }, + /*Message Channel MB*/ + {&hf_plc_mb_mc_reserved, + {"Reserved", "docsis_plc.mb_mc_reserved", + FT_UINT8, BASE_DEC,0 , 0x0E, + NULL, HFILL} + }, + {&hf_plc_mb_mc_pspf_present, + {"Packet Start Pointer Field", "docsis_plc.mb_mc_pspf_present", + FT_UINT8, BASE_DEC, VALS(packet_start_pointer_field) , 0x01, + NULL, HFILL} + }, + {&hf_plc_mb_mc_psp, + {"Packet Start Pointer", "docsis_plc.mb_mc_psp", + FT_UINT16, BASE_DEC, 0 , 0x0, + NULL, HFILL} + }, + //DOCSIS SEGMENT + {&hf_docsis_segment_pfi, + {"Pointer Field Indicator", "docsis_segment.pfi", + FT_UINT8, BASE_DEC, NULL, 0x80, + NULL, HFILL} + }, + {&hf_docsis_segment_reserved, + {"Reserved", "docsis_segment.reserved", + FT_UINT8, BASE_DEC, NULL, 0x40, + NULL, HFILL} + }, + {&hf_docsis_segment_pointerfield, + {"Pointer Field", "docsis_segment.pointerfield", + FT_UINT16, BASE_DEC, NULL, 0x3FFF, + NULL, HFILL} + }, + {&hf_docsis_segment_sequencenumber, + {"Sequence Number", "docsis_segment.sequencenumber", + FT_UINT16, BASE_DEC, NULL, 0xFFF8, + NULL, HFILL} + }, + {&hf_docsis_segment_sidclusterid, + {"SID Cluster ID", "docsis_segment.sidclusterid", + FT_UINT8, BASE_DEC, NULL, 0x07, + NULL, HFILL} + }, + {&hf_docsis_segment_request, + {"Request (N bytes)", "docsis_segment.request", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + {&hf_docsis_segment_hcs, + {"HCS", "docsis_segment.hcs", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL} + }, + {&hf_docsis_segment_data, + {"Data", "docsis_segment.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL} + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_xra, + &ett_xra_tlv, + &ett_xra_tlv_cw_info, + &ett_xra_tlv_ms_info, + &ett_xra_tlv_burst_info, + &ett_plc, + &ett_plc_mb, + &ett_ncp, + &ett_ncp_mb, + &ett_init_ranging + }; + + + /* Register the protocol name and description */ + proto_xra = proto_register_protocol ("Excentis XRA header", "XRA", "xra"); + proto_segment = proto_register_protocol("DOCSIS Segment", "DOCSIS Segment", "docsis_segment"); + proto_plc = proto_register_protocol("DOCSIS PHY Link Channel", "DOCSIS PLC", "docsis_plc"); + proto_ncp = proto_register_protocol("DOCSIS_NCP", "DOCSIS_NCP", "docsis_ncp"); + proto_init_ranging = proto_register_protocol("DOCSIS_INIT_RANGING", "DOCSIS_INIT_RANGING", "docsis_init_ranging"); + + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array (proto_xra, hf, array_length (hf)); + proto_register_subtree_array (ett, array_length (ett)); + + register_dissector ("xra", dissect_xra, proto_xra); + +} + +void +proto_reg_handoff_xra(void) +{ + docsis_handle = find_dissector ("docsis"); + + xra_handle = create_dissector_handle(dissect_xra, proto_xra); + dissector_add_uint("wtap_encap", WTAP_ENCAP_DOCSIS31_XRA31, xra_handle); +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 2 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=2 tabstop=8 expandtab: + * :indentSize=2:tabSize=8:noTabs=true: + */ diff --git a/wiretap/pcap-common.c b/wiretap/pcap-common.c index d0aedb3e68..b401254390 100644 --- a/wiretap/pcap-common.c +++ b/wiretap/pcap-common.c @@ -455,6 +455,9 @@ static const struct { /* Nordic BLE Sniffer */ { 272, WTAP_ENCAP_NORDIC_BLE }, + /* DOCSIS31 XRA31 Sniffer */ + { 273, WTAP_ENCAP_DOCSIS31_XRA31 }, + /* mPackets as specified by 802.3br */ { 274, WTAP_ENCAP_ETHERNET_MPACKET }, diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 7c61cfd2f5..2853923a72 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -907,6 +907,10 @@ static struct encap_type_info encap_table_base[] = { /* WTAP_ENCAP_MA_WFP_CAPTURE_AUTH_V6 */ { "Message Analyzer WFP Capture Auth v6", "message_analyzer_wfp_capture_auth_v6" }, + + /* WTAP_ENCAP_DOCSIS31_XRA31 */ + { "DOCSIS31 XRA31", "docsis31_xra31" }, + }; WS_DLL_LOCAL diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 2072caf05c..d2e328dfaa 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -278,6 +278,7 @@ extern "C" { #define WTAP_ENCAP_MA_WFP_CAPTURE_AUTH_V6 196 #define WTAP_ENCAP_JUNIPER_ST 197 #define WTAP_ENCAP_ETHERNET_MPACKET 198 +#define WTAP_ENCAP_DOCSIS31_XRA31 199 /* After adding new item here, please also add new item to encap_table_base array */