guint packet_mpeg_sect_crc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint start, guint end) { if (mpeg_sect_check_crc) { proto_tree_add_checksum(tree, tvb, end, hf_mpeg_sect_crc, hf_mpeg_sect_crc_status, &ei_mpeg_sect_crc, pinfo, crc32_mpeg2_tvb_offset(tvb, start, end), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY); } else { proto_tree_add_checksum(tree, tvb, end, hf_mpeg_sect_crc, hf_mpeg_sect_crc_status, &ei_mpeg_sect_crc, pinfo, crc32_mpeg2_tvb_offset(tvb, start, end), ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); } return 4; }
static void dissect_stt_checksum(tvbuff_t *tvb, packet_info *pinfo, proto_tree *stt_tree) { gboolean can_checksum = !pinfo->fragmented && tvb_bytes_exist(tvb, 0, tvb_reported_length(tvb)); if (can_checksum && pref_check_checksum) { vec_t cksum_vec[4]; guint32 phdr[2]; /* Set up the fields of the pseudo-header. */ SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len); SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len); switch (pinfo->src.type) { case AT_IPv4: phdr[0] = g_htonl((IP_PROTO_TCP<<16) + tvb_reported_length(tvb)); SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)phdr, 4); break; case AT_IPv6: phdr[0] = g_htonl(tvb_reported_length(tvb)); phdr[1] = g_htonl(IP_PROTO_TCP); SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)phdr, 8); break; default: /* STT runs only atop IPv4 and IPv6.... */ DISSECTOR_ASSERT_NOT_REACHED(); break; } SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, tvb_reported_length(tvb)); proto_tree_add_checksum(stt_tree, tvb, 16, hf_stt_checksum, hf_stt_checksum_status, &ei_stt_checksum_bad, pinfo, in_cksum(cksum_vec, 4), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY); } else { proto_tree_add_checksum(stt_tree, tvb, 16, hf_stt_checksum, hf_stt_checksum_status, &ei_stt_checksum_bad, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); } }
/** Checksums the data. */ static tvbuff_t * checksum_data(tvbuff_t *tvb, proto_tree *tree) { int len = tvb_reported_length(tvb) - 2; if (len < 0) return tvb; proto_tree_add_checksum(tree, tvb, len, hf_sir_fcs, hf_sir_fcs_status, NULL, NULL, crc16_ccitt_tvb(tvb, len), ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY); return tvb_new_subset_length(tvb, 0, len); }
/* GFP has several identical 16 bit CRCs in its header (HECs). Note that * this function increases the offset. */ static void gfp_add_hec_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, const guint len, const int field, const int field_status, expert_field *ei_bad) { guint hec_calc; hec_calc = crc16_r3_ccitt_tvb(tvb, *offset, len); *offset += len; proto_tree_add_checksum(tree, tvb, *offset, field, field_status, ei_bad, pinfo, hec_calc, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY); *offset += 2; }
static void dissect_pe_checksum_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item) { proto_tree_add_checksum(parameter_tree, parameter_tvb, PE_CHECKSUM_OFFSET, hf_pe_checksum, -1, NULL, NULL, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); proto_item_append_text(parameter_item, " (0x%x)", tvb_get_ntohs(parameter_tvb, PE_CHECKSUM_OFFSET)); }
static int dissect_dvb_s2_bb(tvbuff_t *tvb, int cur_off, proto_tree *tree, packet_info *pinfo) { proto_item *ti; proto_tree *dvb_s2_bb_tree; guint8 input8, matype1; guint16 input16, bb_data_len = 0, user_packet_length; int sub_dissected = 0, flag_is_ms = 0, new_off = 0; static const int * bb_header_bitfields[] = { &hf_dvb_s2_bb_matype1_gs, &hf_dvb_s2_bb_matype1_mis, &hf_dvb_s2_bb_matype1_acm, &hf_dvb_s2_bb_matype1_issyi, &hf_dvb_s2_bb_matype1_npd, &hf_dvb_s2_bb_matype1_ro, NULL }; col_append_str(pinfo->cinfo, COL_PROTOCOL, "BB "); col_append_str(pinfo->cinfo, COL_INFO, "Baseband "); /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_dvb_s2_bb, tvb, cur_off, DVB_S2_BB_HEADER_LEN, ENC_NA); dvb_s2_bb_tree = proto_item_add_subtree(ti, ett_dvb_s2_bb); matype1 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1); new_off += 1; if (BIT_IS_CLEAR(matype1, DVB_S2_BB_MIS_POS)) flag_is_ms = 1; proto_tree_add_bitmask_with_flags(dvb_s2_bb_tree, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, hf_dvb_s2_bb_matype1, ett_dvb_s2_bb_matype1, bb_header_bitfields, ENC_BIG_ENDIAN, BMT_NO_FLAGS); input8 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_MATYPE2); new_off += 1; if (flag_is_ms) { proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE2, 1, input8, "Input Stream Identifier (ISI): %d", input8); } else { proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE2, 1, input8, "reserved"); } user_packet_length = input16 = tvb_get_ntohs(tvb, cur_off + DVB_S2_BB_OFFS_UPL); new_off += 2; proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_upl, tvb, cur_off + DVB_S2_BB_OFFS_UPL, 2, input16, "User Packet Length: %d bits (%d bytes)", (guint16) input16, (guint16) input16 / 8); bb_data_len = input16 = tvb_get_ntohs(tvb, cur_off + DVB_S2_BB_OFFS_DFL); bb_data_len /= 8; new_off += 2; proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_dfl, tvb, cur_off + DVB_S2_BB_OFFS_DFL, 2, input16, "%d bits (%d bytes)", input16, input16 / 8); new_off += 1; proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_sync, tvb, cur_off + DVB_S2_BB_OFFS_SYNC, 1, ENC_BIG_ENDIAN); new_off += 2; proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_syncd, tvb, cur_off + DVB_S2_BB_OFFS_SYNCD, 2, ENC_BIG_ENDIAN); new_off += 1; proto_tree_add_checksum(dvb_s2_bb_tree, tvb, cur_off + DVB_S2_BB_OFFS_CRC, hf_dvb_s2_bb_crc, hf_dvb_s2_bb_crc_status, &ei_dvb_s2_bb_crc, pinfo, compute_crc8(tvb, DVB_S2_BB_HEADER_LEN - 1, cur_off), ENC_NA, PROTO_CHECKSUM_VERIFY); switch (matype1 & DVB_S2_BB_TSGS_MASK) { case DVB_S2_BB_TSGS_GENERIC_CONTINUOUS: /* Check GSE constraints on the BB header per 9.2.1 of ETSI TS 102 771 */ if (BIT_IS_SET(matype1, DVB_S2_BB_ISSYI_POS)) { expert_add_info(pinfo, ti, &ei_dvb_s2_bb_issy_invalid); } if (BIT_IS_SET(matype1, DVB_S2_BB_NPD_POS)) { expert_add_info(pinfo, ti, &ei_dvb_s2_bb_npd_invalid); } if (user_packet_length != 0x0000) { expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_upl_invalid, "UPL is 0x%04x. It must be 0x0000 for GSE packets.", user_packet_length); } while (bb_data_len) { /* start DVB-GSE dissector */ sub_dissected = dissect_dvb_s2_gse(tvb, cur_off + new_off, tree, pinfo, bb_data_len); new_off += sub_dissected; if ((sub_dissected <= bb_data_len) && (sub_dissected >= DVB_S2_GSE_MINSIZE)) { bb_data_len -= sub_dissected; if (bb_data_len < DVB_S2_GSE_MINSIZE) bb_data_len = 0; } else { bb_data_len = 0; } } break; case DVB_S2_BB_TSGS_GENERIC_PACKETIZED: proto_tree_add_item(tree, hf_dvb_s2_bb_packetized, tvb, cur_off + new_off, bb_data_len, ENC_NA); new_off += bb_data_len; break; case DVB_S2_BB_TSGS_TRANSPORT_STREAM: proto_tree_add_item(tree, hf_dvb_s2_bb_transport, tvb, cur_off + new_off, bb_data_len, ENC_NA); new_off += bb_data_len; break; default: proto_tree_add_item(tree, hf_dvb_s2_bb_reserved, tvb, cur_off + new_off,bb_data_len, ENC_NA); new_off += bb_data_len; expert_add_info(pinfo, ti, &ei_dvb_s2_bb_reserved); break; } return new_off; }
static void display_xip_serval(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *xip_serval_tree; proto_item *ti, *hl_ti; tvbuff_t *next_tvb; vec_t cksum_vec; gint offset; guint8 xsh_len, protocol, bytes_remaining; /* Get XIP Serval header length, stored as number of 32-bit words. */ xsh_len = tvb_get_guint8(tvb, XSRVL_LEN) << 2; /* Create XIP Serval header tree. */ ti = proto_tree_add_item(tree, proto_xip_serval, tvb, 0, xsh_len, ENC_NA); xip_serval_tree = proto_item_add_subtree(ti, ett_xip_serval_tree); /* Add XIP Serval header length. */ hl_ti = proto_tree_add_item(xip_serval_tree, hf_xip_serval_hl, tvb, XSRVL_LEN, 1, ENC_BIG_ENDIAN); proto_item_append_text(hl_ti, " bytes"); if (tvb_captured_length(tvb) < xsh_len) expert_add_info_format(pinfo, hl_ti, &ei_xip_serval_bad_len, "Header Length field (%d bytes) cannot be greater than actual number of bytes left in packet (%d bytes)", xsh_len, tvb_captured_length(tvb)); /* Add XIP Serval protocol. If it's not data, TCP, or UDP, the * packet is malformed. */ proto_tree_add_item(xip_serval_tree, hf_xip_serval_proto, tvb, XSRVL_PRO, 1, ENC_BIG_ENDIAN); protocol = tvb_get_guint8(tvb, XSRVL_PRO); if (!try_val_to_str(protocol, xip_serval_proto_vals)) expert_add_info_format(pinfo, ti, &ei_xip_serval_bad_proto, "Unrecognized protocol type: %d", protocol); /* Compute checksum. */ SET_CKSUM_VEC_TVB(cksum_vec, tvb, 0, xsh_len); proto_tree_add_checksum(xip_serval_tree, tvb, XSRVL_CHK, hf_xip_serval_check, -1, &ei_xip_serval_bad_checksum, pinfo, in_cksum(&cksum_vec, 1), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM); offset = XSRVL_EXT; /* If there's still more room, check for extension headers. */ bytes_remaining = xsh_len - offset; while (bytes_remaining >= XIP_SERVAL_EXT_MIN_LEN) { gint8 bytes_displayed = display_xip_serval_ext(tvb, pinfo, ti, xip_serval_tree, offset); /* Extension headers are malformed, so we can't say * what the rest of the packet holds. Stop dissecting. */ if (bytes_displayed <= 0) return; offset += bytes_displayed; bytes_remaining -= bytes_displayed; } switch (protocol) { case XIP_SERVAL_PROTO_DATA: next_tvb = tvb_new_subset_remaining(tvb, offset); call_data_dissector(next_tvb, pinfo, tree); break; case IP_PROTO_TCP: { /* Get the Data Offset field of the TCP header, which is * the high nibble of the 12th octet and represents the * size of the TCP header of 32-bit words. */ guint8 tcp_len = hi_nibble(tvb_get_guint8(tvb, offset + 12))*4; next_tvb = tvb_new_subset(tvb, offset, tcp_len, tcp_len); call_dissector(tcp_handle, next_tvb, pinfo, tree); break; } case IP_PROTO_UDP: /* The UDP header is always 8 bytes. */ next_tvb = tvb_new_subset(tvb, offset, 8, 8); call_dissector(udp_handle, next_tvb, pinfo, tree); break; default: break; } }