⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plugins-wimax-mac_hd_generic_decoder.c

📁 Intel的WIMAX代码,主要是mac层code
💻 C
📖 第 1 页 / 共 5 页
字号:
	guint mac_ht, mac_ec, mac_esf, mac_ci, mac_eks, mac_len, mac_cid, cid;
	guint ffb_grant_mgmt_subheader, packing_subheader, fragment_subheader;
	guint mesh_subheader;
	guint packing_length;
	guint32 mac_crc, calculated_crc;
	proto_item *parent_item = NULL;
	proto_item *generic_item = NULL;
	proto_tree *generic_tree = NULL;
	proto_item *child_item = NULL;
	proto_tree *child_tree = NULL;
	tvbuff_t *payload_tvb;
	tvbuff_t *data_pdu_tvb;
	fragment_data *payload_frag;
	gboolean first_arq_fb_payload = TRUE;

	dissector_handle_t mac_payload_handle;

	proto_mac_header_generic_decoder = proto_wimax;
	if (tree)
	{	/* we are being asked for details */
#ifdef DEBUG
		/* update the info column */
		if (check_col(pinfo->cinfo, COL_INFO))
		{
			col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "GMH");
		}
#endif
		/* Get the frame length */
		tvb_len =  tvb_reported_length(tvb);
		if (tvb_len < WIMAX_MAC_HEADER_SIZE)
		{	/* display the error message */
			generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, tvb_len, "Error: the size of Generic MAC Header tvb is too small! (%u bytes)", tvb_len);
			/* add subtree */
			generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
			/* display the Generic MAC Header in Hex */
			proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, tvb_len, FALSE);
			return;
		}
		/* get the parent */
		parent_item = proto_tree_get_parent(tree);
		/* add the MAC header info */
		proto_item_append_text(parent_item, " - Generic MAC Header");
		/* display MAC header message */
		generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, WIMAX_MAC_HEADER_SIZE, "Generic MAC Header (%u bytes)", WIMAX_MAC_HEADER_SIZE);
		/* add MAC header subtree */
		generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
		/* Decode and display the MAC header */
		/* Get the first byte */
		ubyte = tvb_get_guint8(tvb, offset);
		/* get the Header Type (HT) */
		mac_ht = ((ubyte & WIMAX_MAC_HEADER_GENERIC_HT_MASK)?1:0);
		/* get the Encryption Control (EC) */
		mac_ec = ((ubyte & WIMAX_MAC_HEADER_GENERIC_EC_MASK)?1:0);
		/* get the sub types */
		ffb_grant_mgmt_subheader = ((ubyte & GENERIC_SUB_TYPE_0)?1:0);
		packing_subheader = ((ubyte & GENERIC_SUB_TYPE_1)?1:0);
		fragment_subheader = ((ubyte & GENERIC_SUB_TYPE_2)?1:0);
		extended_type = ((ubyte & GENERIC_SUB_TYPE_3)?1:0);
		arq_fb_payload = ((ubyte & GENERIC_SUB_TYPE_4)?1:0);
		mesh_subheader = ((ubyte & GENERIC_SUB_TYPE_5)?1:0);
		/* Get the 2nd byte */
		ubyte = tvb_get_guint8(tvb, (offset+1));
		/* get the Extended subheader field (ESF) */
		mac_esf = ((ubyte & WIMAX_MAC_HEADER_GENERIC_ESF_MASK)?1:0);
		/* get the CRC indicator (CI) */
		mac_ci = ((ubyte & WIMAX_MAC_HEADER_GENERIC_CI_MASK)?1:0);
		/* get the Encryption key sequence (EKS) */
		mac_eks = ((ubyte & WIMAX_MAC_HEADER_GENERIC_EKS_MASK)>>4);
		/* get the MAC length */
		mac_len = (tvb_get_ntohs(tvb, (offset+1)) & WIMAX_MAC_HEADER_GENERIC_LEN);
		/* get the CID */
		mac_cid = tvb_get_ntohs(tvb, (offset+3));
		/* display the Header Type (HT) */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_ht, tvb, offset, 3, FALSE);
		/* display the Encryption Control (EC) */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_ec, tvb, offset, 3, FALSE);
		/* display the sub-types (Type) */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_type_5, tvb, offset, 3, FALSE);
		proto_tree_add_item(generic_tree, hf_mac_header_generic_type_4, tvb, offset, 3, FALSE);
		proto_tree_add_item(generic_tree, hf_mac_header_generic_type_3, tvb, offset, 3, FALSE);
		proto_tree_add_item(generic_tree, hf_mac_header_generic_type_2, tvb, offset, 3, FALSE);
		proto_tree_add_item(generic_tree, hf_mac_header_generic_type_1, tvb, offset, 3, FALSE);
		proto_tree_add_item(generic_tree, hf_mac_header_generic_type_0, tvb, offset, 3, FALSE);
		/* display the Extended sub-header Field (ESF) */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_esf, tvb, offset, 3, FALSE);
		/* display the CRC Indicator (CI) */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_ci, tvb, offset, 3, FALSE);
		/* display the Encryption Key Sequence (EKS) */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_eks, tvb, offset, 3, FALSE);
		/* display the reserved field */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_rsv, tvb, offset, 3, FALSE);
		/* display the length */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_len, tvb, offset, 3, FALSE);
		/* Decode and display the CID */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_cid, tvb, (offset+3), 2, FALSE);
		/* Decode and display the HCS */
		proto_tree_add_item(generic_tree, hf_mac_header_generic_hcs, tvb, (offset+5), 1, FALSE);
		/* get the frame length without MAC header */
		length = mac_len - WIMAX_MAC_HEADER_SIZE;
#ifdef DEBUG
		proto_item_append_text(parent_item, "tvb length=%u, mac length=%u, frame length=%u,", tvb_len, mac_len, length);
#endif
		/* set the offset for the frame */
		offset += WIMAX_MAC_HEADER_SIZE;
		/* the processing of the subheaders is order sensitive */
		/* do not change the order */

		if (mac_ec)
		{
			if (mac_ci)
			{
				if (length >= (gint)sizeof(mac_crc))
				{
					length -= sizeof(mac_crc);
				}
			}
			generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Encrypted PDU (%u bytes)", length);
			/* add payload subtree */
			generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
			proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, length, FALSE);
			goto check_crc;
		}

		/* if Extended subheader is present */
		if (mac_esf)
		{	/* add the Extended subheader info */
			proto_item_append_text(parent_item, ", Extended Subheader(s)");
			ret_length = extended_subheader_decoder(tvb_new_subset(tvb, offset, length, length), pinfo, tree);
			/* update the length and offset */
			length -= ret_length;
			offset += ret_length;
		}
		/* if Mesh subheader is present */
		if (mesh_subheader)
		{	/* update the info column */
			if (check_col(pinfo->cinfo, COL_INFO))
			{
				col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Mesh subhdr");
			}
			/* add the Mesh subheader info */
			proto_item_append_text(parent_item, ", Mesh Subheader");
			/* display Mesh subheader type */
			generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Mesh subheader (2 bytes)");
			/* add Mesh subheader subtree */
			generic_tree = proto_item_add_subtree(generic_item, ett_mac_mesh_subheader_decoder);
			/* decode and display the Mesh subheader */
			proto_tree_add_item(generic_tree, hf_mac_header_generic_mesh_subheader, tvb, offset, 2, FALSE);
			/* update the length and offset */
			length -= 2;
			offset += 2;
		}
		/* if Fast-feedback allocation (DL) subheader or Grant management (UL) subheader is present */
		if (ffb_grant_mgmt_subheader)
		{	/* check if it is downlink packet */
			if (is_down_link(&(pinfo->src)))
			{	/* Fast-feedback allocation (DL) subheader is present */
				/* update the info column */
				if (check_col(pinfo->cinfo, COL_INFO))
				{
					col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Fast-fb subhdr");
				}
				/* add the Fast-feedback subheader info */
				proto_item_append_text(parent_item, ", Fast-feedback Subheader");
				/* display Fast-feedback allocation subheader type */
				generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Fast-feedback allocation (DL) subheader (%u bytes)", length);
				/* add Fast-feedback allocation subheader subtree */
				generic_tree = proto_item_add_subtree(generic_item, ett_mac_fast_fb_subheader_decoder);
				proto_tree_add_item(generic_tree, hf_mac_header_generic_fast_fb_subhd_alloc_offset, tvb, offset, 1, FALSE);
				proto_tree_add_item(generic_tree, hf_mac_header_generic_fast_fb_subhd_fb_type, tvb, offset, 1, FALSE);
				/* update the length and offset */
				length -= 1;
				offset += 1;
			}
			else	/* Grant management (UL) subheader is present */
			{	/* update the info column */
				if (check_col(pinfo->cinfo, COL_INFO))
				{
					col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Grant mgmt subhdr");
				}
				/* add the Grant management subheader info */
				proto_item_append_text(parent_item, ", Grant Management Subheader");
				/* display Grant management subheader type */
				generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, 2, "Grant management (UL) subheader (2 bytes)");
				/* add Grant management subheader subtree */
				generic_tree = proto_item_add_subtree(generic_item, ett_mac_grant_mgmt_subheader_decoder);
				scheduling_service_type = get_service_type();
				switch (scheduling_service_type)
				{
				case SCHEDULE_SERVICE_TYPE_UGS:
					proto_item_append_text(generic_item, ": It looks like UGS is the correct Scheduling Service Type");
				break;
				case SCHEDULE_SERVICE_TYPE_EXT_RTPS:
					proto_item_append_text(generic_item, ": It looks like Extended rtPS is the correct Scheduling Service Type");
				break;
				case -1:
					proto_item_append_text(generic_item, ": Cannot determine the correct Scheduling Service Type");
				break;
				default:
					proto_item_append_text(generic_item, ": It looks like Piggyback Request is the correct Scheduling Service Type");
				break;
				}
				/* Create tree for Scheduling Service Type (UGS) */
				child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ugs_tree, tvb, offset, 2, FALSE);
				child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_si, tvb, offset, 2, FALSE);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_pm, tvb, offset, 2, FALSE);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_fli, tvb, offset, 2, FALSE);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_fl, tvb, offset, 2, FALSE);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_rsv, tvb, offset, 2, FALSE);

				/* Create tree for Scheduling Service Type (Extended RTPS) */
				child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ext_rtps_tree, tvb, offset, 2, FALSE);
				child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_pbr, tvb, offset, 2, FALSE);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_fli, tvb, offset, 2, FALSE);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_fl, tvb, offset, 2, FALSE);

				/* Create tree for Scheduling Service Type (Piggyback Request) */
				child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ext_pbr_tree, tvb, offset, 2, FALSE);
				child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
				proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_pbr, tvb, offset, 2, FALSE);

				/* update the length and offset */
				length -= 2;
				offset += 2;
			}
		}
		/* if Fragmentation subheader is present */
		if (fragment_subheader)
		{	/* update the info column */
			if (check_col(pinfo->cinfo, COL_INFO))
			{
				col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Frag subhdr");
			}
			/* add the Fragmentation subheader info */
			proto_item_append_text(parent_item, ", Frag Subheader");
			/* display Fragmentation subheader type */
			generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, ((arq_enabled|extended_type)?2:1), "Fragmentation subheader (%u bytes)", ((arq_enabled|extended_type)?2:1));
			/* add Fragmentation subheader subtree */
			generic_tree = proto_item_add_subtree(generic_item, ett_mac_frag_subheader_decoder);
			/* Get the fragment type */
			frag_type = (tvb_get_guint8(tvb, offset) & FRAGMENT_TYPE_MASK) >> 6;
			if (arq_fb_payload)
			{	/* get the sequence number */
				seq_number = (tvb_get_ntohs(tvb, offset) & SEQ_NUMBER_MASK_11) >> 3;
				/* decode and display the header */
				proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc_ext, tvb, offset, 2, FALSE);
				proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_bsn, tvb, offset, 2, FALSE);
				proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv_ext, tvb, offset, 2, FALSE);
				/* update the length and offset */
				length -= 2;
				offset += 2;
			}
			else
			{
				if (extended_type)
				{	/* get the sequence number */
					seq_number = (tvb_get_ntohs(tvb, offset) & SEQ_NUMBER_MASK_11) >> 3;
					/* decode and display the header */
					proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc_ext, tvb, offset, 2, FALSE);
					proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fsn_ext, tvb, offset, 2, FALSE);
					proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv_ext, tvb, offset, 2, FALSE);
					/* update the length and offset */
					length -= 2;
					offset += 2;
				}
				else
				{	/* get the sequence number */
					seq_number = (tvb_get_guint8(tvb, offset) & SEQ_NUMBER_MASK) >> 3;
					/* decode and display the header */
					proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc, tvb, offset, 1, FALSE);
					proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fsn, tvb, offset, 1, FALSE);
					proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv, tvb, offset, 1, FALSE);
					/* update the length and offset */
					length -= 1;
					offset += 1;
				}
			}
			frag_len = length;
		}
		else	/* ??? default fragment type: no fragment */
		{
			frag_type = NO_FRAG;
		}
		/* Decode the MAC payload if there is any */
		if (mac_ci)
		{
			if (length < (gint)sizeof(mac_crc))
			{	/* display error message */
				proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Error - the frame is too short (%u bytes)", length);
				return;
			}
			length -= sizeof(mac_crc);
		}
		while (length > 0)
		{
			frag_len = length; /* Can be changed by Packing subhdr */
			if (packing_subheader)
			{
				packing_length = decode_packing_subheader(tvb, pinfo, tree, length, offset, parent_item);
				length -= packing_length;
				offset += packing_length;
				generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, frag_len, "Data transport PDU (%u bytes)", frag_len);
				/* add payload subtree */
				generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
				proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, frag_len, FALSE);
			}
			/* defragment first if it is fragmented */
			if (frag_type == NO_FRAG)
			{	/* not fragmented payload */
				payload_tvb =  tvb_new_subset(tvb, offset, length, length);
				payload_length = length;
				new_payload_len = length;
			}
			else	/* fragmented payload */
			{	/* add the frag */
				/* Make sure cid will not match a previous packet with different data */
				for (i = 0; i < MAX_CID; i++)
				{
					if (cid_list[i] == mac_cid)
					{
						cid_base = i * (0xFFFFFFFF / MAX_CID);
						break;
					}
					if (cid_list[i] == 0)
					{
						cid_list[i] = mac_cid;
						cid_base = i * (0xFFFFFFFF / MAX_CID);
						break;
					}
				}
				cid_index = i;
				while (pinfo->fd->num > cid_adj_array_size)
				{
					cid_adj_array_size += 1024;
					cid_adj_array = g_realloc(cid_adj_array, sizeof(guint) * cid_adj_array_size);
					frag_num_array = g_realloc(frag_num_array, sizeof(guint8) * cid_adj_array_size);
					/* Clear the added memory */
					memset(&cid_adj_array[cid_adj_array_size - 1024], 0, sizeof(guint) * 1024);
				}
				if (first_gmh)
				{
					/* New cid_adjust for each packet with fragment(s) */
					cid_adjust[cid_index] += cid_vernier[cid_index];
					/* cid_vernier must always be 0 at start of packet. */
					cid_vernier[cid_index] = 0;
				}
				/* Create artificial sequence numbers. */
				frag_number[cid_index]++;
				if (frag_type == FIRST_FRAG)
				{
					frag_number[cid_index] = 0;
				}
				if (cid_adj_array[pinfo->fd->num])
				{
					/* We apparently just clicked on the packet again. */
					cid_adjust[cid_index] = cid_adj_array[pinfo->fd->num];
					/* Set the frag_number at start of packet. */
					if (first_gmh)
					{
						frag_number[cid_index] = frag_num_array[pinfo->fd->num];
					}
				} else {
					/* Save for next time we click on this packet. */
					cid_adj_array[pinfo->fd->num] = cid_adjust[cid_index];
					if (first_gmh)
					{
						frag_num_array[pinfo->fd->num] = frag_number[cid_index];
					}
				}
				/* Reset in case we stay in this while() loop to finish the packet. */
				first_gmh = FALSE;
				cid = cid_base + cid_adjust[cid_index] + cid_vernier[cid_index];
				/* Save address pointers. */
				save_src = pinfo->src;
				save_dst = pinfo->dst;
				/* Use dl_src and dl_dst in defrag. */
				pinfo->src = pinfo->dl_src;
				pinfo->dst = pinfo->dl_dst;
				payload_frag = fragment_add_seq(tvb, offset, pinfo, cid, payload_frag_table, frag_number[cid_index], frag_len, ((frag_type==LAST_FRAG)?0:1));
				/* Restore address pointers. */
				pinfo->src = save_src;
				pinfo->dst = save_dst;
				if (frag_type == LAST_FRAG)
				{
					/* Make sure fragment_add_seq() sees next one as a new frame. */
					cid_vernier[cid_index]++;
				}
				/* Don't show reassem packet until last frag. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -