static int dissect_btsmp_auth_req(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint8 value; const guint8 *ph; col_append_str(pinfo->cinfo, COL_INFO, "AuthReq: "); proto_tree_add_bitmask(tree, tvb, offset, hf_btsmp_authreq, ett_btsmp_auth_req, hfx_btsmp_authreq, ENC_LITTLE_ENDIAN); value = tvb_get_guint8(tvb, offset); ph = val_to_str_const(value & 0x03, bonding_flag_vals, "<unknown>"); col_append_sep_str(pinfo->cinfo, COL_INFO, "", ph); if (value & 0x04) col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "MITM"); if (value & 0x08) col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "SecureConnection"); if (value & 0x10) col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Keypress"); if (value & 0xE0) col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Reserved"); return offset + 1; }
static void dissect_wimax_ffb_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint length, num_of_ffbs, i; proto_item *ffb_item = NULL; proto_tree *ffb_tree = NULL; /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Fast Feedback Burst:"); if (tree) { /* we are being asked for details */ /* get the tvb reported length */ length = tvb_reported_length(tvb); /* display Fast Feedback Burst dissector info */ ffb_item = proto_tree_add_protocol_format(tree, proto_wimax_ffb_decoder, tvb, offset, length, "Fast Feedback Burst (%u bytes)", length); /* add Fast Feedback Burst subtree */ ffb_tree = proto_item_add_subtree(ffb_item, ett_wimax_ffb_decoder); /* get the number of FFBs */ num_of_ffbs = tvb_get_guint8(tvb, offset); /* display the number of FFBs */ proto_tree_add_item(ffb_tree, hf_ffb_num_of_ffbs, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the FFB type */ proto_tree_add_item(ffb_tree, hf_ffb_type, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the FFBs */ for(i = 0; i < num_of_ffbs; i++) { proto_tree_add_item(ffb_tree, hf_ffb_subchannel, tvb, offset++, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ffb_tree, hf_ffb_symboloffset, tvb, offset++, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ffb_tree, hf_ffb_value, tvb, offset++, 1, ENC_BIG_ENDIAN); } } }
/* Wimax Mac RES-CMD Message Dissector */ static void dissect_mac_mgmt_msg_res_cmd_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tvb_len; gint tlv_type, tlv_len, tlv_value_offset; proto_item *res_cmd_item; proto_tree *res_cmd_tree; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type RES-CMD */ res_cmd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_res_cmd_decoder, tvb, offset, -1, "Reset Command (RES-CMD)"); /* add MAC RES-CMD subtree */ res_cmd_tree = proto_item_add_subtree(res_cmd_item, ett_mac_mgmt_msg_res_cmd_decoder); /* Decode and display the Reset Command (RES-CMD) */ /* process the RES-CMD TLVs */ while(offset < tvb_len) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RES-CMD TLV error"); proto_tree_add_item(res_cmd_tree, hf_res_cmd_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the TLV value offset */ tlv_value_offset = get_tlv_value_offset(&tlv_info); #ifdef DEBUG /* for debug only */ proto_tree_add_protocol_format(res_cmd_tree, proto_mac_mgmt_msg_res_cmd_decoder, tvb, offset, (tlv_len + tlv_value_offset), "RES-CMD Type: %u (%u bytes, offset=%u, tlv_len=%u, tvb_len=%u)", tlv_type, (tlv_len + tlv_value_offset), offset, tlv_len, tvb_len); #endif /* process RES-CMD TLV Encoded information */ switch (tlv_type) { case HMAC_TUPLE: /* Table 348d */ /* decode and display the HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_res_cmd_decoder, res_cmd_tree, proto_mac_mgmt_msg_res_cmd_decoder, tvb, offset, tlv_len, "HMAC Tuple"); wimax_hmac_tuple_decoder(tlv_tree, tvb, offset+tlv_value_offset, tlv_len); break; case CMAC_TUPLE: /* Table 348b */ /* decode and display the CMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_res_cmd_decoder, res_cmd_tree, proto_mac_mgmt_msg_res_cmd_decoder, tvb, offset, tlv_len, "CMAC Tuple"); wimax_cmac_tuple_decoder(tlv_tree, tvb, offset+tlv_value_offset, tlv_len); break; default: /* display the unknown tlv in hex */ add_tlv_subtree(&tlv_info, res_cmd_tree, hf_res_cmd_unknown_type, tvb, offset, ENC_NA); break; } offset += (tlv_len+tlv_value_offset); } /* end of TLV process while loop */ } }
static void dissect_wimax_hack_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint length, num_of_hacks, i; proto_item *hack_item = NULL; proto_tree *hack_tree = NULL; /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "HARQ ACK Burst:"); if (tree) { /* we are being asked for details */ /* get the tvb reported length */ length = tvb_reported_length(tvb); /* display HARQ ACK Burst dissector info */ hack_item = proto_tree_add_protocol_format(tree, proto_wimax_hack_decoder, tvb, offset, length, "HARQ ACK Burst (%u bytes)", length); /* add HARQ ACK Burst subtree */ hack_tree = proto_item_add_subtree(hack_item, ett_wimax_hack_decoder); /* get the number of HARQ ACKs */ num_of_hacks = tvb_get_guint8(tvb, offset); /* display the number of HARQ ACKs */ proto_tree_add_item(hack_tree, hf_hack_num_of_hacks, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the HARQ ACKs */ for(i = 0; i < num_of_hacks; i++) { proto_tree_add_item(hack_tree, hf_hack_subchannel, tvb, offset++, 1, ENC_BIG_ENDIAN); proto_tree_add_item(hack_tree, hf_hack_symboloffset, tvb, offset++, 1, ENC_BIG_ENDIAN); proto_tree_add_item(hack_tree, hf_hack_half_slot_flag, tvb, offset++, 1, ENC_BIG_ENDIAN); proto_tree_add_item(hack_tree, hf_hack_value, tvb, offset++, 1, ENC_BIG_ENDIAN); } } }
static void dissect_wimax_fch_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; proto_item *fch_item = NULL; proto_tree *fch_tree = NULL; /* save the base station address (once) */ if(!bs_address.len) COPY_ADDRESS(&bs_address, &(pinfo->src)); /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "FCH"); if (tree) { /* we are being asked for details */ /* display FCH dissector info */ fch_item = proto_tree_add_protocol_format(tree, proto_wimax_fch_decoder, tvb, offset, 3, "DL Frame Prefix (24 bits)"); /* add FCH subtree */ fch_tree = proto_item_add_subtree(fch_item, ett_wimax_fch_decoder); /* Decode and display the used sub-channel groups */ proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group0, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group1, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group2, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group3, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group4, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group5, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(fch_tree, hf_fch_reserved_1, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); /* Decode and display the repetition coding indication */ proto_tree_add_item(fch_tree, hf_fch_repetition_coding_indication, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); /* Decode and display the coding indication */ proto_tree_add_item(fch_tree, hf_fch_coding_indication, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); /* Decode and display the DL MAP length */ proto_tree_add_item(fch_tree, hf_fch_dlmap_length, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); proto_tree_add_item(fch_tree, hf_fch_reserved_2, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN); } }
static void dissect_wimax_cdma_code_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint length; proto_item *cdma_item = NULL; proto_tree *cdma_tree = NULL; /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "CDMA Code Attribute"); if (tree) { /* we are being asked for details */ /* get the tvb reported length */ length = tvb_reported_length(tvb); /* display CDMA dissector info */ cdma_item = proto_tree_add_protocol_format(tree, proto_wimax_cdma_code_decoder, tvb, offset, length, "CDMA Code Attribute (%u bytes)", length); /* add CDMA Code subtree */ cdma_tree = proto_item_add_subtree(cdma_item, ett_wimax_cdma_code_decoder); /* display the first CDMA Code */ proto_tree_add_item(cdma_tree, hf_wimax_ranging_code, tvb, offset, 1, FALSE); /* display the 2nd CDMA Code */ proto_tree_add_item(cdma_tree, hf_wimax_ranging_symbol_offset, tvb, offset+1, 1, FALSE); /* display the 3rd CDMA Code */ proto_tree_add_item(cdma_tree, hf_wimax_ranging_subchannel_offset, tvb, offset+2, 1, FALSE); } }
/* 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 int dissect_btsmp_key_dist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, gboolean initiator) { guint8 value; gboolean next = FALSE; if (initiator) { col_append_str(pinfo->cinfo, COL_INFO, " | Initiator Key(s): "); proto_tree_add_bitmask(tree, tvb, offset, hf_btsmp_initiator_key_distribution, ett_btsmp_key_dist, hfx_btsmp_key_distribution, ENC_LITTLE_ENDIAN); } else { col_append_str(pinfo->cinfo, COL_INFO, " | Responder Key(s): "); proto_tree_add_bitmask(tree, tvb, offset, hf_btsmp_responder_key_distribution, ett_btsmp_key_dist, hfx_btsmp_key_distribution, ENC_LITTLE_ENDIAN); } value = tvb_get_guint8(tvb, offset); if (value & 0x01) { col_append_str(pinfo->cinfo, COL_INFO, "LTK"); next = TRUE; } if (value & 0x02) { col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "IRK"); next = TRUE; } if (value & 0x04) { col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "CSRK"); next = TRUE; } if (value & 0x08) { col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "Linkkey"); next = TRUE; } if (value & 0xF0) { col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "Reserved"); } if (!next) { col_append_str(pinfo->cinfo, COL_INFO, "<none>"); } return offset + 1; }
static void decode_iei_control_bits(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) { guint8 control_bits; proto_item *tf; proto_tree *field_tree; control_bits = tvb_get_guint8(bi->tvb, bi->offset); if (bi->nsip_tree) { tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset, ie->total_length, "NS SDU Control bits: %#02x", control_bits); field_tree = proto_item_add_subtree(tf, ett_nsip_control_bits); proto_tree_add_boolean(field_tree, hf_nsip_control_bits_r, bi->tvb, bi->offset, 1, control_bits & NSIP_MASK_CONTROL_BITS_R); proto_tree_add_boolean(field_tree, hf_nsip_control_bits_c, bi->tvb, bi->offset, 1, control_bits & NSIP_MASK_CONTROL_BITS_C); proto_tree_add_uint(field_tree, hf_nsip_control_bits_spare, bi->tvb, bi->offset, 1, control_bits & NSIP_MASK_CONTROL_BITS_SPARE); } bi->offset++; if (check_col(bi->pinfo->cinfo, COL_INFO)) { if (control_bits & NSIP_MASK_CONTROL_BITS_R) { col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Req CF"); proto_item_append_text(bi->ti, ", Request Change Flow"); } if (control_bits & NSIP_MASK_CONTROL_BITS_C) { col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Conf CF"); proto_item_append_text(bi->ti, ", Confirm Change Flow"); } } }
static int dissect_kt_replication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { gint new_offset; guint32 next32, size; guint64 ts; nstime_t ns_ts; proto_item *pi; new_offset = offset; proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN); new_offset++; if (tvb_reported_length_remaining(tvb, new_offset) > 0) { next32 = tvb_get_ntohl(tvb, new_offset); if (next32 <= 1) { /* This means request. the 32 bits are flags */ proto_tree_add_item(tree, hf_kt_flags, tvb, new_offset, 4, ENC_BIG_ENDIAN); new_offset += 4; proto_tree_add_item(tree, hf_kt_ts, tvb, new_offset, 8, ENC_BIG_ENDIAN); new_offset += 8; proto_tree_add_item(tree, hf_kt_sid, tvb, new_offset, 2, ENC_BIG_ENDIAN); new_offset += 2; } else { /* This is a response. The 32 bits are the first half of the ts */ ts = tvb_get_ntoh64(tvb, new_offset); ns_ts.secs = (time_t)(ts/1000000000); ns_ts.nsecs = (int)(ts%1000000000); proto_tree_add_time(tree, hf_kt_ts, tvb, new_offset, 8, &ns_ts); new_offset += 8; size = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_size, tvb, new_offset, 4, size); new_offset += 4; proto_tree_add_item(tree, hf_kt_log, tvb, new_offset, size, ENC_NA); new_offset += size; } } else { /* This is an empty ack to the message with magic 0xB0. */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE); PROTO_ITEM_SET_GENERATED(pi); col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]"); } return new_offset; }
static int parse_teredo_orig(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, e_teredohdr *teredoh) { proto_item *ti = NULL; col_append_sep_str (pinfo->cinfo, COL_INFO, ", ", "Origin indication"); if (tree) { ti = proto_tree_add_item(tree, hf_teredo_orig, tvb, offset, 8, ENC_NA); tree = proto_item_add_subtree(ti, ett_teredo_orig); } offset += 2; teredoh->th_orgport = tvb_get_ntohs(tvb, offset); if (tree) { /* * The "usual arithmetic conversions" will convert * "teredoh->th_orgport" to an "int" (because all * "unsigned short" values will fit in an "int"), * which will zero-extend it. This means that * complementing it will turn all the zeroes in * the upper 16 bits into ones; we just want the * lower 16 bits (containing the port number) * complemented, with the result zero-extended. * * That's what the cast is for. */ proto_tree_add_uint(tree, hf_teredo_orig_port, tvb, offset, 2, (guint16)~teredoh->th_orgport); } offset += 2; teredoh->th_iporgaddr = tvb_get_ipv4(tvb, offset); if (tree) { proto_tree_add_ipv4(tree, hf_teredo_orig_addr, tvb, offset, 4, ~teredoh->th_iporgaddr); } offset += 4; return offset; }
static void dissect_wimax_phy_attributes_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tvb_len; /* guint num_of_slots;*/ proto_item *phy_item = NULL; proto_tree *phy_tree = NULL; /* update the info column */ /*col_append_str(pinfo->cinfo, COL_INFO, "PDU Burst Physical Attributes:");*/ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "PHY-attr"); if (tree) { /* we are being asked for details */ /* get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display PDU Burst Physical Attributes dissector info */ phy_item = proto_tree_add_protocol_format(tree, proto_wimax_phy_attributes_decoder, tvb, offset, tvb_len, "PDU Burst Physical Attributes (%u bytes)", tvb_len); /* add PDU Burst Physical Attributes subtree */ phy_tree = proto_item_add_subtree(phy_item, ett_wimax_phy_attributes_decoder); /* display the subchannelization type */ proto_tree_add_item(phy_tree, hf_phy_attributes_subchannelization_type, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the permbase */ proto_tree_add_item(phy_tree, hf_phy_attributes_permbase, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the modulation rate */ proto_tree_add_item(phy_tree, hf_phy_attributes_modulation_rate, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the encoding type */ proto_tree_add_item(phy_tree, hf_phy_attributes_encoding_type, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the numRepeat */ proto_tree_add_item(phy_tree, hf_phy_attributes_num_repeat, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the symbol offset */ proto_tree_add_item(phy_tree, hf_phy_attributes_symbol_offset, tvb, offset++, 1, ENC_BIG_ENDIAN); /* display the number of slots */ proto_tree_add_item(phy_tree, hf_phy_attributes_num_of_slots, tvb, offset, 2, ENC_BIG_ENDIAN); /* get the number of slots */ /* num_of_slots = tvb_get_guint16(tvb, offset);*/ /* move to next field */ offset += 2; /* display the physical subchannel list */ while(offset < tvb_len) { proto_tree_add_item(phy_tree, hf_phy_attributes_subchannel, tvb, offset++, 1, ENC_BIG_ENDIAN); } } }
static void dissect_mac_mgmt_msg_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint message_type; proto_item *message_item; proto_tree *message_tree; const char* mgt_msg_str; message_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_decoder, tvb, offset, -1, "MAC Management Message Type (%u bytes)", tvb_reported_length(tvb)); message_tree = proto_item_add_subtree(message_item, ett_mac_mgmt_msg_decoder); if (tvb_reported_length(tvb) == 0) { expert_add_info(pinfo, message_item, &ei_empty_payload); return; } /* Get the payload type */ message_type = tvb_get_guint8(tvb, offset); proto_tree_add_item(message_tree, hf_mac_mgmt_msg_type, tvb, offset, 1, ENC_NA); mgt_msg_str = val_to_str_ext_const(message_type, &mgt_msg_abbrv_vals_ext, "Unknown"); /* Display message type in Info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", mgt_msg_str); /* add the payload type into the info column */ if (try_val_to_str_ext(message_type, &mgt_msg_abbrv_vals_ext) == NULL) { /* display the MAC payload in Hex */ proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA); return; } /* add the MAC header info to parent*/ proto_item_append_text(proto_tree_get_parent(tree), ", %s", mgt_msg_str); /* Decode and display the MAC payload */ if (!dissector_try_uint(subdissector_message_table, message_type, tvb_new_subset_remaining(tvb, 1), pinfo, tree)) { proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA); } }
static int ssh_dissect_kex_dh_gex(guint8 msg_code, tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { proto_tree_add_item(tree, hf_ssh2_kex_dh_gex_msg_code, tvb, offset, 1, ENC_NA); offset += 1; col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(msg_code, ssh2_kex_dh_gex_msg_vals, "Unknown (%u)")); switch (msg_code) { case SSH_MSG_KEX_DH_GEX_REQUEST_OLD: proto_tree_add_item(tree, hf_ssh_dh_gex_nbits, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; case SSH_MSG_KEX_DH_GEX_GROUP: offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_p); offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_g); break; case SSH_MSG_KEX_DH_GEX_INIT: offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_e); break; case SSH_MSG_KEX_DH_GEX_REPLY: offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_host_key, hf_ssh_kexdh_host_key_length); offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_f); offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_h_sig, hf_ssh_kexdh_h_sig_length); break; case SSH_MSG_KEX_DH_GEX_REQUEST: proto_tree_add_item(tree, hf_ssh_dh_gex_min, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_ssh_dh_gex_nbits, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_ssh_dh_gex_max, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; } return offset; }
static void dissect_wimax_cdma_code_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; proto_item *cdma_item; proto_tree *cdma_tree; /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "CDMA Code Attribute"); if (tree) { /* we are being asked for details */ /* display CDMA dissector info */ cdma_item = proto_tree_add_item(tree, proto_wimax_cdma_code_decoder, tvb, offset, -1, ENC_NA); /* add CDMA Code subtree */ cdma_tree = proto_item_add_subtree(cdma_item, ett_wimax_cdma_code_decoder); /* display the first CDMA Code */ proto_tree_add_item(cdma_tree, hf_wimax_ranging_code, tvb, offset, 1, ENC_BIG_ENDIAN); /* display the 2nd CDMA Code */ proto_tree_add_item(cdma_tree, hf_wimax_ranging_symbol_offset, tvb, offset+1, 1, ENC_BIG_ENDIAN); /* display the 3rd CDMA Code */ proto_tree_add_item(cdma_tree, hf_wimax_ranging_subchannel_offset, tvb, offset+2, 1, ENC_BIG_ENDIAN); } }
static int ssh_dissect_kex_dh(guint8 msg_code, tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree) { proto_tree_add_item(tree, hf_ssh2_kex_dh_msg_code, tvb, offset, 1, ENC_NA); offset += 1; col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(msg_code, ssh2_kex_dh_msg_vals, "Unknown (%u)")); switch (msg_code) { case SSH_MSG_KEXDH_INIT: offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_e); break; case SSH_MSG_KEXDH_REPLY: offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_host_key, hf_ssh_kexdh_host_key_length); offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_f); offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_h_sig, hf_ssh_kexdh_h_sig_length); break; } return offset; }
static void dissect_fcgi_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; guint8 type; type = tvb_get_guint8(tvb, 1); /* When there are multiple FCGI records in a TCP frame the following code */ /* will append the type for each record to COL_INFO. */ /* XXX: Unfortunately, something in the tcp_dissect_pdus() code is broken */ /* such that only the type for the first FCGI record appears in the */ /* INFO column. (All write attempts to COL_INFO after the first fail */ /* because pinfo->cinfo->writable is FALSE). */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCGI"); col_clear(pinfo->cinfo, COL_INFO); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(type, record_types, "Unknown (%u)")); col_set_fence(pinfo->cinfo, COL_INFO); if (tree) { /* we are being asked for details */ proto_item *ti; proto_tree *fcgi_tree; guint16 clen; guint8 plen; ti = proto_tree_add_item(tree, proto_fcgi, tvb, 0, -1, ENC_NA); proto_item_append_text(ti, " (%s)", val_to_str(type, record_types, "Unknown (%u)")); fcgi_tree = proto_item_add_subtree(ti, ett_fcgi); proto_tree_add_item(fcgi_tree, hf_fcgi_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(fcgi_tree, hf_fcgi_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(fcgi_tree, hf_fcgi_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; clen = tvb_get_ntohs(tvb, offset); proto_tree_add_item(fcgi_tree, hf_fcgi_content_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; plen = tvb_get_guint8(tvb, offset); proto_tree_add_item(fcgi_tree, hf_fcgi_padding_length, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; offset += 1; switch (type) { case FCGI_BEGIN_REQUEST: dissect_begin_request(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_ABORT_REQUEST: dissect_abort_request(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_END_REQUEST: dissect_end_request(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_PARAMS: dissect_params(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_GET_VALUES: dissect_get_values(tvb, fcgi_tree, offset, clen); offset += clen; break; case FCGI_GET_VALUES_RESULT: dissect_get_values_result(tvb, fcgi_tree, offset, clen); offset += clen; break; default: if (clen > 0) { proto_tree_add_item(fcgi_tree, hf_fcgi_content_data, tvb, offset, clen, ENC_NA); offset += clen; } break; } if (plen > 0) { proto_tree_add_item(fcgi_tree, hf_fcgi_padding_data, tvb, offset, plen, ENC_NA); /*offset += plen;*/ } } }
/* Decode RNG-RSP messages. */ void dissect_mac_mgmt_msg_rng_rsp_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ranging_status_item = NULL; proto_item *dl_freq_override_item = NULL; proto_item *ss_mac_address_item = NULL; proto_item *frame_number_item = NULL; proto_item *opportunity_number_item = NULL; guint offset = 0; guint tlv_offset; guint tvb_len, payload_type; proto_item *rng_rsp_item = NULL; proto_item *tlv_item = NULL; proto_tree *rng_rsp_tree = NULL; proto_tree *sub_tree = NULL; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; gint tlv_type; guint tlv_len; guint this_offset = 0; tlv_info_t sub_tlv_info; gint sub_tlv_type; gint sub_tlv_len; guint sub_tlv_offset; float timing_adjust; float power_level_adjust; gint offset_freq_adjust; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, offset); if(payload_type != MAC_MGMT_MSG_RNG_RSP) { return; } if (tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type RNG-RSP */ rng_rsp_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, offset, tvb_len, "MAC Management Message, RNG-RSP (5)"); /* add MAC RNG-RSP subtree */ rng_rsp_tree = proto_item_add_subtree(rng_rsp_item, ett_mac_mgmt_msg_rng_rsp_decoder); /* display the Message Type */ proto_tree_add_item(rng_rsp_tree, hf_rng_rsp_message_type, tvb, offset, 1, FALSE); proto_tree_add_item(rng_rsp_tree, hf_rng_req_reserved, tvb, 1, 1, FALSE); offset += 2; while(offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-RSP TLV error"); proto_tree_add_item(rng_rsp_tree, hf_rng_invalid_tlv, tvb, offset, (tvb_len - offset), FALSE); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case RNG_RSP_TIMING_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Timing Adjust (%u byte(s))", tlv_len); timing_adjust = (float)(gint32)tvb_get_ntohl(tvb, tlv_offset) / 4; tlv_item = proto_tree_add_float_format_value(sub_tree, hf_rng_rsp_timing_adjust, tvb, tlv_offset, 4, timing_adjust, " %.2f modulation symbols", timing_adjust); if ((timing_adjust < -2) || (timing_adjust > 2)) proto_item_append_text(tlv_item, " (during periodic ranging shall not exceed +- 2)"); break; } case RNG_RSP_POWER_LEVEL_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Power Level Adjust (%u byte(s))", tlv_len); power_level_adjust = (float)(gint8)tvb_get_guint8(tvb, tlv_offset) / 4; proto_tree_add_float_format_value(sub_tree, hf_rng_rsp_power_level_adjust, tvb, tlv_offset, 1, power_level_adjust, " %.2f dB", power_level_adjust); break; } case RNG_RSP_OFFSET_FREQ_ADJUST: { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Offset Frequency Adjust (%u byte(s))", tlv_len); offset_freq_adjust = tvb_get_ntohl(tvb, tlv_offset); proto_tree_add_int_format_value(sub_tree, hf_rng_rsp_offset_freq_adjust, tvb, tlv_offset, 4, offset_freq_adjust, " %d Hz", offset_freq_adjust); break; } case RNG_RSP_RANGING_STATUS: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ranging_status, tvb, tlv_offset, 1, FALSE); ranging_status_item = proto_tree_add_item(sub_tree, hf_rng_rsp_ranging_status, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_DL_FREQ_OVERRIDE: { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_freq_override, tvb, tlv_offset, 4, FALSE); dl_freq_override_item = proto_tree_add_item(sub_tree, hf_rng_rsp_dl_freq_override, tvb, tlv_offset, 4, FALSE); proto_item_append_text(dl_freq_override_item, " kHz"); break; } case RNG_RSP_UL_CHANNEL_ID_OVERRIDE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ul_chan_id_override, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ul_chan_id_override, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_DL_OPERATIONAL_BURST_PROFILE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_operational_burst_profile, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_dl_operational_burst_profile_diuc, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_dl_operational_burst_profile_ccc, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_SS_MAC_ADDRESS: if (tlv_len == 6) { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, FALSE); ss_mac_address_item = proto_tree_add_item(sub_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, FALSE); } else { sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_invalid_tlv, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ss_mac_address, tvb, tlv_offset, 6, FALSE); } break; case RNG_RSP_BASIC_CID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_basic_cid, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_basic_cid, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_PRIMARY_MGMT_CID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_primary_mgmt_cid, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_primary_mgmt_cid, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_AAS_BROADCAST_PERMISSION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_broadcast, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_broadcast, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_FRAME_NUMBER: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_frame_number, tvb, tlv_offset, 3, FALSE); frame_number_item = proto_tree_add_item(sub_tree, hf_rng_rsp_frame_number, tvb, tlv_offset, 3, FALSE); break; case RNG_RSP_OPPORTUNITY_NUMBER: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_opportunity_number, tvb, tlv_offset, 1, FALSE); opportunity_number_item = proto_tree_add_item(sub_tree, hf_rng_rsp_opportunity_number, tvb, tlv_offset, 1, FALSE); if (tvb_get_ntohl(tvb, tlv_offset) == 0) proto_item_append_text(opportunity_number_item, " (may not be 0!)"); break; case RNG_RSP_SERVICE_LEVEL_PREDICTION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_service_level_prediction, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_service_level_prediction, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_RESOURCE_RETAIN_FLAG: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_resource_retain_flag, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_resource_retain_flag, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_HO_PROCESS_OPTIMIZATION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ho_process_optimization, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_0, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_1_2, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_3, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_4, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_5, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_6, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_7, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_8, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_9, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_10, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_11, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_12, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_13, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_14, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_process_optimization_15, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_SBC_RSP_ENCODINGS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "SBC-RSP Encodings (%u byte(s))", tlv_len); dissect_mac_mgmt_msg_sbc_rsp_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case RNG_RSP_REG_RSP_ENCODINGS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "REG-RSP Encodings (%u byte(s))", tlv_len); dissect_mac_mgmt_msg_reg_rsp_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; /* Implemented message encoding 33 (Table 367 in IEEE 802.16e-2007) */ case RNG_RSP_DL_OP_BURST_PROFILE_OFDMA: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_dl_op_burst_profile_ofdma, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_least_robust_diuc, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_repetition_coding_indication, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_config_change_count_of_dcd, tvb, tlv_offset, 2, FALSE); break; case RNG_RSP_HO_ID: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ho_id, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ho_id, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_LOCATION_UPDATE_RESPONSE: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_location_update_response, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_location_update_response, tvb, tlv_offset, 1, FALSE); break; case RNG_RSP_PAGING_INFORMATION: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_paging_information, tvb, tlv_offset, 5, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_cycle, tvb, tlv_offset, 2, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_offset, tvb, tlv_offset+2, 1, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_paging_group_id, tvb, tlv_offset+3, 2, FALSE); break; case RNG_RSP_POWER_SAVING_CLASS_PARAMETERS: sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class Parameters (%u byte(s))", tlv_len); dissect_power_saving_class(sub_tree, tlv_type, tvb, tlv_len, pinfo, tlv_offset); break; case RNG_RSP_SA_CHALLENGE_TUPLE: /* Display SA Challenge Tuple header */ sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "SA Challenge Tuple (%u byte(s))", tlv_len); /* add subtree */ /* Use a local copy of tlv_offset */ this_offset = tlv_offset; while(this_offset < tlv_len) { /* Get the sub TLV data. */ init_tlv_info(&sub_tlv_info, tvb, this_offset); /* get the sub TLV type */ sub_tlv_type = get_tlv_type(&sub_tlv_info); /* get the TLV length */ sub_tlv_len = get_tlv_length(&sub_tlv_info); if(tlv_type == -1 || sub_tlv_len > MAX_TLV_LEN || sub_tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RNG-RSP TLV error"); proto_tree_add_item(rng_rsp_tree, hf_rng_invalid_tlv, tvb, tlv_offset, (tvb_len - offset), FALSE); break; } /* get the offset to the sub TLV data */ sub_tlv_offset = this_offset + get_tlv_value_offset(&sub_tlv_info); switch (sub_tlv_type) { case RNG_RSP_SA_CHALLENGE_BS_RANDOM: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_rng_rsp_bs_random, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_rng_rsp_bs_random, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; case RNG_RSP_SA_CHALLENGE_AKID: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_rng_rsp_akid, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_rng_rsp_akid, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; default: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_rng_rsp_message_tree, sub_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; } this_offset = sub_tlv_len + sub_tlv_offset; } break; case DSx_UPLINK_FLOW: /* display Uplink Service Flow Encodings info */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_rsp_decoder, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Uplink QOS Parameters (%u bytes)", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case DSx_DOWNLINK_FLOW: /* display Downlink Service Flow Encodings info */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_rsp_decoder, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Downlink QOS Parameters (%u bytes)", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, sub_tree); break; case RNG_RSP_RANGING_CODE_ATTRIBUTES: /* case SHORT_HMAC_TUPLE: */ sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_rng_rsp_ranging_subchan, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_time_symbol_reference, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_subchannel_reference, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_ranging_code_index, tvb, tlv_offset, 4, FALSE); proto_tree_add_item(sub_tree, hf_rng_rsp_frame_number2, tvb, tlv_offset, 4, FALSE); break; case SHORT_HMAC_TUPLE_COR2: if (include_cor2_changes) { sub_tree = add_protocol_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, proto_mac_mgmt_msg_rng_rsp_decoder, tvb, tlv_offset, tlv_len, "Short HMAC Tuple (%u byte(s))", tlv_len); wimax_short_hmac_tuple_decoder(sub_tree, tvb, tlv_offset, tvb_len - offset); } else { /* Unknown TLV type */ sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_tlv_type, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); } break; default: sub_tree = add_tlv_subtree(&tlv_info, ett_rng_rsp_message_tree, rng_rsp_tree, hf_tlv_type, tvb, tlv_offset, 1, FALSE); proto_tree_add_item(sub_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); break; } offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ if (ranging_status_item && dl_freq_override_item) proto_item_append_text(ranging_status_item, " (shall be set to 2 because Downlink Frequency Override is present)"); if (ss_mac_address_item && frame_number_item) { proto_item_append_text(frame_number_item, " (mutually exclusive with SS MAC Address!)"); proto_item_append_text(ss_mac_address_item, " (mutually exclusive with Frame Number!)"); } if (ss_mac_address_item && opportunity_number_item) { proto_item_append_text(opportunity_number_item, " (mutually exclusive with SS MAC Address!)"); proto_item_append_text(ss_mac_address_item, " (mutually exclusive with Initial Ranging Opportunity Number!)"); } if (!ranging_status_item) proto_item_append_text(rng_rsp_tree, " (Ranging status is missing!)"); } }
void dissect_mac_mgmt_msg_dsd_req_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tvb_len, payload_type, tlv_len, tlv_value_offset; gint tlv_type; proto_item *dsd_item = NULL; proto_tree *dsd_tree = NULL; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; if(tree) { /* we are being asked for details */ /* get the message type */ payload_type = tvb_get_guint8(tvb, offset); /* ensure the message type is DSD REQ/RSP/ACK */ if(payload_type != MAC_MGMT_MSG_DSD_REQ) return; /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC message type */ dsd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_dsd_decoder, tvb, offset, tvb_len, "%s (%u bytes)", val_to_str(payload_type, vals_dsd_msgs, "Unknown"), tvb_len); /* add MAC DSx subtree */ dsd_tree = proto_item_add_subtree(dsd_item, ett_mac_mgmt_msg_dsd_req_decoder); /* Decode and display the DSD message */ /* display the Message Type */ proto_tree_add_item(dsd_tree, hf_dsd_req_message_type, tvb, offset, 1, ENC_BIG_ENDIAN); /* move to next field */ offset++; /* display the Transaction ID */ proto_tree_add_item(dsd_tree, hf_dsd_transaction_id, tvb, offset, 2, ENC_BIG_ENDIAN); /* move to next field */ offset += 2; /* display the Service Flow ID */ proto_tree_add_item(dsd_tree, hf_dsd_service_flow_id, tvb, offset, 4, ENC_BIG_ENDIAN); /* move to next field */ offset += 4; /* process DSD REQ message TLV Encode Information */ while(offset < tvb_len) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DSD-REQ TLV error"); proto_tree_add_item(dsd_tree, hf_dsd_invalid_tlv, tvb, offset, (tvb_len - offset), FALSE); break; } /* get the TLV value offset */ tlv_value_offset = get_tlv_value_offset(&tlv_info); #ifdef DEBUG /* for debug only */ proto_tree_add_protocol_format(dsd_tree, proto_mac_mgmt_msg_dsd_decoder, tvb, offset, tlv_len + tlv_value_offset, "DSD-REQ TLV Type: %u (%u bytes, offset=%u, tvb_len=%u)", tlv_type, tlv_len + tlv_value_offset, offset, tvb_len); #endif /* update the offset */ offset += tlv_value_offset; /* process TLV */ switch (tlv_type) { case HMAC_TUPLE: /* Table 348d */ /* decode and display the HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dsd_req_decoder, dsd_tree, proto_mac_mgmt_msg_dsd_decoder, tvb, offset, tlv_len, "HMAC Tuple (%u byte(s))", tlv_len); wimax_hmac_tuple_decoder(tlv_tree, tvb, offset, tlv_len); break; case CMAC_TUPLE: /* Table 348b */ /* decode and display the CMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dsd_req_decoder, dsd_tree, proto_mac_mgmt_msg_dsd_decoder, tvb, offset, tlv_len, "CMAC Tuple (%u byte(s))", tlv_len); wimax_cmac_tuple_decoder(tlv_tree, tvb, offset, tlv_len); break; default: /* display the unknown tlv in hex */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dsd_req_decoder, dsd_tree, proto_mac_mgmt_msg_dsd_decoder, tvb, offset, tlv_len, "Unknown TLV (%u byte(s))", tlv_len); proto_tree_add_item(tlv_tree, hf_dsd_unknown_type, tvb, (offset - tlv_value_offset), (tlv_len + tlv_value_offset), FALSE); break; } offset += tlv_len; } /* end of while loop */ } }
static int dissect_kt_remove_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { guint32 next32, rnum, ksiz; gint new_offset, rec_start_offset; proto_item *ti; proto_item *pi; proto_tree *rec_tree; new_offset = offset; proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN); new_offset++; next32 = tvb_get_ntohl(tvb, new_offset); if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) { /* request */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST); PROTO_ITEM_SET_GENERATED(pi); proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32); new_offset += 4; rnum = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum); new_offset += 4; while (rnum > 0) { /* Create a sub-tree for each record */ ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA); rec_tree = proto_item_add_subtree(ti, ett_kt_rec); rec_start_offset = new_offset; proto_tree_add_item(rec_tree, hf_kt_dbidx, tvb, new_offset, 2, ENC_BIG_ENDIAN); new_offset += 2; ksiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz); new_offset += 4; proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += ksiz; proto_item_set_len(ti, new_offset - rec_start_offset); rnum--; } } else { /* response */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE); PROTO_ITEM_SET_GENERATED(pi); col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]"); proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, next32); new_offset += 4; } return new_offset; }
/* Decode REG-RSP messages. */ static void dissect_mac_mgmt_msg_reg_rsp_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tlv_offset; guint tvb_len; proto_item *reg_rsp_item; proto_tree *reg_rsp_tree; proto_item *tlv_item = NULL; proto_tree *tlv_tree = NULL; proto_tree *sub_tree = NULL; gboolean hmac_found = FALSE; tlv_info_t tlv_info; gint tlv_type; guint tlv_len; guint this_offset = 0; tlv_info_t sub_tlv_info; gint sub_tlv_type; gint sub_tlv_len; guint sub_tlv_offset; { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type REG-RSP */ reg_rsp_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tvb_len, "MAC Management Message, REG-RSP"); /* add MAC REG-RSP subtree */ reg_rsp_tree = proto_item_add_subtree(reg_rsp_item, ett_mac_mgmt_msg_reg_rsp_decoder); proto_tree_add_item(reg_rsp_tree, hf_reg_rsp_status, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; while (offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if (tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "REG-RSP TLV error"); proto_tree_add_item(reg_rsp_tree, hf_reg_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case REG_ARQ_PARAMETERS: case REG_SS_MGMT_SUPPORT: case REG_IP_MGMT_MODE: case REG_IP_VERSION: case REG_UL_TRANSPORT_CIDS_SUPPORTED: case REG_IP_PHS_SDU_ENCAP: case REG_MAX_CLASSIFIERS_SUPPORTED: case REG_PHS_SUPPORT: case REG_ARQ_SUPPORT: case REG_DSX_FLOW_CONTROL: case REG_MCA_FLOW_CONTROL: case REG_MCAST_POLLING_CIDS: case REG_NUM_DL_TRANS_CID: case REG_MAC_ADDRESS: #ifdef WIMAX_16E_2005 case REG_TLV_T_20_MAX_MAC_DATA_PER_FRAME_SUPPORT: case REG_TLV_T_21_PACKING_SUPPORT: case REG_TLV_T_22_MAC_EXTENDED_RTPS_SUPPORT: case REG_TLV_T_23_MAX_NUM_BURSTS_TRANSMITTED_CONCURRENTLY_TO_THE_MS: case REG_TLV_T_26_METHOD_FOR_ALLOCATING_IP_ADDR_SECONDARY_MGMNT_CONNECTION: case REG_TLV_T_27_HANDOVER_SUPPORTED: case REG_TLV_T_29_HO_PROCESS_OPTIMIZATION_MS_TIMER: case REG_TLV_T_31_MOBILITY_FEATURES_SUPPORTED: case REG_TLV_T_40_ARQ_ACK_TYPE: case REG_TLV_T_41_MS_HO_CONNECTIONS_PARAM_PROCESSING_TIME: case REG_TLV_T_42_MS_HO_TEK_PROCESSING_TIME: case REG_TLV_T_43_MAC_HEADER_AND_EXTENDED_SUBHEADER_SUPPORT: case REG_POWER_SAVING_CLASS_CAPABILITY: #endif dissect_extended_tlv(reg_rsp_tree, tlv_type, tvb, tlv_offset, tlv_len, pinfo, offset, proto_mac_mgmt_msg_reg_rsp_decoder); break; case REG_RSP_SECONDARY_MGMT_CID: add_tlv_subtree(&tlv_info, reg_rsp_tree, hf_reg_rsp_secondary_mgmt_cid, tvb, offset, ENC_BIG_ENDIAN); break; case REG_RSP_TLV_T_36_TOTAL_PROVISIONED_SERVICE_FLOW_DSAs: add_tlv_subtree(&tlv_info, reg_rsp_tree, hf_reg_total_provisioned_sf, tvb, offset, ENC_BIG_ENDIAN); break; case REG_RSP_TLV_T_24_CID_UPDATE_ENCODINGS: /* Display CID update encodings */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_reg_rsp_message_tree, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tlv_len, "CID update encodings"); /* Use a local copy of tlv_offset */ this_offset = tlv_offset; while(this_offset < tlv_len) { /* Get the sub TLV data. */ init_tlv_info(&sub_tlv_info, tvb, this_offset); /* get the sub TLV type */ sub_tlv_type = get_tlv_type(&sub_tlv_info); /* get the TLV length */ sub_tlv_len = get_tlv_length(&sub_tlv_info); if (tlv_type == -1 || sub_tlv_len > MAX_TLV_LEN || sub_tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "REG-RSP TLV error"); proto_tree_add_item(reg_rsp_tree, hf_reg_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the offset to the sub TLV data */ sub_tlv_offset = this_offset + get_tlv_value_offset(&sub_tlv_info); switch (sub_tlv_type) { case REG_RSP_TLV_T_24_1_CID_UPDATE_ENCODINGS_NEW_CID: add_tlv_subtree(&sub_tlv_info, sub_tree, hf_reg_rsp_new_cid_after_ho, tvb, this_offset, ENC_BIG_ENDIAN); break; case REG_RSP_TLV_T_24_2_CID_UPDATE_ENCODINGS_SFID: add_tlv_subtree(&sub_tlv_info, sub_tree, hf_reg_rsp_service_flow_id, tvb, this_offset, ENC_BIG_ENDIAN); break; case REG_RSP_TLV_T_24_3_CID_UPDATE_ENCODINGS_CONNECTION_INFO: tlv_tree = add_protocol_subtree(&sub_tlv_info, ett_reg_rsp_message_tree, sub_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, this_offset, sub_tlv_len, "CID Update Encodings Connection Info"); /* Decode the DSC_RSP subTLV's */ call_dissector(dsc_rsp_handle, tvb_new_subset_length(tvb, sub_tlv_offset, sub_tlv_len), pinfo, tlv_tree); break; default: add_tlv_subtree(&sub_tlv_info, sub_tree, hf_tlv_type, tvb, this_offset, ENC_NA); break; } this_offset = sub_tlv_len + sub_tlv_offset; } break; case REG_RSP_TLV_T_28_HO_SYSTEM_RESOURCE_RETAIN_TIME: tlv_item = add_tlv_subtree(&tlv_info, reg_rsp_tree, hf_reg_rsp_system_resource_retain_time, tvb, offset, ENC_BIG_ENDIAN); if (include_cor2_changes) { proto_item_append_text(tlv_item, " (in units of 100 milliseconds)"); } else { proto_item_append_text(tlv_item, " (multiple of 100 milliseconds)"); } break; case DSx_UPLINK_FLOW: /* display Uplink Service Flow Encodings info */ /* add subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tlv_len, "Uplink Service Flow Encodings"); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset_length(tvb, tlv_offset, tlv_len), pinfo, tlv_tree); break; case DSx_DOWNLINK_FLOW: /* display Downlink Service Flow Encodings info */ /* add subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tlv_len, "Downlink Service Flow Encodings"); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset_length(tvb, tlv_offset, tlv_len), pinfo, tlv_tree); break; case HMAC_TUPLE: /* Table 348d */ /* decode and display the HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tlv_len, "HMAC Tuple"); wimax_hmac_tuple_decoder(tlv_tree, tvb, offset+2, tlv_len); hmac_found = TRUE; break; case CMAC_TUPLE: /* Table 348b */ /* decode and display the CMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tlv_len, "CMAC Tuple"); wimax_cmac_tuple_decoder(tlv_tree, tvb, offset+2, tlv_len); break; case SHORT_HMAC_TUPLE: case SHORT_HMAC_TUPLE_COR2: if ((!include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE)) || (include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE_COR2))) { /* decode and display the Short HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tlv_len, "Short HMAC Tuple"); wimax_short_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len); } else { /* Unknown TLV Type */ add_tlv_subtree(&tlv_info, reg_rsp_tree, hf_tlv_type, tvb, offset, ENC_NA); } break; case VENDOR_SPECIFIC_INFO: case VENDOR_ID_ENCODING: case MAC_VERSION_ENCODING: wimax_common_tlv_encoding_decoder(tvb_new_subset_length(tvb, offset, (tvb_len - offset)), pinfo, reg_rsp_tree); break; default: add_tlv_subtree(&tlv_info, reg_rsp_tree, hf_tlv_type, tvb, offset, ENC_NA); break; } offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ if (!hmac_found) proto_item_append_text(reg_rsp_tree, " (HMAC Tuple is missing !)"); } }
/* UCD dissector */ static void dissect_mac_mgmt_msg_ucd_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tvb_len, length; gint tlv_type, tlv_len, tlv_offset, tlv_value_offset; tlv_info_t tlv_info; gchar* proto_str; { /* we are being asked for details */ proto_item *ucd_item; proto_tree *ucd_tree; guint ucd_ranging_backoff_start; guint ucd_ranging_backoff_end; guint ucd_request_backoff_start; guint ucd_request_backoff_end; tvb_len = tvb_reported_length(tvb); /* display MAC payload type UCD */ ucd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, -1, "Uplink Channel Descriptor (UCD)"); ucd_tree = proto_item_add_subtree(ucd_item, ett_mac_mgmt_msg_ucd_decoder); /* Decode and display the Uplink Channel Descriptor (UCD) */ /* display the Configuration Change Count */ proto_tree_add_item(ucd_tree, hf_ucd_config_change_count, tvb, offset, 1, ENC_NA); offset++; /* get the ranging backoff start */ ucd_ranging_backoff_start = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(ucd_tree, hf_ucd_ranging_backoff_start, tvb, offset, 1, (1 << ucd_ranging_backoff_start), "2^%u = %u", ucd_ranging_backoff_start, (1 << ucd_ranging_backoff_start)); offset++; /* get the ranging backoff end */ ucd_ranging_backoff_end = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(ucd_tree, hf_ucd_ranging_backoff_end, tvb, offset, 1, (1 << ucd_ranging_backoff_end), "2^%u = %u", ucd_ranging_backoff_end, (1 << ucd_ranging_backoff_end)); offset++; /* get the request backoff start */ ucd_request_backoff_start = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(ucd_tree, hf_ucd_request_backoff_start, tvb, offset, 1, (1 << ucd_request_backoff_start), "2^%u = %u", ucd_request_backoff_start, (1 << ucd_request_backoff_start)); offset++; /* get the request backoff end */ ucd_request_backoff_end = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(ucd_tree, hf_ucd_request_backoff_end, tvb, offset, 1, (1 << ucd_request_backoff_end), "2^%u = %u", ucd_request_backoff_end, (1 << ucd_request_backoff_end)); offset++; while(offset < tvb_len) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "UCD TLV error"); proto_tree_add_item(ucd_tree,hf_ucd_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the TLV value offset */ tlv_value_offset = get_tlv_value_offset(&tlv_info); #ifdef DEBUG /* for debug only */ proto_tree_add_protocol_format(ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset, (tlv_len + tlv_value_offset), "UCD Type: %u (%u bytes, offset=%u, tvb_len=%u)", tlv_type, tlv_len, offset, tvb_len); #endif /* update the offset */ offset += tlv_value_offset; /* process UCD TLV Encoded information */ if (include_cor2_changes) { switch (tlv_type) { case UCD_TLV_T_203_UL_PUSC_SUBCHANNEL_ROTATION: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_203_ul_pusc_subchannel_rotation, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_205_RELATIVE_POWER_OFFSET_UL_HARQ_BURST: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_205_relative_power_offset_ul_harq_burst, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_206_RELATIVE_POWER_OFFSET_UL_BURST_CONTAINING_MAC_MGMT_MSG: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_206_relative_power_offset_ul_burst_containing_mac_mgmt_msg, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_207_UL_INITIAL_TRANSMIT_TIMING: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_207_ul_initial_transmit_timing, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_210_FAST_FEEDBACK_REGION: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_210_fast_feedback_region, tvb, offset-tlv_value_offset, ENC_NA); break; } case UCD_TLV_T_211_HARQ_ACK_REGION: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_211_harq_ack_region, tvb, offset-tlv_value_offset, ENC_NA); break; } case UCD_TLV_T_212_RANGING_REGION: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_212_ranging_region, tvb, offset-tlv_value_offset, ENC_NA); break; } case UCD_TLV_T_213_SOUNDING_REGION: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_213_sounding_region, tvb, offset-tlv_value_offset, ENC_NA); break; } } } switch (tlv_type) { proto_tree *tlv_tree; proto_item *tlv_item1; guint ul_burst_uiuc; guint utemp; case UCD_UPLINK_BURST_PROFILE: { /* get the UIUC */ ul_burst_uiuc = tvb_get_guint8(tvb, offset) & 0x0F; /* add TLV subtree */ proto_str = wmem_strdup_printf(wmem_packet_scope(), "Uplink Burst Profile (UIUC = %u)", ul_burst_uiuc); tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_ucd_decoder, ucd_tree, proto_mac_mgmt_msg_ucd_decoder, tvb, offset-tlv_value_offset, tlv_len, proto_str); proto_tree_add_item(tlv_tree, hf_ucd_ul_burst_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ucd_ul_burst_uiuc, tvb, offset, 1, ENC_BIG_ENDIAN); for (tlv_offset = 1; tlv_offset < tlv_len;) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, (offset+tlv_offset)); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); if(tlv_type == -1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "UL Burst Profile error"); proto_tree_add_item(tlv_tree, hf_ucd_invalid_tlv, tvb, offset, (tlv_len - offset - tlv_offset), ENC_NA); break; } /* get the TLV length */ length = get_tlv_length(&tlv_info); switch (tlv_type) { proto_item *tlv_item2; case UCD_BURST_FEC: { add_tlv_subtree(&tlv_info, tlv_tree, hf_ucd_burst_fec, tvb, (offset+tlv_offset), ENC_BIG_ENDIAN); break; } case UCD_BURST_RANGING_DATA_RATIO: { tlv_item2 = add_tlv_subtree(&tlv_info, tlv_tree, hf_ucd_burst_ranging_data_ratio, tvb, (offset+tlv_offset), ENC_BIG_ENDIAN); proto_item_append_text(tlv_item2, " dB"); break; } #if 0 /* for OFDM */ case UCD_BURST_POWER_BOOST: { tlv_item2 = add_tlv_subtree(&tlv_info, tlv_tree, hf_ucd_burst_power_boost, tvb, (offset+tlv_offset), ENC_BIG_ENDIAN); proto_item_append_text(tlv_item2, " dB"); break; } case UCD_BURST_TCS_ENABLE: { add_tlv_subtree(&tlv_info, tlv_tree, hf_ucd_burst_tcs_enable, tvb, (offset+tlv_offset), 1, ENC_BIG_ENDIAN); break; } #endif default: /* ??? */ break; } tlv_offset += (length+get_tlv_value_offset(&tlv_info)); } break; } case UCD_RESERVATION_TIMEOUT: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_res_timeout, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_BW_REQ_SIZE: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_bw_req_size, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " PS"); break; } case UCD_RANGING_REQ_SIZE: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_ranging_req_size, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " PS"); break; } case UCD_FREQUENCY: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_freq, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " kHz"); break; } case UCD_TLV_T_7_HO_RANGING_START: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_ho_ranging_start, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_ho_ranging_start, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_8_RANGING_HO_END: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_ho_ranging_end, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_ho_ranging_end, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_158_OPTIONAL_PERMUTATION_UL_ALLOCATED_SUBCHANNELS_BITMAP: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_158_optional_permutation_ul_allocated_subchannels_bitmap, tvb, offset-tlv_value_offset, ENC_NA); break; } case UCD_TLV_T_159_BAND_AMC_ALLOCATION_THRESHHOLD: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_159_band_amc_allocation_threshold, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " dB"); break; } case UCD_TLV_T_160_BAND_AMC_RELEASE_THRESHOLD: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_160_band_amc_release_threshold, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " dB"); break; } case UCD_TLV_T_161_BAND_AMC_ALLOCATION_TIMER: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_161_band_amc_allocation_timer, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " frames"); break; } case UCD_TLV_T_162_BAND_AMC_RELEASE_TIMER: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_161_band_amc_allocation_timer, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " frames"); break; } case UCD_TLV_T_163_BAND_STATUS_REPORT_MAX_PERIOD: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_163_band_status_report_max_period, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " frames"); break; } case UCD_TLV_T_164_BAND_AMC_RETRY_TIMER: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_164_band_amc_retry_timer, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " frames"); break; } case UCD_TLV_T_170_SAFETY_CHANNEL_RETRY_TIMER: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_170_safety_channel_retry_timer, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " frames"); break; } case UCD_TLV_T_171_HARQ_ACK_DELAY_FOR_DL_BURST: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_171_harq_ack_delay_dl_burst, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " frames offset"); break; } case UCD_TLV_T_172_CQICH_BAND_AMC_TRANSITION_DELAY: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_172_cqich_band_amc_transition_delay, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item1, " frames"); break; } case UCD_TLV_T_174_MAXIMUM_RETRANSMISSION: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_174_maximum_retransmission, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_176_SIZE_OF_CQICH_ID_FIELD: { utemp = tvb_get_guint8(tvb, offset); cqich_id_size = 0; /* Default is 0 */ if (utemp && utemp < 8) { /* Set for CQICH_Alloc_IE */ cqich_id_size = utemp + 2; } add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_176_size_of_cqich_id_field, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_177_NORMALIZED_CN_OVERRIDE_2: { /* add TLV subtree */ tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_177_normalized_cn_override2, tvb, offset-tlv_value_offset, ENC_NA|ENC_ASCII); tlv_tree = proto_item_add_subtree(tlv_item1, ett_mac_mgmt_msg_ucd_decoder); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_177_normalized_cn_override2_first_line, tvb, offset + 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_177_normalized_cn_override2_list, tvb, offset + 3, 7, ENC_ASCII|ENC_NA); break; } case UCD_TLV_T_186_UPPER_BOUND__AAS_PREAMBLE: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_186_upper_bound_aas_preamble, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_187_LOWER_BOUND_AAS_PREAMBLE: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_187_lower_bound_aas_preamble, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_188_ALLOW_AAS_BEAM_SELECT_MESSAGE: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_188_allow_aas_beam_select_message, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_189_USE_CQICH_INDICATION_FLAG: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_189_use_cqich_indication_flag, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_190_MS_SPECIFIC_UP_POWER_OFFSET_ADJUSTMENT_STEP: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_190_ms_specific_up_power_addjustment_step, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_191_MS_SPECIFIC_DOWN_POWER_OFSET_ADJUSTMENT_STEP: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_191_ms_specific_down_power_addjustment_step, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_192_MIN_LEVEL_POWER_OFFSET_ADJUSTMENT: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_192_min_level_power_offset_adjustment, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_193_MAX_LEVEL_POWER_OFFSETR_ADJUSTMENT: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_193_max_level_power_offset_adjustment, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_194_HANDOVER_RANGING_CODES: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_194_handover_ranging_codes, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_195_INITIAL_RANGING_INTERVAL: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_195_initial_ranging_interval, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_196_TX_POWER_REPORT: { tlv_item1 = add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_196_tx_power_report, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); tlv_tree = proto_item_add_subtree(tlv_item1, ett_mac_mgmt_msg_ucd_decoder); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_threshold, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_interval, tvb , offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_a_p_avg, tvb, (offset + 1), 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_threshold_icqch, tvb, (offset + 1), 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_interval_icqch, tvb, (offset + 2), 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_ucd_tlv_t_196_tx_power_report_a_p_avg_icqch, tvb, (offset + 2), 1, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_197_NORMALIZED_CN_FOR_CHANNEL_SOUNDING: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_195_initial_ranging_interval, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_TLV_T_198_INTIAL_RANGING_BACKOFF_START: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_initial_range_backoff_start, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_initial_range_backoff_start, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_199_INITIAL_RANGING_BACKOFF_END: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_initial_range_backoff_end, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_initial_range_backoff_end, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_200_BANDWIDTH_REQUESET_BACKOFF_START: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_bandwidth_backoff_start, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_bandwidth_backoff_start, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_201_BANDWIDTH_REQUEST_BACKOFF_END: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_bandwidth_backoff_end, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_bandwidth_backoff_end, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_TLV_T_202_UPLINK_BURST_PROFILE_FOR_MULTIPLE_FEC_TYPES: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_202_uplink_burst_profile_for_multiple_fec_types, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_INITIAL_RANGING_CODES: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_150_initial_ranging_codes, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_PERIODIC_RANGING_CODES: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_151_periodic_ranging_codes, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_BANDWIDTH_REQUEST_CODES: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_152_bandwidth_request_codes, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_PERIODIC_RANGING_BACKOFF_START: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_periodic_ranging_backoff_start, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_periodic_ranging_backoff_start, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_PERIODIC_RANGING_BACKOFF_END: { tlv_tree = add_tlv_subtree_no_item(&tlv_info, ucd_tree, hf_ucd_periodic_ranging_backoff_end, tvb, offset-tlv_value_offset); utemp = tvb_get_guint8(tvb, offset); proto_tree_add_uint_format_value(tlv_tree, hf_ucd_periodic_ranging_backoff_end, tvb, offset, tvb_len, utemp, "2^%u = %u", utemp, (1 << utemp)); break; } case UCD_START_OF_RANGING_CODES_GROUP: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_155_start_of_ranging_codes_group, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_PERMUTATION_BASE: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_tlv_t_156_permutation_base, tvb, offset-tlv_value_offset, ENC_BIG_ENDIAN); break; } case UCD_UL_ALLOCATED_SUBCHANNELS_BITMAP: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_ul_allocated_subchannles_bitmap, tvb, offset-tlv_value_offset, ENC_NA); break; } case UCD_TLV_T_203_UL_PUSC_SUBCHANNEL_ROTATION: case UCD_TLV_T_205_RELATIVE_POWER_OFFSET_UL_HARQ_BURST: case UCD_TLV_T_206_RELATIVE_POWER_OFFSET_UL_BURST_CONTAINING_MAC_MGMT_MSG: case UCD_TLV_T_207_UL_INITIAL_TRANSMIT_TIMING: case UCD_TLV_T_210_FAST_FEEDBACK_REGION: case UCD_TLV_T_211_HARQ_ACK_REGION: case UCD_TLV_T_212_RANGING_REGION: case UCD_TLV_T_213_SOUNDING_REGION: { /* Unknown TLV type if cor2 not enabled. */ if (!include_cor2_changes) { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_invalid_tlv, tvb, offset-tlv_value_offset, ENC_NA); } break; } default: { add_tlv_subtree(&tlv_info, ucd_tree, hf_ucd_invalid_tlv, tvb, offset-tlv_value_offset, ENC_NA); } } /* end of switch(tlv_type) */ offset += tlv_len; } /* end of TLV process while loop */ } }
/* * Dissector that returns: * * The amount of data in the protocol's PDU, if it was able to * dissect all the data; * * 0, if the tvbuff doesn't contain a PDU for that protocol; * * The negative of the amount of additional data needed, if * we need more data (e.g., from subsequent TCP segments) to * dissect the entire PDU. */ static int dissect_ccn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint tvb_size = 0; proto_tree *ccn_tree; proto_item *ti = NULL; const unsigned char *ccnb; struct ccn_skeleton_decoder skel_decoder; struct ccn_skeleton_decoder *sd; struct ccn_charbuf *c; int packet_type = 0; int packet_type_length = 0; /* a couple of basic checks to rule out packets that are definitely not ours */ tvb_size = tvb_length(tvb); if (tvb_size < CCN_MIN_PACKET_SIZE || tvb_get_guint8(tvb, 0) == 0) return (0); sd = &skel_decoder; memset(sd, 0, sizeof(*sd)); sd->state |= CCN_DSTATE_PAUSE; ccnb = ep_tvb_memdup(tvb, 0, tvb_size); ccn_skeleton_decode(sd, ccnb, tvb_size); if (sd->state < 0) return (0); if (CCN_GET_TT_FROM_DSTATE(sd->state) == CCN_DTAG) { packet_type = sd->numval; packet_type_length = sd->index; } else { return (0); } memset(sd, 0, sizeof(*sd)); ccn_skeleton_decode(sd, ccnb, tvb_size); if (!CCN_FINAL_DSTATE(sd->state)) { pinfo->desegment_offset = 0; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return (-1); /* what should this be? */ } /* Make it visible that we're taking this packet */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "CCN"); } /* Clear out stuff in the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_clear(pinfo->cinfo, COL_INFO); } c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, tvb_size, 1); /* Add the packet type and CCN URI to the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x")); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, ccn_charbuf_as_string(c)); } if (tree == NULL) { ccn_charbuf_destroy(&c); return (sd->index); } ti = proto_tree_add_protocol_format(tree, proto_ccn, tvb, 0, -1, "Content-centric Networking Protocol, %s, %s", val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"), ccn_charbuf_as_string(c)); ccn_tree = proto_item_add_subtree(ti, ett_ccn); ccn_charbuf_destroy(&c); ti = proto_tree_add_uint(ccn_tree, hf_ccn_type, tvb, 0, packet_type_length, packet_type); switch (packet_type) { case CCN_DTAG_ContentObject: if (0 > dissect_ccn_contentobject(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; case CCN_DTAG_Interest: if (0 > dissect_ccn_interest(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; } return (sd->index); }
/* WiMax MAC Management DCD message (table 15) dissector */ void dissect_mac_mgmt_msg_dcd_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tvb_len, payload_type, length; gint tlv_type, tlv_len, tlv_offset, tlv_value_offset; guint dl_burst_diuc, dl_num_regions; proto_item *dcd_item = NULL; proto_tree *dcd_tree = NULL; proto_tree *tlv_tree = NULL; proto_tree *sub_tree = NULL; tlv_info_t tlv_info; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, offset); if(payload_type != MAC_MGMT_MSG_DCD) { return; } if(tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type DCD */ dcd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, tvb_len, "Downlink Channel Descriptor (DCD) (%u bytes)", tvb_len); /* add MAC DCD subtree */ dcd_tree = proto_item_add_subtree(dcd_item, ett_mac_mgmt_msg_dcd_decoder); /* Decode and display the Downlink Channel Descriptor (DCD) */ /* display the Message Type */ proto_tree_add_item(dcd_tree, hf_dcd_message_type, tvb, offset, 1, ENC_BIG_ENDIAN); /* set the offset for the Downlink Channel ID */ offset++; /* display the Downlink Channel ID */ proto_tree_add_item(dcd_tree, hf_dcd_downlink_channel_id, tvb, offset, 1, ENC_BIG_ENDIAN); /* set the offset for the Configuration Change Count */ offset++; /* display the Configuration Change Count */ proto_tree_add_item(dcd_tree, hf_dcd_config_change_count, tvb, offset, 1, ENC_BIG_ENDIAN); /* set the offset for the TLV Encoded info */ offset++; /* process the DCD TLV Encoded information (table 358) */ while(offset < tvb_len) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DCD TLV error"); proto_tree_add_item(dcd_tree, hf_dcd_invalid_tlv, tvb, offset, (tvb_len - offset), ENC_NA); break; } /* get the TLV value offset */ tlv_value_offset = get_tlv_value_offset(&tlv_info); #ifdef DEBUG /* for debug only */ proto_tree_add_protocol_format(dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, (tlv_len + tlv_value_offset), "DCD Type: %u (%u bytes, offset=%u, tvb_len=%u)", tlv_type, tlv_len, offset, tvb_len); #endif /* update the offset */ offset += tlv_value_offset; /* process DCD TLVs */ switch (tlv_type) { case DCD_DOWNLINK_BURST_PROFILE: { /* Downlink Burst Profile TLV (table 363)*/ /* get the DIUC */ dl_burst_diuc = (tvb_get_guint8(tvb, offset) & 0x0F); /* display TLV info */ /* add TLV subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, tlv_len, "Downlink_Burst_Profile (DIUC=%u) (%u bytes)", (dl_burst_diuc+1), tlv_len); /* detail display */ proto_tree_add_item(tlv_tree, hf_dcd_dl_burst_profile_rsv, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_dl_burst_profile_diuc, tvb, offset, 1, ENC_BIG_ENDIAN); /* process subTLVs */ for (tlv_offset = 1; tlv_offset < tlv_len; ) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, (offset+tlv_offset)); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ length = get_tlv_length(&tlv_info); if(tlv_type == -1 || length > MAX_TLV_LEN || length < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DL Burst Profile TLV error"); proto_tree_add_item(tlv_tree, hf_dcd_invalid_tlv, tvb, offset, (tlv_len - offset - tlv_offset), ENC_NA); break; } /* update the offset */ tlv_offset += get_tlv_value_offset(&tlv_info); switch (tlv_type) { case DCD_BURST_FREQUENCY: { proto_item *tlv_item = NULL; sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, hf_dcd_burst_freq, tvb, (offset+tlv_offset), 1, FALSE); tlv_item = proto_tree_add_item(sub_tree, hf_dcd_burst_freq, tvb, (offset+tlv_offset), 1, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " kHz"); break; } case DCD_BURST_FEC_CODE_TYPE: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, hf_dcd_burst_fec, tvb, (offset+tlv_offset), 1, FALSE); proto_tree_add_item(sub_tree, hf_dcd_burst_fec, tvb, (offset+tlv_offset), 1, ENC_BIG_ENDIAN); break; } case DCD_BURST_DIUC_EXIT_THRESHOLD: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, hf_dcd_burst_diuc_exit_threshold, tvb, (offset+tlv_offset), length, FALSE); proto_tree_add_item(sub_tree, hf_dcd_burst_diuc_exit_threshold, tvb, (offset+tlv_offset), length, ENC_BIG_ENDIAN); break; } case DCD_BURST_DIUC_ENTRY_THRESHOLD: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, hf_dcd_burst_diuc_entry_threshold, tvb, (offset+tlv_offset), length, FALSE); proto_tree_add_item(sub_tree, hf_dcd_burst_diuc_entry_threshold, tvb, (offset+tlv_offset), length, ENC_BIG_ENDIAN); break; } case DCD_BURST_TCS_ENABLE: { sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, hf_dcd_burst_tcs, tvb, (offset+tlv_offset), length, FALSE); proto_tree_add_item(sub_tree, hf_dcd_burst_tcs, tvb, (offset+tlv_offset), 1, ENC_BIG_ENDIAN); break; } default: /* ??? */ break; } tlv_offset += length; } break; } case DCD_BS_EIRP: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_bs_eirp, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_bs_eirp, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " dBm"); break; } case DCD_FRAME_DURATION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_frame_duration, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_frame_duration, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_PHY_TYPE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_phy_type, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_phy_type, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_POWER_ADJUSTMENT: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_power_adjustment, tvb, offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_power_adjustment, tvb, offset, 1, ENC_BIG_ENDIAN); break; } case DCD_CHANNEL_NR: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_channel_nr, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_channel_nr, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TTG: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_ttg, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_ttg, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " PS"); break; } case DCD_RTG: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_rtg, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_rtg, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " PS"); break; } #ifdef WIMAX_16D_2004 case DCD_RSS: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_rss, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_rss, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " dBm"); break; } #else case DCD_EIRXP: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_eirxp, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_eirxp, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " dBm"); break; } #endif case DCD_CHANNEL_SWITCH_FRAME_NR: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_channel_switch_frame_nr, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_channel_switch_frame_nr, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_FREQUENCY: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_frequency, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_frequency, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " kHz"); break; } case DCD_BS_ID: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_bs_id, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_bs_id, tvb, offset, tlv_len, ENC_NA); break; } case DCD_FRAME_DURATION_CODE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_frame_duration_code, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_frame_duration_code, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_FRAME_NR: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_frame_nr, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_frame_nr, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } #ifdef WIMAX_16D_2004 case DCD_SIZE_CQICH_ID: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_size_cqich_id, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_size_cqich_id, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } #endif case DCD_H_ARQ_ACK_DELAY: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_h_arq_ack_delay, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_h_arq_ack_delay, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " frame offset"); break; } case DCD_MAC_VERSION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_mac_version, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_mac_version, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_19_PERMUTATION_TYPE_FOR_BROADCAST_REGION_IN_HARQ_ZONE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_19_permutation_type_for_broadcast_regions_in_harq_zone, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_19_permutation_type_for_broadcast_regions_in_harq_zone, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_20_MAXIMUM_RETRANSMISSION: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_20_maximum_retransmission, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_20_maximum_retransmission, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_21_DEFAULT_RSSI_AND_CINR_AVERAGING_PARAMETER: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, 1, "Default RSSI and CINR averaging parameter (%u byte(s))", tlv_len); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_21_default_rssi_and_cinr_averaging_parameter, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_21_default_rssi_and_cinr_averaging_parameter_physical_cinr_measurements, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_21_default_rssi_and_cinr_averaging_parameter_rssi_measurements, tvb, offset, 1, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_22_DL_AMC_ALLOCATED_PHYSICAL_BANDS_BITMAP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_22_dl_amc_allocated_physical_bands_bitmap, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_22_dl_amc_allocated_physical_bands_bitmap, tvb, offset, tlv_len, ENC_NA); break; } case DCD_TLV_T_34_DL_REGION_DEFINITION: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, tlv_len, "DL region definition (%u byte(s))", tlv_len); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_34_dl_region_definition, tvb, offset, tlv_len, ENC_NA); dl_num_regions = tvb_get_guint8(tvb, offset); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_34_dl_region_definition_num_region, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_34_dl_region_definition_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); tlv_offset = offset; for(length = 0; length < dl_num_regions; length++) { proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_34_dl_region_definition_symbol_offset, tvb, tlv_offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_34_dl_region_definition_subchannel_offset, tvb, (tlv_offset+1), 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_34_dl_region_definition_num_symbols, tvb, (tlv_offset+2), 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_34_dl_region_definition_num_subchannels, tvb, (tlv_offset+3), 1, ENC_BIG_ENDIAN); tlv_offset += 4; } break; } case DCD_TLV_T_50_HO_TYPE_SUPPORT: { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, tlv_len, "HO type support (%u byte(s))", tlv_len); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_50_ho_type_support, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_50_ho_type_support_ho, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_50_ho_type_support_mdho, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_50_ho_type_support_fbss_ho, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_50_ho_type_support_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_31_H_ADD_THRESHOLD: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_31_h_add_threshold, tvb, offset, 1, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_31_h_add_threshold, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " dB"); break; } case DCD_TLV_T_32_H_DELETE_THRESHOLD: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_32_h_delete_threshold, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_32_h_delete_threshold, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " dB"); break; } case DCD_TLV_T_33_ASR: { proto_item *tlv_item = NULL; tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, tlv_len, "ASR Slot Length (M) and Switching Period (L) (%u byte(s))", tlv_len); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_33_asr, tvb, offset, 1, ENC_BIG_ENDIAN); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_33_asr_m, tvb, offset, 1, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " frames"); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_33_asr_l, tvb, offset, 1, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " frames"); break; } case DCD_TLV_T_35_PAGING_GROUP_ID: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_35_paging_group_id, tvb, offset, 1, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_35_paging_group_id, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_36_TUSC1_PERMUTATION_ACTIVE_SUBCHANNELS_BITMAP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_36_tusc1_permutation_active_subchannels_bitmap, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_36_tusc1_permutation_active_subchannels_bitmap, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_37_TUSC2_PERMUTATION_ACTIVE_SUBCHANNELS_BITMAP: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_37_tusc2_permutation_active_subchannels_bitmap, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_37_tusc2_permutation_active_subchannels_bitmap, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_51_HYSTERSIS_MARGIN: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_51_hysteresis_margin, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_51_hysteresis_margin, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " dB"); break; } case DCD_TLV_T_52_TIME_TO_TRIGGER_DURATION: { proto_item *tlv_item = NULL; tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_52_time_to_trigger_duration, tvb, offset, tlv_len, FALSE); tlv_item = proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_52_time_to_trigger_duration, tvb, offset, tlv_len, ENC_BIG_ENDIAN); proto_item_append_text(tlv_item, " ms"); break; } case DCD_TLV_T_54_TRIGGER: { /* Trigger TLV (table 358a & 358b) */ /* add TLV subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, tlv_len, "DCD Trigger (%u bytes)", tlv_len); for (tlv_offset = 0; tlv_offset < tlv_len; ) { /* get the TLV information */ init_tlv_info(&tlv_info, tvb, (offset + tlv_offset)); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ length = get_tlv_length(&tlv_info); if(tlv_type == -1 || length > MAX_TLV_LEN || length < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Trigger TLV error"); proto_tree_add_item(tlv_tree, hf_dcd_invalid_tlv, tvb, offset, (tlv_len - offset - tlv_offset), ENC_NA); break; } /* update the offset */ tlv_offset += get_tlv_value_offset(&tlv_info); /* table 358a */ switch (tlv_type) { case DCD_TLV_T_541_TYPE_FUNCTION_ACTION: { /* table 358b */ sub_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, (offset + tlv_offset), length, "Trigger; Type/function/action description (%u byte(s))", tlv_len); proto_tree_add_item(sub_tree, hf_dcd_tlv_t_541_type, tvb, (offset + tlv_offset), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_dcd_tlv_t_541_function, tvb, (offset + tlv_offset), 1, ENC_BIG_ENDIAN); proto_tree_add_item(sub_tree, hf_dcd_tlv_t_541_action, tvb, (offset + tlv_offset), 1, ENC_BIG_ENDIAN); } break; case DCD_TLV_T542_TRIGGER_VALUE: sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, hf_dcd_tlv_t_542_trigger_value, tvb, (offset + tlv_offset), length, FALSE); proto_tree_add_item(sub_tree, hf_dcd_tlv_t_542_trigger_value, tvb, (offset + tlv_offset), length, ENC_BIG_ENDIAN); break; case DCD_TLV_T_543_TRIGGER_AVERAGING_DURATION: sub_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, tlv_tree, hf_dcd_tlv_t_543_trigger_averaging_duration, tvb, (offset + tlv_offset), length, FALSE); proto_tree_add_item(sub_tree, hf_dcd_tlv_t_543_trigger_averaging_duration, tvb, (offset + tlv_offset), length, ENC_BIG_ENDIAN); break; } tlv_offset += length; } break; } case DCD_TLV_T_60_NOISE_AND_INTERFERENCE: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_60_noise_interference, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_60_noise_interference, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_153_DOWNLINK_BURST_PROFILE_FOR_MULTIPLE_FEC_TYPES: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_153_downlink_burst_profile_for_mutiple_fec_types, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_153_downlink_burst_profile_for_mutiple_fec_types, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_RESTART_COUNT: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_restart_count, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_restart_count, tvb, offset, tlv_len, ENC_BIG_ENDIAN); break; } case DCD_TLV_T_45_PAGING_INTERVAL_LENGTH: { if (include_cor2_changes) { tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, proto_mac_mgmt_msg_dcd_decoder, tvb, offset, tlv_len, "Reserved (%u byte(s))", tlv_len); proto_tree_add_text(tlv_tree, tvb, offset, tlv_len, "Reserved"); } else { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_tlv_t_45_paging_interval_length, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_tlv_t_45_paging_interval_length, tvb, offset, tlv_len, ENC_BIG_ENDIAN); } break; } default: { tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_dcd_decoder, dcd_tree, hf_dcd_unknown_type, tvb, offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_dcd_unknown_type, tvb, offset, tlv_len, ENC_NA); break; } } offset += tlv_len; } /* end of TLV process while loop */ } }
/* dissect EDID data from the receiver return the offset after the dissected data */ static gint dissect_hdmi_edid(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) { proto_item *yi; proto_tree *edid_tree; guint64 edid_hdr; guint16 manf_id; gchar manf_id_str[4]; /* 3 letters + 0-termination */ guint8 week, year; int year_hf; edid_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_hdmi_edid, NULL, "Extended Display Identification Data (EDID)"); edid_hdr = tvb_get_ntoh64(tvb, offset); if (edid_hdr != EDID_HDR_VALUE) return offset; /* XXX handle fragmented EDID messages */ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "EDID"); proto_tree_add_item(edid_tree, hf_hdmi_edid_hdr, tvb, offset, 8, ENC_LITTLE_ENDIAN); offset += 8; /* read as big endian for easier splitting */ manf_id = tvb_get_ntohs(tvb, offset); /* XXX check that MSB is 0 */ manf_id_str[0] = CAPITAL_LETTER(manf_id, 10); manf_id_str[1] = CAPITAL_LETTER(manf_id, 5); manf_id_str[2] = CAPITAL_LETTER(manf_id, 0); manf_id_str[3] = 0; proto_tree_add_string(edid_tree, hf_hdmi_edid_manf_id, tvb, offset, 2, manf_id_str); offset += 2; proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_prod_code, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_serial, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; week = tvb_get_guint8(tvb, offset); proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_week, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; year_hf = week == 255 ? hf_hdmi_edid_mod_year : hf_hdmi_edid_manf_year; year = tvb_get_guint8(tvb, offset); yi = proto_tree_add_item(edid_tree, year_hf, tvb, offset, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(yi, " (year %d)", 1990+year); offset += 1; proto_tree_add_item(edid_tree, hf_hdmi_edid_version, tvb, offset, 2, ENC_BIG_ENDIAN); /* XXX dissect the parts following the EDID header */ return tvb_reported_length(tvb); }
static void dissect_omapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *omapi_tree; ptvcursor_t* cursor; guint32 authlength; guint32 msglength; guint32 objlength; col_set_str(pinfo->cinfo, COL_PROTOCOL, "OMAPI"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_omapi, tvb, 0, -1, ENC_NA); omapi_tree = proto_item_add_subtree(ti, ett_omapi); cursor = ptvcursor_new(omapi_tree, tvb, 0); if (tvb_reported_length_remaining(tvb, 0) < 8) { /* Payload too small for OMAPI */ DISSECTOR_ASSERT_NOT_REACHED(); } else if (tvb_reported_length_remaining(tvb, 0) < 24) { /* This is a startup message */ ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); col_set_str(pinfo->cinfo, COL_INFO, "Status message"); proto_item_append_text(ti, ", Status message"); return; } else if ( !(tvb_get_ntohl(tvb, 8) || tvb_get_ntohl(tvb, 12)) ) { /* This is a startup message, and more */ ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); col_append_str(pinfo->cinfo, COL_INFO, "Status message"); proto_item_append_text(ti, ", Status message"); } ptvcursor_add(cursor, hf_omapi_auth_id, 4, ENC_BIG_ENDIAN); authlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_auth_len, 4, ENC_BIG_ENDIAN); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)")); proto_item_append_text(ti, ", Opcode: %s", val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)")); ptvcursor_add(cursor, hf_omapi_opcode, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_handle, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_id, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_rid, 4, ENC_BIG_ENDIAN); msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); while (msglength) { ptvcursor_add(cursor, hf_omapi_msg_name_len, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_msg_name, msglength, ENC_ASCII|ENC_NA); msglength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_msg_value_len, 4, ENC_BIG_ENDIAN); if (msglength == 0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string"); } else if (msglength == (guint32)~0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value"); } else { ptvcursor_add(cursor, hf_omapi_msg_value, msglength, ENC_ASCII|ENC_NA); } msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); } proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Message end tag"); ptvcursor_advance(cursor, 2); objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); while (objlength) { ptvcursor_add(cursor, hf_omapi_obj_name_len, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_obj_name, objlength, ENC_ASCII|ENC_NA); objlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_obj_value_len, 4, ENC_BIG_ENDIAN); if (objlength == 0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string"); } else if (objlength == (guint32)~0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value"); } else { ptvcursor_add(cursor, hf_omapi_obj_value, objlength, ENC_NA); } objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); } proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Object end tag"); ptvcursor_advance(cursor, 2); if (authlength > 0) { ptvcursor_add(cursor, hf_omapi_signature, authlength, ENC_NA); } }
/* WiMax MAC to MAC protocol dissector */ static void dissect_m2m(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti = NULL; proto_item *m2m_item = NULL; proto_tree *m2m_tree = NULL; proto_tree *tlv_tree = NULL; gint burst_number = 0; gint length, offset = 0; gint tlv_count; gint tlv_type, tlv_len, tlv_offset, tlv_value; gint tlv_frag_type = 0; gint tlv_frag_number = 0; tlv_info_t m2m_tlv_info; gint hf; guint encoding; guint frame_number; int expected_len; /* display the M2M protocol name */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiMax"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo, COL_INFO); { /* we are being asked for details */ m2m_item = proto_tree_add_item(tree, proto_m2m, tvb, 0, -1, ENC_NA); m2m_tree = proto_item_add_subtree(m2m_item, ett_m2m); /* get the tvb reported length */ length = tvb_reported_length(tvb); /* add the size info */ /* proto_item_append_text(m2m_item, " (%u bytes) - Packet Sequence Number,Number of TLVs", length); */ proto_item_append_text(m2m_item, " (%u bytes)", length); /* display the sequence number */ proto_tree_add_item(m2m_tree, hf_m2m_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* display the TLV count */ proto_tree_add_item(m2m_tree, hf_m2m_tlv_count, tvb, offset, 2, ENC_BIG_ENDIAN); tlv_count = tvb_get_ntohs(tvb, offset); offset += 2; /* parses the TLVs within current packet */ while ( tlv_count > 0) { /* init MAC to MAC TLV information */ init_tlv_info(&m2m_tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&m2m_tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&m2m_tlv_info); if(tlv_type == -1 || tlv_len > 64000 || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "M2M TLV error"); /* display the invalid TLV in HEX */ proto_tree_add_item(m2m_tree, hf_wimax_invalid_tlv, tvb, offset, (length - offset), ENC_NA); break; } /* get the TLV value offset */ tlv_offset = get_tlv_value_offset(&m2m_tlv_info); /* display TLV type */ ti = proto_tree_add_protocol_format(m2m_tree, proto_m2m, tvb, offset, (tlv_len + tlv_offset), "%s", val_to_str(tlv_type, tlv_name, "Unknown TLV")); /* add TLV subtree */ tlv_tree = proto_item_add_subtree(ti, ett_m2m_tlv); /* update the offset */ offset += tlv_offset; /* add the size info */ /* decode TLV content (TLV value) */ expected_len = 0; hf = 0; encoding = ENC_NA; switch (tlv_type) { case TLV_PROTO_VER: /* get the protocol version */ tlv_value = tvb_get_guint8( tvb, offset ); /* add the description */ proto_item_append_text(ti, ": %d", tlv_value); hf = hf_m2m_value_protocol_vers_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_BURST_NUM: /* get the burst number */ burst_number = tvb_get_guint8( tvb, offset ); /* add the description */ proto_item_append_text(ti, ": %d", burst_number); hf = hf_m2m_value_burst_num_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_FRAG_TYPE: /* add the description */ tlv_frag_type = tvb_get_guint8( tvb, offset ); proto_item_append_text(ti, ": %s", val_to_str(tlv_frag_type, tlv_frag_type_name, "Unknown")); hf = hf_m2m_value_frag_type_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_FRAG_NUM: /* get the fragment number */ tlv_frag_number = tvb_get_guint8( tvb, offset ); /* add the description */ proto_item_append_text(ti, ": %d", tlv_frag_number); hf = hf_m2m_value_frag_num_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_PDU_BURST: /* display PDU Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the PDU Burst */ pdu_burst_decoder(tree, tvb, offset, tlv_len, pinfo, burst_number, tlv_frag_type, tlv_frag_number); hf = hf_m2m_value_pdu_burst; encoding = ENC_NA; break; case TLV_FAST_FB: /* display the Fast Feedback Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the Fast Feedback Burst */ fast_feedback_burst_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_fast_fb; encoding = ENC_NA; break; case TLV_FRAME_NUM: /* get the frame number */ frame_number = tvb_get_ntoh24( tvb, offset ); /* add the description */ proto_tree_add_item(tlv_tree, hf_m2m_frame_number, tvb, offset, 3, ENC_BIG_ENDIAN); proto_item_append_text(ti, ": %d", frame_number); break; case TLV_FCH_BURST: /* add the description */ tlv_value = tvb_get_ntoh24( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); /* decode and display the TLV FCH burst */ fch_burst_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_fch_burst_uint24; encoding = ENC_BIG_ENDIAN; expected_len = 3; break; case TLV_CDMA_CODE: /* add the description */ tlv_value = tvb_get_ntoh24( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); /* decode and display the CDMA Code */ cdma_code_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_cdma_code_uint24; encoding = ENC_BIG_ENDIAN; expected_len = 3; break; case TLV_CRC16_STATUS: /* add the description */ tlv_value = tvb_get_guint8( tvb, offset ); proto_item_append_text(ti, ": %s", val_to_str(tlv_value, tlv_crc16_status, "Unknown")); hf = hf_m2m_value_crc16_status_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_BURST_POWER: /* add the description */ tlv_value = tvb_get_ntohs( tvb, offset ); proto_item_append_text(ti, ": %d", tlv_value); hf = hf_m2m_value_burst_power_uint16; encoding = ENC_BIG_ENDIAN; expected_len = 2; break; case TLV_BURST_CINR: /* add the description */ tlv_value = tvb_get_ntohs( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); hf = hf_m2m_value_burst_cinr_uint16; encoding = ENC_BIG_ENDIAN; expected_len = 2; break; case TLV_PREAMBLE: /* add the description */ tlv_value = tvb_get_ntohs( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); hf = hf_m2m_value_preamble_uint16; encoding = ENC_BIG_ENDIAN; expected_len = 2; break; case TLV_HARQ_ACK_BURST: /* display the Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the HARQ ACK Bursts */ harq_ack_bursts_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_harq_ack_burst_bytes; encoding = ENC_NA; break; case TLV_PHY_ATTRIBUTES: /* display the Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the PDU Burst Physical Attributes */ physical_attributes_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_phy_attributes; encoding = ENC_NA; break; case TLV_EXTENDED_TLV: /* display the Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the Extended TLV */ extended_tlv_decoder(pinfo); break; default: /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Unknown TLV Type"); break; } /* expand the TLV detail */ if (hf) { if (offset - tlv_offset == expected_len) { proto_tree_add_tlv(&m2m_tlv_info, tvb, offset - tlv_offset, pinfo, tlv_tree, hf, encoding); } else { expert_add_info_format(pinfo, NULL, &ei_m2m_unexpected_length, "Expected length %d, got %d.", expected_len, offset - tlv_offset); } } offset += tlv_len; /* update tlv_count */ tlv_count--; } } }
static int dissect_kt_play_script(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { guint32 next32, rnum, ksiz, vsiz, nsiz; gint new_offset, rec_start_offset; proto_item *ti; proto_item *pi; proto_tree *rec_tree; new_offset = offset; proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN); new_offset++; next32 = tvb_get_ntohl(tvb, new_offset); if (next32 == 0) { if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) { /* There's more data after the 32 bits. This is a request */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST); PROTO_ITEM_SET_GENERATED(pi); proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32); new_offset += 4; nsiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_nsiz, tvb, new_offset, 4, nsiz); new_offset += 4; rnum = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum); new_offset += 4; proto_tree_add_item(tree, hf_kt_name, tvb, new_offset, nsiz, ENC_ASCII|ENC_NA); new_offset += nsiz; while (rnum > 0) { /* Create a sub-tree for each record */ ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA); rec_tree = proto_item_add_subtree(ti, ett_kt_rec); rec_start_offset = new_offset; ksiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz); new_offset += 4; vsiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz); new_offset += 4; proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += ksiz; proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += vsiz; proto_item_set_len(ti, new_offset - rec_start_offset); rnum--; } } else { /* Nothing remaining after the 32 bits. This is a response with no records. */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE); PROTO_ITEM_SET_GENERATED(pi); col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]"); proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, next32); new_offset += 4; } } else { /* response - one or more records */ pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE); PROTO_ITEM_SET_GENERATED(pi); col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]"); rnum = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, rnum); new_offset += 4; while (rnum > 0) { /* Create a sub-tree for each record */ ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA); rec_tree = proto_item_add_subtree(ti, ett_kt_rec); rec_start_offset = new_offset; ksiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz); new_offset += 4; vsiz = tvb_get_ntohl(tvb, new_offset); proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz); new_offset += 4; proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += ksiz; proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA); if (kt_present_key_val_as_ascii) { pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(pi); } new_offset += vsiz; proto_item_set_len(ti, new_offset - rec_start_offset); rnum--; } } return new_offset; }
static int parse_teredo_auth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, e_teredohdr *teredoh) { guint idlen, aulen; col_append_sep_str (pinfo->cinfo, COL_INFO, ", ", "Authentication header"); teredoh->th_indtyp = 1; offset += 2; idlen = tvb_get_guint8(tvb, offset); teredoh->th_cidlen = idlen; offset++; aulen = tvb_get_guint8(tvb, offset); teredoh->th_authdlen = aulen; offset++; if (tree) { proto_item *ti; ti = proto_tree_add_item(tree, hf_teredo_auth, tvb, offset-4, 13 + idlen + aulen, ENC_NA); tree = proto_item_add_subtree(ti, ett_teredo_auth); proto_tree_add_item(tree, hf_teredo_auth_idlen, tvb, offset - 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_teredo_auth_aulen, tvb, offset - 1, 1, ENC_BIG_ENDIAN); /* idlen is usually zero */ if (idlen) { proto_tree_add_item(tree, hf_teredo_auth_id, tvb, offset, idlen, ENC_NA); offset += idlen; } /* aulen is usually zero */ if (aulen) { proto_tree_add_item(tree, hf_teredo_auth_value, tvb, offset, aulen, ENC_NA); offset += aulen; } proto_tree_add_item(tree, hf_teredo_auth_nonce, tvb, offset, 8, ENC_NA); offset += 8; proto_tree_add_item(tree, hf_teredo_auth_conf, tvb, offset, 1, ENC_NA); offset++; } else offset += idlen + aulen + 9; tvb_memcpy(tvb, teredoh->th_nonce, offset - 9, 8); teredoh->th_conf = tvb_get_guint8(tvb, offset - 1); return offset; }
static void dissect_wai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Format of WAPI protocol packet in WAI authentication system 0 2 3 4 6 8 10 11 12 ------------------------------------------------------------------------------- | Ver. | Type | Subtype | Reserved | Length | packet | fragm. | flag | data | | | seq. no | seq. no | | |-----------------------------------------------------------------------------| Figure 18 from [ref:1] */ #define WAI_MESSAGE_LENGTH 12 /*Length of all fields without 'Data' field*/ #define WAI_DATA_OFFSET WAI_MESSAGE_LENGTH guint16 version; guint8 subtype; guint16 length; guint16 packet_num; guint8 fragment_num; guint8 flags; fragment_head *frag_msg; proto_tree *wai_tree = NULL; tvbuff_t *next_tvb; tvbuff_t *new_tvb; const gchar *subtype_name = "Unknown type"; length = tvb_get_ntohs(tvb, 6)-WAI_MESSAGE_LENGTH; subtype = tvb_get_guint8(tvb, 3); /* quick sanity check */ if ((length != tvb_reported_length (tvb)-WAI_MESSAGE_LENGTH) || (subtype > WAI_SUB_MULTICAST_ANNOUNCE_RESP)) { return; } col_set_str(pinfo->cinfo, COL_PROTOCOL, "WAI"); col_clear(pinfo->cinfo, COL_INFO); version = tvb_get_ntohs(tvb, 0); if (version == 1) { subtype_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type"); } col_append_fstr(pinfo->cinfo, COL_INFO, "%s", subtype_name); /* Field lengths and offsets in WAI protocol described above */ packet_num = tvb_get_ntohs(tvb, 8); fragment_num = tvb_get_guint8(tvb, 10); flags = tvb_get_guint8(tvb, 11); if (tree) { proto_item *wai_item; wai_item = proto_tree_add_item(tree, proto_wai, tvb, 0, -1, ENC_NA); proto_item_set_text (wai_item, "WAI Protocol (%s)", val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type")); wai_tree = proto_item_add_subtree(wai_item, ett_wai); /* Field lengths and offsets in WAI protocol described above */ proto_tree_add_item(wai_tree, hf_wai_version, tvb, 0, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_type, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_subtype, tvb, 3, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_reserved, tvb, 4, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_length, tvb, 6, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_seq, tvb, 8, 2, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_fragm_seq, tvb, 10, 1, ENC_BIG_ENDIAN); proto_tree_add_item(wai_tree, hf_wai_flag, tvb, 11, 1, ENC_BIG_ENDIAN); } frag_msg = fragment_add_seq_check (&wai_reassembly_table, tvb, WAI_DATA_OFFSET, pinfo, packet_num, NULL, fragment_num, length, flags); next_tvb = tvb_new_subset_remaining(tvb, WAI_DATA_OFFSET); /* Replace INFO column if message is fragmented and call data_handle */ if (flags) { col_add_fstr(pinfo->cinfo, COL_INFO, "Fragment (%d) of message, data not dissected", fragment_num); process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo, "Reassembled WAI", frag_msg, &wai_frag_items, NULL, wai_tree); call_dissector(data_handle, next_tvb, pinfo, tree); } else { /* If this is the last fragment of fragmented message, then reassamble and dissect otherwise only dissect */ if (fragment_num > 0) { new_tvb = process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo, "Reassembled WAI", frag_msg, &wai_frag_items, NULL, wai_tree); if (new_tvb) { col_set_str(pinfo->cinfo, COL_INFO, "Last fragment of message, data dissected"); col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", subtype_name); next_tvb=new_tvb; length = tvb_reported_length (next_tvb); } } /* dissect Data field of WAI packet */ if (tree) { dissect_wai_data(next_tvb, wai_tree, subtype, length); } } }