static void dissect_mpeg_sect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint section_length = 0; gboolean syntax_indicator = FALSE; guint8 table_id; proto_item *ti; proto_tree *mpeg_sect_tree; table_id = tvb_get_guint8(tvb, offset); /* Check if a dissector can parse the current table */ if (dissector_try_uint(mpeg_sect_tid_dissector_table, table_id, tvb, pinfo, tree)) return; /* If no dissector is registered, use the common one */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG SECT"); col_add_fstr(pinfo->cinfo, COL_INFO, "Table ID 0x%02x", table_id); ti = proto_tree_add_item(tree, proto_mpeg_sect, tvb, offset, -1, ENC_NA); mpeg_sect_tree = proto_item_add_subtree(ti, ett_mpeg_sect); proto_item_append_text(ti, " Table_ID=0x%02x", table_id); packet_mpeg_sect_header(tvb, offset, mpeg_sect_tree, §ion_length, &syntax_indicator); if (syntax_indicator) packet_mpeg_sect_crc(tvb, pinfo, mpeg_sect_tree, 0, (section_length-1)); }
static void dissect_mpeg_ca(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0, length = 0; proto_item *ti = NULL; proto_tree *mpeg_ca_tree = NULL; /* The TVB should start right after the section_length in the Section packet */ col_clear(pinfo->cinfo, COL_INFO); col_set_str(pinfo->cinfo, COL_INFO, "Conditional Access Table (CA)"); if (!tree) return; ti = proto_tree_add_item(tree, proto_mpeg_ca, tvb, offset, -1, ENC_NA); mpeg_ca_tree = proto_item_add_subtree(ti, ett_mpeg_ca); offset += packet_mpeg_sect_header(tvb, offset, mpeg_ca_tree, &length, NULL); length -= 4; proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_reserved, tvb, offset, 3, ENC_BIG_ENDIAN); proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_version_number, tvb, offset, 3, ENC_BIG_ENDIAN); proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_current_next_indicator, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* Parse all the programs */ while (offset < length) offset += proto_mpeg_descriptor_dissect(tvb, offset, mpeg_ca_tree); packet_mpeg_sect_crc(tvb, pinfo, mpeg_ca_tree, 0, offset); }
static void dissect_dvb_tot(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint descriptor_len; proto_item *ti; proto_tree *dvb_tot_tree; nstime_t utc_time; col_set_str(pinfo->cinfo, COL_INFO, "Time Offset Table (TOT)"); ti = proto_tree_add_item(tree, proto_dvb_tot, tvb, offset, -1, ENC_NA); dvb_tot_tree = proto_item_add_subtree(ti, ett_dvb_tot); offset += packet_mpeg_sect_header(tvb, offset, dvb_tot_tree, NULL, NULL); if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) { proto_tree_add_text(dvb_tot_tree, tvb, offset, 5, "UTC Time : Unparseable time"); } else { proto_tree_add_time_format(dvb_tot_tree, hf_dvb_tot_utc_time, tvb, offset, 5, &utc_time, "UTC Time : %s UTC", abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE)); } offset += 5; descriptor_len = tvb_get_ntohs(tvb, offset) & DVB_TOT_DESCRIPTORS_LOOP_LENGTH_MASK; proto_tree_add_item(dvb_tot_tree, hf_dvb_tot_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_tot_tree, hf_dvb_tot_descriptors_loop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; offset += proto_mpeg_descriptor_loop_dissect(tvb, offset, descriptor_len, dvb_tot_tree); offset += packet_mpeg_sect_crc(tvb, pinfo, dvb_tot_tree, 0, offset); proto_item_set_len(ti, offset); }
static void dissect_etv_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int proto, int hf_filter_info, int hf_reserved ) { tvbuff_t *sub_tvb; guint offset = 0; proto_item *ti; proto_item *pi; proto_tree *etv_tree; proto_item *items[PACKET_MPEG_SECT_PI__SIZE]; gboolean ssi; guint reserved; guint8 reserved2; guint16 filter_info; guint sect_len; ti = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA); etv_tree = proto_item_add_subtree(ti, ett_etv); offset += packet_mpeg_sect_header_extra(tvb, offset, etv_tree, §_len, &reserved, &ssi, items); if (FALSE != ssi) { proto_item *msg_error; msg_error = items[PACKET_MPEG_SECT_PI__SSI]; PROTO_ITEM_SET_GENERATED(msg_error); expert_add_info_format(pinfo, msg_error, PI_MALFORMED, PI_ERROR, "Invalid section_syntax_indicator (should be 0)"); } if (4 != reserved) { proto_item *msg_error; msg_error = items[PACKET_MPEG_SECT_PI__RESERVED]; PROTO_ITEM_SET_GENERATED(msg_error); expert_add_info_format(pinfo, msg_error, PI_MALFORMED, PI_ERROR, "Invalid reserved1 bits (should all be 100)"); } col_append_fstr(pinfo->cinfo, COL_INFO, ", Length: %u", sect_len); proto_item_append_text(ti, " Length=%u", sect_len); if (1021 < sect_len) { proto_item *msg_error; msg_error = items[PACKET_MPEG_SECT_PI__LENGTH]; PROTO_ITEM_SET_GENERATED(msg_error); expert_add_info_format(pinfo, msg_error, PI_MALFORMED, PI_ERROR, "Invalid section_length (must not exceed 1021)"); } filter_info = tvb_get_ntohs(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Filter: 0x%x", filter_info); proto_item_append_text(ti, " Filter=0x%x", filter_info); pi = proto_tree_add_item(etv_tree, hf_filter_info, tvb, offset, 2, ENC_BIG_ENDIAN); if ((proto_etv_dii == proto) && (0xFBFB != filter_info)) { PROTO_ITEM_SET_GENERATED(pi); expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR, "Invalid filter_info value (must be 0xFBFB)"); } else if ((proto_etv_ddb == proto) && ((filter_info < 1) || (0xfbef < filter_info))) { PROTO_ITEM_SET_GENERATED(pi); expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR, "Invalid filter_info value (must be [0x0001-0xFBEF] inclusive)"); } offset += 2; reserved2 = tvb_get_guint8(tvb, offset); pi = proto_tree_add_item(etv_tree, hf_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); if (0 != reserved2) { PROTO_ITEM_SET_GENERATED(pi); expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR, "Invalid reserved2 bits (should all be 0)"); } offset += 1; sub_tvb = tvb_new_subset(tvb, offset, sect_len-7, sect_len-7); call_dissector(dsmcc_handle, sub_tvb, pinfo, tree); sect_len += 3 - 4; /* add header, remove crc */ packet_mpeg_sect_crc(tvb, pinfo, etv_tree, 0, sect_len); }
static void dissect_dvb_sdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0, length = 0, descriptor_end = 0; guint16 svc_id = 0, descriptor_len = 0; proto_item *ti = NULL; proto_tree *dvb_sdt_tree = NULL; proto_item *si = NULL; proto_tree *dvb_sdt_service_tree = NULL; /* The TVB should start right after the section_length in the Section packet */ col_clear(pinfo->cinfo, COL_INFO); col_set_str(pinfo->cinfo, COL_INFO, "Service Description Table (SDT)"); if (!tree) return; ti = proto_tree_add_item(tree, proto_dvb_sdt, tvb, offset, -1, ENC_NA); dvb_sdt_tree = proto_item_add_subtree(ti, ett_dvb_sdt); offset += packet_mpeg_sect_header(tvb, offset, dvb_sdt_tree, &length, NULL); length -= 4; proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_transport_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_reserved1, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_version_number, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_current_next_indicator, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_original_network_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dvb_sdt_tree, hf_dvb_sdt_reserved2, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; if (offset >= length) return; /* Parse all the services */ while (offset < length) { svc_id = tvb_get_ntohs(tvb, offset); si = proto_tree_add_text(dvb_sdt_tree, tvb, offset, 5, "Service 0x%04hx", svc_id); dvb_sdt_service_tree = proto_item_add_subtree(si, ett_dvb_sdt_service); proto_tree_add_item(dvb_sdt_service_tree, hf_dvb_sdt_service_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dvb_sdt_service_tree, hf_dvb_sdt_reserved3, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_sdt_service_tree, hf_dvb_sdt_eit_schedule_flag, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_sdt_service_tree, hf_dvb_sdt_eit_present_following_flag, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(dvb_sdt_service_tree, hf_dvb_sdt_running_status, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_sdt_service_tree, hf_dvb_sdt_free_ca_mode, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_sdt_service_tree, hf_dvb_sdt_descriptors_loop_length, tvb, offset, 2, ENC_BIG_ENDIAN); descriptor_len = tvb_get_ntohs(tvb, offset) & DVB_SDT_DESCRIPTORS_LOOP_LENGTH_MASK; offset += 2; descriptor_end = offset + descriptor_len; while (offset < descriptor_end) offset += proto_mpeg_descriptor_dissect(tvb, offset, dvb_sdt_service_tree); } packet_mpeg_sect_crc(tvb, pinfo, dvb_sdt_tree, 0, offset); }
static void dissect_mpeg_pat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0, length = 0; guint16 prog_num = 0, prog_pid; proto_item *ti = NULL; proto_tree *mpeg_pat_tree = NULL; proto_item *pi = NULL; proto_tree *mpeg_pat_prog_tree = NULL; /* The TVB should start right after the section_length in the Section packet */ col_clear(pinfo->cinfo, COL_INFO); col_set_str(pinfo->cinfo, COL_INFO, "Program Association Table (PAT)"); ti = proto_tree_add_item(tree, proto_mpeg_pat, tvb, offset, -1, ENC_NA); mpeg_pat_tree = proto_item_add_subtree(ti, ett_mpeg_pat); if (!tree) return; offset += packet_mpeg_sect_header(tvb, offset, mpeg_pat_tree, &length, NULL); length -= 4; proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_transport_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_version_number, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_current_next_indicator, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; if (offset >= length) return; /* Parse all the programs */ while (offset < length) { prog_num = tvb_get_ntohs(tvb, offset); prog_pid = tvb_get_ntohs(tvb, offset + 2) & MPEG_PAT_PROGRAM_MAP_PID_MASK; pi = proto_tree_add_text(mpeg_pat_tree, tvb, offset, 4, "Program 0x%04hx -> PID 0x%04hx", prog_num, prog_pid); mpeg_pat_prog_tree = proto_item_add_subtree(pi, ett_mpeg_pat_prog); proto_tree_add_item(mpeg_pat_prog_tree, hf_mpeg_pat_program_number, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(mpeg_pat_prog_tree, hf_mpeg_pat_program_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(mpeg_pat_prog_tree, hf_mpeg_pat_program_map_pid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } packet_mpeg_sect_crc(tvb, pinfo, mpeg_pat_tree, 0, offset); }
static void dissect_dvb_eit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0, length = 0; guint descriptor_len, descriptor_end; guint16 evt_id; proto_item *ti; proto_tree *dvb_eit_tree; proto_item *ei; proto_tree *dvb_eit_event_tree; proto_item *duration_item; nstime_t start_time; col_set_str(pinfo->cinfo, COL_INFO, "Event Information Table (EIT)"); ti = proto_tree_add_item(tree, proto_dvb_eit, tvb, offset, -1, ENC_NA); dvb_eit_tree = proto_item_add_subtree(ti, ett_dvb_eit); offset += packet_mpeg_sect_header(tvb, offset, dvb_eit_tree, &length, NULL); length -= 4; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_service_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_version_number, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_current_next_indicator, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_transport_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_original_network_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_segment_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_last_table_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (offset >= length) { packet_mpeg_sect_crc(tvb, pinfo, dvb_eit_tree, 0, offset); return; } /* Parse all the events */ while (offset < length) { evt_id = tvb_get_ntohs(tvb, offset); ei = proto_tree_add_text(dvb_eit_tree, tvb, offset, 12, "Event 0x%04hx", evt_id); dvb_eit_event_tree = proto_item_add_subtree(ei, ett_dvb_eit_event); proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_event_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (tvb_memeql(tvb, offset, "\xFF\xFF\xFF\xFF\xFF", 5)) { if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &start_time) < 0) { proto_tree_add_text(tree, tvb, offset, 5, "Unparseable time"); } else { proto_tree_add_time_format(dvb_eit_event_tree, hf_dvb_eit_start_time, tvb, offset, 5, &start_time, "Start Time: %s UTC", abs_time_to_str(&start_time, ABSOLUTE_TIME_UTC, FALSE)); } } else { proto_tree_add_text(tree, tvb, offset, 5, "Start Time: Undefined (0xFFFFFFFFFF)"); } offset += 5; duration_item = proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_duration, tvb, offset, 3, ENC_BIG_ENDIAN); proto_item_append_text(duration_item, " (%02u:%02u:%02u)", MPEG_SECT_BCD44_TO_DEC(tvb_get_guint8(tvb, offset)), MPEG_SECT_BCD44_TO_DEC(tvb_get_guint8(tvb, offset + 1)), MPEG_SECT_BCD44_TO_DEC(tvb_get_guint8(tvb, offset + 2))); offset += 3; proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_running_status, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_free_ca_mode, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_descriptors_loop_length, tvb, offset, 2, ENC_BIG_ENDIAN); descriptor_len = tvb_get_ntohs(tvb, offset) & DVB_EIT_DESCRIPTORS_LOOP_LENGTH_MASK; offset += 2; descriptor_end = offset + descriptor_len; while (offset < descriptor_end) offset += proto_mpeg_descriptor_dissect(tvb, offset, dvb_eit_event_tree); } offset += packet_mpeg_sect_crc(tvb, pinfo, dvb_eit_tree, 0, offset); proto_item_set_len(ti, offset); }
static void dissect_dvb_data_mpe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0, tot_len = 0; guint8 llc_snap_flag; int i; proto_item *ti; proto_tree *dvb_data_mpe_tree; tvbuff_t *mac_tvb; tvbuff_t *mac_bytes_tvb[6]; tvbuff_t *data_tvb; /* The TVB should start right after the section_length in the Section packet */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "DVB-DATA"); col_set_str(pinfo->cinfo, COL_INFO, "MultiProtocol Encapsulation"); ti = proto_tree_add_item(tree, proto_dvb_data_mpe, tvb, offset, -1, ENC_NA); dvb_data_mpe_tree = proto_item_add_subtree(ti, ett_dvb_data_mpe); offset += packet_mpeg_sect_header(tvb, offset, dvb_data_mpe_tree, &tot_len, NULL); /* Parse the DMC-CC private section header */ mac_bytes_tvb[5] = tvb_new_subset(tvb, offset, 1, 1); offset += 1; mac_bytes_tvb[4] = tvb_new_subset(tvb, offset, 1, 1); offset += 1; proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_payload_scrambling_control, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_address_scrambling_control, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_llc_snap_flag, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_current_next_indicator, tvb, offset, 1, ENC_BIG_ENDIAN); llc_snap_flag = tvb_get_guint8(tvb, offset) & DVB_DATA_MPE_LLC_SNAP_FLAG_MASK; offset += 1; proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; for (i = 3; i >= 0; i--) { mac_bytes_tvb[i] = tvb_new_subset(tvb, offset, 1, 1); offset += 1; } mac_tvb = tvb_new_composite(); for (i = 0; i < 6; i++) tvb_composite_append(mac_tvb, mac_bytes_tvb[i]); tvb_composite_finalize(mac_tvb); proto_tree_add_item(dvb_data_mpe_tree, hf_dvb_data_mpe_dst_mac, mac_tvb, 0 , 6, ENC_NA); col_add_str(pinfo->cinfo, COL_RES_DL_DST, tvb_ether_to_str(mac_tvb, 0)); data_tvb = tvb_new_subset_remaining(tvb, offset); if (llc_snap_flag) { call_dissector(llc_handle, data_tvb, pinfo, tree); } else { call_dissector(ip_handle, data_tvb, pinfo, tree); } packet_mpeg_sect_crc(tvb, pinfo, dvb_data_mpe_tree, 0, tot_len - 1); return; }
static void dissect_dvb_bat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0, length = 0, ts_loop_end; guint16 ts_id, descriptor_len, ts_loop_len; proto_item *ti; proto_tree *dvb_bat_tree; proto_item *tsi; proto_tree *transport_stream_tree; col_set_str(pinfo->cinfo, COL_INFO, "Bouquet Association Table (BAT)"); ti = proto_tree_add_item(tree, proto_dvb_bat, tvb, offset, -1, ENC_NA); dvb_bat_tree = proto_item_add_subtree(ti, ett_dvb_bat); offset += packet_mpeg_sect_header(tvb, offset, dvb_bat_tree, &length, NULL); length -= 4; proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_bouquet_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_reserved1, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_version_number, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_current_next_indicator, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; descriptor_len = tvb_get_ntohs(tvb, offset) & DVB_BAT_BOUQUET_DESCRIPTORS_LENGTH_MASK; proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_bouquet_descriptors_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; offset += proto_mpeg_descriptor_loop_dissect(tvb, offset, descriptor_len, dvb_bat_tree); ts_loop_len = tvb_get_ntohs(tvb, offset) & DVB_BAT_TRANSPORT_STREAM_LOOP_LENGTH_MASK; proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_reserved3, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(dvb_bat_tree, hf_dvb_bat_transport_stream_loop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; ts_loop_end = offset + ts_loop_len; while (offset < ts_loop_end) { ts_id = tvb_get_ntohs(tvb, offset); descriptor_len = tvb_get_ntohs(tvb, offset + 4) & DVB_BAT_TRANSPORT_DESCRIPTORS_LENGTH_MASK; tsi = proto_tree_add_text(dvb_bat_tree, tvb, offset, 6 + descriptor_len, "Transport Stream 0x%04x", ts_id); transport_stream_tree = proto_item_add_subtree(tsi, ett_dvb_bat_transport_stream); proto_tree_add_item(transport_stream_tree, hf_dvb_bat_transport_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(transport_stream_tree, hf_dvb_bat_original_network_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(transport_stream_tree, hf_dvb_bat_reserved4, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(transport_stream_tree, hf_dvb_bat_transport_descriptors_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; offset += proto_mpeg_descriptor_loop_dissect(tvb, offset, descriptor_len, transport_stream_tree); } offset += packet_mpeg_sect_crc(tvb, pinfo, dvb_bat_tree, 0, offset); proto_item_set_len(ti, offset); }
static void dissect_eiss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0, packet_length, sect_len; proto_item *ti; proto_item *pi; proto_tree *eiss_tree; proto_item *items[PACKET_MPEG_SECT_PI__SIZE]; gboolean ssi; guint reserved; guint8 reserved2; guint8 sect_num, last_sect_num; guint16 eiss_application_type; guint8 platform_id_length; col_set_str(pinfo->cinfo, COL_PROTOCOL, "EISS"); ti = proto_tree_add_item(tree, proto_eiss, tvb, offset, -1, ENC_NA); eiss_tree = proto_item_add_subtree(ti, ett_eiss); offset += packet_mpeg_sect_header_extra(tvb, offset, eiss_tree, §_len, &reserved, &ssi, items); packet_length = sect_len + 3 - 4; /* + for the header, - for the crc */ if (FALSE != ssi) { proto_item *msg_error; msg_error = items[PACKET_MPEG_SECT_PI__SSI]; PROTO_ITEM_SET_GENERATED(msg_error); expert_add_info(pinfo, msg_error, &ei_eiss_invalid_section_syntax_indicator); } if (0 != reserved) { proto_item *msg_error; msg_error = items[PACKET_MPEG_SECT_PI__RESERVED]; PROTO_ITEM_SET_GENERATED(msg_error); expert_add_info_format(pinfo, msg_error, &ei_eiss_invalid_reserved_bits, "Invalid reserved1 bits (should all be 0)"); } if (1021 < sect_len) { proto_item *msg_error; msg_error = items[PACKET_MPEG_SECT_PI__LENGTH]; PROTO_ITEM_SET_GENERATED(msg_error); expert_add_info(pinfo, msg_error, &ei_eiss_invalid_section_length); } reserved2 = tvb_get_guint8(tvb, offset); pi = proto_tree_add_item(eiss_tree, hf_eiss_reserved2, tvb, offset, 1, ENC_BIG_ENDIAN); if (0 != reserved2) { expert_add_info_format(pinfo, pi, &ei_eiss_invalid_reserved_bits, "Invalid reserved2 bits (should all be 0)"); } offset++; sect_num = tvb_get_guint8(tvb, offset); last_sect_num = tvb_get_guint8(tvb, offset + 1); pi = proto_tree_add_item(eiss_tree, hf_eiss_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); if (last_sect_num < sect_num) { expert_add_info(pinfo, pi, &ei_eiss_section_number); } offset++; proto_tree_add_item(eiss_tree, hf_eiss_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(eiss_tree, hf_eiss_protocol_version_major, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(eiss_tree, hf_eiss_protocol_version_minor, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; eiss_application_type = tvb_get_ntohs(tvb, offset); pi = proto_tree_add_item(eiss_tree, hf_eiss_application_type, tvb, offset, 2, ENC_BIG_ENDIAN); if (8 != eiss_application_type) { expert_add_info(pinfo, pi, &ei_eiss_application_type); } offset += 2; proto_tree_add_item(eiss_tree, hf_eiss_organisation_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(eiss_tree, hf_eiss_application_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; platform_id_length = tvb_get_guint8(tvb, offset); pi = proto_tree_add_item(eiss_tree, hf_eiss_platform_id_length, tvb, offset, 1, ENC_BIG_ENDIAN); if (0 != platform_id_length % 15) { expert_add_info(pinfo, pi, &ei_eiss_platform_id_length); } offset++; while (0 < platform_id_length) { guint tmp; tmp = dissect_etv_bif_platform_ids(tvb, eiss_tree, offset); offset += tmp; if (platform_id_length < tmp) { platform_id_length = 0; /* error */ } else { platform_id_length -= tmp; } } if (0 < packet_length) { proto_tree *eiss_desc_tree; pi = proto_tree_add_text(eiss_tree, tvb, offset, packet_length-offset, "%s", "EISS Descriptor(s)"); eiss_desc_tree = proto_item_add_subtree(pi, ett_eiss_desc); while (offset < packet_length) { offset += dissect_eiss_descriptors(tvb, pinfo, eiss_desc_tree, offset); } } packet_mpeg_sect_crc(tvb, pinfo, eiss_tree, 0, sect_len - 1); }