diff options
author | Martin Kaiser <wireshark@kaiser.cx> | 2013-10-28 21:49:56 +0000 |
---|---|---|
committer | Martin Kaiser <wireshark@kaiser.cx> | 2013-10-28 21:49:56 +0000 |
commit | 6ef5eb635cbe9dfb4954588dcacedfc3779667de (patch) | |
tree | b98d1d4490d0a00145467413e70f18848302f183 /epan/dissectors/packet-mp2t.c | |
parent | 447d3938edef370b542915eb025650f18be1e5b0 (diff) |
TABs -> spaces
add editor modelines
svn path=/trunk/; revision=52934
Diffstat (limited to 'epan/dissectors/packet-mp2t.c')
-rw-r--r-- | epan/dissectors/packet-mp2t.c | 2418 |
1 files changed, 1202 insertions, 1216 deletions
diff --git a/epan/dissectors/packet-mp2t.c b/epan/dissectors/packet-mp2t.c index b32826fb6c..5035552e58 100644 --- a/epan/dissectors/packet-mp2t.c +++ b/epan/dissectors/packet-mp2t.c @@ -42,10 +42,10 @@ /* The MPEG2 TS packet size */ #define MP2T_PACKET_SIZE 188 -#define MP2T_SYNC_BYTE 0x47 +#define MP2T_SYNC_BYTE 0x47 -#define MP2T_PID_DOCSIS 0x1FFE -#define MP2T_PID_NULL 0x1FFF +#define MP2T_PID_DOCSIS 0x1FFE +#define MP2T_PID_NULL 0x1FFF static dissector_handle_t mp2t_handle; @@ -77,23 +77,23 @@ static int hf_mp2t_cc = -1; static int hf_mp2t_analysis_skips = -1; static int hf_mp2t_analysis_drops = -1; -#define MP2T_SYNC_BYTE_MASK 0xFF000000 -#define MP2T_TEI_MASK 0x00800000 -#define MP2T_PUSI_MASK 0x00400000 -#define MP2T_TP_MASK 0x00200000 -#define MP2T_PID_MASK 0x001FFF00 -#define MP2T_TSC_MASK 0x000000C0 -#define MP2T_AFC_MASK 0x00000030 -#define MP2T_CC_MASK 0x0000000F - -#define MP2T_SYNC_BYTE_SHIFT 24 -#define MP2T_TEI_SHIFT 23 -#define MP2T_PUSI_SHIFT 22 -#define MP2T_TP_SHIFT 21 -#define MP2T_PID_SHIFT 8 -#define MP2T_TSC_SHIFT 6 -#define MP2T_AFC_SHIFT 4 -#define MP2T_CC_SHIFT 0 +#define MP2T_SYNC_BYTE_MASK 0xFF000000 +#define MP2T_TEI_MASK 0x00800000 +#define MP2T_PUSI_MASK 0x00400000 +#define MP2T_TP_MASK 0x00200000 +#define MP2T_PID_MASK 0x001FFF00 +#define MP2T_TSC_MASK 0x000000C0 +#define MP2T_AFC_MASK 0x00000030 +#define MP2T_CC_MASK 0x0000000F + +#define MP2T_SYNC_BYTE_SHIFT 24 +#define MP2T_TEI_SHIFT 23 +#define MP2T_PUSI_SHIFT 22 +#define MP2T_TP_SHIFT 21 +#define MP2T_PID_SHIFT 8 +#define MP2T_TSC_SHIFT 6 +#define MP2T_AFC_SHIFT 4 +#define MP2T_CC_SHIFT 0 static int hf_mp2t_af = -1; static int hf_mp2t_af_length = -1; @@ -106,23 +106,23 @@ static int hf_mp2t_af_sp_flag = -1; static int hf_mp2t_af_tpd_flag = -1; static int hf_mp2t_af_afe_flag = -1; -#define MP2T_AF_DI_MASK 0x80 -#define MP2T_AF_RAI_MASK 0x40 -#define MP2T_AF_ESPI_MASK 0x20 -#define MP2T_AF_PCR_MASK 0x10 -#define MP2T_AF_OPCR_MASK 0x08 -#define MP2T_AF_SP_MASK 0x04 -#define MP2T_AF_TPD_MASK 0x02 -#define MP2T_AF_AFE_MASK 0x01 - -#define MP2T_AF_DI_SHIFT 7 -#define MP2T_AF_RAI_SHIFT 6 -#define MP2T_AF_ESPI_SHIFT 5 -#define MP2T_AF_PCR_SHIFT 4 -#define MP2T_AF_OPCR_SHIFT 3 -#define MP2T_AF_SP_SHIFT 2 -#define MP2T_AF_TPD_SHIFT 1 -#define MP2T_AF_AFE_SHIFT 0 +#define MP2T_AF_DI_MASK 0x80 +#define MP2T_AF_RAI_MASK 0x40 +#define MP2T_AF_ESPI_MASK 0x20 +#define MP2T_AF_PCR_MASK 0x10 +#define MP2T_AF_OPCR_MASK 0x08 +#define MP2T_AF_SP_MASK 0x04 +#define MP2T_AF_TPD_MASK 0x02 +#define MP2T_AF_AFE_MASK 0x01 + +#define MP2T_AF_DI_SHIFT 7 +#define MP2T_AF_RAI_SHIFT 6 +#define MP2T_AF_ESPI_SHIFT 5 +#define MP2T_AF_PCR_SHIFT 4 +#define MP2T_AF_OPCR_SHIFT 3 +#define MP2T_AF_SP_SHIFT 2 +#define MP2T_AF_TPD_SHIFT 1 +#define MP2T_AF_AFE_SHIFT 0 static int hf_mp2t_af_pcr = -1; static int hf_mp2t_af_opcr = -1; @@ -138,9 +138,9 @@ static int hf_mp2t_af_e_pr_flag = -1; static int hf_mp2t_af_e_ss_flag = -1; static int hf_mp2t_af_e_reserved = -1; -#define MP2T_AF_E_LTW_FLAG_MASK 0x80 -#define MP2T_AF_E_PR_FLAG_MASK 0x40 -#define MP2T_AF_E_SS_FLAG_MASK 0x20 +#define MP2T_AF_E_LTW_FLAG_MASK 0x80 +#define MP2T_AF_E_PR_FLAG_MASK 0x40 +#define MP2T_AF_E_SS_FLAG_MASK 0x20 static int hf_mp2t_af_e_reserved_bytes = -1; static int hf_mp2t_af_stuffing_bytes = -1; @@ -165,48 +165,48 @@ static int hf_mp2t_pointer = -1; static const value_string mp2t_sync_byte_vals[] = { - { MP2T_SYNC_BYTE, "Correct" }, - { 0, NULL } + { MP2T_SYNC_BYTE, "Correct" }, + { 0, NULL } }; static const value_string mp2t_pid_vals[] = { - { 0x0000, "Program Association Table" }, - { 0x0001, "Conditional Access Table" }, - { 0x0002, "Transport Stream Description Table" }, - { 0x0003, "Reserved" }, - { 0x0004, "Reserved" }, - { 0x0005, "Reserved" }, - { 0x0006, "Reserved" }, - { 0x0007, "Reserved" }, - { 0x0008, "Reserved" }, - { 0x0009, "Reserved" }, - { 0x000A, "Reserved" }, - { 0x000B, "Reserved" }, - { 0x000C, "Reserved" }, - { 0x000D, "Reserved" }, - { 0x000E, "Reserved" }, - { 0x000F, "Reserved" }, - { 0x1FFE, "DOCSIS Data-over-cable well-known PID" }, - { 0x1FFF, "Null packet" }, - { 0, NULL } + { 0x0000, "Program Association Table" }, + { 0x0001, "Conditional Access Table" }, + { 0x0002, "Transport Stream Description Table" }, + { 0x0003, "Reserved" }, + { 0x0004, "Reserved" }, + { 0x0005, "Reserved" }, + { 0x0006, "Reserved" }, + { 0x0007, "Reserved" }, + { 0x0008, "Reserved" }, + { 0x0009, "Reserved" }, + { 0x000A, "Reserved" }, + { 0x000B, "Reserved" }, + { 0x000C, "Reserved" }, + { 0x000D, "Reserved" }, + { 0x000E, "Reserved" }, + { 0x000F, "Reserved" }, + { 0x1FFE, "DOCSIS Data-over-cable well-known PID" }, + { 0x1FFF, "Null packet" }, + { 0, NULL } }; /* Values below according ETSI ETR 289 */ static const value_string mp2t_tsc_vals[] = { - { 0, "Not scrambled" }, - { 1, "Reserved" }, - { 2, "Packet scrambled with Even Key" }, - { 3, "Packet scrambled with Odd Key" }, - { 0, NULL } + { 0, "Not scrambled" }, + { 1, "Reserved" }, + { 2, "Packet scrambled with Even Key" }, + { 3, "Packet scrambled with Odd Key" }, + { 0, NULL } }; static const value_string mp2t_afc_vals[] = { - { 0, "Reserved" }, - { 1, "Payload only" }, - { 2, "Adaptation Field only" }, - { 3, "Adaptation Field and Payload" }, - { 0, NULL } + { 0, "Reserved" }, + { 1, "Payload only" }, + { 2, "Adaptation Field only" }, + { 3, "Adaptation Field and Payload" }, + { 0, NULL } }; static gint ett_msg_fragment = -1; @@ -226,26 +226,26 @@ static expert_field ei_mp2t_pointer = EI_INIT; static expert_field ei_mp2t_cc_drop = EI_INIT; static const fragment_items mp2t_msg_frag_items = { - /* Fragment subtrees */ - &ett_msg_fragment, - &ett_msg_fragments, - /* Fragment fields */ - &hf_msg_fragments, - &hf_msg_fragment, - &hf_msg_fragment_overlap, - &hf_msg_fragment_overlap_conflicts, - &hf_msg_fragment_multiple_tails, - &hf_msg_fragment_too_long_fragment, - &hf_msg_fragment_error, - &hf_msg_fragment_count, - /* Reassembled in field */ - &hf_msg_reassembled_in, - /* Reassembled length field */ - &hf_msg_reassembled_length, - /* Reassembled data field */ - NULL, - /* Tag */ - "Message fragments" + /* Fragment subtrees */ + &ett_msg_fragment, + &ett_msg_fragments, + /* Fragment fields */ + &hf_msg_fragments, + &hf_msg_fragment, + &hf_msg_fragment_overlap, + &hf_msg_fragment_overlap_conflicts, + &hf_msg_fragment_multiple_tails, + &hf_msg_fragment_too_long_fragment, + &hf_msg_fragment_error, + &hf_msg_fragment_count, + /* Reassembled in field */ + &hf_msg_reassembled_in, + /* Reassembled length field */ + &hf_msg_reassembled_length, + /* Reassembled data field */ + NULL, + /* Tag */ + "Message fragments" }; @@ -274,152 +274,152 @@ static const fragment_items mp2t_msg_frag_items = { typedef struct mp2t_analysis_data { - /* This structure contains a tree containing data for the - * individual pid's, this is only used when packets are - * processed sequencially. - */ - wmem_tree_t *pid_table; - - /* When detecting a CC drop, store that information for the - * given frame. This info is needed, when clicking around in - * wireshark, as the pid table data only makes sense during - * sequential processing. The flag pinfo->fd->flags.visited is - * used to tell the difference. - * - */ - wmem_tree_t *frame_table; - - /* Total counters per conversation / multicast stream */ - guint32 total_skips; - guint32 total_discontinuity; + /* This structure contains a tree containing data for the + * individual pid's, this is only used when packets are + * processed sequencially. + */ + wmem_tree_t *pid_table; + + /* When detecting a CC drop, store that information for the + * given frame. This info is needed, when clicking around in + * wireshark, as the pid table data only makes sense during + * sequential processing. The flag pinfo->fd->flags.visited is + * used to tell the difference. + * + */ + wmem_tree_t *frame_table; + + /* Total counters per conversation / multicast stream */ + guint32 total_skips; + guint32 total_discontinuity; } mp2t_analysis_data_t; enum pid_payload_type { - pid_pload_unknown, - pid_pload_docsis, - pid_pload_pes, - pid_pload_sect, - pid_pload_null + pid_pload_unknown, + pid_pload_docsis, + pid_pload_pes, + pid_pload_sect, + pid_pload_null }; typedef struct subpacket_analysis_data { - guint32 frag_cur_pos; - guint32 frag_tot_len; - gboolean fragmentation; - guint32 frag_id; + guint32 frag_cur_pos; + guint32 frag_tot_len; + gboolean fragmentation; + guint32 frag_id; } subpacket_analysis_data_t; typedef struct packet_analysis_data { - /* Contain information for each MPEG2-TS packet in the current big packet */ - wmem_tree_t *subpacket_table; + /* Contain information for each MPEG2-TS packet in the current big packet */ + wmem_tree_t *subpacket_table; } packet_analysis_data_t; /* Analysis TS frame info needed during sequential processing */ typedef struct pid_analysis_data { - guint16 pid; - gint8 cc_prev; /* Previous CC number */ - enum pid_payload_type pload_type; - - /* Fragments information used for first pass */ - gboolean fragmentation; - guint32 frag_cur_pos; - guint32 frag_tot_len; - guint32 frag_id; + guint16 pid; + gint8 cc_prev; /* Previous CC number */ + enum pid_payload_type pload_type; + + /* Fragments information used for first pass */ + gboolean fragmentation; + guint32 frag_cur_pos; + guint32 frag_tot_len; + guint32 frag_id; } pid_analysis_data_t; /* Analysis info stored for a TS frame */ typedef struct ts_analysis_data { - guint16 pid; - gint8 cc_prev; /* Previous CC number */ - guint8 skips; /* Skips between CCs max 14 */ + guint16 pid; + gint8 cc_prev; /* Previous CC number */ + guint8 skips; /* Skips between CCs max 14 */ } ts_analysis_data_t; typedef struct frame_analysis_data { - /* As each frame has several pid's, thus need a pid data - * structure per TS frame. - */ - wmem_tree_t *ts_table; + /* As each frame has several pid's, thus need a pid data + * structure per TS frame. + */ + wmem_tree_t *ts_table; } frame_analysis_data_t; static mp2t_analysis_data_t * init_mp2t_conversation_data(void) { - mp2t_analysis_data_t *mp2t_data = NULL; + mp2t_analysis_data_t *mp2t_data = NULL; - mp2t_data = wmem_new0(wmem_file_scope(), struct mp2t_analysis_data); + mp2t_data = wmem_new0(wmem_file_scope(), struct mp2t_analysis_data); - mp2t_data->pid_table = wmem_tree_new(wmem_file_scope()); + mp2t_data->pid_table = wmem_tree_new(wmem_file_scope()); - mp2t_data->frame_table = wmem_tree_new(wmem_file_scope()); + mp2t_data->frame_table = wmem_tree_new(wmem_file_scope()); - mp2t_data->total_skips = 0; - mp2t_data->total_discontinuity = 0; + mp2t_data->total_skips = 0; + mp2t_data->total_discontinuity = 0; - return mp2t_data; + return mp2t_data; } static mp2t_analysis_data_t * get_mp2t_conversation_data(conversation_t *conv) { - mp2t_analysis_data_t *mp2t_data = NULL; + mp2t_analysis_data_t *mp2t_data = NULL; - mp2t_data = (mp2t_analysis_data_t *)conversation_get_proto_data(conv, proto_mp2t); - if (!mp2t_data) { - mp2t_data = init_mp2t_conversation_data(); - conversation_add_proto_data(conv, proto_mp2t, mp2t_data); - } + mp2t_data = (mp2t_analysis_data_t *)conversation_get_proto_data(conv, proto_mp2t); + if (!mp2t_data) { + mp2t_data = init_mp2t_conversation_data(); + conversation_add_proto_data(conv, proto_mp2t, mp2t_data); + } - return mp2t_data; + return mp2t_data; } static frame_analysis_data_t * init_frame_analysis_data(mp2t_analysis_data_t *mp2t_data, packet_info *pinfo) { - frame_analysis_data_t *frame_analysis_data_p = NULL; + frame_analysis_data_t *frame_analysis_data_p = NULL; - frame_analysis_data_p = wmem_new0(wmem_file_scope(), struct frame_analysis_data); - frame_analysis_data_p->ts_table = wmem_tree_new(wmem_file_scope()); - /* Insert into mp2t tree */ - wmem_tree_insert32(mp2t_data->frame_table, pinfo->fd->num, - (void *)frame_analysis_data_p); + frame_analysis_data_p = wmem_new0(wmem_file_scope(), struct frame_analysis_data); + frame_analysis_data_p->ts_table = wmem_tree_new(wmem_file_scope()); + /* Insert into mp2t tree */ + wmem_tree_insert32(mp2t_data->frame_table, pinfo->fd->num, + (void *)frame_analysis_data_p); - return frame_analysis_data_p; + return frame_analysis_data_p; } static frame_analysis_data_t * get_frame_analysis_data(mp2t_analysis_data_t *mp2t_data, packet_info *pinfo) { - frame_analysis_data_t *frame_analysis_data_p = NULL; - frame_analysis_data_p = (frame_analysis_data_t *)wmem_tree_lookup32(mp2t_data->frame_table, pinfo->fd->num); - return frame_analysis_data_p; + frame_analysis_data_t *frame_analysis_data_p = NULL; + frame_analysis_data_p = (frame_analysis_data_t *)wmem_tree_lookup32(mp2t_data->frame_table, pinfo->fd->num); + return frame_analysis_data_p; } static pid_analysis_data_t * get_pid_analysis(guint32 pid, conversation_t *conv) { + pid_analysis_data_t *pid_data = NULL; + mp2t_analysis_data_t *mp2t_data = NULL; - pid_analysis_data_t *pid_data = NULL; - mp2t_analysis_data_t *mp2t_data = NULL; + mp2t_data = get_mp2t_conversation_data(conv); - mp2t_data = get_mp2t_conversation_data(conv); + pid_data = (pid_analysis_data_t *)wmem_tree_lookup32(mp2t_data->pid_table, pid); + if (!pid_data) { + pid_data = wmem_new0(wmem_file_scope(), struct pid_analysis_data); + pid_data->cc_prev = -1; + pid_data->pid = pid; + pid_data->frag_id = (pid << (32 - 13)) | 0x1; - pid_data = (pid_analysis_data_t *)wmem_tree_lookup32(mp2t_data->pid_table, pid); - if (!pid_data) { - pid_data = wmem_new0(wmem_file_scope(), struct pid_analysis_data); - pid_data->cc_prev = -1; - pid_data->pid = pid; - pid_data->frag_id = (pid << (32 - 13)) | 0x1; - - wmem_tree_insert32(mp2t_data->pid_table, pid, (void *)pid_data); - } - return pid_data; + wmem_tree_insert32(mp2t_data->pid_table, pid, (void *)pid_data); + } + return pid_data; } + /* Structure to handle packets, spanned across * multiple MPEG packets */ @@ -427,136 +427,127 @@ static reassembly_table mp2t_reassembly_table; static void mp2t_dissect_packet(tvbuff_t *tvb, enum pid_payload_type pload_type, - packet_info *pinfo, proto_tree *tree) + packet_info *pinfo, proto_tree *tree) { - dissector_handle_t handle = NULL; - - - switch (pload_type) { - case pid_pload_docsis: - handle = docsis_handle; - break; - case pid_pload_pes: - handle = mpeg_pes_handle; - break; - case pid_pload_sect: - handle = mpeg_sect_handle; - break; - default: - /* Should not happen */ - break; - - } - - if (handle) - call_dissector(handle, tvb, pinfo, tree); - else - call_dissector(data_handle, tvb, pinfo, tree); - - + dissector_handle_t handle = NULL; + + switch (pload_type) { + case pid_pload_docsis: + handle = docsis_handle; + break; + case pid_pload_pes: + handle = mpeg_pes_handle; + break; + case pid_pload_sect: + handle = mpeg_sect_handle; + break; + default: + /* Should not happen */ + break; + } + + if (handle) + call_dissector(handle, tvb, pinfo, tree); + else + call_dissector(data_handle, tvb, pinfo, tree); } guint mp2t_get_packet_length(tvbuff_t *tvb, guint offset, packet_info *pinfo, - guint32 frag_id, enum pid_payload_type pload_type) + guint32 frag_id, enum pid_payload_type pload_type) { - - fragment_head *frag = NULL; - tvbuff_t *len_tvb = NULL, *frag_tvb = NULL, *data_tvb = NULL; - gint pkt_len = 0; - guint remaining_len; - - - remaining_len = tvb_length_remaining(tvb, offset); - frag = fragment_get(&mp2t_reassembly_table, pinfo, frag_id, NULL); - if (frag) - frag = frag->next; - - if (!frag) { /* First frame */ - - if ( (pload_type == pid_pload_docsis && remaining_len < 4) || - (pload_type == pid_pload_sect && remaining_len < 3) || - (pload_type == pid_pload_pes && remaining_len < 5) ) { - /* Not enough info to determine the size of the encapulated packet */ - /* Just add the fragment and we'll check out the length later */ - return -1; - } - - len_tvb = tvb; - - } else { - /* Create a composite tvb out of the two */ - frag_tvb = tvb_new_proxy(frag->tvb_data); - len_tvb = tvb_new_composite(); - tvb_composite_append(len_tvb, frag_tvb); - - data_tvb = tvb_new_subset_remaining(tvb, offset); - tvb_composite_append(len_tvb, data_tvb); - tvb_composite_finalize(len_tvb); - - offset = frag->offset; - - } - - /* Get the next packet's size if possible */ - - switch (pload_type) { - case pid_pload_docsis: - pkt_len = tvb_get_ntohs(len_tvb, offset + 2) + 6; - break; - case pid_pload_pes: - pkt_len = tvb_get_ntohs(len_tvb, offset + 4); - if (pkt_len) /* A size of 0 means size not bounded */ - pkt_len += 6; - break; - case pid_pload_sect: - pkt_len = (tvb_get_ntohs(len_tvb, offset + 1) & 0xFFF) + 3; - break; - default: - /* Should not happen */ - break; - } - - if (frag_tvb) - tvb_free(frag_tvb); - - return pkt_len; + fragment_head *frag = NULL; + tvbuff_t *len_tvb = NULL, *frag_tvb = NULL, *data_tvb = NULL; + gint pkt_len = 0; + guint remaining_len; + + remaining_len = tvb_length_remaining(tvb, offset); + frag = fragment_get(&mp2t_reassembly_table, pinfo, frag_id, NULL); + if (frag) + frag = frag->next; + + if (!frag) { /* First frame */ + if ( (pload_type == pid_pload_docsis && remaining_len < 4) || + (pload_type == pid_pload_sect && remaining_len < 3) || + (pload_type == pid_pload_pes && remaining_len < 5) ) { + /* Not enough info to determine the size of the encapulated packet */ + /* Just add the fragment and we'll check out the length later */ + return -1; + } + + len_tvb = tvb; + } else { + /* Create a composite tvb out of the two */ + frag_tvb = tvb_new_proxy(frag->tvb_data); + len_tvb = tvb_new_composite(); + tvb_composite_append(len_tvb, frag_tvb); + + data_tvb = tvb_new_subset_remaining(tvb, offset); + tvb_composite_append(len_tvb, data_tvb); + tvb_composite_finalize(len_tvb); + + offset = frag->offset; + } + + /* Get the next packet's size if possible */ + switch (pload_type) { + case pid_pload_docsis: + pkt_len = tvb_get_ntohs(len_tvb, offset + 2) + 6; + break; + case pid_pload_pes: + pkt_len = tvb_get_ntohs(len_tvb, offset + 4); + if (pkt_len) /* A size of 0 means size not bounded */ + pkt_len += 6; + break; + case pid_pload_sect: + pkt_len = (tvb_get_ntohs(len_tvb, offset + 1) & 0xFFF) + 3; + break; + default: + /* Should not happen */ + break; + } + + if (frag_tvb) + tvb_free(frag_tvb); + + return pkt_len; } static void mp2t_fragment_handle(tvbuff_t *tvb, guint offset, packet_info *pinfo, - proto_tree *tree, guint32 frag_id, - guint frag_offset, guint frag_len, - gboolean fragment_last, enum pid_payload_type pload_type) + proto_tree *tree, guint32 frag_id, + guint frag_offset, guint frag_len, + gboolean fragment_last, enum pid_payload_type pload_type) { - /* proto_item *ti; */ - fragment_head *frag_msg = NULL; - tvbuff_t *new_tvb = NULL; - gboolean save_fragmented; - - save_fragmented = pinfo->fragmented; - pinfo->fragmented = TRUE; - - /* check length; send frame for reassembly */ - frag_msg = fragment_add_check(&mp2t_reassembly_table, - tvb, offset, pinfo, frag_id, NULL, - frag_offset, - frag_len, - !fragment_last); - - new_tvb = process_reassembled_data(tvb, offset, pinfo, - "Reassembled MP2T", - frag_msg, &mp2t_msg_frag_items, - NULL, tree); - - if (new_tvb) { - /* ti = */ proto_tree_add_text(tree, tvb, 0, 0, "MPEG TS Packet (reassembled)"); - mp2t_dissect_packet(new_tvb, pload_type, pinfo, tree); - } - - pinfo->fragmented = save_fragmented; + /* proto_item *ti; */ + fragment_head *frag_msg = NULL; + tvbuff_t *new_tvb = NULL; + gboolean save_fragmented; + + save_fragmented = pinfo->fragmented; + pinfo->fragmented = TRUE; + + /* check length; send frame for reassembly */ + frag_msg = fragment_add_check(&mp2t_reassembly_table, + tvb, offset, pinfo, frag_id, NULL, + frag_offset, + frag_len, + !fragment_last); + + new_tvb = process_reassembled_data(tvb, offset, pinfo, + "Reassembled MP2T", + frag_msg, &mp2t_msg_frag_items, + NULL, tree); + + if (new_tvb) { + /* ti = */ proto_tree_add_text(tree, tvb, 0, 0, "MPEG TS Packet (reassembled)"); + mp2t_dissect_packet(new_tvb, pload_type, pinfo, tree); + } + + pinfo->fragmented = save_fragmented; } + /* Decoding of DOCSIS MAC frames within MPEG packets. MAC frames may begin anywhere * within an MPEG packet or span multiple MPEG packets. * payload_unit_start_indicator bit in MPEG header, and pointer field are used to @@ -578,220 +569,209 @@ mp2t_fragment_handle(tvbuff_t *tvb, guint offset, packet_info *pinfo, */ static void mp2t_process_fragmented_payload(tvbuff_t *tvb, gint offset, guint remaining_len, packet_info *pinfo, - proto_tree *tree, proto_tree *header_tree, guint32 pusi_flag, - pid_analysis_data_t *pid_analysis) + proto_tree *tree, proto_tree *header_tree, guint32 pusi_flag, + pid_analysis_data_t *pid_analysis) { - tvbuff_t *next_tvb; - guint8 pointer = 0; - proto_item *pi; - guint stuff_len = 0; - proto_item *si; - proto_tree *stuff_tree; - packet_analysis_data_t *pdata = NULL; - subpacket_analysis_data_t *spdata = NULL; - guint32 frag_cur_pos = 0, frag_tot_len = 0; - gboolean fragmentation = FALSE; - guint32 frag_id = 0; - - if (pusi_flag && pid_analysis->pload_type == pid_pload_unknown - && remaining_len > 3) { - /* We should already have identified if it was a DOCSIS packet - * Remaining possibility is PES or SECT */ - if (tvb_get_ntoh24(tvb, offset) == 0x000001) { - /* Looks like a PES packet to me ... */ - pid_analysis->pload_type = pid_pload_pes; - } else { - /* Most probably a SECT packet */ - pid_analysis->pload_type = pid_pload_sect; - } - - } - - /* Unable to determine the payload type, do nothing */ - if (pid_analysis->pload_type == pid_pload_unknown) - return; - - /* PES packet don't have pointer fields, others do */ - if (pusi_flag && pid_analysis->pload_type != pid_pload_pes) { - pointer = tvb_get_guint8(tvb, offset); - pi = proto_tree_add_item(header_tree, hf_mp2t_pointer, tvb, offset, 1, ENC_BIG_ENDIAN); - offset++; - remaining_len--; - if (pointer > remaining_len) { - /* Bogus pointer */ - expert_add_info_format(pinfo, pi, &ei_mp2t_pointer, - "Pointer value is too large (> remaining data length %u)", - remaining_len); - } - - } - - if (!pinfo->fd->flags.visited) { - /* Get values from our current PID analysis */ - frag_cur_pos = pid_analysis->frag_cur_pos; - frag_tot_len = pid_analysis->frag_tot_len; - fragmentation = pid_analysis->fragmentation; - frag_id = pid_analysis->frag_id; - pdata = (packet_analysis_data_t *)p_get_proto_data(pinfo->fd, proto_mp2t, 0); - if (!pdata) { - pdata = wmem_new0(wmem_file_scope(), packet_analysis_data_t); - pdata->subpacket_table = wmem_tree_new(wmem_file_scope()); - p_add_proto_data(pinfo->fd, proto_mp2t, 0, pdata); - - } else { - spdata = (subpacket_analysis_data_t *)wmem_tree_lookup32(pdata->subpacket_table, offset); - } - - if (!spdata) { - spdata = wmem_new0(wmem_file_scope(), subpacket_analysis_data_t); - /* Save the info into pdata from pid_analysis */ - spdata->frag_cur_pos = frag_cur_pos; - spdata->frag_tot_len = frag_tot_len; - spdata->fragmentation = fragmentation; - spdata->frag_id = frag_id; - wmem_tree_insert32(pdata->subpacket_table, offset, (void *)spdata); - - } - - } else { - /* Get saved values */ - pdata = (packet_analysis_data_t *)p_get_proto_data(pinfo->fd, proto_mp2t, 0); - if (!pdata) { - /* Occurs for the first packets in the capture which cannot be reassembled */ - return; - } - - spdata = (subpacket_analysis_data_t *)wmem_tree_lookup32(pdata->subpacket_table, offset); - if (!spdata) { - /* Occurs for the first sub packets in the capture which cannot be reassembled */ - return; - } - - frag_cur_pos = spdata->frag_cur_pos; - frag_tot_len = spdata->frag_tot_len; - fragmentation = spdata->fragmentation; - frag_id = spdata->frag_id; - } - - if (frag_tot_len == (guint)-1) { - frag_tot_len = mp2t_get_packet_length(tvb, offset, pinfo, frag_id, pid_analysis->pload_type); - - if (frag_tot_len == (guint)-1) { - return; - } - - } - - - /* The beginning of a new packet is present */ - if (pusi_flag) { - - if (pointer > remaining_len) { - /* - * Quit, so we don't use the bogus pointer value; - * that could cause remaining_len to become - * "negative", meaning it becomes a very large - * positive value. - */ - return; - } - - /* Looks like we already have some stuff in the buffer */ - if (fragmentation) { - mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, - pointer, TRUE, pid_analysis->pload_type); - frag_id++; - } - - offset += pointer; - remaining_len -= pointer; - fragmentation = FALSE; - frag_cur_pos = 0; - frag_tot_len = 0; - - if (!remaining_len) { - /* Shouldn't happen */ - goto save_state; - } - - while (remaining_len > 0) { - - /* Skip stuff bytes */ - stuff_len = 0; - while ((tvb_get_guint8(tvb, offset + stuff_len) == 0xFF)) { - stuff_len++; - if (stuff_len >= remaining_len) { - remaining_len = 0; - break; - } - } - - if (stuff_len) { - si = proto_tree_add_text(tree, tvb, offset, stuff_len, "Stuffing"); - stuff_tree = proto_item_add_subtree(si, ett_stuff); - proto_tree_add_item(stuff_tree, hf_mp2t_stuff_bytes, tvb, offset, stuff_len, ENC_NA); - offset += stuff_len; - if (stuff_len >= remaining_len) { - goto save_state; - } - remaining_len -= stuff_len; - - } - - - /* Get the next packet's size if possible */ - frag_tot_len = mp2t_get_packet_length(tvb, offset, pinfo, frag_id, pid_analysis->pload_type); - if (frag_tot_len == (guint)-1 || !frag_tot_len) { - mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, 0, remaining_len, FALSE, pid_analysis->pload_type); - fragmentation = TRUE; - /*offset += remaining_len;*/ - frag_cur_pos += remaining_len; - goto save_state; - } - - /* Check for full packets within this TS frame */ - if (frag_tot_len && - frag_tot_len <= remaining_len) { - next_tvb = tvb_new_subset(tvb, offset, frag_tot_len, frag_tot_len); - mp2t_dissect_packet(next_tvb, pid_analysis->pload_type, pinfo, tree); - remaining_len -= frag_tot_len; - offset += frag_tot_len; - frag_tot_len = 0; - } else { - break; - } - - } - - if (remaining_len == 0) { - pid_analysis->frag_cur_pos = 0; - pid_analysis->frag_tot_len = 0; - goto save_state; - - } - - } - - /* There are remaining bytes. Add them to the fragment list */ - - if ((frag_tot_len && frag_cur_pos + remaining_len >= frag_tot_len) || (!frag_tot_len && pusi_flag)) { - mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, remaining_len, TRUE, pid_analysis->pload_type); - frag_id++; - fragmentation = FALSE; - frag_cur_pos = 0; - frag_tot_len = 0; - } else { - mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, remaining_len, FALSE, pid_analysis->pload_type); - fragmentation = TRUE; - frag_cur_pos += remaining_len; - } + tvbuff_t *next_tvb; + guint8 pointer = 0; + proto_item *pi; + guint stuff_len = 0; + proto_item *si; + proto_tree *stuff_tree; + packet_analysis_data_t *pdata = NULL; + subpacket_analysis_data_t *spdata = NULL; + guint32 frag_cur_pos = 0, frag_tot_len = 0; + gboolean fragmentation = FALSE; + guint32 frag_id = 0; + + if (pusi_flag && pid_analysis->pload_type == pid_pload_unknown + && remaining_len > 3) { + /* We should already have identified if it was a DOCSIS packet + * Remaining possibility is PES or SECT */ + if (tvb_get_ntoh24(tvb, offset) == 0x000001) { + /* Looks like a PES packet to me ... */ + pid_analysis->pload_type = pid_pload_pes; + } else { + /* Most probably a SECT packet */ + pid_analysis->pload_type = pid_pload_sect; + } + } + + /* Unable to determine the payload type, do nothing */ + if (pid_analysis->pload_type == pid_pload_unknown) + return; + + /* PES packet don't have pointer fields, others do */ + if (pusi_flag && pid_analysis->pload_type != pid_pload_pes) { + pointer = tvb_get_guint8(tvb, offset); + pi = proto_tree_add_item(header_tree, hf_mp2t_pointer, tvb, offset, 1, ENC_BIG_ENDIAN); + offset++; + remaining_len--; + if (pointer > remaining_len) { + /* Bogus pointer */ + expert_add_info_format(pinfo, pi, &ei_mp2t_pointer, + "Pointer value is too large (> remaining data length %u)", + remaining_len); + } + } + + if (!pinfo->fd->flags.visited) { + /* Get values from our current PID analysis */ + frag_cur_pos = pid_analysis->frag_cur_pos; + frag_tot_len = pid_analysis->frag_tot_len; + fragmentation = pid_analysis->fragmentation; + frag_id = pid_analysis->frag_id; + pdata = (packet_analysis_data_t *)p_get_proto_data(pinfo->fd, proto_mp2t, 0); + if (!pdata) { + pdata = wmem_new0(wmem_file_scope(), packet_analysis_data_t); + pdata->subpacket_table = wmem_tree_new(wmem_file_scope()); + p_add_proto_data(pinfo->fd, proto_mp2t, 0, pdata); + + } else { + spdata = (subpacket_analysis_data_t *)wmem_tree_lookup32(pdata->subpacket_table, offset); + } + + if (!spdata) { + spdata = wmem_new0(wmem_file_scope(), subpacket_analysis_data_t); + /* Save the info into pdata from pid_analysis */ + spdata->frag_cur_pos = frag_cur_pos; + spdata->frag_tot_len = frag_tot_len; + spdata->fragmentation = fragmentation; + spdata->frag_id = frag_id; + wmem_tree_insert32(pdata->subpacket_table, offset, (void *)spdata); + } + } else { + /* Get saved values */ + pdata = (packet_analysis_data_t *)p_get_proto_data(pinfo->fd, proto_mp2t, 0); + if (!pdata) { + /* Occurs for the first packets in the capture which cannot be reassembled */ + return; + } + + spdata = (subpacket_analysis_data_t *)wmem_tree_lookup32(pdata->subpacket_table, offset); + if (!spdata) { + /* Occurs for the first sub packets in the capture which cannot be reassembled */ + return; + } + + frag_cur_pos = spdata->frag_cur_pos; + frag_tot_len = spdata->frag_tot_len; + fragmentation = spdata->fragmentation; + frag_id = spdata->frag_id; + } + + if (frag_tot_len == (guint)-1) { + frag_tot_len = mp2t_get_packet_length(tvb, offset, pinfo, frag_id, pid_analysis->pload_type); + + if (frag_tot_len == (guint)-1) { + return; + } + } + + + /* The beginning of a new packet is present */ + if (pusi_flag) { + if (pointer > remaining_len) { + /* + * Quit, so we don't use the bogus pointer value; + * that could cause remaining_len to become + * "negative", meaning it becomes a very large + * positive value. + */ + return; + } + + /* Looks like we already have some stuff in the buffer */ + if (fragmentation) { + mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, + pointer, TRUE, pid_analysis->pload_type); + frag_id++; + } + + offset += pointer; + remaining_len -= pointer; + fragmentation = FALSE; + frag_cur_pos = 0; + frag_tot_len = 0; + + if (!remaining_len) { + /* Shouldn't happen */ + goto save_state; + } + + while (remaining_len > 0) { + /* Skip stuff bytes */ + stuff_len = 0; + while ((tvb_get_guint8(tvb, offset + stuff_len) == 0xFF)) { + stuff_len++; + if (stuff_len >= remaining_len) { + remaining_len = 0; + break; + } + } + + if (stuff_len) { + si = proto_tree_add_text(tree, tvb, offset, stuff_len, "Stuffing"); + stuff_tree = proto_item_add_subtree(si, ett_stuff); + proto_tree_add_item(stuff_tree, hf_mp2t_stuff_bytes, tvb, offset, stuff_len, ENC_NA); + offset += stuff_len; + if (stuff_len >= remaining_len) { + goto save_state; + } + remaining_len -= stuff_len; + } + + /* Get the next packet's size if possible */ + frag_tot_len = mp2t_get_packet_length(tvb, offset, pinfo, frag_id, pid_analysis->pload_type); + if (frag_tot_len == (guint)-1 || !frag_tot_len) { + mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, 0, remaining_len, FALSE, pid_analysis->pload_type); + fragmentation = TRUE; + /*offset += remaining_len;*/ + frag_cur_pos += remaining_len; + goto save_state; + } + + /* Check for full packets within this TS frame */ + if (frag_tot_len && + frag_tot_len <= remaining_len) { + next_tvb = tvb_new_subset(tvb, offset, frag_tot_len, frag_tot_len); + mp2t_dissect_packet(next_tvb, pid_analysis->pload_type, pinfo, tree); + remaining_len -= frag_tot_len; + offset += frag_tot_len; + frag_tot_len = 0; + } else { + break; + } + } + + if (remaining_len == 0) { + pid_analysis->frag_cur_pos = 0; + pid_analysis->frag_tot_len = 0; + goto save_state; + + } + + } + + /* There are remaining bytes. Add them to the fragment list */ + + if ((frag_tot_len && frag_cur_pos + remaining_len >= frag_tot_len) || (!frag_tot_len && pusi_flag)) { + mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, remaining_len, TRUE, pid_analysis->pload_type); + frag_id++; + fragmentation = FALSE; + frag_cur_pos = 0; + frag_tot_len = 0; + } else { + mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, remaining_len, FALSE, pid_analysis->pload_type); + fragmentation = TRUE; + frag_cur_pos += remaining_len; + } save_state: - - pid_analysis->fragmentation = fragmentation; - pid_analysis->frag_cur_pos = frag_cur_pos; - pid_analysis->frag_tot_len = frag_tot_len; - pid_analysis->frag_id = frag_id; + pid_analysis->fragmentation = fragmentation; + pid_analysis->frag_cur_pos = frag_cur_pos; + pid_analysis->frag_tot_len = frag_tot_len; + pid_analysis->frag_id = frag_id; } @@ -803,757 +783,751 @@ save_state: static guint32 calc_skips(gint32 curr, gint32 prev) { - int res = 0; + int res = 0; - /* Only count the missing TS frames in between prev and curr. - * The "prev" frame CC number seen is confirmed received, it's - * the next frames CC counter which is the first known missing - * TS frame - */ - prev += 1; + /* Only count the missing TS frames in between prev and curr. + * The "prev" frame CC number seen is confirmed received, it's + * the next frames CC counter which is the first known missing + * TS frame + */ + prev += 1; - /* Calc missing TS frame 'skips' */ - res = curr - prev; + /* Calc missing TS frame 'skips' */ + res = curr - prev; - /* Handle wrap around */ - if (res < 0) - res += 16; + /* Handle wrap around */ + if (res < 0) + res += 16; - return res; + return res; } #define KEY(pid, cc) ((pid << 4)|cc) static guint32 detect_cc_drops(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, - guint32 pid, gint32 cc_curr, conversation_t *conv) + guint32 pid, gint32 cc_curr, conversation_t *conv) { - gint32 cc_prev = -1; - pid_analysis_data_t *pid_data = NULL; - ts_analysis_data_t *ts_data = NULL; - mp2t_analysis_data_t *mp2t_data = NULL; - frame_analysis_data_t *frame_analysis_data_p = NULL; - proto_item *flags_item; - - guint32 detected_drop = 0; - guint32 skips = 0; - - mp2t_data = get_mp2t_conversation_data(conv); - - /* The initial sequencial processing stage */ - if (!pinfo->fd->flags.visited) { - - /* This is the sequencial processing stage */ - pid_data = get_pid_analysis(pid, conv); - - cc_prev = pid_data->cc_prev; - pid_data->cc_prev = cc_curr; - - /* Null packet always have a CC value equal 0 */ - if (pid == 0x1fff) - return 0; - - /* Its allowed that (cc_prev == cc_curr) if adaptation field */ - if (cc_prev == cc_curr) - return 0; - - /* Have not seen this pid before */ - if (cc_prev == -1) - return 0; - - /* Detect if CC is not increasing by one all the time */ - if (cc_curr != ((cc_prev+1) & MP2T_CC_MASK)) { - detected_drop = 1; - - skips = calc_skips(cc_curr, cc_prev); - - mp2t_data->total_skips += skips; - mp2t_data->total_discontinuity++; - /* TODO: if (skips > 7) signal_loss++; ??? */ - } - } - - /* Save the info about the dropped packet */ - if (detected_drop && !pinfo->fd->flags.visited) { - - /* Lookup frame data, contains TS pid data objects */ - frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo); - if (!frame_analysis_data_p) - frame_analysis_data_p = init_frame_analysis_data(mp2t_data, pinfo); - - /* Create and store a new TS frame pid_data object. - This indicate that we have a drop - */ - ts_data = wmem_new0(wmem_file_scope(), struct ts_analysis_data); - ts_data->cc_prev = cc_prev; - ts_data->pid = pid; - ts_data->skips = skips; - wmem_tree_insert32(frame_analysis_data_p->ts_table, KEY(pid, cc_curr), - (void *)ts_data); - } - - /* See if we stored info about drops */ - if (pinfo->fd->flags.visited) { - - /* Lookup frame data, contains TS pid data objects */ - frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo); - if (!frame_analysis_data_p) - return 0; /* No stored frame data -> no drops*/ - else { - ts_data = (struct ts_analysis_data *)wmem_tree_lookup32(frame_analysis_data_p->ts_table, - KEY(pid, cc_curr)); - - if (ts_data) { - if (ts_data->skips > 0) { - detected_drop = 1; - cc_prev = ts_data->cc_prev; - skips = ts_data->skips; - } - } - } - - } - - /* Add info to the proto tree about drops */ - if (detected_drop) { - expert_add_info_format(pinfo, tree, &ei_mp2t_cc_drop, - "Detected %d missing TS frames before this (last_cc:%d total skips:%d discontinuity:%d)", - skips, cc_prev, - mp2t_data->total_skips, - mp2t_data->total_discontinuity - ); - - flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_skips, - tvb, 0, 0, skips); - PROTO_ITEM_SET_GENERATED(flags_item); - - flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_drops, - - tvb, 0, 0, 1); - PROTO_ITEM_SET_GENERATED(flags_item); - - } - return skips; + gint32 cc_prev = -1; + pid_analysis_data_t *pid_data = NULL; + ts_analysis_data_t *ts_data = NULL; + mp2t_analysis_data_t *mp2t_data = NULL; + frame_analysis_data_t *frame_analysis_data_p = NULL; + proto_item *flags_item; + + guint32 detected_drop = 0; + guint32 skips = 0; + + mp2t_data = get_mp2t_conversation_data(conv); + + /* The initial sequencial processing stage */ + if (!pinfo->fd->flags.visited) { + /* This is the sequencial processing stage */ + pid_data = get_pid_analysis(pid, conv); + + cc_prev = pid_data->cc_prev; + pid_data->cc_prev = cc_curr; + + /* Null packet always have a CC value equal 0 */ + if (pid == 0x1fff) + return 0; + + /* Its allowed that (cc_prev == cc_curr) if adaptation field */ + if (cc_prev == cc_curr) + return 0; + + /* Have not seen this pid before */ + if (cc_prev == -1) + return 0; + + /* Detect if CC is not increasing by one all the time */ + if (cc_curr != ((cc_prev+1) & MP2T_CC_MASK)) { + detected_drop = 1; + + skips = calc_skips(cc_curr, cc_prev); + + mp2t_data->total_skips += skips; + mp2t_data->total_discontinuity++; + /* TODO: if (skips > 7) signal_loss++; ??? */ + } + } + + /* Save the info about the dropped packet */ + if (detected_drop && !pinfo->fd->flags.visited) { + /* Lookup frame data, contains TS pid data objects */ + frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo); + if (!frame_analysis_data_p) + frame_analysis_data_p = init_frame_analysis_data(mp2t_data, pinfo); + + /* Create and store a new TS frame pid_data object. + This indicate that we have a drop + */ + ts_data = wmem_new0(wmem_file_scope(), struct ts_analysis_data); + ts_data->cc_prev = cc_prev; + ts_data->pid = pid; + ts_data->skips = skips; + wmem_tree_insert32(frame_analysis_data_p->ts_table, KEY(pid, cc_curr), + (void *)ts_data); + } + + /* See if we stored info about drops */ + if (pinfo->fd->flags.visited) { + + /* Lookup frame data, contains TS pid data objects */ + frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo); + if (!frame_analysis_data_p) + return 0; /* No stored frame data -> no drops*/ + else { + ts_data = (struct ts_analysis_data *)wmem_tree_lookup32(frame_analysis_data_p->ts_table, + KEY(pid, cc_curr)); + + if (ts_data) { + if (ts_data->skips > 0) { + detected_drop = 1; + cc_prev = ts_data->cc_prev; + skips = ts_data->skips; + } + } + } + } + + /* Add info to the proto tree about drops */ + if (detected_drop) { + expert_add_info_format(pinfo, tree, &ei_mp2t_cc_drop, + "Detected %d missing TS frames before this (last_cc:%d total skips:%d discontinuity:%d)", + skips, cc_prev, + mp2t_data->total_skips, + mp2t_data->total_discontinuity + ); + + flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_skips, + tvb, 0, 0, skips); + PROTO_ITEM_SET_GENERATED(flags_item); + + flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_drops, + tvb, 0, 0, 1); + PROTO_ITEM_SET_GENERATED(flags_item); + } + return skips; } static void dissect_tsp(tvbuff_t *tvb, volatile gint offset, packet_info *pinfo, - proto_tree *tree, conversation_t *conv) + proto_tree *tree, conversation_t *conv) { - guint32 header; - guint afc; - gint start_offset = offset; - volatile gint payload_len; - pid_analysis_data_t *pid_analysis; - - guint32 skips; - guint32 pid; - guint32 cc; - guint32 pusi_flag; - - guint32 tsc; - - proto_item *ti = NULL; - proto_item *hi = NULL; - proto_item *item = NULL; - proto_tree *mp2t_tree = NULL; - proto_tree *mp2t_header_tree = NULL; - proto_tree *mp2t_af_tree = NULL; - proto_tree *mp2t_analysis_tree = NULL; - proto_item *afci = NULL; - - ti = proto_tree_add_item( tree, proto_mp2t, tvb, offset, MP2T_PACKET_SIZE, ENC_NA ); - mp2t_tree = proto_item_add_subtree( ti, ett_mp2t ); - - header = tvb_get_ntohl(tvb, offset); - - pid = (header & MP2T_PID_MASK) >> MP2T_PID_SHIFT; - cc = (header & MP2T_CC_MASK) >> MP2T_CC_SHIFT; - tsc = (header & MP2T_TSC_MASK); - pusi_flag = (header & 0x00400000); - proto_item_append_text(ti, " PID=0x%x CC=%d", pid, cc); - col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG TS"); - - hi = proto_tree_add_item( mp2t_tree, hf_mp2t_header, tvb, offset, 4, ENC_BIG_ENDIAN); - mp2t_header_tree = proto_item_add_subtree( hi, ett_mp2t_header ); - - proto_tree_add_item( mp2t_header_tree, hf_mp2t_sync_byte, tvb, offset, 4, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_header_tree, hf_mp2t_tei, tvb, offset, 4, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_header_tree, hf_mp2t_pusi, tvb, offset, 4, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_header_tree, hf_mp2t_tp, tvb, offset, 4, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_header_tree, hf_mp2t_pid, tvb, offset, 4, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_header_tree, hf_mp2t_tsc, tvb, offset, 4, ENC_BIG_ENDIAN); - afci = proto_tree_add_item( mp2t_header_tree, hf_mp2t_afc, tvb, offset, 4, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_header_tree, hf_mp2t_cc, tvb, offset, 4, ENC_BIG_ENDIAN); - - afc = (header & MP2T_AFC_MASK) >> MP2T_AFC_SHIFT; - - pid_analysis = get_pid_analysis(pid, conv); - - /* Find out the payload type based on the payload */ - if (pid_analysis->pload_type == pid_pload_unknown) { - if (pid == MP2T_PID_NULL) { - pid_analysis->pload_type = pid_pload_null; - } else if (pid == MP2T_PID_DOCSIS) { - pid_analysis->pload_type = pid_pload_docsis; - } - } - - if (pid_analysis->pload_type == pid_pload_docsis && afc) { - /* DOCSIS packets should not have an adaptation field */ - proto_item_append_text(afci, " (Invalid for DOCSIS packets, should be 0)"); - } - - if (pid_analysis->pload_type == pid_pload_null) { - /* Nothing more to do */ - col_set_str(pinfo->cinfo, COL_INFO, "NULL packet"); - proto_item_append_text(afci, " (Should be 0 for NULL packets)"); - return; - } - - offset += 4; - - /* Create a subtree for analysis stuff */ - item = proto_tree_add_text(mp2t_tree, tvb, offset, 0, "MPEG2 PCR Analysis"); - PROTO_ITEM_SET_GENERATED(item); - mp2t_analysis_tree = proto_item_add_subtree(item, ett_mp2t_analysis); - - skips = detect_cc_drops(tvb, mp2t_analysis_tree, pinfo, pid, cc, conv); - if (skips > 0) - proto_item_append_text(ti, " skips=%d", skips); - - if (afc == 2 || afc == 3) - { - gint af_start_offset = offset; - - guint8 af_length; - guint8 af_flags; - gint stuffing_len; - - - af_length = tvb_get_guint8(tvb, offset); - - proto_tree_add_item( mp2t_tree, hf_mp2t_af_length, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - /* fix issues where afc==3 but af_length==0 - * Adaptaion field...spec section 2.4.3.5: The value 0 is for inserting a single - * stuffing byte in a Transport Stream packet. When the adaptation_field_control - * value is '11', the value of the adaptation_field_length shall be in the range 0 to 182. - */ - if (af_length > 0 ) { - hi = proto_tree_add_item( mp2t_tree, hf_mp2t_af, tvb, offset, af_length, ENC_NA); - mp2t_af_tree = proto_item_add_subtree( hi, ett_mp2t_af ); - - af_flags = tvb_get_guint8(tvb, offset); - - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_di, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_rai, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_espi, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_pcr_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_opcr_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sp_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_afe_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - - offset += 1; - - if (af_flags & MP2T_AF_PCR_MASK) { - guint64 pcr_base = 0; - guint32 pcr_ext = 0; - guint8 tmp; - - tmp = tvb_get_guint8(tvb, offset); - pcr_base = (pcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - pcr_base = (pcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - pcr_base = (pcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - pcr_base = (pcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - pcr_base = (pcr_base << 1) | ((tmp >> 7) & 0x01); - pcr_ext = (tmp & 0x01); - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - pcr_ext = (pcr_ext << 8) | tmp; - offset += 1; - - proto_tree_add_none_format(mp2t_af_tree, hf_mp2t_af_pcr, tvb, offset - 6, 6, - "Program Clock Reference: base(%" G_GINT64_MODIFIER "u) * 300 + ext(%u) = %" G_GINT64_MODIFIER "u", - pcr_base, pcr_ext, pcr_base * 300 + pcr_ext); - } - - if (af_flags & MP2T_AF_OPCR_MASK) { - guint64 opcr_base = 0; - guint32 opcr_ext = 0; - guint8 tmp = 0; - - tmp = tvb_get_guint8(tvb, offset); - opcr_base = (opcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - opcr_base = (opcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - opcr_base = (opcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - opcr_base = (opcr_base << 8) | tmp; - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - opcr_base = (opcr_base << 1) | ((tmp >> 7) & 0x01); - opcr_ext = (tmp & 0x01); - offset += 1; - - tmp = tvb_get_guint8(tvb, offset); - opcr_ext = (opcr_ext << 8) | tmp; - offset += 1; - - proto_tree_add_none_format(mp2t_af_tree, hf_mp2t_af_opcr, tvb, offset - 6, 6, - "Original Program Clock Reference: base(%" G_GINT64_MODIFIER "u) * 300 + ext(%u) = %" G_GINT64_MODIFIER "u", - opcr_base, opcr_ext, opcr_base * 300 + opcr_ext); - - offset += 6; - } - - if (af_flags & MP2T_AF_SP_MASK) { - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sc, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - } - - if (af_flags & MP2T_AF_TPD_MASK) { - guint8 tpd_len; - - tpd_len = tvb_get_guint8(tvb, offset); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_length, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd, tvb, offset, tpd_len, ENC_NA); - offset += tpd_len; - } - - if (af_flags & MP2T_AF_AFE_MASK) { - guint8 e_len; - guint8 e_flags; - gint e_start_offset = offset; - gint reserved_len = 0; - - e_len = tvb_get_guint8(tvb, offset); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_length, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - - e_flags = tvb_get_guint8(tvb, offset); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltw_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ss_flag, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - - if (e_flags & MP2T_AF_E_LTW_FLAG_MASK) { - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwv_flag, tvb, offset, 2, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwo, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; - } - - if (e_flags & MP2T_AF_E_PR_FLAG_MASK) { - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_reserved, tvb, offset, 3, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr, tvb, offset, 3, ENC_BIG_ENDIAN); - offset += 3; - } - - if (e_flags & MP2T_AF_E_SS_FLAG_MASK) { - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_st, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_32_30, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_1, tvb, offset, 1, ENC_BIG_ENDIAN); - offset += 1; - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_29_15, tvb, offset, 2, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_2, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_14_0, tvb, offset, 2, ENC_BIG_ENDIAN); - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_3, tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; - } - - reserved_len = (e_len + 1) - (offset - e_start_offset); - if (reserved_len > 0) { - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved_bytes, tvb, offset, reserved_len, ENC_NA); - offset += reserved_len; - } - } - - stuffing_len = (af_length + 1) - (offset - af_start_offset); - if (stuffing_len > 0) { - proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_stuffing_bytes, tvb, offset, stuffing_len, ENC_NA); - offset += stuffing_len; - } - } - } - - if ((offset - start_offset) < MP2T_PACKET_SIZE) - payload_len = MP2T_PACKET_SIZE - (offset - start_offset); - else - payload_len = 0; - - if (!payload_len) - return; - - if (afc == 2) { - col_set_str(pinfo->cinfo, COL_INFO, "Adaptation field only"); - /* The rest of the packet is stuffing bytes */ - proto_tree_add_item( mp2t_tree, hf_mp2t_stuff_bytes, tvb, offset, payload_len, ENC_NA); - offset += payload_len; - } - - if (!tsc) { - mp2t_process_fragmented_payload(tvb, offset, payload_len, pinfo, tree, mp2t_tree, pusi_flag, pid_analysis); - } else { - /* Payload is scrambled */ - col_set_str(pinfo->cinfo, COL_INFO, "Scrambled TS payload"); - } + guint32 header; + guint afc; + gint start_offset = offset; + volatile gint payload_len; + pid_analysis_data_t *pid_analysis; + + guint32 skips; + guint32 pid; + guint32 cc; + guint32 pusi_flag; + + guint32 tsc; + + proto_item *ti = NULL; + proto_item *hi = NULL; + proto_item *item = NULL; + proto_tree *mp2t_tree = NULL; + proto_tree *mp2t_header_tree = NULL; + proto_tree *mp2t_af_tree = NULL; + proto_tree *mp2t_analysis_tree = NULL; + proto_item *afci = NULL; + + ti = proto_tree_add_item( tree, proto_mp2t, tvb, offset, MP2T_PACKET_SIZE, ENC_NA ); + mp2t_tree = proto_item_add_subtree( ti, ett_mp2t ); + + header = tvb_get_ntohl(tvb, offset); + + pid = (header & MP2T_PID_MASK) >> MP2T_PID_SHIFT; + cc = (header & MP2T_CC_MASK) >> MP2T_CC_SHIFT; + tsc = (header & MP2T_TSC_MASK); + pusi_flag = (header & 0x00400000); + proto_item_append_text(ti, " PID=0x%x CC=%d", pid, cc); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG TS"); + + hi = proto_tree_add_item( mp2t_tree, hf_mp2t_header, tvb, offset, 4, ENC_BIG_ENDIAN); + mp2t_header_tree = proto_item_add_subtree( hi, ett_mp2t_header ); + + proto_tree_add_item( mp2t_header_tree, hf_mp2t_sync_byte, tvb, offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_header_tree, hf_mp2t_tei, tvb, offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_header_tree, hf_mp2t_pusi, tvb, offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_header_tree, hf_mp2t_tp, tvb, offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_header_tree, hf_mp2t_pid, tvb, offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_header_tree, hf_mp2t_tsc, tvb, offset, 4, ENC_BIG_ENDIAN); + afci = proto_tree_add_item( mp2t_header_tree, hf_mp2t_afc, tvb, offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_header_tree, hf_mp2t_cc, tvb, offset, 4, ENC_BIG_ENDIAN); + + afc = (header & MP2T_AFC_MASK) >> MP2T_AFC_SHIFT; + + pid_analysis = get_pid_analysis(pid, conv); + + /* Find out the payload type based on the payload */ + if (pid_analysis->pload_type == pid_pload_unknown) { + if (pid == MP2T_PID_NULL) { + pid_analysis->pload_type = pid_pload_null; + } else if (pid == MP2T_PID_DOCSIS) { + pid_analysis->pload_type = pid_pload_docsis; + } + } + + if (pid_analysis->pload_type == pid_pload_docsis && afc) { + /* DOCSIS packets should not have an adaptation field */ + proto_item_append_text(afci, " (Invalid for DOCSIS packets, should be 0)"); + } + + if (pid_analysis->pload_type == pid_pload_null) { + /* Nothing more to do */ + col_set_str(pinfo->cinfo, COL_INFO, "NULL packet"); + proto_item_append_text(afci, " (Should be 0 for NULL packets)"); + return; + } + + offset += 4; + + /* Create a subtree for analysis stuff */ + item = proto_tree_add_text(mp2t_tree, tvb, offset, 0, "MPEG2 PCR Analysis"); + PROTO_ITEM_SET_GENERATED(item); + mp2t_analysis_tree = proto_item_add_subtree(item, ett_mp2t_analysis); + + skips = detect_cc_drops(tvb, mp2t_analysis_tree, pinfo, pid, cc, conv); + if (skips > 0) + proto_item_append_text(ti, " skips=%d", skips); + + if (afc == 2 || afc == 3) + { + gint af_start_offset = offset; + + guint8 af_length; + guint8 af_flags; + gint stuffing_len; + + + af_length = tvb_get_guint8(tvb, offset); + + proto_tree_add_item( mp2t_tree, hf_mp2t_af_length, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + /* fix issues where afc==3 but af_length==0 + * Adaptaion field...spec section 2.4.3.5: The value 0 is for inserting a single + * stuffing byte in a Transport Stream packet. When the adaptation_field_control + * value is '11', the value of the adaptation_field_length shall be in the range 0 to 182. + */ + if (af_length > 0 ) { + hi = proto_tree_add_item( mp2t_tree, hf_mp2t_af, tvb, offset, af_length, ENC_NA); + mp2t_af_tree = proto_item_add_subtree( hi, ett_mp2t_af ); + + af_flags = tvb_get_guint8(tvb, offset); + + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_di, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_rai, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_espi, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_pcr_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_opcr_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sp_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_afe_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + + offset += 1; + + if (af_flags & MP2T_AF_PCR_MASK) { + guint64 pcr_base = 0; + guint32 pcr_ext = 0; + guint8 tmp; + + tmp = tvb_get_guint8(tvb, offset); + pcr_base = (pcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + pcr_base = (pcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + pcr_base = (pcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + pcr_base = (pcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + pcr_base = (pcr_base << 1) | ((tmp >> 7) & 0x01); + pcr_ext = (tmp & 0x01); + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + pcr_ext = (pcr_ext << 8) | tmp; + offset += 1; + + proto_tree_add_none_format(mp2t_af_tree, hf_mp2t_af_pcr, tvb, offset - 6, 6, + "Program Clock Reference: base(%" G_GINT64_MODIFIER "u) * 300 + ext(%u) = %" G_GINT64_MODIFIER "u", + pcr_base, pcr_ext, pcr_base * 300 + pcr_ext); + } + + if (af_flags & MP2T_AF_OPCR_MASK) { + guint64 opcr_base = 0; + guint32 opcr_ext = 0; + guint8 tmp = 0; + + tmp = tvb_get_guint8(tvb, offset); + opcr_base = (opcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + opcr_base = (opcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + opcr_base = (opcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + opcr_base = (opcr_base << 8) | tmp; + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + opcr_base = (opcr_base << 1) | ((tmp >> 7) & 0x01); + opcr_ext = (tmp & 0x01); + offset += 1; + + tmp = tvb_get_guint8(tvb, offset); + opcr_ext = (opcr_ext << 8) | tmp; + offset += 1; + + proto_tree_add_none_format(mp2t_af_tree, hf_mp2t_af_opcr, tvb, offset - 6, 6, + "Original Program Clock Reference: base(%" G_GINT64_MODIFIER "u) * 300 + ext(%u) = %" G_GINT64_MODIFIER "u", + opcr_base, opcr_ext, opcr_base * 300 + opcr_ext); + + offset += 6; + } + + if (af_flags & MP2T_AF_SP_MASK) { + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sc, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + } + + if (af_flags & MP2T_AF_TPD_MASK) { + guint8 tpd_len; + + tpd_len = tvb_get_guint8(tvb, offset); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_length, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd, tvb, offset, tpd_len, ENC_NA); + offset += tpd_len; + } + + if (af_flags & MP2T_AF_AFE_MASK) { + guint8 e_len; + guint8 e_flags; + gint e_start_offset = offset; + gint reserved_len = 0; + + e_len = tvb_get_guint8(tvb, offset); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_length, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + e_flags = tvb_get_guint8(tvb, offset); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltw_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ss_flag, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + if (e_flags & MP2T_AF_E_LTW_FLAG_MASK) { + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwv_flag, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwo, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + } + + if (e_flags & MP2T_AF_E_PR_FLAG_MASK) { + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_reserved, tvb, offset, 3, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr, tvb, offset, 3, ENC_BIG_ENDIAN); + offset += 3; + } + + if (e_flags & MP2T_AF_E_SS_FLAG_MASK) { + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_st, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_32_30, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_1, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_29_15, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_2, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_14_0, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_3, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + } + + reserved_len = (e_len + 1) - (offset - e_start_offset); + if (reserved_len > 0) { + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved_bytes, tvb, offset, reserved_len, ENC_NA); + offset += reserved_len; + } + } + + stuffing_len = (af_length + 1) - (offset - af_start_offset); + if (stuffing_len > 0) { + proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_stuffing_bytes, tvb, offset, stuffing_len, ENC_NA); + offset += stuffing_len; + } + } + } + + if ((offset - start_offset) < MP2T_PACKET_SIZE) + payload_len = MP2T_PACKET_SIZE - (offset - start_offset); + else + payload_len = 0; + + if (!payload_len) + return; + + if (afc == 2) { + col_set_str(pinfo->cinfo, COL_INFO, "Adaptation field only"); + /* The rest of the packet is stuffing bytes */ + proto_tree_add_item( mp2t_tree, hf_mp2t_stuff_bytes, tvb, offset, payload_len, ENC_NA); + offset += payload_len; + } + + if (!tsc) { + mp2t_process_fragmented_payload(tvb, offset, payload_len, pinfo, tree, mp2t_tree, pusi_flag, pid_analysis); + } else { + /* Payload is scrambled */ + col_set_str(pinfo->cinfo, COL_INFO, "Scrambled TS payload"); + } } static void dissect_mp2t( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) { - guint offset = 0; - conversation_t *conv; - - conv = find_or_create_conversation(pinfo); + guint offset = 0; + conversation_t *conv; - for (; tvb_reported_length_remaining(tvb, offset) >= MP2T_PACKET_SIZE; offset += MP2T_PACKET_SIZE) { + conv = find_or_create_conversation(pinfo); - dissect_tsp(tvb, offset, pinfo, tree, conv); - } + for (; tvb_reported_length_remaining(tvb, offset) >= MP2T_PACKET_SIZE; offset += MP2T_PACKET_SIZE) { + dissect_tsp(tvb, offset, pinfo, tree, conv); + } } static gboolean heur_dissect_mp2t( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ ) { - gint length; - guint offset = 0; - - length = tvb_length_remaining(tvb, offset); - if (length == 0) { - /* Nothing to check for */ - return FALSE; - } - if ((length % MP2T_PACKET_SIZE) != 0) { - /* Not a multiple of the MPEG-2 transport packet size */ - return FALSE; - } else { - while (tvb_offset_exists(tvb, offset)) { - if (tvb_get_guint8(tvb, offset) != MP2T_SYNC_BYTE) { - /* No sync byte at the appropriate offset */ - return FALSE; - } - offset += MP2T_PACKET_SIZE; - } - } - - dissect_mp2t(tvb, pinfo, tree); - return TRUE; + gint length; + guint offset = 0; + + length = tvb_length_remaining(tvb, offset); + if (length == 0) { + /* Nothing to check for */ + return FALSE; + } + if ((length % MP2T_PACKET_SIZE) != 0) { + /* Not a multiple of the MPEG-2 transport packet size */ + return FALSE; + } else { + while (tvb_offset_exists(tvb, offset)) { + if (tvb_get_guint8(tvb, offset) != MP2T_SYNC_BYTE) { + /* No sync byte at the appropriate offset */ + return FALSE; + } + offset += MP2T_PACKET_SIZE; + } + } + + dissect_mp2t(tvb, pinfo, tree); + return TRUE; } static void mp2t_init(void) { - reassembly_table_init(&mp2t_reassembly_table, - &addresses_reassembly_table_functions); + reassembly_table_init(&mp2t_reassembly_table, + &addresses_reassembly_table_functions); } void proto_register_mp2t(void) { - static hf_register_info hf[] = { - { &hf_mp2t_header, { - "Header", "mp2t.header", - FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_sync_byte, { - "Sync Byte", "mp2t.sync_byte", - FT_UINT32, BASE_HEX, VALS(mp2t_sync_byte_vals), MP2T_SYNC_BYTE_MASK, NULL, HFILL - } } , - { &hf_mp2t_tei, { - "Transport Error Indicator", "mp2t.tei", - FT_UINT32, BASE_DEC, NULL, MP2T_TEI_MASK, NULL, HFILL - } } , - { &hf_mp2t_pusi, { - "Payload Unit Start Indicator", "mp2t.pusi", - FT_UINT32, BASE_DEC, NULL, MP2T_PUSI_MASK, NULL, HFILL - } } , - { &hf_mp2t_tp, { - "Transport Priority", "mp2t.tp", - FT_UINT32, BASE_DEC, NULL, MP2T_TP_MASK, NULL, HFILL - } } , - { &hf_mp2t_pid, { - "PID", "mp2t.pid", - FT_UINT32, BASE_HEX, VALS(mp2t_pid_vals), MP2T_PID_MASK, NULL, HFILL - } } , - { &hf_mp2t_tsc, { - "Transport Scrambling Control", "mp2t.tsc", - FT_UINT32, BASE_HEX, VALS(mp2t_tsc_vals), MP2T_TSC_MASK, NULL, HFILL - } } , - { &hf_mp2t_afc, { - "Adaptation Field Control", "mp2t.afc", - FT_UINT32, BASE_HEX, VALS(mp2t_afc_vals) , MP2T_AFC_MASK, NULL, HFILL - } } , - { &hf_mp2t_cc, { - "Continuity Counter", "mp2t.cc", - FT_UINT32, BASE_DEC, NULL, MP2T_CC_MASK, NULL, HFILL - } } , + static hf_register_info hf[] = { + { &hf_mp2t_header, { + "Header", "mp2t.header", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_sync_byte, { + "Sync Byte", "mp2t.sync_byte", + FT_UINT32, BASE_HEX, VALS(mp2t_sync_byte_vals), MP2T_SYNC_BYTE_MASK, NULL, HFILL + } } , + { &hf_mp2t_tei, { + "Transport Error Indicator", "mp2t.tei", + FT_UINT32, BASE_DEC, NULL, MP2T_TEI_MASK, NULL, HFILL + } } , + { &hf_mp2t_pusi, { + "Payload Unit Start Indicator", "mp2t.pusi", + FT_UINT32, BASE_DEC, NULL, MP2T_PUSI_MASK, NULL, HFILL + } } , + { &hf_mp2t_tp, { + "Transport Priority", "mp2t.tp", + FT_UINT32, BASE_DEC, NULL, MP2T_TP_MASK, NULL, HFILL + } } , + { &hf_mp2t_pid, { + "PID", "mp2t.pid", + FT_UINT32, BASE_HEX, VALS(mp2t_pid_vals), MP2T_PID_MASK, NULL, HFILL + } } , + { &hf_mp2t_tsc, { + "Transport Scrambling Control", "mp2t.tsc", + FT_UINT32, BASE_HEX, VALS(mp2t_tsc_vals), MP2T_TSC_MASK, NULL, HFILL + } } , + { &hf_mp2t_afc, { + "Adaptation Field Control", "mp2t.afc", + FT_UINT32, BASE_HEX, VALS(mp2t_afc_vals) , MP2T_AFC_MASK, NULL, HFILL + } } , + { &hf_mp2t_cc, { + "Continuity Counter", "mp2t.cc", + FT_UINT32, BASE_DEC, NULL, MP2T_CC_MASK, NULL, HFILL + } } , #if 0 - { &hf_mp2t_analysis_flags, { - "MPEG2-TS Analysis Flags", "mp2t.analysis.flags", - FT_NONE, BASE_NONE, NULL, 0x0, - "This frame has some of the MPEG2 analysis flags set", HFILL - } } , + { &hf_mp2t_analysis_flags, { + "MPEG2-TS Analysis Flags", "mp2t.analysis.flags", + FT_NONE, BASE_NONE, NULL, 0x0, + "This frame has some of the MPEG2 analysis flags set", HFILL + } } , #endif - { &hf_mp2t_analysis_skips, { - "TS Continuity Counter Skips", "mp2t.analysis.skips", - FT_UINT8, BASE_DEC, NULL, 0x0, - "Missing TS frames according to CC counter values", HFILL - } } , - { &hf_mp2t_analysis_drops, { - "Some frames dropped", "mp2t.analysis.drops", - FT_UINT8, BASE_DEC, NULL, 0x0, - "Discontinuity: A number of TS frames were dropped", HFILL - } } , - { &hf_mp2t_af, { - "Adaptation Field", "mp2t.af", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_af_length, { - "Adaptation Field Length", "mp2t.af.length", - FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL - } } , - { &hf_mp2t_af_di, { - "Discontinuity Indicator", "mp2t.af.di", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_DI_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_rai, { - "Random Access Indicator", "mp2t.af.rai", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_RAI_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_espi, { - "Elementary Stream Priority Indicator", "mp2t.af.espi", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_ESPI_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_pcr_flag, { - "PCR Flag", "mp2t.af.pcr_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_PCR_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_opcr_flag, { - "OPCR Flag", "mp2t.af.opcr_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_OPCR_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_sp_flag, { - "Splicing Point Flag", "mp2t.af.sp_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_SP_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_tpd_flag, { - "Transport Private Data Flag", "mp2t.af.tpd_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_TPD_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_afe_flag, { - "Adaptation Field Extension Flag", "mp2t.af.afe_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_AFE_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_pcr, { - "Program Clock Reference", "mp2t.af.pcr", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_af_opcr, { - "Original Program Clock Reference", "mp2t.af.opcr", - FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_af_sc, { - "Splice Countdown", "mp2t.af.sc", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_af_tpd_length, { - "Transport Private Data Length", "mp2t.af.tpd_length", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_af_tpd, { - "Transport Private Data", "mp2t.af.tpd", - FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_af_e_length, { - "Adaptation Field Extension Length", "mp2t.af.e_length", - FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL - } } , - { &hf_mp2t_af_e_ltw_flag, { - "LTW Flag", "mp2t.af.e.ltw_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_LTW_FLAG_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_e_pr_flag, { - "Piecewise Rate Flag", "mp2t.af.e.pr_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_PR_FLAG_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_e_ss_flag, { - "Seamless Splice Flag", "mp2t.af.e.ss_flag", - FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_SS_FLAG_MASK, NULL, HFILL - } } , - { &hf_mp2t_af_e_reserved, { - "Reserved", "mp2t.af.e.reserved", - FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL - } } , - { &hf_mp2t_af_e_reserved_bytes, { - "Reserved", "mp2t.af.e.reserved_bytes", - FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL - } } , - { &hf_mp2t_af_stuffing_bytes, { - "Stuffing", "mp2t.af.stuffing_bytes", - FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL - } } , - { &hf_mp2t_af_e_ltwv_flag, { - "LTW Valid Flag", "mp2t.af.e.ltwv_flag", - FT_UINT16, BASE_DEC, NULL, 0x8000, NULL, HFILL - } } , - { &hf_mp2t_af_e_ltwo, { - "LTW Offset", "mp2t.af.e.ltwo", - FT_UINT16, BASE_DEC, NULL, 0x7FFF, NULL, HFILL - } } , - { &hf_mp2t_af_e_pr_reserved, { - "Reserved", "mp2t.af.e.pr_reserved", - FT_UINT24, BASE_DEC, NULL, 0xC00000, NULL, HFILL - } } , - { &hf_mp2t_af_e_pr, { - "Piecewise Rate", "mp2t.af.e.pr", - FT_UINT24, BASE_DEC, NULL, 0x3FFFFF, NULL, HFILL - } } , - { &hf_mp2t_af_e_st, { - "Splice Type", "mp2t.af.e.st", - FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL - } } , - { &hf_mp2t_af_e_dnau_32_30, { - "DTS Next AU[32...30]", "mp2t.af.e.dnau_32_30", - FT_UINT8, BASE_DEC, NULL, 0x0E, NULL, HFILL - } } , - { &hf_mp2t_af_e_m_1, { - "Marker Bit", "mp2t.af.e.m_1", - FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL - } } , - { &hf_mp2t_af_e_dnau_29_15, { - "DTS Next AU[29...15]", "mp2t.af.e.dnau_29_15", - FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL - } } , - { &hf_mp2t_af_e_m_2, { - "Marker Bit", "mp2t.af.e.m_2", - FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL - } } , - { &hf_mp2t_af_e_dnau_14_0, { - "DTS Next AU[14...0]", "mp2t.af.e.dnau_14_0", - FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL - } } , - { &hf_mp2t_af_e_m_3, { - "Marker Bit", "mp2t.af.e.m_3", - FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL - } } , + { &hf_mp2t_analysis_skips, { + "TS Continuity Counter Skips", "mp2t.analysis.skips", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Missing TS frames according to CC counter values", HFILL + } } , + { &hf_mp2t_analysis_drops, { + "Some frames dropped", "mp2t.analysis.drops", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Discontinuity: A number of TS frames were dropped", HFILL + } } , + { &hf_mp2t_af, { + "Adaptation Field", "mp2t.af", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_af_length, { + "Adaptation Field Length", "mp2t.af.length", + FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL + } } , + { &hf_mp2t_af_di, { + "Discontinuity Indicator", "mp2t.af.di", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_DI_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_rai, { + "Random Access Indicator", "mp2t.af.rai", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_RAI_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_espi, { + "Elementary Stream Priority Indicator", "mp2t.af.espi", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_ESPI_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_pcr_flag, { + "PCR Flag", "mp2t.af.pcr_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_PCR_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_opcr_flag, { + "OPCR Flag", "mp2t.af.opcr_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_OPCR_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_sp_flag, { + "Splicing Point Flag", "mp2t.af.sp_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_SP_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_tpd_flag, { + "Transport Private Data Flag", "mp2t.af.tpd_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_TPD_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_afe_flag, { + "Adaptation Field Extension Flag", "mp2t.af.afe_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_AFE_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_pcr, { + "Program Clock Reference", "mp2t.af.pcr", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_af_opcr, { + "Original Program Clock Reference", "mp2t.af.opcr", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_af_sc, { + "Splice Countdown", "mp2t.af.sc", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_af_tpd_length, { + "Transport Private Data Length", "mp2t.af.tpd_length", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_af_tpd, { + "Transport Private Data", "mp2t.af.tpd", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_af_e_length, { + "Adaptation Field Extension Length", "mp2t.af.e_length", + FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL + } } , + { &hf_mp2t_af_e_ltw_flag, { + "LTW Flag", "mp2t.af.e.ltw_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_LTW_FLAG_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_e_pr_flag, { + "Piecewise Rate Flag", "mp2t.af.e.pr_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_PR_FLAG_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_e_ss_flag, { + "Seamless Splice Flag", "mp2t.af.e.ss_flag", + FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_SS_FLAG_MASK, NULL, HFILL + } } , + { &hf_mp2t_af_e_reserved, { + "Reserved", "mp2t.af.e.reserved", + FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL + } } , + { &hf_mp2t_af_e_reserved_bytes, { + "Reserved", "mp2t.af.e.reserved_bytes", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL + } } , + { &hf_mp2t_af_stuffing_bytes, { + "Stuffing", "mp2t.af.stuffing_bytes", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL + } } , + { &hf_mp2t_af_e_ltwv_flag, { + "LTW Valid Flag", "mp2t.af.e.ltwv_flag", + FT_UINT16, BASE_DEC, NULL, 0x8000, NULL, HFILL + } } , + { &hf_mp2t_af_e_ltwo, { + "LTW Offset", "mp2t.af.e.ltwo", + FT_UINT16, BASE_DEC, NULL, 0x7FFF, NULL, HFILL + } } , + { &hf_mp2t_af_e_pr_reserved, { + "Reserved", "mp2t.af.e.pr_reserved", + FT_UINT24, BASE_DEC, NULL, 0xC00000, NULL, HFILL + } } , + { &hf_mp2t_af_e_pr, { + "Piecewise Rate", "mp2t.af.e.pr", + FT_UINT24, BASE_DEC, NULL, 0x3FFFFF, NULL, HFILL + } } , + { &hf_mp2t_af_e_st, { + "Splice Type", "mp2t.af.e.st", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL + } } , + { &hf_mp2t_af_e_dnau_32_30, { + "DTS Next AU[32...30]", "mp2t.af.e.dnau_32_30", + FT_UINT8, BASE_DEC, NULL, 0x0E, NULL, HFILL + } } , + { &hf_mp2t_af_e_m_1, { + "Marker Bit", "mp2t.af.e.m_1", + FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL + } } , + { &hf_mp2t_af_e_dnau_29_15, { + "DTS Next AU[29...15]", "mp2t.af.e.dnau_29_15", + FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL + } } , + { &hf_mp2t_af_e_m_2, { + "Marker Bit", "mp2t.af.e.m_2", + FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL + } } , + { &hf_mp2t_af_e_dnau_14_0, { + "DTS Next AU[14...0]", "mp2t.af.e.dnau_14_0", + FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL + } } , + { &hf_mp2t_af_e_m_3, { + "Marker Bit", "mp2t.af.e.m_3", + FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL + } } , #if 0 - { &hf_mp2t_payload, { - "Payload", "mp2t.payload", - FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL - } } , + { &hf_mp2t_payload, { + "Payload", "mp2t.payload", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL + } } , #endif - { &hf_mp2t_stuff_bytes, { - "Stuffing", "mp2t.stuff_bytes", - FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL - } }, - { &hf_mp2t_pointer, { - "Pointer", "mp2t.pointer", - FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL - } }, - { &hf_msg_fragments, { - "Message fragments", "mp2t.msg.fragments", - FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_fragment, { - "Message fragment", "mp2t.msg.fragment", - FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_fragment_overlap, { - "Message fragment overlap", "mp2t.msg.fragment.overlap", - FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_fragment_overlap_conflicts, { - "Message fragment overlapping with conflicting data", - "mp2t.msg.fragment.overlap.conflicts", - FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_fragment_multiple_tails, { - "Message has multiple tail fragments", - "mp2t.msg.fragment.multiple_tails", - FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_fragment_too_long_fragment, { - "Message fragment too long", "mp2t.msg.fragment.too_long_fragment", - FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_fragment_error, { - "Message defragmentation error", "mp2t.msg.fragment.error", - FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_fragment_count, { - "Message fragment count", "mp2t.msg.fragment.count", - FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_reassembled_in, { - "Reassembled in", "mp2t.msg.reassembled.in", - FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL - } }, - { &hf_msg_reassembled_length, { - "Reassembled MP2T length", "mp2t.msg.reassembled.length", - FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL - } } - }; - - static gint *ett[] = - { - &ett_mp2t, - &ett_mp2t_header, - &ett_mp2t_af, - &ett_mp2t_analysis, - &ett_stuff, - &ett_msg_fragment, - &ett_msg_fragments - }; - - static ei_register_info ei[] = { - { &ei_mp2t_pointer, { "mp2t.pointer", PI_MALFORMED, PI_ERROR, "Pointer value is too large", EXPFILL }}, - { &ei_mp2t_cc_drop, { "mp2t.cc.drop", PI_MALFORMED, PI_ERROR, "Detected missing TS frames", EXPFILL }}, - }; - - expert_module_t* expert_mp2t; - - proto_mp2t = proto_register_protocol("ISO/IEC 13818-1", "MP2T", "mp2t"); - - mp2t_handle = register_dissector("mp2t", dissect_mp2t, proto_mp2t); - - proto_register_field_array(proto_mp2t, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); - expert_mp2t = expert_register_protocol(proto_mp2t); - expert_register_field_array(expert_mp2t, ei, array_length(ei)); - - register_heur_dissector_list("mp2t.pid", &heur_subdissector_list); - /* Register init of processing of fragmented DEPI packets */ - register_init_routine(mp2t_init); + { &hf_mp2t_stuff_bytes, { + "Stuffing", "mp2t.stuff_bytes", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL + } }, + { &hf_mp2t_pointer, { + "Pointer", "mp2t.pointer", + FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL + } }, + { &hf_msg_fragments, { + "Message fragments", "mp2t.msg.fragments", + FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_fragment, { + "Message fragment", "mp2t.msg.fragment", + FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_fragment_overlap, { + "Message fragment overlap", "mp2t.msg.fragment.overlap", + FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_fragment_overlap_conflicts, { + "Message fragment overlapping with conflicting data", + "mp2t.msg.fragment.overlap.conflicts", + FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_fragment_multiple_tails, { + "Message has multiple tail fragments", + "mp2t.msg.fragment.multiple_tails", + FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_fragment_too_long_fragment, { + "Message fragment too long", "mp2t.msg.fragment.too_long_fragment", + FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_fragment_error, { + "Message defragmentation error", "mp2t.msg.fragment.error", + FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_fragment_count, { + "Message fragment count", "mp2t.msg.fragment.count", + FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_reassembled_in, { + "Reassembled in", "mp2t.msg.reassembled.in", + FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL + } }, + { &hf_msg_reassembled_length, { + "Reassembled MP2T length", "mp2t.msg.reassembled.length", + FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL + } } + }; + + static gint *ett[] = + { + &ett_mp2t, + &ett_mp2t_header, + &ett_mp2t_af, + &ett_mp2t_analysis, + &ett_stuff, + &ett_msg_fragment, + &ett_msg_fragments + }; + + static ei_register_info ei[] = { + { &ei_mp2t_pointer, { "mp2t.pointer", PI_MALFORMED, PI_ERROR, "Pointer value is too large", EXPFILL }}, + { &ei_mp2t_cc_drop, { "mp2t.cc.drop", PI_MALFORMED, PI_ERROR, "Detected missing TS frames", EXPFILL }}, + }; + + expert_module_t* expert_mp2t; + + proto_mp2t = proto_register_protocol("ISO/IEC 13818-1", "MP2T", "mp2t"); + + mp2t_handle = register_dissector("mp2t", dissect_mp2t, proto_mp2t); + + proto_register_field_array(proto_mp2t, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + expert_mp2t = expert_register_protocol(proto_mp2t); + expert_register_field_array(expert_mp2t, ei, array_length(ei)); + + register_heur_dissector_list("mp2t.pid", &heur_subdissector_list); + /* Register init of processing of fragmented DEPI packets */ + register_init_routine(mp2t_init); } @@ -1561,16 +1535,28 @@ proto_register_mp2t(void) void proto_reg_handoff_mp2t(void) { - heur_dissector_add("udp", heur_dissect_mp2t, proto_mp2t); + heur_dissector_add("udp", heur_dissect_mp2t, proto_mp2t); - dissector_add_uint("rtp.pt", PT_MP2T, mp2t_handle); - dissector_add_handle("udp.port", mp2t_handle); /* for decode-as */ - heur_dissector_add("usb.bulk", heur_dissect_mp2t, proto_mp2t); - dissector_add_uint("wtap_encap", WTAP_ENCAP_MPEG_2_TS, mp2t_handle); + dissector_add_uint("rtp.pt", PT_MP2T, mp2t_handle); + dissector_add_handle("udp.port", mp2t_handle); /* for decode-as */ + heur_dissector_add("usb.bulk", heur_dissect_mp2t, proto_mp2t); + dissector_add_uint("wtap_encap", WTAP_ENCAP_MPEG_2_TS, mp2t_handle); - docsis_handle = find_dissector("docsis"); - mpeg_pes_handle = find_dissector("mpeg-pes"); - mpeg_sect_handle = find_dissector("mpeg_sect"); - data_handle = find_dissector("data"); + docsis_handle = find_dissector("docsis"); + mpeg_pes_handle = find_dissector("mpeg-pes"); + mpeg_sect_handle = find_dissector("mpeg_sect"); + data_handle = find_dissector("data"); } +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |