/* M2TP Message */ static void dissect_m2tp_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_item *m2tp_item, proto_tree *m2tp_tree, proto_tree *tree) { gint offset, length, padding_length, total_length; tvbuff_t *common_header_tvb, *parameter_tvb; offset = 0; /* extract and process the common header */ common_header_tvb = tvb_new_subset_length(message_tvb, offset, COMMON_HEADER_LENGTH); dissect_m2tp_common_header(common_header_tvb, pinfo, m2tp_tree); offset += COMMON_HEADER_LENGTH; /* extract zero or more parameters and process them individually */ while(tvb_reported_length_remaining(message_tvb, offset) > 0) { length = tvb_get_ntohs(message_tvb, offset + PARAMETER_LENGTH_OFFSET); padding_length = nr_of_padding_bytes(length); total_length = length + padding_length; /* create a tvb for the parameter including the padding bytes */ parameter_tvb = tvb_new_subset_length(message_tvb, offset, total_length); dissect_m2tp_parameter(parameter_tvb, pinfo, m2tp_tree, m2tp_item, tree); /* get rid of the handled parameter */ offset += total_length; } }
/** Checksums the data. */ static tvbuff_t * checksum_data(tvbuff_t *tvb, proto_tree *tree) { proto_item *hidden_item; int len = tvb_length(tvb) - 2; if (len < 0) return tvb; if (tree) { guint16 actual_fcs = tvb_get_letohs(tvb, len); guint16 calculated_fcs = crc16_ccitt_tvb(tvb, len); if (calculated_fcs == actual_fcs) { proto_tree_add_uint_format(tree, hf_sir_fcs, tvb, len, 2, actual_fcs, "Frame check sequence: 0x%04x (correct)", actual_fcs); } else { hidden_item = proto_tree_add_boolean(tree, hf_sir_fcs_bad, tvb, len, 2, TRUE); PROTO_ITEM_SET_HIDDEN(hidden_item); proto_tree_add_uint_format(tree, hf_sir_fcs, tvb, len, 2, actual_fcs, "Frame check sequence: 0x%04x " "(incorrect, should be 0x%04x)", actual_fcs, calculated_fcs); } } return tvb_new_subset_length(tvb, 0, len); }
static void dissect_lapbether(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *lapbether_tree, *ti; int len; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "LAPBETHER"); col_clear(pinfo->cinfo, COL_INFO); len = tvb_get_guint8(tvb, 0) + tvb_get_guint8(tvb, 1) * 256; if (tree) { ti = proto_tree_add_protocol_format(tree, proto_lapbether, tvb, 0, 2, "LAPBETHER"); lapbether_tree = proto_item_add_subtree(ti, ett_lapbether); proto_tree_add_uint_format(lapbether_tree, hf_lapbether_length, tvb, 0, 2, len, "Length: %u", len); } next_tvb = tvb_new_subset_length(tvb, 2, len); call_dissector(lapb_handle, next_tvb, pinfo, tree); }
static void dissect_ss_info_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree) { guint saved_offset; gint8 appclass; gboolean pc; gboolean ind = FALSE; guint32 component_len = 0; guint32 header_end_offset; guint32 header_len; asn1_ctx_t asn1_ctx; tvbuff_t *ss_tvb = NULL; static gint comp_type_tag; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); saved_offset = offset; col_append_str(pinfo->cinfo, COL_PROTOCOL, "/"); col_set_fence(pinfo->cinfo, COL_PROTOCOL); while (len > (offset - saved_offset)) { /* get the length of the component. there can be multiple components in one message */ header_end_offset = get_ber_identifier(tvb, offset, &appclass, &pc, &comp_type_tag); header_end_offset = get_ber_length(tvb, header_end_offset, &component_len, &ind); header_len = header_end_offset -offset; component_len += header_len; ss_tvb = tvb_new_subset_length(tvb, offset, component_len); col_append_str(pinfo->cinfo, COL_INFO, "(GSM MAP) "); col_set_fence(pinfo->cinfo, COL_INFO); call_dissector(gsm_map_handle, ss_tvb, pinfo, tree); offset += component_len; } }
static void call_pres_dissector(tvbuff_t *tvb, int offset, guint16 param_len, packet_info *pinfo, proto_tree *tree, proto_tree *param_tree, struct SESSION_DATA_STRUCTURE *session) { /* do we have OSI presentation packet dissector ? */ if(!pres_handle) { /* No - display as data */ if (tree) { proto_tree_add_text(param_tree, tvb, offset, param_len, "User data"); } } else { /* Yes - call presentation dissector */ tvbuff_t *next_tvb; next_tvb = tvb_new_subset_length(tvb, offset, param_len); /* Pass the session pdu to the presentation dissector */ call_dissector_with_data(pres_handle, next_tvb, pinfo, tree, session); } }
static void dissect_v8_message_data(tvbuff_t *message_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree) { guint32 message_data_length; guint8 type; tvbuff_t *message_data_tvb; message_data_length = tvb_get_ntohl(message_tvb, V8_LENGTH_OFFSET) - V8_HEADER_LENGTH; if ((gint) message_data_length < 1) { proto_tree_add_expert_format(m2pa_tree, pinfo, &ei_length, message_tvb, V8_LENGTH_OFFSET, 4, "Invalid message data length: %u", message_data_length); /* XXX - is this really necessary? Can we just return since the expert info can still find the "malformed" packet? */ THROW(ReportedBoundsError); } message_data_tvb = tvb_new_subset_length(message_tvb, V8_MESSAGE_DATA_OFFSET, message_data_length); type = tvb_get_guint8(message_tvb, V8_TYPE_OFFSET); switch(type) { case V8_USER_DATA_TYPE: dissect_v8_user_data_message(message_data_tvb, pinfo, m2pa_item, m2pa_tree, tree); break; case V8_LINK_STATUS_TYPE: dissect_v8_link_status_message(message_data_tvb, pinfo, m2pa_tree); break; default: dissect_unknown_message(message_data_tvb, m2pa_tree); } }
static void dissect_v8_message_data(tvbuff_t *message_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree) { guint32 message_data_length; guint8 type; tvbuff_t *message_data_tvb; message_data_length = tvb_get_ntohl(message_tvb, V8_LENGTH_OFFSET) - V8_HEADER_LENGTH; if ((gint) message_data_length < 1) { proto_tree_add_expert_format(m2pa_tree, pinfo, &ei_length, message_tvb, V8_LENGTH_OFFSET, 4, "Invalid message data length: %u", message_data_length); return; } message_data_tvb = tvb_new_subset_length(message_tvb, V8_MESSAGE_DATA_OFFSET, message_data_length); type = tvb_get_guint8(message_tvb, V8_TYPE_OFFSET); switch(type) { case V8_USER_DATA_TYPE: dissect_v8_user_data_message(message_data_tvb, pinfo, m2pa_item, m2pa_tree, tree); break; case V8_LINK_STATUS_TYPE: dissect_v8_link_status_message(message_data_tvb, pinfo, m2pa_tree); break; default: dissect_unknown_message(message_data_tvb, m2pa_tree); } }
/* MS-GPEF section 2.2.1.2.2 EfsKey*/ static int dissect_gpef_efskey(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree) { proto_item *item = NULL; proto_tree *tree = NULL; int old_offset = offset; guint32 length1, sid_offset; guint32 cert_length, cert_offset; tvbuff_t *next_tvb; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); if (parent_tree) { item = proto_tree_add_item(parent_tree, hf_gpef_efskey, tvb, -1, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_gpef_efskey); } /* length 1 */ length1 = tvb_get_letohl(tvb, offset); proto_tree_add_item(tree, hf_gpef_efskey_length1, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* length 2 */ proto_tree_add_item(tree, hf_gpef_efskey_length2, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* sid offset */ sid_offset = tvb_get_letohl(tvb, offset); proto_tree_add_item(tree, hf_gpef_efskey_sid_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* reserved */ offset += 4; /* cert length */ cert_length = tvb_get_letohl(tvb, offset); proto_tree_add_item(tree, hf_gpef_efskey_cert_length, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* cert offset */ cert_offset = tvb_get_letohl(tvb, offset); proto_tree_add_item(tree, hf_gpef_efskey_cert_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); /*offset += 4;*/ /* reserved, must be 0x20 0x00 0x00 0x00 */ /*offset += 4;*/ /* sid */ dissect_nt_sid(tvb, old_offset+4+sid_offset, tree, "sid", NULL, -1); /* certificate */ next_tvb = tvb_new_subset_length(tvb, old_offset+4+cert_offset, cert_length); (void)dissect_x509af_Certificate(FALSE, next_tvb, 0, &asn1_ctx, tree, hf_gpef_efskey_certificate); offset = old_offset + length1; proto_item_set_len(item, offset-old_offset); return offset; }
/* Dissection */ static void dissect_macmgmt (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { const guint8 *src, *dst; guint16 msg_len; proto_item *mgt_hdr_it; proto_tree *mgt_hdr_tree; tvbuff_t *payload_tvb; guint8 type; col_set_str (pinfo->cinfo, COL_PROTOCOL, "DOCSIS MGMT"); col_clear(pinfo->cinfo, COL_INFO); src = tvb_get_ptr (tvb, 6, 6); dst = tvb_get_ptr (tvb, 0, 6); SET_ADDRESS (&pinfo->dl_src, AT_ETHER, 6, src); SET_ADDRESS (&pinfo->src, AT_ETHER, 6, src); SET_ADDRESS (&pinfo->dl_dst, AT_ETHER, 6, dst); SET_ADDRESS (&pinfo->dst, AT_ETHER, 6, dst); if (tree) { mgt_hdr_it = proto_tree_add_protocol_format (tree, proto_docsis_mgmt, tvb, 0, 20, "Mac Management"); mgt_hdr_tree = proto_item_add_subtree (mgt_hdr_it, ett_docsis_mgmt); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_dst_addr, tvb, 0, 6, ENC_NA); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_src_addr, tvb, 6, 6, ENC_NA); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_msg_len, tvb, 12, 2, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_dsap, tvb, 14, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_ssap, tvb, 15, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_control, tvb, 16, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_version, tvb, 17, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_type, tvb, 18, 1, ENC_BIG_ENDIAN); proto_tree_add_item (mgt_hdr_tree, hf_docsis_mgt_rsvd, tvb, 19, 1, ENC_BIG_ENDIAN); } /* Code to Call subdissector */ /* sub-dissectors are based on the type field */ type = tvb_get_guint8 (tvb, 18); msg_len = tvb_get_ntohs (tvb, 12); payload_tvb = tvb_new_subset_length (tvb, 20, msg_len - 6); if (dissector_try_uint (docsis_mgmt_dissector_table, type, payload_tvb, pinfo, tree)) return; else call_dissector (data_handle, payload_tvb, pinfo, tree); }
/* Code to actually dissect the packets */ static void dissect_dpnss_link(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *item; proto_tree *dpnss_link_tree; guint8 octet; tvbuff_t *protocol_data_tvb; guint16 protocol_data_length; gboolean uton; uton = pinfo->pseudo_header->l1event.uton; /* Make entries in src and dst column */ col_set_str(pinfo->cinfo, COL_DEF_SRC, uton?"TE":"NT"); col_set_str(pinfo->cinfo, COL_DEF_DST, uton?"NT":"TE"); /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "DPNSS"); item = proto_tree_add_item(tree, proto_dpnss_link, tvb, 0, -1, ENC_NA); dpnss_link_tree = proto_item_add_subtree(item, ett_dpnss_link); proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_address_framegroup, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_address_crbit, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_address_extension, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_address2_reserved, tvb, 1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_address2_dlcId, tvb, 1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_address2_dlcIdNr, tvb, 1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_address2_extension, tvb, 1, 1, ENC_BIG_ENDIAN); /* * XXX - DPNSS's layer 2 protocol appears to be Yet Another * HDLC Derivative; should this use the xDLC control field * dissector code? */ proto_tree_add_item(dpnss_link_tree, hf_dpnss_link_control_frameType, tvb, 2, 1, ENC_BIG_ENDIAN); octet = tvb_get_guint8(tvb, 2); switch (octet){ case FRAME_TYPE_UI_EVEN: case FRAME_TYPE_UI_ODD: protocol_data_length=tvb_length(tvb)-LINK_HEADER_SIZE; protocol_data_tvb=tvb_new_subset_length(tvb, LINK_HEADER_SIZE, protocol_data_length); if (dpnss_handle && protocol_data_length>0) { call_dissector(dpnss_handle, protocol_data_tvb, pinfo, tree); } break; default: break; } }
static void dissect_wimax_pdu_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset; guint mac_ht, mac_ec; guint first_byte, length; guint mac_hcs, mac_hcs_calculated; proto_item *pdu_item = NULL; proto_tree *pdu_tree = NULL; #ifndef STATIC_DATA /* generate the table of CRC32 remainders for all possible bytes */ wimax_mac_gen_crc32_table(); /* generate the table of CRC8 remainders for all possible bytes */ wimax_mac_gen_crc8_table(); #endif /* parsing the PDU burst */ for(offset = 0; offset < tvb_reported_length(tvb); ) { if (offset == 0) { first_gmh = TRUE; } else { first_gmh = FALSE; } /* get the length of the remainder */ length = tvb_reported_length_remaining(tvb, offset); /* get the first byte at offset */ first_byte = tvb_get_guint8(tvb, offset); /* check for padding */ if(first_byte == WIMAX_PDU_PADDING_MASK) { /* Padding */ /* display message */ pdu_item = proto_tree_add_protocol_format(tree, proto_wimax_pdu_decoder, tvb, offset, length, "Padding (%u bytes)", length); /* add subtree */ pdu_tree = proto_item_add_subtree(pdu_item, ett_wimax_pdu_decoder); /* display the padding in Hex */ proto_tree_add_item(pdu_tree, hf_wimax_value_bytes, tvb, offset, length, ENC_NA); break; } else if((first_byte & WIMAX_MAP_TYPE_MASK) == WIMAX_HARQ_MAP_MSG_IND) { /* HARQ MAP message (no mac header) */ /* get the HARQ MAp Message Length */ length = ((tvb_get_ntohs(tvb, offset) & WIMAX_HARQ_MAP_MSG_LENGTH_MASK1) >> 2); if (length == 0) { length = 3; /* At least 3 bytes. This prevents endless loop */ } call_dissector(wimax_harq_map_handle, tvb_new_subset_length(tvb,offset,length), pinfo, tree); offset += length; continue; } else if((first_byte & WIMAX_MAP_TYPE_MASK) == WIMAX_COMPRESSED_DL_MAP_IND)
/* Decode and display the FCH burst */ static void fch_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo) { if(wimax_fch_burst_handle) { /* call FCH dissector */ call_dissector(wimax_fch_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree); } else /* display FCH info */ { /* update the info column */ col_append_str(pinfo->cinfo, COL_INFO, "FCH Burst: DL Frame Prefix"); } }
/* Decode and display the CDMA Code Attribute */ static void cdma_code_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo) { if(wimax_cdma_code_burst_handle) { /* call CDMA dissector */ call_dissector(wimax_cdma_code_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree); } else /* display CDMA Code Attribute info */ { /* update the info column */ col_append_str(pinfo->cinfo, COL_INFO, "CDMA Code Attribute"); } }
/* Decode and display the PDU Burst */ static void pdu_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo, gint burst_number, gint frag_type, gint frag_number) { fragment_head *pdu_frag; tvbuff_t *pdu_tvb = NULL; /* update the info column */ switch (frag_type) { case TLV_FIRST_FRAG: col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "First TLV Fragment (%d)", frag_number); break; case TLV_LAST_FRAG: col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Last TLV Fragment (%d)", frag_number); break; case TLV_MIDDLE_FRAG: col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Middle TLV Fragment %d", frag_number); break; } if(frag_type == TLV_NO_FRAG) { /* not fragmented PDU */ pdu_tvb = tvb_new_subset_length(tvb, offset, length); } else /* fragmented PDU */ { /* add the fragment */ pdu_frag = fragment_add_seq(&pdu_reassembly_table, tvb, offset, pinfo, burst_number, NULL, frag_number - 1, length, ((frag_type==TLV_LAST_FRAG)?0:1), 0); if(pdu_frag && frag_type == TLV_LAST_FRAG) { /* create the new tvb for defragmented frame */ pdu_tvb = tvb_new_chain(tvb, pdu_frag->tvb_data); /* add the defragmented data to the data source list */ add_new_data_source(pinfo, pdu_tvb, "Reassembled WiMax PDU Frame"); } else { pdu_tvb = NULL; if(frag_type == TLV_LAST_FRAG) { /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Incomplete PDU frame"); } } } /* process the defragmented PDU burst */ if(pdu_tvb) { if(wimax_pdu_burst_handle) {/* decode and display PDU Burst */ call_dissector(wimax_pdu_burst_handle, pdu_tvb, pinfo, tree); } else /* display PDU Burst info */ { /* update the info column */ col_append_str(pinfo->cinfo, COL_INFO, "PDU Burst"); } } }
static void dissect_dsmcc_adaptation_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *sub_tvb; guint offset = 0; proto_item *pi; proto_tree *sub_tree; guint8 type, tmp; guint16 ca_len; type = tvb_get_guint8(tvb, offset); if (1 == type) { sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_dsmcc_adaptation_header, NULL, "Adaptation Header"); proto_tree_add_item(sub_tree, hf_dsmcc_adaptation_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset +=1; tmp = tvb_get_guint8(tvb, offset); pi = proto_tree_add_item(sub_tree, hf_dsmcc_adaptation_ca_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); if (0xff != tmp) { expert_add_info_format(pinfo, pi, &ei_dsmcc_invalid_value, "Invalid value - should be 0xff"); } offset +=1; proto_tree_add_item(sub_tree, hf_dsmcc_adaptation_ca_system_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; ca_len = tvb_get_ntohs(tvb, offset); proto_tree_add_item(sub_tree, hf_dsmcc_adaptation_ca_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; sub_tvb = tvb_new_subset_length(tvb, offset, ca_len); call_dissector(data_handle, sub_tvb, pinfo, tree); } else if (2 == type) { sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_dsmcc_adaptation_header, NULL, "Adaptation Header"); proto_tree_add_item(sub_tree, hf_dsmcc_adaptation_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset +=1; tmp = tvb_get_guint8(tvb, offset); pi = proto_tree_add_item(sub_tree, hf_dsmcc_adaptation_user_id_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); if (0xff != tmp) { expert_add_info_format(pinfo, pi, &ei_dsmcc_invalid_value, "Invalid value - should be 0xff"); } /*offset +=1;*/ /* TODO: handle the userId */ } else { sub_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_dsmcc_adaptation_header, NULL, "Unknown Adaptation Header"); proto_tree_add_item(sub_tree, hf_dsmcc_adaptation_type, tvb, offset, 1, ENC_BIG_ENDIAN); } }
/* Decode and display the Fast Feedback Burst */ static void fast_feedback_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo) { if(wimax_ffb_burst_handle) { /* display the TLV Fast Feedback Burst dissector info */ call_dissector(wimax_ffb_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree); } else /* display the Fast Feedback Burst info */ { /* update the info column */ col_append_str(pinfo->cinfo, COL_INFO, "Fast Feedback Burst"); } }
static void harq_ack_bursts_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo) { if(wimax_hack_burst_handle) { /* call the TLV HARQ ACK Bursts dissector */ call_dissector(wimax_hack_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree); } else /* display the TLV HARQ ACK Bursts info */ { /* update the info column */ col_append_str(pinfo->cinfo, COL_INFO, "HARQ ACK Bursts"); } }
static void dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *wlan_tvb; proto_tree *ti, *cwids_tree; volatile int offset = 0; guint16 capturelen; col_set_str(pinfo->cinfo, COL_PROTOCOL, "CWIDS"); col_set_str(pinfo->cinfo, COL_INFO, "Cwids: "); /* FIXME: col_set_fence(pinfo->cinfo, all-cols, only addr-cols?); */ cwids_tree = NULL; while(tvb_reported_length_remaining(tvb, offset) > 0) { struct ieee_802_11_phdr phdr; ti = proto_tree_add_item(tree, proto_cwids, tvb, offset, 28, ENC_NA); cwids_tree = proto_item_add_subtree(ti, ett_cwids); phdr.fcs_len = 0; /* no FCS */ phdr.decrypted = FALSE; phdr.datapad = FALSE; phdr.presence_flags = PHDR_802_11_HAS_CHANNEL; proto_tree_add_item(cwids_tree, hf_cwids_version, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(cwids_tree, hf_cwids_unknown1, tvb, offset, 7, ENC_NA); offset += 7; phdr.channel = tvb_get_guint8(tvb, offset); proto_tree_add_item(cwids_tree, hf_cwids_channel, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(cwids_tree, hf_cwids_unknown2, tvb, offset, 6, ENC_NA); offset += 6; proto_tree_add_item(cwids_tree, hf_cwids_reallength, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; capturelen = tvb_get_ntohs(tvb, offset); proto_tree_add_item(cwids_tree, hf_cwids_capturelen, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(cwids_tree, hf_cwids_unknown3, tvb, offset, 8, ENC_NA); offset += 8; wlan_tvb = tvb_new_subset_length(tvb, offset, capturelen); /* Continue after ieee80211 dissection errors */ TRY { call_dissector_with_data(ieee80211_radio_handle, wlan_tvb, pinfo, tree, &phdr); } CATCH_BOUNDS_ERRORS { show_exception(wlan_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); expert_add_info(pinfo, ti, &ie_ieee80211_subpacket); } ENDTRY; offset += capturelen; } }
static void physical_attributes_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo) { if(wimax_phy_attributes_burst_handle) { /* call the TLV PDU Burst Physical Attributes dissector */ call_dissector(wimax_phy_attributes_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree); } else /* display the TLV PDU Burst Physical Attributes info */ { /* update the info column */ col_append_str(pinfo->cinfo, COL_INFO, "PHY-attr"); } }
/** 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); }
static void dissect_nwmtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NW MTP"); col_clear(pinfo->cinfo, COL_INFO); while (tvb_reported_length_remaining(tvb, offset) > 0) { const gchar *type; proto_item *ti; proto_item *nwmtp_tree; guint32 len; tvbuff_t *next_tvb; /* update the info column */ type = val_to_str_const(tvb_get_guint8(tvb, offset + 1), nwmtp_data_type_vals, "Unknown"); col_set_str(pinfo->cinfo, COL_INFO, type); len = tvb_get_ntohl(tvb, offset + 8); if (tree) { ti = proto_tree_add_protocol_format(tree, proto_nwmtp, tvb, offset, len + 12, "NexusWare C7 UDP Protocol"); nwmtp_tree = proto_item_add_subtree(ti, ett_mwmtp); proto_tree_add_item(nwmtp_tree, hf_nwmtp_transp_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(nwmtp_tree, hf_nwmtp_data_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(nwmtp_tree, hf_nwmtp_data_index, tvb, offset + 2, 2, ENC_BIG_ENDIAN); proto_tree_add_item(nwmtp_tree, hf_nwmtp_user_context, tvb, offset + 4, 4, ENC_BIG_ENDIAN); proto_tree_add_item(nwmtp_tree, hf_nwmtp_data_length, tvb, offset + 8, 4, ENC_BIG_ENDIAN); } next_tvb = tvb_new_subset_length(tvb, offset + 12, len); if (tvb_length(next_tvb) > 0) call_dissector(mtp_handle, next_tvb, pinfo, tree); /* Check for overflows, which probably can't happen, but better * safe than sorry. See * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8169 */ DISSECTOR_ASSERT(len < G_MAXUINT32 - 11); DISSECTOR_ASSERT((guint64)offset + len + 12 < G_MAXINT); offset += len + 12; } }
static void dissect_mtp2_msu(tvbuff_t *su_tvb, packet_info *pinfo, proto_item *mtp2_item, proto_item *tree) { gint sif_sio_length; tvbuff_t *sif_sio_tvb; col_set_str(pinfo->cinfo, COL_INFO, "MSU "); if (use_extended_sequence_numbers) { sif_sio_length = tvb_captured_length(su_tvb) - EXTENDED_HEADER_LENGTH; sif_sio_tvb = tvb_new_subset_length(su_tvb, EXTENDED_SIO_OFFSET, sif_sio_length); } else { sif_sio_length = tvb_captured_length(su_tvb) - HEADER_LENGTH; sif_sio_tvb = tvb_new_subset_length(su_tvb, SIO_OFFSET, sif_sio_length); } call_dissector(mtp3_handle, sif_sio_tvb, pinfo, tree); if (tree) { if (use_extended_sequence_numbers) proto_item_set_len(mtp2_item, EXTENDED_HEADER_LENGTH); else proto_item_set_len(mtp2_item, HEADER_LENGTH); } }
static void dissect_error_causes(tvbuff_t *error_causes_tvb, proto_tree *parameter_tree) { guint16 length, total_length; gint offset; tvbuff_t *error_cause_tvb; offset = 0; while(tvb_reported_length_remaining(error_causes_tvb, offset) > 0) { length = tvb_get_ntohs(error_causes_tvb, offset + CAUSE_LENGTH_OFFSET); total_length = ADD_PADDING(length); error_cause_tvb = tvb_new_subset_length(error_causes_tvb, offset , total_length); dissect_error_cause(error_cause_tvb, parameter_tree); offset += total_length; } }
static void dissect_srp_command(tvbuff_t * tvb, packet_info * pinfo, proto_tree * srp_tree) { tvbuff_t *next_tvb; guint payload_len; if( srp_tree ) proto_tree_add_item(srp_tree,hf_srp_seqno,tvb,1,1,ENC_BIG_ENDIAN); payload_len = tvb_reported_length_remaining(tvb,4); next_tvb = tvb_new_subset_length(tvb, 2, payload_len); /* XXX currently, we always dissect as CCSRL. It's only that in * H324/Annex C though. */ call_dissector(ccsrl_handle, next_tvb, pinfo, srp_tree ); }
static void dissect_protocol_data_parameter(tvbuff_t *parameter_tvb, proto_item *parameter_item, packet_info *pinfo, proto_tree *tree) { guint16 protocol_data_length; tvbuff_t *protocol_data_tvb; protocol_data_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH; protocol_data_tvb = tvb_new_subset_length(parameter_tvb, PROTOCOL_DATA_OFFSET, protocol_data_length); if(dpnss_handle){ call_dissector(dpnss_handle, protocol_data_tvb, pinfo, tree); return; } call_dissector(data_handle, protocol_data_tvb, pinfo, tree); proto_item_append_text(parameter_item, " (%u byte%s)", protocol_data_length, plurality(protocol_data_length, "", "s")); }
/* 3GPP TS 23.041 version 11.4.0 * 9.4.2.2.5 CB Data */ static void dissect_sabp_cb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *cbs_page_item; proto_tree *subtree; tvbuff_t *page_tvb, *unpacked_tvb; int offset = 0; int n; guint8 nr_pages, len, cb_inf_msg_len; /* Octet 1 Number-of-Pages */ nr_pages = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_sabp_no_of_pages, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* * NOTE: n equal to or less than 15 */ if(nr_pages > 15){ /* Error */ return; } for (n = 0; n < nr_pages; n++) { subtree = proto_tree_add_subtree_format(tree, tvb, offset, 83, ett_sabp_cbs_page, NULL, "CB page %u data", n+1); /* octet 2 - 83 CBS-Message-Information-Page 1 */ cbs_page_item = proto_tree_add_item(subtree, hf_sabp_cb_msg_inf_page, tvb, offset, 82, ENC_NA); cb_inf_msg_len = tvb_get_guint8(tvb,offset+82); page_tvb = tvb_new_subset_length(tvb, offset, cb_inf_msg_len); unpacked_tvb = dissect_cbs_data(sms_encoding, page_tvb, subtree, pinfo, 0); len = tvb_captured_length(unpacked_tvb); if (unpacked_tvb != NULL){ if (tree != NULL){ proto_tree *cbs_page_subtree = proto_item_add_subtree(cbs_page_item, ett_sabp_cbs_page_content); proto_tree_add_item(cbs_page_subtree, hf_sabp_cbs_page_content, unpacked_tvb, 0, len, ENC_UTF_8|ENC_NA); } } offset = offset+82; /* 84 CBS-Message-Information-Length 1 */ proto_tree_add_item(subtree, hf_sabp_cb_inf_len, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; } }
static void dissect_parameters(tvbuff_t *parameters_tvb, proto_tree *tree) { gint offset, length, total_length, remaining_length; tvbuff_t *parameter_tvb; offset = 0; while((remaining_length = tvb_reported_length_remaining(parameters_tvb, offset)) > 0) { length = tvb_get_ntohs(parameters_tvb, offset + PARAMETER_LENGTH_OFFSET); total_length = ADD_PADDING(length); if (remaining_length >= length) total_length = MIN(total_length, remaining_length); /* create a tvb for the parameter including the padding bytes */ parameter_tvb = tvb_new_subset_length(parameters_tvb, offset, total_length); dissect_parameter(parameter_tvb, tree); /* get rid of the handled parameter */ offset += total_length; } }
/* Protocol Data */ static void dissect_m2tp_protocol_data_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, proto_item *parameter_item, packet_info *pinfo, proto_item *m2tp_item, proto_tree *tree) { guint16 length, protocol_data_length, padding_length; tvbuff_t *mtp2_tvb; length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET); padding_length = nr_of_padding_bytes(length); protocol_data_length = length - PARAMETER_HEADER_LENGTH; mtp2_tvb = tvb_new_subset_length(parameter_tvb, PARAMETER_VALUE_OFFSET, protocol_data_length); call_dissector(mtp2_handle, mtp2_tvb, pinfo, tree); if (parameter_tree) { proto_item_set_text(parameter_item, "Protocol data (SS7 message)"); proto_item_set_len(parameter_item, proto_item_get_len(parameter_item) - protocol_data_length - padding_length); proto_item_set_len(m2tp_item, proto_item_get_len(m2tp_item) - protocol_data_length - padding_length); } }
static void dissect_cbsp_content_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, gint len, proto_tree *tree, guint8 sms_encoding, proto_item *ti) { proto_item *cbs_page_item; tvbuff_t *next_tvb, *unpacked_tvb; const guint8 *pstr; proto_tree_add_item(tree, hf_cbsp_user_info_length, tvb, offset, 1, ENC_NA); cbs_page_item = proto_tree_add_item(tree, hf_cbsp_cb_msg_page, tvb, offset+1, len-1, ENC_NA); next_tvb = tvb_new_subset_length(tvb, offset+1, len-1); unpacked_tvb = dissect_cbs_data(sms_encoding, next_tvb, tree, pinfo, 0); if (tree) { guint captured_len = tvb_captured_length(unpacked_tvb); proto_tree *cbs_page_subtree = proto_item_add_subtree(cbs_page_item, ett_cbsp_cbs_page_content); proto_tree_add_item_ret_string(cbs_page_subtree, hf_cbsp_cbs_page_content, unpacked_tvb, 0, captured_len, ENC_UTF_8|ENC_NA, wmem_packet_scope(), &pstr); proto_item_append_text(ti, ": '%s'", pstr); } }
static int dissect_eth_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mint_tree, volatile guint32 offset, guint32 length) { tvbuff_t *eth_tvb; #ifdef MINT_DEVELOPMENT col_set_writable(pinfo->cinfo, FALSE); #endif eth_tvb = tvb_new_subset_length(tvb, offset, length); /* Continue after Ethernet dissection errors */ TRY { call_dissector(eth_handle, eth_tvb, pinfo, mint_tree); } CATCH_NONFATAL_ERRORS { show_exception(eth_tvb, pinfo, mint_tree, EXCEPT_CODE, GET_MESSAGE); } ENDTRY; offset += length; #ifdef MINT_DEVELOPMENT col_set_writable(pinfo->cinfo, TRUE); #endif return offset; }