Esempio n. 1
0
/* 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 */
	}
}
/* 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!)");

	}
}
Esempio n. 3
0
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 */
	}
}
Esempio n. 4
0
/* 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 */
	}
}
Esempio n. 5
0
/* 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 !)");
	}
}
Esempio n. 6
0
/* 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 */
	}
}
Esempio n. 7
0
/* Decode RNG-REQ messages. */
static void dissect_mac_mgmt_msg_rng_req_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint offset = 0;
	guint tlv_offset;
	guint tvb_len;
	proto_item *rng_req_item, *tlv_item;
	proto_tree *rng_req_tree, *tlv_tree;
	tlv_info_t tlv_info;
	gint tlv_type;
	gint tlv_len;

	{	/* we are being asked for details */

		/* Get the tvb reported length */
		tvb_len =  tvb_reported_length(tvb);
		/* display MAC payload type RNG-REQ */
		rng_req_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, tvb_len, "MAC Management Message, RNG-REQ");
		/* add MAC RNG-REQ subtree */
		rng_req_tree = proto_item_add_subtree(rng_req_item, ett_mac_mgmt_msg_rng_req_decoder);
		/* display the Message Type */
		proto_tree_add_item(rng_req_tree, hf_rng_req_reserved, tvb, 0, 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, "RNG-REQ TLV error");
				proto_tree_add_item(rng_req_tree, hf_rng_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 RNG_REQ_DL_BURST_PROFILE:
					/* add TLV subtree */
					tlv_item = add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_dl_burst_profile, tvb, offset, ENC_BIG_ENDIAN);
					tlv_tree = proto_item_add_subtree(tlv_item, ett_mac_mgmt_msg_rng_req_decoder);
					proto_tree_add_item(tlv_tree, hf_rng_req_dl_burst_profile_diuc, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					proto_tree_add_item(tlv_tree, hf_rng_req_dl_burst_profile_lsb_ccc, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					break;
				case RNG_REQ_SS_MAC_ADDRESS:
					add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_ss_mac_address, tvb, offset, ENC_NA);
					break;
				case RNG_REQ_RANGING_ANOMALIES:
					tlv_item = add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_ranging_anomalies, tvb, offset, ENC_BIG_ENDIAN);
					tlv_tree = proto_item_add_subtree(tlv_item, ett_mac_mgmt_msg_rng_req_decoder);
					proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_max_power, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_min_power, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					proto_tree_add_item(tlv_tree, hf_rng_req_ranging_anomalies_timing_adj, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					break;
				case RNG_REQ_AAS_BROADCAST:
					add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_aas_broadcast, tvb, offset, ENC_BIG_ENDIAN);
					break;
				case RNG_REQ_SERVING_BS_ID:
					add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_serving_bs_id, tvb, offset, ENC_NA);
					break;
				case RNG_REQ_RANGING_PURPOSE_INDICATION:
					/* display the Ranging Purpose Flags */
					tlv_item = add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_ranging_purpose_indication, tvb, offset, ENC_BIG_ENDIAN);
					tlv_tree = proto_item_add_subtree(tlv_item, ett_mac_mgmt_msg_rng_req_decoder);
					proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_ho_indication, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_location_update_request, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					proto_tree_add_item(tlv_tree, hf_rng_req_ranging_purpose_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					break;
				case RNG_REQ_HO_ID:
					add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_ho_id, tvb, offset, ENC_BIG_ENDIAN);
					break;
				case RNG_REQ_POWER_DOWN_INDICATOR:
					add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_power_down_indicator, tvb, offset, ENC_BIG_ENDIAN);
					break;
				case RNG_REQ_REQUESTED_DNLK_REP_CODING_LEVEL:
					tlv_item = add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_requested_rep_coding_level, tvb, offset, ENC_BIG_ENDIAN);
					tlv_tree = proto_item_add_subtree(tlv_item, ett_mac_mgmt_msg_rng_req_decoder);
					proto_tree_add_item(tlv_tree, hf_rng_req_repetition_coding_level, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					proto_tree_add_item(tlv_tree, hf_rng_req_requested_downlink_repetition_coding_level_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
					break;
				case RNG_REQ_CMAC_KEY_COUNT:
					if (include_cor2_changes) {
						add_tlv_subtree(&tlv_info, rng_req_tree, hf_rng_req_cmac_key_count, tvb, offset, ENC_BIG_ENDIAN);
					} else {
						/* Unknown TLV type */
						add_tlv_subtree(&tlv_info, rng_req_tree, hf_tlv_type, tvb, offset, ENC_NA);
					}
					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_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, tlv_len, "Short HMAC Tuple");
						wimax_short_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tvb_len - offset);
					} else {
						/* Unknown TLV Type */
						add_tlv_subtree(&tlv_info, rng_req_tree, hf_tlv_type, tvb, offset, ENC_NA);
					}
					break;
				case MAC_VERSION_ENCODING:
					offset += wimax_common_tlv_encoding_decoder(tvb_new_subset_remaining(tvb, offset), pinfo, rng_req_tree);
					continue;
					break;
				case RNG_REQ_POWER_SAVING_CLASS_PARAMETERS:
					tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, tlv_len, "Power Saving Class Parameters");
					dissect_power_saving_class(tlv_tree, tlv_type, tvb, tlv_len, pinfo, tlv_offset);
					break;
				default:
					add_tlv_subtree(&tlv_info, rng_req_tree, hf_tlv_type, tvb, offset, ENC_NA);
					break;
			}
			/* update the offset */
			offset = tlv_len + tlv_offset;
		}	/* end of TLV process while loop */
	}
}
Esempio n. 8
0
/* Decode DREG-CMD messages. */
void dissect_mac_mgmt_msg_dreg_cmd_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint offset = 0;
	guint tlv_offset;
	guint tvb_len, payload_type;
	proto_item *dreg_cmd_item = NULL;
	proto_tree *dreg_cmd_tree = NULL;
	proto_tree *tlv_tree = NULL;
	tlv_info_t tlv_info;
	gint tlv_type;
	gint tlv_len;
	gboolean hmac_found = FALSE;

	/* Ensure the right payload type */
	payload_type = tvb_get_guint8(tvb, 0);
	if(payload_type != MAC_MGMT_MSG_DREG_CMD)
	{
		return;
	}

	if (tree)
	{	/* we are being asked for details */

		/* Get the tvb reported length */
		tvb_len =  tvb_reported_length(tvb);
		/* display MAC payload type DREG-CMD */
		dreg_cmd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, 0, tvb_len, "MAC Management Message, DREG-CMD (29)");
		/* add MAC DREG CMD subtree */
		dreg_cmd_tree = proto_item_add_subtree(dreg_cmd_item, ett_mac_mgmt_msg_dreg_decoder);
		/* display the Message Type */
		proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_message_type, tvb, offset, 1, FALSE);
		offset ++;
		/* display the Action Code */
		if (include_cor2_changes)
			proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_action_cor2, tvb, offset, 1, FALSE);
		else
			proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_action, tvb, offset, 1, FALSE);
		/* show the Reserved bits */
		proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_reserved, tvb, offset, 1, FALSE);
		offset ++;

		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 */
				if (check_col(pinfo->cinfo, COL_INFO))
				{
					col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DREG-CMD TLV error");
				}
				proto_tree_add_item(dreg_cmd_tree, hf_dreg_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 HMAC_TUPLE:	/* Table 348d */
					/* decode and display the HMAC Tuple */
					tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, tlv_offset, tlv_len, "HMAC Tuple (%u byte(s))", tlv_len);
					wimax_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, 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_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, tlv_offset, tlv_len, "CMAC Tuple (%u byte(s))", tlv_len);
					wimax_cmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len);
					break;
				default:
					/* Decode DREG-CMD sub-TLV's */
					tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, tlv_offset, tlv_len, "DREG-CMD sub-TLV's (%u byte(s))", tlv_len);
					dissect_dreg_tlv(tlv_tree, tlv_type, tvb, tlv_offset, tlv_len);
					break;
			}

			offset = tlv_len + tlv_offset;
		}	/* end of TLV process while loop */
		if (!hmac_found)
			proto_item_append_text(dreg_cmd_tree, " (HMAC Tuple is missing !)");
	}
}
Esempio n. 9
0
/* Decode DREG-REQ messages. */
static void dissect_mac_mgmt_msg_dreg_req_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint offset = 0;
	guint tlv_offset;
	guint tvb_len;
	proto_item *dreg_req_item;
	proto_tree *dreg_req_tree;
	proto_tree *tlv_tree = NULL;
	tlv_info_t tlv_info;
	gint tlv_type;
	gint tlv_len;
	gboolean hmac_found = FALSE;

	{	/* we are being asked for details */

		/* Get the tvb reported length */
		tvb_len =  tvb_reported_length(tvb);
		/* display MAC payload type DREG-REQ */
		dreg_req_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_dreg_req_decoder, tvb, 0, -1, "MAC Management Message, DREG-REQ");
		/* add MAC DREG REQ subtree */
		dreg_req_tree = proto_item_add_subtree(dreg_req_item, ett_mac_mgmt_msg_dreg_decoder);
		/* display the Action Code */
		proto_tree_add_item(dreg_req_tree, hf_dreg_req_action, tvb, offset, 1, ENC_BIG_ENDIAN);
		/* show the Reserved bits */
		proto_tree_add_item(dreg_req_tree, hf_dreg_req_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset++;

		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, "DREG-REQ TLV error");
				proto_tree_add_item(dreg_req_tree, hf_dreg_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 HMAC_TUPLE:	/* Table 348d */
					/* decode and display the HMAC Tuple */
					tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_req_tree, proto_mac_mgmt_msg_dreg_req_decoder, tvb, tlv_offset, tlv_len, "HMAC Tuple (%u byte(s))", tlv_len);
					wimax_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, 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_dreg_decoder, dreg_req_tree, proto_mac_mgmt_msg_dreg_req_decoder, tvb, tlv_offset, tlv_len, "CMAC Tuple (%u byte(s))", tlv_len);
					wimax_cmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len);
					break;
				default:
					/* Decode DREG-REQ sub-TLV's */
					tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_req_tree, proto_mac_mgmt_msg_dreg_req_decoder, tvb, tlv_offset, tlv_len, "DREG-REQ sub-TLV's (%u byte(s))", tlv_len);
					dissect_dreg_tlv(tlv_tree, tlv_type, tvb, tlv_offset, tlv_len);
					break;
			}


			offset = tlv_len + tlv_offset;
		}	/* end of TLV process while loop */
		if (!hmac_found)
			proto_item_append_text(dreg_req_tree, " (HMAC Tuple is missing !)");
	}
}
Esempio n. 10
0
/* Decode RNG Power Saving Class parameters (Sub TLV's). */
void dissect_power_saving_class(proto_tree *rng_req_tree, gint tlv_type, tvbuff_t *tvb, guint compound_tlv_len, packet_info *pinfo, guint offset)
{
	proto_item *tlv_item = NULL;
	proto_tree *tlv_tree = NULL;
	proto_tree *power_saving_class_tree = NULL;
	guint tlv_len;
	guint tlv_offset;
	tlv_info_t tlv_info;

	/* Add a subtree for the power saving class parameters */
	tlv_item = proto_tree_add_protocol_format(rng_req_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, offset, compound_tlv_len, "Power saving class parameters (%u bytes)", compound_tlv_len);
	power_saving_class_tree = proto_item_add_subtree(tlv_item, ett_mac_mgmt_msg_rng_req_decoder);

	/* Update the compound_tlv_len to include the offset */
	compound_tlv_len += offset;

	while(offset < compound_tlv_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-REQ TLV error");
			proto_tree_add_item(power_saving_class_tree, hf_rng_invalid_tlv, tvb, offset, (compound_tlv_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 RNG_POWER_SAVING_CLASS_FLAGS:
				/* display Power Saving Class Flags */
				/* add subtree */
				tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, proto_mac_mgmt_msg_rng_req_decoder, tvb, tlv_offset, tlv_len, "Power Saving Class (%u byte)", tlv_len);
				proto_tree_add_item(tlv_tree, hf_rng_definition_of_power_saving_class_present, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tlv_tree, hf_rng_activation_of_power_saving_class, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tlv_tree, hf_rng_trf_ind_required, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_reserved, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_POWER_SAVING_CLASS_ID:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_class_id, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_id, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_POWER_SAVING_CLASS_TYPE:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_class_type, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_class_type, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_START_FRAME_NUMBER:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_first_sleep_window_frame, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_first_sleep_window_frame, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_INITIAL_SLEEP_WINDOW:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_initial_sleep_window, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_initial_sleep_window, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_LISTENING_WINDOW:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_listening_window, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_listening_window, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_FINAL_SLEEP_WINDOW_BASE:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_final_sleep_window_base, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_final_sleep_window_base, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_FINAL_SLEEP_WINDOW_EXPONENT:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_final_sleep_window_exp, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_final_sleep_window_exp, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_SLPID:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_slpid, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_slpid, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			case RNG_CID:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_included_cid, tvb, tlv_offset, 2, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_included_cid, tvb, tlv_offset, 2, ENC_BIG_ENDIAN);
				break;
			case RNG_DIRECTION:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_rng_power_saving_mgmt_connection_direction, tvb, tlv_offset, 1, FALSE);
				proto_tree_add_item(tlv_tree, hf_rng_power_saving_mgmt_connection_direction, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
				break;
			default:
				tlv_tree = add_tlv_subtree(&tlv_info, ett_mac_mgmt_msg_rng_req_decoder, power_saving_class_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE);
				proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, ENC_NA);
				break;
		}
		/* update the offset */
		offset = tlv_len + tlv_offset;
	}	/* end of TLV process while loop */
}