Пример #1
0
static int
dissect_btsmp_auth_req(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
    guint8 value;
    const guint8 *ph;

    col_append_str(pinfo->cinfo, COL_INFO, "AuthReq: ");
    proto_tree_add_bitmask(tree, tvb, offset, hf_btsmp_authreq, ett_btsmp_auth_req, hfx_btsmp_authreq, ENC_LITTLE_ENDIAN);

    value = tvb_get_guint8(tvb, offset);

    ph = val_to_str_const(value & 0x03, bonding_flag_vals, "<unknown>");
    col_append_sep_str(pinfo->cinfo, COL_INFO, "", ph);

    if (value & 0x04)
        col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "MITM");
    if (value & 0x08)
        col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "SecureConnection");
    if (value & 0x10)
        col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Keypress");
    if (value & 0xE0)
        col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Reserved");

    return offset + 1;
}
Пример #2
0
static void dissect_wimax_ffb_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
	guint length, num_of_ffbs, i;
	proto_item *ffb_item = NULL;
	proto_tree *ffb_tree = NULL;

	/* update the info column */
	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Fast Feedback Burst:");
	if (tree)
	{	/* we are being asked for details */
		/* get the tvb reported length */
		length = tvb_reported_length(tvb);
		/* display Fast Feedback Burst dissector info */
		ffb_item = proto_tree_add_protocol_format(tree, proto_wimax_ffb_decoder, tvb, offset, length, "Fast Feedback Burst (%u bytes)", length);
		/* add Fast Feedback Burst subtree */
		ffb_tree = proto_item_add_subtree(ffb_item, ett_wimax_ffb_decoder);
		/* get the number of FFBs */
		num_of_ffbs =  tvb_get_guint8(tvb, offset);
		/* display the number of FFBs */
		proto_tree_add_item(ffb_tree, hf_ffb_num_of_ffbs, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the FFB type */
		proto_tree_add_item(ffb_tree, hf_ffb_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the FFBs */
		for(i = 0; i < num_of_ffbs; i++)
		{
			proto_tree_add_item(ffb_tree, hf_ffb_subchannel, tvb, offset++, 1, ENC_BIG_ENDIAN);
			proto_tree_add_item(ffb_tree, hf_ffb_symboloffset, tvb, offset++, 1, ENC_BIG_ENDIAN);
			proto_tree_add_item(ffb_tree, hf_ffb_value, tvb, offset++, 1, ENC_BIG_ENDIAN);
		}
	}
}
Пример #3
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 */
	}
}
Пример #4
0
static void dissect_wimax_hack_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
	guint length, num_of_hacks, i;
	proto_item *hack_item = NULL;
	proto_tree *hack_tree = NULL;

	/* update the info column */
	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "HARQ ACK Burst:");
	if (tree)
	{	/* we are being asked for details */
		/* get the tvb reported length */
		length = tvb_reported_length(tvb);
		/* display HARQ ACK Burst dissector info */
		hack_item = proto_tree_add_protocol_format(tree, proto_wimax_hack_decoder, tvb, offset, length, "HARQ ACK Burst (%u bytes)", length);
		/* add HARQ ACK Burst subtree */
		hack_tree = proto_item_add_subtree(hack_item, ett_wimax_hack_decoder);
		/* get the number of HARQ ACKs */
		num_of_hacks =  tvb_get_guint8(tvb, offset);
		/* display the number of HARQ ACKs */
		proto_tree_add_item(hack_tree, hf_hack_num_of_hacks, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the HARQ ACKs */
		for(i = 0; i < num_of_hacks; i++)
		{
			proto_tree_add_item(hack_tree, hf_hack_subchannel, tvb, offset++, 1, ENC_BIG_ENDIAN);
			proto_tree_add_item(hack_tree, hf_hack_symboloffset, tvb, offset++, 1, ENC_BIG_ENDIAN);
			proto_tree_add_item(hack_tree, hf_hack_half_slot_flag, tvb, offset++, 1, ENC_BIG_ENDIAN);
			proto_tree_add_item(hack_tree, hf_hack_value, tvb, offset++, 1, ENC_BIG_ENDIAN);
		}
	}
}
Пример #5
0
static void dissect_wimax_fch_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
	proto_item *fch_item = NULL;
	proto_tree *fch_tree = NULL;

	/* save the base station address (once) */
	if(!bs_address.len)
		COPY_ADDRESS(&bs_address, &(pinfo->src));
	/* update the info column */
	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "FCH");
	if (tree)
	{	/* we are being asked for details */
		/* display FCH dissector info */
		fch_item = proto_tree_add_protocol_format(tree, proto_wimax_fch_decoder, tvb, offset, 3, "DL Frame Prefix (24 bits)");
		/* add FCH subtree */
		fch_tree = proto_item_add_subtree(fch_item, ett_wimax_fch_decoder);
		/* Decode and display the used sub-channel groups */
		proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group0, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group1, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group2, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group3, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group4, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		proto_tree_add_item(fch_tree, hf_fch_used_subchannel_group5, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		proto_tree_add_item(fch_tree, hf_fch_reserved_1, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		/* Decode and display the repetition coding indication */
		proto_tree_add_item(fch_tree, hf_fch_repetition_coding_indication, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		/* Decode and display the coding indication */
		proto_tree_add_item(fch_tree, hf_fch_coding_indication, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		/* Decode and display the DL MAP length */
		proto_tree_add_item(fch_tree, hf_fch_dlmap_length, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
		proto_tree_add_item(fch_tree, hf_fch_reserved_2, tvb, offset, FCH_BURST_LENGTH, ENC_BIG_ENDIAN);
	}
}
static void dissect_wimax_cdma_code_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
	guint length;
	proto_item *cdma_item = NULL;

	proto_tree *cdma_tree = NULL;

	/* update the info column */
	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "CDMA Code Attribute");
	if (tree)
	{	/* we are being asked for details */
		/* get the tvb reported length */
		length = tvb_reported_length(tvb);
		/* display CDMA dissector info */
		cdma_item = proto_tree_add_protocol_format(tree, proto_wimax_cdma_code_decoder, tvb, offset, length, "CDMA Code Attribute (%u bytes)", length);
		/* add CDMA Code subtree */
		cdma_tree = proto_item_add_subtree(cdma_item, ett_wimax_cdma_code_decoder);
		/* display the first CDMA Code */
		proto_tree_add_item(cdma_tree, hf_wimax_ranging_code, tvb, offset, 1, FALSE);
		/* display the 2nd CDMA Code */
		proto_tree_add_item(cdma_tree, hf_wimax_ranging_symbol_offset, tvb, offset+1, 1, FALSE);
		/* display the 3rd CDMA Code */
		proto_tree_add_item(cdma_tree, hf_wimax_ranging_subchannel_offset, tvb, offset+2, 1, FALSE);
	}
}
Пример #7
0
/* Decode and display the PDU Burst */
static void pdu_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo, gint burst_number, gint frag_type, gint frag_number)
{
	fragment_head *pdu_frag;
	tvbuff_t *pdu_tvb = NULL;

	/* update the info column */
	switch (frag_type)
	{
		case TLV_FIRST_FRAG:
			col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "First TLV Fragment (%d)", frag_number);
		break;
		case TLV_LAST_FRAG:
			col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Last TLV Fragment (%d)", frag_number);
		break;
		case TLV_MIDDLE_FRAG:
			col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Middle TLV Fragment %d", frag_number);
		break;
	}
	if(frag_type == TLV_NO_FRAG)
	{	/* not fragmented PDU */
		pdu_tvb =  tvb_new_subset_length(tvb, offset, length);
	}
	else	/* fragmented PDU */
	{	/* add the fragment */
		pdu_frag = fragment_add_seq(&pdu_reassembly_table, tvb, offset, pinfo, burst_number, NULL, frag_number - 1, length, ((frag_type==TLV_LAST_FRAG)?0:1), 0);
		if(pdu_frag && frag_type == TLV_LAST_FRAG)
		{
			/* create the new tvb for defragmented frame */
			pdu_tvb = tvb_new_chain(tvb, pdu_frag->tvb_data);
			/* add the defragmented data to the data source list */
			add_new_data_source(pinfo, pdu_tvb, "Reassembled WiMax PDU Frame");
		}
		else
		{
			pdu_tvb = NULL;
			if(frag_type == TLV_LAST_FRAG)
			{	/* update the info column */
				col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Incomplete PDU frame");
			}
		}
	}
	/* process the defragmented PDU burst */
	if(pdu_tvb)
	{
		if(wimax_pdu_burst_handle)
		{/* decode and display PDU Burst */
			call_dissector(wimax_pdu_burst_handle, pdu_tvb, pinfo, tree);
		}
		else	/* display PDU Burst info */
		{	/* update the info column */
			col_append_str(pinfo->cinfo, COL_INFO, "PDU Burst");
		}
	}
}
Пример #8
0
static int
dissect_btsmp_key_dist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, gboolean initiator)
{
    guint8 value;
    gboolean next = FALSE;

    if (initiator) {
        col_append_str(pinfo->cinfo, COL_INFO, " | Initiator Key(s): ");
        proto_tree_add_bitmask(tree, tvb, offset, hf_btsmp_initiator_key_distribution, ett_btsmp_key_dist, hfx_btsmp_key_distribution, ENC_LITTLE_ENDIAN);
    } else {
        col_append_str(pinfo->cinfo, COL_INFO, " | Responder Key(s): ");
        proto_tree_add_bitmask(tree, tvb, offset, hf_btsmp_responder_key_distribution, ett_btsmp_key_dist, hfx_btsmp_key_distribution, ENC_LITTLE_ENDIAN);
    }

    value = tvb_get_guint8(tvb, offset);

    if (value & 0x01) {
        col_append_str(pinfo->cinfo, COL_INFO, "LTK");
        next = TRUE;
    }
    if (value & 0x02) {
        col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "IRK");
        next = TRUE;
    }
    if (value & 0x04) {
        col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "CSRK");
        next = TRUE;
    }
    if (value & 0x08) {
        col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "Linkkey");
        next = TRUE;
    }
    if (value & 0xF0) {
        col_append_sep_str(pinfo->cinfo, COL_INFO, next ? ", " : "", "Reserved");
    }
    if (!next) {
        col_append_str(pinfo->cinfo, COL_INFO, "<none>");
    }

    return offset + 1;
}
Пример #9
0
static void
decode_iei_control_bits(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
  guint8 control_bits;
  proto_item *tf;
  proto_tree *field_tree;

  control_bits = tvb_get_guint8(bi->tvb, bi->offset);

  if (bi->nsip_tree) {
    tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
                             ie->total_length,
                             "NS SDU Control bits: %#02x", control_bits);

    field_tree = proto_item_add_subtree(tf, ett_nsip_control_bits);
    proto_tree_add_boolean(field_tree, hf_nsip_control_bits_r, bi->tvb,
                           bi->offset, 1,
                           control_bits & NSIP_MASK_CONTROL_BITS_R);
    proto_tree_add_boolean(field_tree, hf_nsip_control_bits_c, bi->tvb,
                           bi->offset, 1,
                           control_bits & NSIP_MASK_CONTROL_BITS_C);
    proto_tree_add_uint(field_tree, hf_nsip_control_bits_spare,
                           bi->tvb, bi->offset, 1,
                           control_bits & NSIP_MASK_CONTROL_BITS_SPARE);
  }
  bi->offset++;

  if (check_col(bi->pinfo->cinfo, COL_INFO)) {
    if (control_bits & NSIP_MASK_CONTROL_BITS_R) {
      col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Req CF");
      proto_item_append_text(bi->ti, ", Request Change Flow");
    }

    if (control_bits & NSIP_MASK_CONTROL_BITS_C) {
      col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Conf CF");
      proto_item_append_text(bi->ti, ", Confirm Change Flow");
    }
  }
}
Пример #10
0
static int
dissect_kt_replication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    gint new_offset;
    guint32 next32, size;
    guint64 ts;
    nstime_t ns_ts;
    proto_item *pi;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    if (tvb_reported_length_remaining(tvb, new_offset) > 0) {
        next32 = tvb_get_ntohl(tvb, new_offset);
        if (next32 <= 1) { /* This means request. the 32 bits are flags */
            proto_tree_add_item(tree, hf_kt_flags, tvb, new_offset, 4, ENC_BIG_ENDIAN);
            new_offset += 4;

            proto_tree_add_item(tree, hf_kt_ts, tvb, new_offset, 8, ENC_BIG_ENDIAN);
            new_offset += 8;

            proto_tree_add_item(tree, hf_kt_sid, tvb, new_offset, 2, ENC_BIG_ENDIAN);
            new_offset += 2;
        } else { /* This is a response. The 32 bits are the first half of the ts */
            ts = tvb_get_ntoh64(tvb, new_offset);
            ns_ts.secs = (time_t)(ts/1000000000);
            ns_ts.nsecs = (int)(ts%1000000000);
            proto_tree_add_time(tree, hf_kt_ts, tvb, new_offset, 8, &ns_ts);
            new_offset += 8;

            size = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_size, tvb, new_offset, 4, size);
            new_offset += 4;

            proto_tree_add_item(tree, hf_kt_log, tvb, new_offset, size, ENC_NA);
            new_offset += size;
        }
    } else {
        /* This is an empty ack to the message with magic 0xB0. */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
        PROTO_ITEM_SET_GENERATED(pi);
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");
    }

    return new_offset;
}
Пример #11
0
static int
parse_teredo_orig(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
			int offset, e_teredohdr *teredoh)
{
	proto_item *ti = NULL;

	col_append_sep_str (pinfo->cinfo, COL_INFO, ", ",
					"Origin indication");

	if (tree) {
		ti = proto_tree_add_item(tree, hf_teredo_orig, tvb, offset,
						8, ENC_NA);
		tree = proto_item_add_subtree(ti, ett_teredo_orig);
	}
	offset += 2;

	teredoh->th_orgport = tvb_get_ntohs(tvb, offset);
	if (tree) {
		/*
		 * The "usual arithmetic conversions" will convert
		 * "teredoh->th_orgport" to an "int" (because all
		 * "unsigned short" values will fit in an "int"),
		 * which will zero-extend it.  This means that
		 * complementing it will turn all the zeroes in
		 * the upper 16 bits into ones; we just want the
		 * lower 16 bits (containing the port number)
		 * complemented, with the result zero-extended.
		 *
		 * That's what the cast is for.
		 */
		proto_tree_add_uint(tree, hf_teredo_orig_port, tvb,
					offset, 2,
					(guint16)~teredoh->th_orgport);
	}
	offset += 2;

	teredoh->th_iporgaddr = tvb_get_ipv4(tvb, offset);
	if (tree) {
		proto_tree_add_ipv4(tree, hf_teredo_orig_addr, tvb,
					offset, 4, ~teredoh->th_iporgaddr);
	}
	offset += 4;

	return offset;
}
Пример #12
0
static void dissect_wimax_phy_attributes_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint offset = 0;
	guint tvb_len;
/*	guint num_of_slots;*/
	proto_item *phy_item = NULL;
	proto_tree *phy_tree = NULL;

	/* update the info column */
	/*col_append_str(pinfo->cinfo, COL_INFO, "PDU Burst Physical Attributes:");*/
	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "PHY-attr");
	if (tree)
	{	/* we are being asked for details */
		/* get the tvb reported length */
		tvb_len = tvb_reported_length(tvb);
		/* display PDU Burst Physical Attributes dissector info */
		phy_item = proto_tree_add_protocol_format(tree, proto_wimax_phy_attributes_decoder, tvb, offset, tvb_len, "PDU Burst Physical Attributes (%u bytes)", tvb_len);
		/* add PDU Burst Physical Attributes subtree */
		phy_tree = proto_item_add_subtree(phy_item, ett_wimax_phy_attributes_decoder);
		/* display the subchannelization type */
		proto_tree_add_item(phy_tree, hf_phy_attributes_subchannelization_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the permbase */
		proto_tree_add_item(phy_tree, hf_phy_attributes_permbase, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the modulation rate */
		proto_tree_add_item(phy_tree, hf_phy_attributes_modulation_rate, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the encoding type */
		proto_tree_add_item(phy_tree, hf_phy_attributes_encoding_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the numRepeat */
		proto_tree_add_item(phy_tree, hf_phy_attributes_num_repeat, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the symbol offset */
		proto_tree_add_item(phy_tree, hf_phy_attributes_symbol_offset, tvb, offset++, 1, ENC_BIG_ENDIAN);
		/* display the number of slots */
		proto_tree_add_item(phy_tree, hf_phy_attributes_num_of_slots, tvb, offset, 2, ENC_BIG_ENDIAN);
		/* get the number of slots */
/*		num_of_slots =  tvb_get_guint16(tvb, offset);*/
		/* move to next field */
		offset += 2;
		/* display the physical subchannel list */
		while(offset < tvb_len)
		{
			proto_tree_add_item(phy_tree, hf_phy_attributes_subchannel, tvb, offset++, 1, ENC_BIG_ENDIAN);
		}
	}
}
Пример #13
0
static void dissect_mac_mgmt_msg_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint offset = 0;
	guint message_type;
	proto_item *message_item;
	proto_tree *message_tree;
	const char* mgt_msg_str;

	message_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_decoder, tvb, offset, -1,
					"MAC Management Message Type (%u bytes)", tvb_reported_length(tvb));
	message_tree = proto_item_add_subtree(message_item, ett_mac_mgmt_msg_decoder);

	if (tvb_reported_length(tvb) == 0)
	{
		expert_add_info(pinfo, message_item, &ei_empty_payload);
		return;
	}

	/* Get the payload type */
	message_type = tvb_get_guint8(tvb, offset);
	proto_tree_add_item(message_tree, hf_mac_mgmt_msg_type, tvb, offset, 1, ENC_NA);
	mgt_msg_str = val_to_str_ext_const(message_type, &mgt_msg_abbrv_vals_ext, "Unknown");

	/* Display message type in Info column */
	col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", mgt_msg_str);

	/* add the payload type into the info column */
	if (try_val_to_str_ext(message_type, &mgt_msg_abbrv_vals_ext) == NULL)
	{
		/* display the MAC payload in Hex */
		proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA);
		return;
	}

	/* add the MAC header info to parent*/
	proto_item_append_text(proto_tree_get_parent(tree), ", %s", mgt_msg_str);

	/* Decode and display the MAC payload */
	if (!dissector_try_uint(subdissector_message_table, message_type,
		tvb_new_subset_remaining(tvb, 1), pinfo, tree))
	{
		proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA);
	}
}
Пример #14
0
static int ssh_dissect_kex_dh_gex(guint8 msg_code, tvbuff_t *tvb,
		packet_info *pinfo, int offset, proto_tree *tree)
{
	proto_tree_add_item(tree, hf_ssh2_kex_dh_gex_msg_code, tvb, offset, 1, ENC_NA);
	offset += 1;

	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
		val_to_str(msg_code, ssh2_kex_dh_gex_msg_vals, "Unknown (%u)"));

	switch (msg_code) {
	case SSH_MSG_KEX_DH_GEX_REQUEST_OLD:
		proto_tree_add_item(tree, hf_ssh_dh_gex_nbits, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		break;

	case SSH_MSG_KEX_DH_GEX_GROUP:
		offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_p);
		offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_g);
		break;

	case SSH_MSG_KEX_DH_GEX_INIT:
		offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_e);
		break;

	case SSH_MSG_KEX_DH_GEX_REPLY:
		offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_host_key, hf_ssh_kexdh_host_key_length);
		offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_f);
		offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_h_sig, hf_ssh_kexdh_h_sig_length);
		break;

	case SSH_MSG_KEX_DH_GEX_REQUEST:
		proto_tree_add_item(tree, hf_ssh_dh_gex_min, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		proto_tree_add_item(tree, hf_ssh_dh_gex_nbits, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		proto_tree_add_item(tree, hf_ssh_dh_gex_max, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		break;
	}

	return offset;
}
static void dissect_wimax_cdma_code_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
	proto_item *cdma_item;
	proto_tree *cdma_tree;

	/* update the info column */
	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "CDMA Code Attribute");
	if (tree)
	{	/* we are being asked for details */
		/* display CDMA dissector info */
		cdma_item = proto_tree_add_item(tree, proto_wimax_cdma_code_decoder, tvb, offset, -1, ENC_NA);
		/* add CDMA Code subtree */
		cdma_tree = proto_item_add_subtree(cdma_item, ett_wimax_cdma_code_decoder);
		/* display the first CDMA Code */
		proto_tree_add_item(cdma_tree, hf_wimax_ranging_code, tvb, offset, 1, ENC_BIG_ENDIAN);
		/* display the 2nd CDMA Code */
		proto_tree_add_item(cdma_tree, hf_wimax_ranging_symbol_offset, tvb, offset+1, 1, ENC_BIG_ENDIAN);
		/* display the 3rd CDMA Code */
		proto_tree_add_item(cdma_tree, hf_wimax_ranging_subchannel_offset, tvb, offset+2, 1, ENC_BIG_ENDIAN);
	}
}
Пример #16
0
static int ssh_dissect_kex_dh(guint8 msg_code, tvbuff_t *tvb,
		packet_info *pinfo, int offset, proto_tree *tree)
{
	proto_tree_add_item(tree, hf_ssh2_kex_dh_msg_code, tvb, offset, 1, ENC_NA);
	offset += 1;

	col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
		val_to_str(msg_code, ssh2_kex_dh_msg_vals, "Unknown (%u)"));

	switch (msg_code) {
	case SSH_MSG_KEXDH_INIT:
		offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_e);
		break;

	case SSH_MSG_KEXDH_REPLY:
		offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_host_key, hf_ssh_kexdh_host_key_length);
		offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_f);
		offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_h_sig, hf_ssh_kexdh_h_sig_length);
		break;
	}

	return offset;
}
Пример #17
0
static void
dissect_fcgi_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
   gint offset = 0;
   guint8 type;

   type = tvb_get_guint8(tvb, 1);

   /* When there are multiple FCGI records in a TCP frame the following code */
   /* will append the type for each record to COL_INFO.                      */
   /* XXX: Unfortunately, something in the tcp_dissect_pdus() code is broken */
   /*      such that only the type for the first FCGI record appears in the  */
   /*      INFO column. (All write attempts to COL_INFO after the first fail */
   /*      because pinfo->cinfo->writable is FALSE).                         */
   col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCGI");
   col_clear(pinfo->cinfo, COL_INFO);
   col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
                      val_to_str(type, record_types, "Unknown (%u)"));
   col_set_fence(pinfo->cinfo, COL_INFO);

   if (tree) { /* we are being asked for details */
      proto_item *ti;
      proto_tree *fcgi_tree;
      guint16 clen;
      guint8 plen;

      ti = proto_tree_add_item(tree, proto_fcgi, tvb, 0, -1, ENC_NA);
      proto_item_append_text(ti, " (%s)",
                             val_to_str(type, record_types, "Unknown (%u)"));
      fcgi_tree = proto_item_add_subtree(ti, ett_fcgi);

      proto_tree_add_item(fcgi_tree, hf_fcgi_version, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      proto_tree_add_item(fcgi_tree, hf_fcgi_type, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      proto_tree_add_item(fcgi_tree, hf_fcgi_id, tvb, offset, 2, ENC_BIG_ENDIAN);
      offset += 2;

      clen = tvb_get_ntohs(tvb, offset);
      proto_tree_add_item(fcgi_tree, hf_fcgi_content_length, tvb, offset, 2, ENC_BIG_ENDIAN);
      offset += 2;

      plen = tvb_get_guint8(tvb, offset);
      proto_tree_add_item(fcgi_tree, hf_fcgi_padding_length, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      offset += 1;

      switch (type)
      {
      case FCGI_BEGIN_REQUEST:
         dissect_begin_request(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_ABORT_REQUEST:
         dissect_abort_request(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_END_REQUEST:
         dissect_end_request(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_PARAMS:
         dissect_params(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_GET_VALUES:
         dissect_get_values(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_GET_VALUES_RESULT:
         dissect_get_values_result(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      default:
         if (clen > 0) {
            proto_tree_add_item(fcgi_tree, hf_fcgi_content_data, tvb, offset, clen, ENC_NA);
            offset += clen;
         }
         break;
      }

      if (plen > 0) {
         proto_tree_add_item(fcgi_tree, hf_fcgi_padding_data, tvb, offset, plen, ENC_NA);
         /*offset += plen;*/
      }
   }
}
Пример #18
0
/* 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!)");

	}
}
Пример #19
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 */
	}
}
Пример #20
0
static int
dissect_kt_remove_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    guint32 next32, rnum, ksiz;
    gint new_offset, rec_start_offset;
    proto_item *ti;
    proto_item *pi;
    proto_tree *rec_tree;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    next32 = tvb_get_ntohl(tvb, new_offset);

    if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) { /* request */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST);
        PROTO_ITEM_SET_GENERATED(pi);

        proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32);
        new_offset += 4;

        rnum = tvb_get_ntohl(tvb, new_offset);
        proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum);
        new_offset += 4;

        while (rnum > 0) {
            /* Create a sub-tree for each record */
            ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
            rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
            rec_start_offset = new_offset;

            proto_tree_add_item(rec_tree, hf_kt_dbidx, tvb, new_offset, 2, ENC_BIG_ENDIAN);
            new_offset += 2;

            ksiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
            new_offset += 4;

            proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                PROTO_ITEM_SET_GENERATED(pi);
            }
            new_offset += ksiz;

            proto_item_set_len(ti, new_offset - rec_start_offset);
            rnum--;
        }
    } else { /* response */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
        PROTO_ITEM_SET_GENERATED(pi);
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

        proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, next32);
        new_offset += 4;
    }

    return new_offset;
}
Пример #21
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 !)");
	}
}
Пример #22
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 */
	}
}
Пример #23
0
/*
 * Dissector that returns:
 *
 *	The amount of data in the protocol's PDU, if it was able to
 *	dissect all the data;
 *
 *	0, if the tvbuff doesn't contain a PDU for that protocol;
 *
 *	The negative of the amount of additional data needed, if
 *	we need more data (e.g., from subsequent TCP segments) to
 *	dissect the entire PDU.
 */
static int
dissect_ccn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint tvb_size = 0;
    proto_tree *ccn_tree;
    proto_item *ti = NULL;
    const unsigned char *ccnb;
    struct ccn_skeleton_decoder skel_decoder;
    struct ccn_skeleton_decoder *sd;
    struct ccn_charbuf *c;
    int packet_type = 0;
    int packet_type_length = 0;
    /* a couple of basic checks to rule out packets that are definitely not ours */
    tvb_size = tvb_length(tvb);
    if (tvb_size < CCN_MIN_PACKET_SIZE || tvb_get_guint8(tvb, 0) == 0)
        return (0);

    sd = &skel_decoder;
    memset(sd, 0, sizeof(*sd));
    sd->state |= CCN_DSTATE_PAUSE;
    ccnb = ep_tvb_memdup(tvb, 0, tvb_size);
    ccn_skeleton_decode(sd, ccnb, tvb_size);
    if (sd->state < 0)
        return (0);
    if (CCN_GET_TT_FROM_DSTATE(sd->state) == CCN_DTAG) {
        packet_type = sd->numval;
        packet_type_length = sd->index;
    } else {
        return (0);
    }
    memset(sd, 0, sizeof(*sd));
    ccn_skeleton_decode(sd, ccnb, tvb_size);
    if (!CCN_FINAL_DSTATE(sd->state)) {
        pinfo->desegment_offset = 0;
        pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
        return (-1); /* what should this be? */
    }

    /* Make it visible that we're taking this packet */
    if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "CCN");
    }

    /* Clear out stuff in the info column */
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_clear(pinfo->cinfo, COL_INFO);
    }

    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, tvb_size, 1);

    /* Add the packet type and CCN URI to the info column */
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_add_str(pinfo->cinfo, COL_INFO,
                    val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"));
        col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, ccn_charbuf_as_string(c));
    }

    if (tree == NULL) {
        ccn_charbuf_destroy(&c);
        return (sd->index);
    }

    ti = proto_tree_add_protocol_format(tree, proto_ccn, tvb, 0, -1,
                                        "Content-centric Networking Protocol, %s, %s",
                                        val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"),
                                        ccn_charbuf_as_string(c));
    ccn_tree = proto_item_add_subtree(ti, ett_ccn);
    ccn_charbuf_destroy(&c);
    ti = proto_tree_add_uint(ccn_tree, hf_ccn_type, tvb, 0, packet_type_length, packet_type);

    switch (packet_type) {
    case CCN_DTAG_ContentObject:
        if (0 > dissect_ccn_contentobject(ccnb, sd->index, tvb, pinfo, ccn_tree))
            return (0);
        break;
    case CCN_DTAG_Interest:
        if (0 > dissect_ccn_interest(ccnb, sd->index, tvb, pinfo, ccn_tree))
            return (0);
        break;
    }

    return (sd->index);
}
Пример #24
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 */
	}
}
Пример #25
0
/* dissect EDID data from the receiver
   return the offset after the dissected data */
static gint
dissect_hdmi_edid(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree)
{
    proto_item *yi;
    proto_tree *edid_tree;
    guint64     edid_hdr;
    guint16     manf_id;
    gchar       manf_id_str[4]; /* 3 letters + 0-termination */
    guint8      week, year;
    int         year_hf;

    edid_tree = proto_tree_add_subtree(tree, tvb,
            offset, -1, ett_hdmi_edid, NULL,
            "Extended Display Identification Data (EDID)");

    edid_hdr = tvb_get_ntoh64(tvb, offset);
    if (edid_hdr != EDID_HDR_VALUE)
        return offset; /* XXX handle fragmented EDID messages */

    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "EDID");

    proto_tree_add_item(edid_tree, hf_hdmi_edid_hdr,
            tvb, offset, 8, ENC_LITTLE_ENDIAN);
    offset += 8;

    /* read as big endian for easier splitting */
    manf_id = tvb_get_ntohs(tvb, offset);
    /* XXX check that MSB is 0 */
    manf_id_str[0] = CAPITAL_LETTER(manf_id, 10);
    manf_id_str[1] = CAPITAL_LETTER(manf_id,  5);
    manf_id_str[2] = CAPITAL_LETTER(manf_id,  0);
    manf_id_str[3] = 0;
    proto_tree_add_string(edid_tree, hf_hdmi_edid_manf_id,
            tvb, offset, 2, manf_id_str);
    offset += 2;

    proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_prod_code,
            tvb, offset, 2, ENC_LITTLE_ENDIAN);
    offset += 2;

    proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_serial,
            tvb, offset, 4, ENC_LITTLE_ENDIAN);
    offset += 4;

    week = tvb_get_guint8(tvb, offset);
    proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_week,
            tvb, offset, 1, ENC_LITTLE_ENDIAN);
    offset += 1;

    year_hf = week == 255 ? hf_hdmi_edid_mod_year : hf_hdmi_edid_manf_year;
    year = tvb_get_guint8(tvb, offset);
    yi = proto_tree_add_item(edid_tree, year_hf,
            tvb, offset, 1, ENC_LITTLE_ENDIAN);
    proto_item_append_text(yi, " (year %d)", 1990+year);
    offset += 1;

    proto_tree_add_item(edid_tree, hf_hdmi_edid_version, tvb, offset, 2, ENC_BIG_ENDIAN);

    /* XXX dissect the parts following the EDID header */

    return tvb_reported_length(tvb);
}
Пример #26
0
static void
dissect_omapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_item *ti;
  proto_tree *omapi_tree;
  ptvcursor_t* cursor;

  guint32 authlength;
  guint32 msglength;
  guint32 objlength;


  col_set_str(pinfo->cinfo, COL_PROTOCOL, "OMAPI");

  col_clear(pinfo->cinfo, COL_INFO);

  ti = proto_tree_add_item(tree, proto_omapi, tvb, 0, -1, ENC_NA);
  omapi_tree = proto_item_add_subtree(ti, ett_omapi);
  cursor = ptvcursor_new(omapi_tree, tvb, 0);

  if (tvb_reported_length_remaining(tvb, 0) < 8)
  {
    /* Payload too small for OMAPI */
    DISSECTOR_ASSERT_NOT_REACHED();
  }
  else if (tvb_reported_length_remaining(tvb, 0) < 24)
  {
    /* This is a startup message */
    ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN);

    col_set_str(pinfo->cinfo, COL_INFO, "Status message");
    proto_item_append_text(ti, ", Status message");

    return;
  }
  else if ( !(tvb_get_ntohl(tvb, 8) || tvb_get_ntohl(tvb, 12)) )
  {
    /* This is a startup message, and more */
    ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN);

    col_append_str(pinfo->cinfo, COL_INFO, "Status message");

    proto_item_append_text(ti, ", Status message");
  }

  ptvcursor_add(cursor, hf_omapi_auth_id, 4, ENC_BIG_ENDIAN);
  authlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor));
  ptvcursor_add(cursor, hf_omapi_auth_len, 4, ENC_BIG_ENDIAN);

  col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
      val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)"));

  proto_item_append_text(ti, ", Opcode: %s",
    val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)"));

  ptvcursor_add(cursor, hf_omapi_opcode, 4, ENC_BIG_ENDIAN);
  ptvcursor_add(cursor, hf_omapi_handle, 4, ENC_BIG_ENDIAN);
  ptvcursor_add(cursor, hf_omapi_id, 4, ENC_BIG_ENDIAN);
  ptvcursor_add(cursor, hf_omapi_rid, 4, ENC_BIG_ENDIAN);

  msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  while (msglength)
  {
    ptvcursor_add(cursor, hf_omapi_msg_name_len, 2, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_msg_name, msglength, ENC_ASCII|ENC_NA);
    msglength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor));
    ptvcursor_add(cursor, hf_omapi_msg_value_len, 4, ENC_BIG_ENDIAN);

    if (msglength == 0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string");
    }
    else if (msglength == (guint32)~0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value");
    }
    else
    {
      ptvcursor_add(cursor, hf_omapi_msg_value, msglength, ENC_ASCII|ENC_NA);
    }

    msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  }

  proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Message end tag");
  ptvcursor_advance(cursor, 2);

  objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  while (objlength)
  {
    ptvcursor_add(cursor, hf_omapi_obj_name_len, 2, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_obj_name, objlength, ENC_ASCII|ENC_NA);
    objlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor));
    ptvcursor_add(cursor, hf_omapi_obj_value_len, 4, ENC_BIG_ENDIAN);

    if (objlength == 0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string");
    }
    else if (objlength == (guint32)~0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value");
    }
    else
    {
      ptvcursor_add(cursor, hf_omapi_obj_value, objlength, ENC_NA);
    }

    objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  }

  proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Object end tag");
  ptvcursor_advance(cursor, 2);

  if (authlength > 0) {
    ptvcursor_add(cursor, hf_omapi_signature, authlength, ENC_NA);
  }
}
Пример #27
0
/* WiMax MAC to MAC protocol dissector */
static void dissect_m2m(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti = NULL;
	proto_item *m2m_item = NULL;
	proto_tree *m2m_tree = NULL;
	proto_tree *tlv_tree = NULL;
	gint burst_number = 0;
	gint length, offset = 0;
	gint tlv_count;
	gint tlv_type, tlv_len, tlv_offset, tlv_value;
	gint tlv_frag_type = 0;
	gint tlv_frag_number = 0;
	tlv_info_t m2m_tlv_info;
	gint hf;
	guint encoding;
	guint frame_number;
	int expected_len;

	/* display the M2M protocol name */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiMax");

	/* Clear out stuff in the info column */
	col_clear(pinfo->cinfo, COL_INFO);


	{	/* we are being asked for details */
		m2m_item = proto_tree_add_item(tree, proto_m2m, tvb, 0, -1, ENC_NA);
		m2m_tree = proto_item_add_subtree(m2m_item, ett_m2m);
		/* get the tvb reported length */
		length =  tvb_reported_length(tvb);
		/* add the size info */
		/*
		proto_item_append_text(m2m_item, " (%u bytes) - Packet Sequence Number,Number of TLVs", length);
		*/
		proto_item_append_text(m2m_item, " (%u bytes)", length);
		/* display the sequence number */
		proto_tree_add_item(m2m_tree, hf_m2m_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;
		/* display the TLV count */
		proto_tree_add_item(m2m_tree, hf_m2m_tlv_count, tvb, offset, 2, ENC_BIG_ENDIAN);
		tlv_count = tvb_get_ntohs(tvb, offset);
		offset += 2;
		/* parses the TLVs within current packet */
		while ( tlv_count > 0)
		{	/* init MAC to MAC TLV information */
			init_tlv_info(&m2m_tlv_info, tvb, offset);
			/* get the TLV type */
			tlv_type = get_tlv_type(&m2m_tlv_info);
			/* get the TLV length */
			tlv_len = get_tlv_length(&m2m_tlv_info);
			if(tlv_type == -1 || tlv_len > 64000 || tlv_len < 1)
			{	/* invalid tlv info */
				col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "M2M TLV error");
				/* display the invalid TLV in HEX */
				proto_tree_add_item(m2m_tree, hf_wimax_invalid_tlv, tvb, offset, (length - offset), ENC_NA);
				break;
			}
			/* get the TLV value offset */
			tlv_offset = get_tlv_value_offset(&m2m_tlv_info);
			/* display TLV type */
			ti = proto_tree_add_protocol_format(m2m_tree, proto_m2m, tvb, offset, (tlv_len + tlv_offset), "%s", val_to_str(tlv_type, tlv_name, "Unknown TLV"));
			/* add TLV subtree */
			tlv_tree = proto_item_add_subtree(ti, ett_m2m_tlv);
			/* update the offset */
			offset += tlv_offset;
			/* add the size info */
			/* decode TLV content (TLV value) */
			expected_len = 0;
			hf = 0;
			encoding = ENC_NA;
			switch (tlv_type)
			{
				case TLV_PROTO_VER:
					/* get the protocol version */
					tlv_value = tvb_get_guint8( tvb, offset );
					/* add the description */
					proto_item_append_text(ti, ": %d", tlv_value);
					hf = hf_m2m_value_protocol_vers_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_BURST_NUM:
					/* get the burst number */
					burst_number = tvb_get_guint8( tvb, offset );
					/* add the description */
					proto_item_append_text(ti, ": %d", burst_number);
					hf = hf_m2m_value_burst_num_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_FRAG_TYPE:
					/* add the description */
					tlv_frag_type = tvb_get_guint8( tvb, offset );
					proto_item_append_text(ti, ": %s", val_to_str(tlv_frag_type, tlv_frag_type_name, "Unknown"));
					hf = hf_m2m_value_frag_type_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_FRAG_NUM:
					/* get the fragment number */
					tlv_frag_number = tvb_get_guint8( tvb, offset );
					/* add the description */
					proto_item_append_text(ti, ": %d", tlv_frag_number);
					hf = hf_m2m_value_frag_num_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_PDU_BURST:
					/* display PDU Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the PDU Burst */
					pdu_burst_decoder(tree, tvb, offset, tlv_len, pinfo, burst_number, tlv_frag_type, tlv_frag_number);
					hf = hf_m2m_value_pdu_burst;
					encoding = ENC_NA;
				break;

				case TLV_FAST_FB:
					/* display the Fast Feedback Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the Fast Feedback Burst */
					fast_feedback_burst_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_fast_fb;
					encoding = ENC_NA;
				break;

				case TLV_FRAME_NUM:
					/* get the frame number */
					frame_number = tvb_get_ntoh24( tvb, offset );
					/* add the description */
					proto_tree_add_item(tlv_tree, hf_m2m_frame_number, tvb, offset, 3, ENC_BIG_ENDIAN);
					proto_item_append_text(ti, ": %d", frame_number);
				break;

				case TLV_FCH_BURST:
					/* add the description */
					tlv_value = tvb_get_ntoh24( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					/* decode and display the TLV FCH burst */
					fch_burst_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_fch_burst_uint24;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 3;
				break;

				case TLV_CDMA_CODE:
					/* add the description */
					tlv_value = tvb_get_ntoh24( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					/* decode and display the CDMA Code */
					cdma_code_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_cdma_code_uint24;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 3;
				break;

				case TLV_CRC16_STATUS:
					/* add the description */
					tlv_value = tvb_get_guint8( tvb, offset );
					proto_item_append_text(ti, ": %s", val_to_str(tlv_value, tlv_crc16_status, "Unknown"));
					hf = hf_m2m_value_crc16_status_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_BURST_POWER:
					/* add the description */
					tlv_value = tvb_get_ntohs( tvb, offset );
					proto_item_append_text(ti, ": %d", tlv_value);
					hf = hf_m2m_value_burst_power_uint16;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 2;
				break;

				case TLV_BURST_CINR:
					/* add the description */
					tlv_value = tvb_get_ntohs( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					hf = hf_m2m_value_burst_cinr_uint16;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 2;
				break;

				case TLV_PREAMBLE:
					/* add the description */
					tlv_value = tvb_get_ntohs( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					hf = hf_m2m_value_preamble_uint16;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 2;
				break;

				case TLV_HARQ_ACK_BURST:
					/* display the Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the HARQ ACK Bursts */
					harq_ack_bursts_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_harq_ack_burst_bytes;
					encoding = ENC_NA;
				break;

				case TLV_PHY_ATTRIBUTES:
					/* display the Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the PDU Burst Physical Attributes */
					physical_attributes_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_phy_attributes;
					encoding = ENC_NA;
				break;

				case TLV_EXTENDED_TLV:
					/* display the Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the Extended TLV */
					extended_tlv_decoder(pinfo);
				break;

				default:
					/* update the info column */
					col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Unknown TLV Type");
				break;
			}
			/* expand the TLV detail */
			if (hf) {
				if (offset - tlv_offset == expected_len) {
					proto_tree_add_tlv(&m2m_tlv_info, tvb, offset - tlv_offset, pinfo, tlv_tree, hf, encoding);
				} else {
					expert_add_info_format(pinfo, NULL, &ei_m2m_unexpected_length, "Expected length %d, got %d.", expected_len, offset - tlv_offset);
				}
			}
			offset += tlv_len;
			/* update tlv_count */
			tlv_count--;
		}
	}
}
Пример #28
0
static int
dissect_kt_play_script(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    guint32 next32, rnum, ksiz, vsiz, nsiz;
    gint new_offset, rec_start_offset;
    proto_item *ti;
    proto_item *pi;
    proto_tree *rec_tree;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    next32 = tvb_get_ntohl(tvb, new_offset);

    if (next32 == 0) {
        if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) {
            /* There's more data after the 32 bits. This is a request */
            pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST);
            PROTO_ITEM_SET_GENERATED(pi);

            proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32);
            new_offset += 4;

            nsiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_nsiz, tvb, new_offset, 4, nsiz);
            new_offset += 4;

            rnum = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum);
            new_offset += 4;

            proto_tree_add_item(tree, hf_kt_name, tvb, new_offset, nsiz, ENC_ASCII|ENC_NA);
            new_offset += nsiz;

            while (rnum > 0) {
                /* Create a sub-tree for each record */
                ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
                rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
                rec_start_offset = new_offset;

                ksiz = tvb_get_ntohl(tvb, new_offset);
                proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
                new_offset += 4;

                vsiz = tvb_get_ntohl(tvb, new_offset);
                proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz);
                new_offset += 4;

                proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
                if (kt_present_key_val_as_ascii) {
                    pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                    PROTO_ITEM_SET_GENERATED(pi);
                }
                new_offset += ksiz;

                proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA);
                if (kt_present_key_val_as_ascii) {
                    pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA);
                    PROTO_ITEM_SET_GENERATED(pi);
                }
                new_offset += vsiz;

                proto_item_set_len(ti, new_offset - rec_start_offset);
                rnum--;
            }
        } else {
            /* Nothing remaining after the 32 bits. This is a response with no records. */
            pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
            PROTO_ITEM_SET_GENERATED(pi);
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

            proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, next32);
            new_offset += 4;
        }
    } else { /* response - one or more records */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
        PROTO_ITEM_SET_GENERATED(pi);
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

        rnum = tvb_get_ntohl(tvb, new_offset);
        proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, rnum);
        new_offset += 4;

        while (rnum > 0) {
            /* Create a sub-tree for each record */
            ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
            rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
            rec_start_offset = new_offset;

            ksiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
            new_offset += 4;

            vsiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz);
            new_offset += 4;

            proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                PROTO_ITEM_SET_GENERATED(pi);
            }
            new_offset += ksiz;

            proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA);
                PROTO_ITEM_SET_GENERATED(pi);
            }
            new_offset += vsiz;

            proto_item_set_len(ti, new_offset - rec_start_offset);
            rnum--;
        }
    }

    return new_offset;
}
Пример #29
0
static int
parse_teredo_auth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
			int offset, e_teredohdr *teredoh)
{
	guint idlen, aulen;

	col_append_sep_str (pinfo->cinfo, COL_INFO, ", ",
					"Authentication header");

	teredoh->th_indtyp = 1;
	offset += 2;

	idlen = tvb_get_guint8(tvb, offset);
	teredoh->th_cidlen = idlen;
	offset++;

	aulen = tvb_get_guint8(tvb, offset);
	teredoh->th_authdlen = aulen;
	offset++;

	if (tree) {
		proto_item *ti;

		ti = proto_tree_add_item(tree, hf_teredo_auth, tvb, offset-4,
						13 + idlen + aulen, ENC_NA);
		tree = proto_item_add_subtree(ti, ett_teredo_auth);

		proto_tree_add_item(tree, hf_teredo_auth_idlen, tvb,
					offset - 2, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(tree, hf_teredo_auth_aulen, tvb,
					offset - 1, 1, ENC_BIG_ENDIAN);

		/* idlen is usually zero */
		if (idlen) {
			proto_tree_add_item(tree, hf_teredo_auth_id, tvb,
						offset, idlen, ENC_NA);
			offset += idlen;
		}

		/* aulen is usually zero */
		if (aulen) {
			proto_tree_add_item(tree, hf_teredo_auth_value, tvb,
						offset, aulen, ENC_NA);
			offset += aulen;
		}

		proto_tree_add_item(tree, hf_teredo_auth_nonce, tvb,
					offset, 8, ENC_NA);
		offset += 8;

		proto_tree_add_item(tree, hf_teredo_auth_conf, tvb,
					offset, 1, ENC_NA);
		offset++;
	}
	else
		offset += idlen + aulen + 9;

	tvb_memcpy(tvb, teredoh->th_nonce, offset - 9, 8);
	teredoh->th_conf = tvb_get_guint8(tvb, offset - 1);

	return offset;
}
Пример #30
0
static void
dissect_wai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Format of WAPI protocol packet in WAI authentication system

0      2      3         4         6         8        10        11      12
-------------------------------------------------------------------------------
| Ver. | Type | Subtype | Reserved | Length | packet  |  fragm. | flag | data |
|                                           | seq. no | seq. no |             |
|-----------------------------------------------------------------------------|
Figure 18 from [ref:1]
*/
#define WAI_MESSAGE_LENGTH 12   /*Length of all fields without 'Data' field*/
#define WAI_DATA_OFFSET    WAI_MESSAGE_LENGTH
    guint16        version;
    guint8         subtype;
    guint16        length;
    guint16        packet_num;
    guint8         fragment_num;
    guint8         flags;
    fragment_head *frag_msg;
    proto_tree    *wai_tree     = NULL;
    tvbuff_t      *next_tvb;
    tvbuff_t      *new_tvb;
    const gchar   *subtype_name = "Unknown type";

    length = tvb_get_ntohs(tvb, 6)-WAI_MESSAGE_LENGTH;
    subtype = tvb_get_guint8(tvb, 3);

    /* quick sanity check */
    if ((length != tvb_reported_length (tvb)-WAI_MESSAGE_LENGTH) ||
        (subtype > WAI_SUB_MULTICAST_ANNOUNCE_RESP)) {
        return;
    }

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "WAI");
    col_clear(pinfo->cinfo, COL_INFO);
    version = tvb_get_ntohs(tvb, 0);

    if (version == 1) {
        subtype_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type");
    }
    col_append_fstr(pinfo->cinfo, COL_INFO, "%s", subtype_name);

    /* Field lengths and offsets in WAI protocol described above */
    packet_num   = tvb_get_ntohs(tvb, 8);
    fragment_num = tvb_get_guint8(tvb, 10);
    flags        = tvb_get_guint8(tvb, 11);

    if (tree) {
        proto_item *wai_item;

        wai_item = proto_tree_add_item(tree, proto_wai, tvb, 0, -1, ENC_NA);

        proto_item_set_text (wai_item, "WAI Protocol (%s)",
                                val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type"));
        wai_tree = proto_item_add_subtree(wai_item, ett_wai);

        /* Field lengths and offsets in WAI protocol described above */
        proto_tree_add_item(wai_tree, hf_wai_version,   tvb, 0,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_type,      tvb, 2,  1, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_subtype,   tvb, 3,  1, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_reserved,  tvb, 4,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_length,    tvb, 6,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_seq,       tvb, 8,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_fragm_seq, tvb, 10, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_flag,      tvb, 11, 1, ENC_BIG_ENDIAN);
    }

    frag_msg =  fragment_add_seq_check (&wai_reassembly_table,
                                        tvb, WAI_DATA_OFFSET,
                                        pinfo,
                                        packet_num,
                                        NULL,
                                        fragment_num,
                                        length,
                                        flags);

    next_tvb = tvb_new_subset_remaining(tvb, WAI_DATA_OFFSET);

    /* Replace INFO column if message is fragmented and call data_handle */
    if (flags) {
        col_add_fstr(pinfo->cinfo, COL_INFO,
                     "Fragment (%d) of message, data not dissected", fragment_num);

        process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo,
                                 "Reassembled WAI", frag_msg, &wai_frag_items,
                                 NULL, wai_tree);

        call_dissector(data_handle, next_tvb, pinfo, tree);
    } else {
        /* If this is the last fragment of fragmented message, then reassamble and dissect
           otherwise only dissect */
        if (fragment_num > 0) {
            new_tvb = process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo,
                                               "Reassembled WAI", frag_msg, &wai_frag_items,
                                               NULL, wai_tree);

            if (new_tvb) {
                col_set_str(pinfo->cinfo, COL_INFO, "Last fragment of message, data dissected");
                col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", subtype_name);
                next_tvb=new_tvb;
                length = tvb_reported_length (next_tvb);
            }
        }
        /* dissect Data field of WAI packet */
        if (tree) {
            dissect_wai_data(next_tvb, wai_tree, subtype, length);
        }
    }

}