コード例 #1
0
static void dissect_ismacryp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint ismacryp_version)
{
	guint set_version;           /* ISMACryp version used during dissection */
	proto_item *ismacryp_item;
	proto_tree *ismacryp_tree;
	proto_tree *ismacryp_message_tree;
	
	/* select and display ISMACryp version */
	if ((ismacryp_version!=version_type) && override_flag){ 
		/* override -> use manual preference setting */
		if (check_col(pinfo->cinfo, COL_INFO)){
			col_append_str(pinfo->cinfo, COL_INFO, " Manual version");
		}
		set_version = version_type; /* set to preference value */
	}
	else {
		set_version = ismacryp_version;
	}

	if (set_version == V11){
		if (check_col(pinfo->cinfo, COL_PROTOCOL))
			col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_11);
		/* display mode */
		if (pref_user_mode == FALSE){	
			if (check_col( pinfo->cinfo, COL_INFO))	
				col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",val_to_str(mode, modetypenames, "user mode"));
		}
		if (pref_user_mode == TRUE){	
			if ( check_col( pinfo->cinfo, COL_INFO))
				col_append_fstr(pinfo->cinfo, COL_INFO, ", %s","user mode");
		}
		user_mode = pref_user_mode;
	}
	if (set_version == V20){
		if (check_col(pinfo->cinfo, COL_PROTOCOL))
			col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_20);
		user_mode = TRUE;
		/* display mode */
		if (check_col( pinfo->cinfo, COL_INFO))	
			col_append_fstr(pinfo->cinfo, COL_INFO, ", %s","user mode");
	}
	/* select correct AU values depending on version & selected mode in preferences menu if not in user_mode */
	if (user_mode == TRUE){ /* use values set in preference menu */
		au_size_length = pref_au_size_length;
		au_index_length = pref_au_index_length;
		au_index_delta_length = pref_au_index_delta_length;
		cts_delta_length = pref_cts_delta_length;
		dts_delta_length = pref_dts_delta_length;
		random_access_indication = pref_random_access_indication;
		stream_state_indication = pref_stream_state_indication;				
	} /* end if user_mode == TRUE */
	if (user_mode == FALSE){
		switch (mode){
			case AAC_HBR_MODE:
				au_size_length = 13;
				au_index_length = 3;
				au_index_delta_length = 3;
				cts_delta_length = 0;
				dts_delta_length = 0;
				random_access_indication = FALSE;
				stream_state_indication = 0;
				break;
			case MPEG4_VIDEO_MODE:
				au_size_length = 0;
				au_index_length = 0;
				au_index_delta_length = 0;
				cts_delta_length = 0;
				dts_delta_length = 22;
				random_access_indication = TRUE;
				stream_state_indication = 0;
				break;
			case AVC_VIDEO_MODE:
				au_size_length = 0;
				au_index_length = 0;
				au_index_delta_length = 0;
				cts_delta_length = 0;
				dts_delta_length = 22;
				random_access_indication = TRUE;
				stream_state_indication = 0;
				break;
			default:
				DISSECTOR_ASSERT_NOT_REACHED();
				break;
		} /* end switch */
	} /* end if user_mode == FALSE */
	
	/* navigate through buffer */
	if (tree)
	{
		/* we are being asked for details */
		
		guint16 au_headers_length = 0; /* total length of AU headers */
		guint16 totalbits =0;          /* keeps track of total number of AU header bits treated (used to determine end of AU headers) */
		int deltabits = -1;            /* keeps track of extra bits per AU header treated (used to determine end of AU heafers ) */
		guint16 totalbit_offset = 0;   /* total offset in bits*/
		int nbpadding_bits = 0;        /* number of padding bits*/
		offset_struct s_offset;
		offset_struct* poffset;
		guint16 nbmessage_bytes = 0;   /*nb of message data bytes */
		s_offset.offset_bytes = 0;     /* initialise byte offset */
		s_offset.offset_bits = 0;      /* initialise bit offset */
		poffset = &s_offset;
		
		ismacryp_item = proto_tree_add_item(tree, proto_ismacryp, tvb, 0, -1, FALSE);
		ismacryp_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp);
		proto_item_append_text(tree, ", %s", "ismacryp packet"); /* add text to tree */	 	
		
		/* ismacryp_tree analysis */
		/* we are being asked for details */ 
		/* get total length of AU headers (first 2 bytes) */
		ismacryp_item = proto_tree_add_item(ismacryp_tree, hf_ismacryp_au_headers_length, 
						    tvb, poffset->offset_bytes, AU_HEADERS_LENGTH_SIZE, FALSE );
		proto_item_append_text(ismacryp_item, " (bits)"); /* add text to AU Header tree indicating length */
		au_headers_length=tvb_get_ntohs(tvb,poffset->offset_bytes); /* 2 byte au headers length */
		poffset->offset_bytes+=AU_HEADERS_LENGTH_SIZE;
		/* ADD HEADER(S) BRANCH  */
	
		/* AU Header loop */
		totalbits=(poffset->offset_bytes*8)+poffset->offset_bits;
		while( ((totalbits-8*AU_HEADERS_LENGTH_SIZE)<au_headers_length) && deltabits!=0 ) /* subtract AU headers length bits*/
		{
			poffset=dissect_auheader( tvb, poffset, pinfo, ismacryp_tree, set_version);
			deltabits=(poffset->offset_bytes*8)+poffset->offset_bits - totalbits; /* if zero this means no actual AU header so exit while loop */
			totalbits+=deltabits;	
		}
		/* reached end of AU Header(s) */
		/* sanity check if actual total AU headers length in bits i.e. totalbits is */
		/*  the same as expected AU headers length from 2 bytes at start of buffer */
		if ( (totalbits-8*AU_HEADERS_LENGTH_SIZE) != au_headers_length) /* something wrong */
		{
			proto_item_append_text(ismacryp_item, 
					       " Error - expected total AU headers size (%d bits) "
					       "does not match calculated size (%d bits) - check parameters!",
					       au_headers_length,(totalbits-8*AU_HEADERS_LENGTH_SIZE));
		}
		/* add padding if need to byte align */
		if (poffset->offset_bits!=0)
		{
			totalbit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
			nbpadding_bits = (8-poffset->offset_bits); /* number of padding bits for byte alignment */ 
			ismacryp_item = proto_tree_add_bits_item(ismacryp_tree, hf_ismacryp_padding,
								 tvb, totalbit_offset, nbpadding_bits , FALSE); /* padding bits */
			proto_item_append_text(ismacryp_item, ": Length=%d bits",nbpadding_bits); /* add padding info */
			add_bits(poffset, nbpadding_bits);
		}
		/* ADD MESSAGE BRANCH  */
		ismacryp_item = proto_tree_add_item( ismacryp_tree, hf_ismacryp_message, 
						     tvb, poffset->offset_bytes, -1, FALSE );
		ismacryp_message_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_message);
		proto_item_append_text(ismacryp_item, ", %s", "Encrypted data"); /* add text to Message tree */
		nbmessage_bytes = tvb_reported_length_remaining(tvb, poffset->offset_bytes);
		proto_item_append_text(ismacryp_item, ", Length= %d bytes", nbmessage_bytes ); /* add length of message */
	
		/* ismacryp message tree analysis (encrypted AUs) */
		if (ismacryp_message_tree)
		{	/* we are being asked for details */
			poffset->offset_bytes+= nbmessage_bytes;	/* */
		}  /* end message details */
		/* end ismacryp tree details */		
	} /* end if tree */
}	
コード例 #2
0
ファイル: packet-btobex.c プロジェクト: asriadi/wireshark
static int
dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo)
{
    proto_tree *hdrs_tree   = NULL;
    proto_tree *hdr_tree    = NULL;
    proto_item *hdr         = NULL;
    proto_item *handle_item;
    gint        item_length = -1;
    guint8      hdr_id, i;

    if (tvb_length_remaining(tvb, offset) > 0) {
        proto_item *hdrs;
        hdrs      = proto_tree_add_text(tree, tvb, offset, item_length, "Headers");
        hdrs_tree = proto_item_add_subtree(hdrs, ett_btobex_hdrs);
    }
    else {
        return offset;
    }

    while (tvb_length_remaining(tvb, offset) > 0) {
        hdr_id = tvb_get_guint8(tvb, offset);

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x40:  /* byte sequence */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x80:  /* 1 byte */
                item_length = 2;
                break;
            case 0xc0:  /* 4 bytes */
                item_length = 5;
                break;
        }

        hdr = proto_tree_add_text(hdrs_tree, tvb, offset, item_length, "%s",
                                  val_to_str_ext_const(hdr_id, &header_id_vals_ext, "Unknown"));
        hdr_tree = proto_item_add_subtree(hdr, ett_btobex_hdr);

        proto_tree_add_item(hdr_tree, hf_hdr_id, tvb, offset, 1, ENC_BIG_ENDIAN);

        offset++;

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                {
                    proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;

                    if ((item_length - 3) > 0) {
                        char *str;

                        display_unicode_string(tvb, hdr_tree, offset, &str);
                        proto_item_append_text(hdr_tree, " (\"%s\")", str);
                        col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", str);
                    }
                    else {
                        col_append_str(pinfo->cinfo, COL_INFO, " \"\"");
                    }

                    offset += item_length - 3;
                }
                break;
            case 0x40:  /* byte sequence */
                proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                handle_item = proto_tree_add_item(hdr_tree, hf_hdr_val_byte_seq, tvb, offset, item_length - 3, ENC_NA);

                if (((hdr_id == 0x46) || (hdr_id == 0x4a)) && (item_length == 19)) { /* target or who */
                    for(i=0; target_vals[i].strptr != NULL; i++) {
                        if (tvb_memeql(tvb, offset, target_vals[i].value, 16) == 0) {
                            proto_item_append_text(handle_item, ": %s", target_vals[i].strptr);
                            proto_item_append_text(hdr_tree, " (%s)", target_vals[i].strptr);
                            col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", target_vals[i].strptr);
                        }
                    }
                }

                if (!tvb_strneql(tvb, offset, "<?xml", 5))
                {
                    tvbuff_t* next_tvb = tvb_new_subset_remaining(tvb, offset);

                    call_dissector(xml_handle, next_tvb, pinfo, tree);
                }
                else if (is_ascii_str(tvb_get_ptr(tvb, offset,item_length - 3), item_length - 3))
                {
                    proto_item_append_text(hdr_tree, " (\"%s\")", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                    col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                }

                offset += item_length - 3;
                break;
            case 0x80:  /* 1 byte */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_byte, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset++;
                break;
            case 0xc0:  /* 4 bytes */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_long, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            default:
                break;
        }
    }

    return offset;
}
コード例 #3
0
static int
dissect_xtp_traffic_cntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		guint32 offset) {
	guint32 len = tvb_length_remaining(tvb, offset);
	guint32 start = offset;
	proto_item *top_ti;
	proto_tree *xtp_subtree;
	struct xtp_traffic_cntl tcntl[1];

	top_ti = proto_tree_add_text(tree, tvb, offset, len,
				"Traffic Control Segment");
	xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_tcntl);

	if (len < XTP_TRAFFIC_CNTL_LEN) {
		proto_item_append_text(top_ti,
				", bogus length(%u, must be at least %u)",
				len, XTP_TRAFFIC_CNTL_LEN);
		return 0;
	}

	/** parse **/
	/* rseq(8) */
	tcntl->rseq = tvb_get_ntohl(tvb, offset);
	tcntl->rseq <<= 32;
	tcntl->rseq += tvb_get_ntohl(tvb, offset+4);
	offset += 8;
	/* alloc(8) */
	tcntl->alloc = tvb_get_ntohl(tvb, offset);
	tcntl->alloc <<= 32;
	tcntl->alloc += tvb_get_ntohl(tvb, offset+4);
	offset += 8;
	/* echo(4) */
	tcntl->echo = tvb_get_ntohl(tvb, offset);
	offset += 4;
	/* rsvd(4) */
	tcntl->rsvd = tvb_get_ntohl(tvb, offset);
	offset += 4;
	/* xkey(8) */
	tcntl->xkey = tvb_get_ntohl(tvb, offset);
	tcntl->xkey <<= 32;
	tcntl->xkey += tvb_get_ntohl(tvb, offset+4);

	/** add summary **/
	col_append_fstr(pinfo->cinfo, COL_INFO,
			" Recv-Seq=%" G_GINT64_MODIFIER "u", tcntl->rseq);
	col_append_fstr(pinfo->cinfo, COL_INFO,
			" Alloc=%" G_GINT64_MODIFIER "u", tcntl->alloc);

	proto_item_append_text(top_ti,
			", Recv-Seq: %" G_GINT64_MODIFIER "u", tcntl->rseq);

	/** display **/
	offset = start;
	/* rseq(8) */
	proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_rseq,
			tvb, offset, 8, tcntl->rseq);
	offset += 8;
	/* alloc(8) */
	proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_alloc,
			tvb, offset, 8, tcntl->alloc);
	offset += 4;
	/* echo(4) */
	proto_tree_add_uint(xtp_subtree, hf_xtp_tcntl_echo,
			tvb, offset, 4, tcntl->echo);
	offset += 4;
	/* rsvd(4) */
	proto_tree_add_uint(xtp_subtree, hf_xtp_tcntl_rsvd,
			tvb, offset, 4, tcntl->rsvd);
	offset += 4;
	/* xkey(8) */
	proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_xkey,
			tvb, offset, 8, tcntl->xkey);
	offset += 8;

	return (offset - start);
}
コード例 #4
0
static
void dissect_pw_satop(tvbuff_t * tvb_original
					,packet_info * pinfo
					,proto_tree * tree
					,pwc_demux_type_t demux)
{
	const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/
	gint packet_size;
	gint payload_size;
	gint padding_size;
	pwc_packet_properties_t properties;
	enum {
		PAY_NO_IDEA = 0
		,PAY_LIKE_E1
		,PAY_LIKE_T1
		,PAY_LIKE_E3_T3
		,PAY_LIKE_OCTET_ALIGNED_T1
	} payload_properties;

	properties = PWC_PACKET_PROPERTIES_T_INITIALIZER;
	payload_properties = PAY_NO_IDEA;
	packet_size = tvb_reported_length_remaining(tvb_original, 0);
	/*
	 * FIXME
	 * "4" below should be replaced by something like "min_packet_size_this_dissector"
	 * Also call to dissect_try_cw_first_nibble() should be moved before this block
	 */
	if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */
	{
		if (tree)
		{
			proto_item  *item;
			item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
				"PW packet size (%d) is too small to carry sensible information"
				,(int)packet_size);
		}
		col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
		col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small");
		return;
	}

	switch (demux)
	{
	case PWC_DEMUX_MPLS:
		if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree))
		{
			return;
		}
		break;
	case PWC_DEMUX_UDP:
		break;
	default:
		DISSECTOR_ASSERT_NOT_REACHED();
		return;
	}

	/* check how "good" is this packet */
	/* also decide payload length from packet size and CW */
	properties = 0;
	if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/))
	{
		properties |= PWC_CW_BAD_BITS03;
	}
	if (0 != (tvb_get_guint8(tvb_original, 0) & 0x03 /*rsv*/))
	{
		properties |= PWC_CW_BAD_RSV;
	}
	if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/))
	{
		properties |= PWC_CW_BAD_FRAG;
	}
	{
		/* RFC4553:
		 * [...MAY be used to carry the length of the SAToP
		 * packet (defined as the size of the SAToP header + the payload
		 * size) if it is less than 64 bytes, and MUST be set to zero
		 * otherwise... ]
		 *
		 * Note that this differs from RFC4385's definition of length:
		 * [ If the MPLS payload is less than 64 bytes, the length field
		 * MUST be set to the length of the PW payload...]
		 *
		 * We will use RFC4553's definition here.
		 */
		int cw_len;
		gint payload_size_from_packet;

		cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f;
		payload_size_from_packet = packet_size - encaps_size;
		if (cw_len != 0)
		{
			gint payload_size_from_cw;
			payload_size_from_cw = cw_len - encaps_size;
			/*
			 * Assumptions for error case,
			 * will be overwritten if no errors found:
			 */
			payload_size = payload_size_from_packet;
			padding_size = 0;

			if (payload_size_from_cw < 0)
			{
				properties |= PWC_CW_BAD_PAYLEN_LT_0;
			}
			else if (payload_size_from_cw > payload_size_from_packet)
			{
				properties |= PWC_CW_BAD_PAYLEN_GT_PACKET;
			}
			else if (payload_size_from_packet >= 64)
			{
				properties |= PWC_CW_BAD_LEN_MUST_BE_0;
			}
			else /* ok */
			{
				payload_size = payload_size_from_cw;
				padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */
			}
		}
		else
		{
			payload_size = payload_size_from_packet;
			padding_size = 0;
		}
	}
	if (payload_size == 0)
	{
		/*
		 * As CW.L it indicates that PW payload is invalid, dissector should
		 * not blame packets with bad payload (including "bad" or "strange" SIZE of
		 * payload) when L bit is set.
		 */
		if (0 == (tvb_get_guint8(tvb_original, 0) & 0x08 /*L bit*/))
		{
			properties |= PWC_PAY_SIZE_BAD;
		}
	}

	/* guess about payload type */
	if (payload_size == 256)
	{
		payload_properties = PAY_LIKE_E1;
	}
	else if (payload_size == 192)
	{
		payload_properties = PAY_LIKE_T1;
	}
	else if (payload_size == 1024)
	{
		payload_properties = PAY_LIKE_E3_T3;
	}
	else if ((payload_size != 0) && (payload_size % 25 == 0))
	{
		payload_properties = PAY_LIKE_OCTET_ALIGNED_T1;
	}
	else
	{
		payload_properties = PAY_NO_IDEA; /*we do not have any ideas about payload type*/
	}

	/* fill up columns*/
	if (check_col(pinfo->cinfo, COL_PROTOCOL))
	{
		col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
	}
	if (check_col(pinfo->cinfo, COL_INFO))
	{
		col_clear(pinfo->cinfo, COL_INFO);
		if (properties & PWC_ANYOF_CW_BAD)
		{
			col_append_str(pinfo->cinfo, COL_INFO, "CW:Bad, ");
		}

		if (properties & PWC_PAY_SIZE_BAD)
		{
			col_append_str(pinfo->cinfo, COL_INFO, "Payload size:0 (Bad)");
		}
		else
		{
			col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size);
		}

		if (padding_size != 0)
		{
			col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size);
		}
	}


	if (tree)
	{
		proto_item* item;
		item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
		pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE);
		pwc_item_append_text_n_items(item,(int)payload_size,"octet");
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				proto_item* item2;
				tvb = tvb_new_subset(tvb_original, 0, PWC_SIZEOF_CW, PWC_SIZEOF_CW);
				item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA);
				pwc_item_append_cw(item2, tvb_get_ntohl(tvb, 0),FALSE);
				{
					proto_tree* tree3;
					tree3 = proto_item_add_subtree(item2, ett);
					{
						proto_item* item3;
						if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/
						{
							item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN);
							expert_add_info_format(pinfo, item3, PI_MALFORMED, PI_ERROR
								,"Bits 0..3 of Control Word must be 0");
						}

						proto_tree_add_item(tree3, hf_cw_l  , tvb, 0, 1, ENC_BIG_ENDIAN);
						proto_tree_add_item(tree3, hf_cw_r  , tvb, 0, 1, ENC_BIG_ENDIAN);

						item3 = proto_tree_add_item(tree3, hf_cw_rsv, tvb, 0, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_RSV)
						{
							expert_add_info_format(pinfo, item3, PI_MALFORMED, PI_ERROR
								,"RSV bits of Control Word must be 0");
						}

						item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_FRAG)
						{
							expert_add_info_format(pinfo, item3, PI_MALFORMED, PI_ERROR
								,"Fragmentation of payload is not allowed for SAToP");
						}

						item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_PAYLEN_LT_0)
						{
							expert_add_info_format(pinfo, item3, PI_MALFORMED, PI_ERROR
								,"Bad Length: too small, must be > %d"
								,(int)encaps_size);
						}
						if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET)
						{
							expert_add_info_format(pinfo, item3, PI_MALFORMED, PI_ERROR
								,"Bad Length: must be <= than PSN packet size (%d)"
								,(int)packet_size);
						}
						if (properties & PWC_CW_BAD_LEN_MUST_BE_0)
						{
							expert_add_info_format(pinfo, item3, PI_MALFORMED, PI_ERROR
								,"Bad Length: must be 0 if SAToP packet size (%d) is > 64"
								,(int)packet_size);
						}

						proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN);
					}
				}
			}
		}

		/* payload */
		if (properties & PWC_PAY_SIZE_BAD)
		{
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
				"SAToP payload: none found. Size of payload must be <> 0");
		}
		else if (payload_size == 0)
		{
			expert_add_info_format(pinfo, item, PI_UNDECODED, PI_NOTE,
				"SAToP payload: omitted to conserve bandwidth");
		}
		else
		{

			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				proto_item* item2;
				tvbuff_t* tvb;
				tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW, payload_size, payload_size);
				item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA);
				pwc_item_append_text_n_items(item2,(int)payload_size,"octet");
				{
					proto_tree* tree3;
					const char* s;
					switch(payload_properties)
					{
					case PAY_LIKE_E1:
						s = " (looks like E1)";
						break;
					case PAY_LIKE_T1:
						s = " (looks like T1)";
						break;
					case PAY_LIKE_E3_T3:
						s = " (looks like E3/T3)";
						break;
					case PAY_LIKE_OCTET_ALIGNED_T1:
						s = " (looks like octet-aligned T1)";
						break;
					case PAY_NO_IDEA:
					default:
						s = "";
						break;
					}
					proto_item_append_text(item2, "%s", s);
					tree3 = proto_item_add_subtree(item2, ett);
					call_dissector(data_handle, tvb, pinfo, tree3);
					item2 = proto_tree_add_int(tree3, hf_payload_l, tvb, 0, 0
						,(int)payload_size); /* allow filtering */
					PROTO_ITEM_SET_HIDDEN(item2);
				}
			}
		}

		/* padding */
		if (padding_size > 0)
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1);
				call_dissector(pw_padding_handle, tvb, pinfo, tree2);
			}
		}
	}
	return;
}
コード例 #5
0
/*Dissect the telegram*/
static int
dissect_esio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

/* Set up structures needed to add the protocol subtree and manage it */
       proto_item *ti, *et, *hi;
       proto_tree *esio_tree, *esio_header_tree, *esio_transfer_header_tree,
            *esio_data_tansfer_tree, *esio_data_tree;

       gint    i;
       gint    offset;
       guint8  esio_nbr_data_transfers;
       guint16 esio_telegram_type;
       guint16 esio_tlg_type;
       guint16 esio_transfer_length;
       guint32 esio_transfer_dest_id;
       guint32 esio_src_id;
       guint32 esio_dst_id;

/* does this look like an sbus pdu? */
       if (!is_esio_pdu(tvb)) {
              return 0;
       }

/* Make entries in Protocol column and Info column on summary display */
       col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESIO");
       col_clear(pinfo->cinfo, COL_INFO);
       esio_telegram_type = tvb_get_guint8(tvb,5);
       if (check_col(pinfo->cinfo, COL_INFO)) {
              switch (esio_telegram_type) {
                     case ESIO_TRANSFER:
                            esio_src_id = tvb_get_ntohl(tvb,16);
                            esio_nbr_data_transfers = tvb_get_guint8(tvb, 20);
                            esio_dst_id = tvb_get_ntohl(tvb,26);
                            col_add_fstr( pinfo->cinfo, COL_INFO,
                                          "Data transfer: Src ID: %d, Dst ID(s): %d",
                                          esio_src_id, esio_dst_id);
                            if (esio_nbr_data_transfers > 1) {
                                   col_append_fstr( pinfo->cinfo, COL_INFO,
                                                    " ...");
                            }
                            break;
                     case ESIO_STATUS:
                            esio_src_id = tvb_get_ntohl(tvb,16);
                            col_add_fstr( pinfo->cinfo, COL_INFO,
                                          "Status/diag telegram: Src ID: %d",
                                          esio_src_id);
                            break;
                     default:
                            /* All other telegrams */
                            col_set_str( pinfo->cinfo, COL_INFO,
                                         "Unknown telegram");
                            break;
              }

       }
/* create display subtree for the protocol */
       if (tree) {
              offset =0;
              ti = proto_tree_add_item(tree, proto_esio, tvb, offset, -1, ENC_NA);
              esio_tree = proto_item_add_subtree(ti, ett_esio);
/*Add subtree for Ether-S-I/O header*/
              et = proto_tree_add_text(esio_tree, tvb, offset, 12, "Ether-S-I/O header");
              esio_header_tree = proto_item_add_subtree(et, ett_esio_header);
              offset +=4; /*first four bytes are "ESIO"*/
/* add items to the Ether-S-I/O header subtree*/
              esio_tlg_type = tvb_get_ntohs(tvb,offset);
              proto_tree_add_item(esio_header_tree,
                                  hf_esio_type, tvb, offset, 2, ENC_BIG_ENDIAN);
              offset += 2;
              proto_tree_add_item(esio_header_tree,
                                  hf_esio_version, tvb, offset, 2, ENC_BIG_ENDIAN);
              offset += 2;
              proto_tree_add_item(esio_header_tree,
                                  hf_esio_length, tvb, offset, 2, ENC_BIG_ENDIAN);
              offset += 2;
              proto_tree_add_item(esio_header_tree,
                                  hf_esio_transaction_id, tvb, offset, 2, ENC_BIG_ENDIAN);
              offset += 2;
              switch (esio_tlg_type) {
                     case ESIO_TRANSFER:
                            /*Add subtree for Ether-S-I/O header*/
                            et = proto_tree_add_text(esio_tree, tvb, offset, 12, "Transfer header");
                            esio_transfer_header_tree = proto_item_add_subtree(et, ett_esio_transfer_header);
                            proto_tree_add_item(esio_transfer_header_tree,
                                                hf_esio_tlg_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                            offset += 4;
                            proto_tree_add_item(esio_transfer_header_tree,
                                                hf_esio_src_stn_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                            offset += 4;
                            esio_nbr_data_transfers = tvb_get_guint8(tvb,offset);
                            proto_tree_add_item(esio_transfer_header_tree,
                                                hf_esio_data_nbr, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;
                            proto_tree_add_item(esio_transfer_header_tree,
                                                hf_esio_data_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;
                            for (i=((esio_nbr_data_transfers)); i>0; i--) {
                                   /*Add subtree(s) for Ether-S-I/O data transfers*/
                                   esio_transfer_dest_id = tvb_get_ntohl(tvb,(offset+4));
                                   esio_transfer_length = tvb_get_ntohs(tvb,(offset+8));
                                   et = proto_tree_add_text(esio_tree, tvb, offset,
                                                            (esio_transfer_length + 10), "Data transfer to ID: %d ",
                                                            esio_transfer_dest_id);
                                   esio_data_tansfer_tree = proto_item_add_subtree(et, ett_esio_transfer_data);
                                   proto_tree_add_item(esio_data_tansfer_tree,
                                                       hf_esio_data_transfer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                                   offset += 4;
                                   proto_tree_add_item(esio_data_tansfer_tree,
                                                       hf_esio_data_dest_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                                   offset += 4;
                                   proto_tree_add_item(esio_data_tansfer_tree,
                                                       hf_esio_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                                   offset += 2;
                                   /*here comes the data*/
                                   et = proto_tree_add_text(esio_data_tansfer_tree, tvb, offset,
                                                            esio_transfer_length, "Data bytes ");
                                   esio_data_tree = proto_item_add_subtree(et, ett_esio_data);
                                   for (i=((esio_transfer_length)); i>0; i--) {
                                          proto_tree_add_item(esio_data_tree,
                                                              hf_esio_data, tvb, offset,
                                                              1, ENC_BIG_ENDIAN);
                                          offset += 1;
                                   }
                            }
                            break;
                     case ESIO_STATUS:
                            proto_tree_add_item(esio_tree,
                                                hf_esio_sts_type, tvb, offset, 2, ENC_BIG_ENDIAN);
                            offset += 2;
                            proto_tree_add_item(esio_tree,
                                                hf_esio_sts_size, tvb, offset, 2, ENC_BIG_ENDIAN);
                            offset += 2;
                            proto_tree_add_item(esio_tree,
                                                hf_esio_src_stn_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                            offset += 4;
                            proto_tree_add_item(esio_tree,
                                                hf_esio_rio_sts, tvb, offset,
                                                1, ENC_BIG_ENDIAN);
                            offset += 1;
                            hi = proto_tree_add_item(esio_tree,
                                                     hf_esio_rio_tlgs_lost, tvb, offset,
                                                     1, ENC_BIG_ENDIAN);
                            expert_add_info_format(pinfo, hi, PI_SEQUENCE, PI_NOTE,
                                                   "Telegram(s) lost");
                            offset += 1;
                            proto_tree_add_item(esio_tree,
                                                hf_esio_rio_diag, tvb, offset,
                                                1, ENC_BIG_ENDIAN);
                            offset += 1;
                            proto_tree_add_item(esio_tree,
                                                hf_esio_rio_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;
                            break;
                     default:
                            break;
              }
       } /*end of tree*/
       return tvb_length(tvb);
/*End of dissect_sbus*/
}
コード例 #6
0
ファイル: packet-icep.c プロジェクト: MultipathDTLS/wireshark
/*
 * This function dissects an "Ice params", adds hf(s) to "tree" and returns consumed
 * bytes in "*consumed", if errors "*consumed" is -1.
 */
static void dissect_ice_params(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
                               guint32 offset, gint32 *consumed)
{
    /*  p. 612, chapter 23.3.2 and p. 587, 23.2.2:
     *  "params" is an Encapsulation
     *
     *  struct Encapsulation {
     *      int size;
     *      byte major;
     *      byte minor;
     *      //(size - 6) bytes of data
     *  }
     *
     */

    gint32 size = 0;
    gint tvb_data_remained = 0;

    (*consumed) = 0;

    /* check first 6 bytes */
    if ( !tvb_bytes_exist(tvb, offset, ICEP_MIN_PARAMS_SIZE) ) {

        expert_add_info(pinfo, item, &ei_icep_params_missing);
        col_append_str(pinfo->cinfo, COL_INFO, " (params missing)");

        (*consumed) = -1;
        return;
    }

    /* get the size */
    size = tvb_get_letohl(tvb, offset);

    DBG1("params.size --> %d\n", size);

    if ( size < ICEP_MIN_PARAMS_SIZE ) {

        expert_add_info(pinfo, item, &ei_icep_params_size);
        col_append_str(pinfo->cinfo, COL_INFO, " (params size too small)");

        (*consumed) = -1;
        return;
    }

    if ( tree ) {

        proto_tree_add_item(tree, hf_icep_params_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        offset += 4;
        (*consumed) += 4;

        proto_tree_add_item(tree, hf_icep_params_major, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset += 1;
        (*consumed)++;

        proto_tree_add_item(tree, hf_icep_params_minor, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset += 1;
        (*consumed)++;

    } else {
        /* skip size, major, minor */
        offset += 6;
        (*consumed) += 6;
    }

    if( size == ICEP_MIN_PARAMS_SIZE ) /* no encapsulatd data present, it's normal */
        return;

    /* check if I got all encapsulated data */
    tvb_data_remained = tvb_reported_length_remaining(tvb, offset);

    if ( tvb_data_remained < ( size - ICEP_MIN_PARAMS_SIZE ) ) {

        expert_add_info_format(pinfo, item, &ei_icep_params_encapsulated, "missing encapsulated data (%d bytes)", size - ICEP_MIN_PARAMS_SIZE - tvb_data_remained);

        col_append_fstr(pinfo->cinfo, COL_INFO,
                    " (missing encapsulated data (%d bytes))",
                    size - ICEP_MIN_PARAMS_SIZE - tvb_data_remained);

        (*consumed) = -1;
        return;
    }

    /* encapsulated params */
    proto_tree_add_item(tree, hf_icep_params_encapsulated, tvb, offset, (size - ICEP_MIN_PARAMS_SIZE), ENC_NA);

    (*consumed) += (size - ICEP_MIN_PARAMS_SIZE);
}
コード例 #7
0
ファイル: packet-icep.c プロジェクト: MultipathDTLS/wireshark
static void dissect_icep_batch_request(tvbuff_t *tvb, guint32 offset,
                                        packet_info *pinfo, proto_tree *icep_tree, proto_item* icep_item)
{
    /*  p. 613, chapter 23.3.3
     *  A batch request msg is a "sequence" of batch request
     *  Sequence is Size + elements
     *
     *  struct BatchRequestData {
     *   Ice::Identity id;
     *   Ice::StringSeq facet;
     *   string operation;
     *   byte mode;
     *   Ice::Context context;
     *   Encapsulation params;
     *  }
     *
     * NOTE!!!:
     * The only real implementation of the Ice protocol puts a 32bit count in front
     * of a Batch Request, *not* an Ice::Sequence (as the standard says). Basically the
     * same people wrote both code and standard so I'll follow the code.
     */

    proto_item *ti = NULL;
    proto_tree *icep_sub_tree = NULL;
    guint32 num_reqs = 0;
    guint32 i = 0;
    gint32 consumed = 0;

    DBG0("dissect batch request\n");

    /* check for first 4 byte */
    if ( !tvb_bytes_exist(tvb, offset, 4) ) {

        expert_add_info_format(pinfo, icep_item, &ei_icep_length, "counter of batch requests missing");
        col_append_str(pinfo->cinfo, COL_INFO, " (counter of batch requests missing)");
        return;
    }

    num_reqs = tvb_get_letohl(tvb, offset);
    offset += 4;

    DBG1("batch_requests.count --> %d\n", num_reqs);

    if ( num_reqs > icep_max_batch_requests ) {

        expert_add_info_format(pinfo, icep_item, &ei_icep_batch_requests, "too many batch requests (%d)", num_reqs);

        col_append_fstr(pinfo->cinfo, COL_INFO, " (too many batch requests, %d)", num_reqs);
        return;
    }

    if ( num_reqs == 0 ) {

        proto_tree_add_expert(icep_tree, pinfo, &ei_icep_empty_batch, tvb, offset, -1);
        col_append_str(pinfo->cinfo, COL_INFO, " (empty batch requests sequence)");

        return;
    }


    col_append_str(pinfo->cinfo, COL_INFO, ":");

    /*
     * process requests
     */

    for ( i = 0; i < num_reqs; i++ ) {

        DBG1("looping through sequence of batch requests, loop #%d\n", i);

        /* create display subtree for this message type */

        icep_sub_tree = proto_tree_add_subtree_format(icep_tree, tvb, offset, -1,
                         ett_icep_msg, &ti, "Batch Request Message Body: #%d", i);

        if (i != 0) {
            col_append_str(pinfo->cinfo, COL_INFO, ",");
        }

        dissect_icep_request_common(tvb, offset, pinfo, icep_sub_tree, ti, &consumed);

        if ( consumed == -1 )
            return;

        if ( icep_tree && ti )
            proto_item_set_len(ti, consumed);

        offset += consumed;
        DBG1("consumed --> %d\n", consumed);
    }
}
コード例 #8
0
/* Code to actually dissect the packets */
static void
dissect_csm_encaps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item  *ti, *subitem;
    proto_tree  *csm_encaps_tree = NULL;
    proto_tree  *csm_encaps_control_tree = NULL;
    guint16      function_code, channel, class_type;
    guint        control, type, sequence, length;
    guint        i;
    gboolean     show_error_param= FALSE;
    const gchar *str_function_name;


    function_code = tvb_get_letohs(tvb, 10);
    control = tvb_get_guint8(tvb, 3);

    class_type = tvb_get_guint8(tvb, 9);
    class_type = class_type<<8;
    class_type|= tvb_get_guint8(tvb, 8);

    type     = tvb_get_guint8(tvb, 8);
    sequence = tvb_get_guint8(tvb, 2);
    length   = tvb_get_guint8(tvb, 6);
    channel  = tvb_get_ntohs(tvb, 4);


    if (CSM_ENCAPS_CTRL_ACK&control)
        show_error_param= FALSE;
    else
    {
        if (csm_to_host(function_code, class_type)) /* exclusive messages to host */
            show_error_param= FALSE;
        else
        {
            if (type == CSM_ENCAPS_TYPE_RESPONSE)
                show_error_param= TRUE;
            else
                show_error_param= FALSE;
        }
    }


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

    col_clear(pinfo->cinfo, COL_INFO);


    if (CSM_ENCAPS_CTRL_ACK&control)
    {
        if (CSM_ENCAPS_CTRL_ACK_TO_HOST&control)
            col_append_fstr(pinfo->cinfo, COL_INFO,
                            "<-- ACK                                 Ch: 0x%04X, Seq: %2d (To Host)",
                            channel, sequence);
        else
            col_append_fstr(pinfo->cinfo, COL_INFO,
                            "--> ACK                                 Ch: 0x%04X, Seq: %2d (From Host)",
                            channel, sequence);
    }
    else
    {
        str_function_name= csm_fc(function_code, class_type);
        if ((type == CSM_ENCAPS_TYPE_RESPONSE) || (csm_to_host(function_code, class_type)))
            col_append_fstr(pinfo->cinfo, COL_INFO,
                            "<-- %-35s Ch: 0x%04X, Seq: %2d (To Host)",
                            str_function_name, channel, sequence);
        else
            col_append_fstr(pinfo->cinfo, COL_INFO,
                            "--> %-35s Ch: 0x%04X, Seq: %2d (From Host)",
                            str_function_name, channel, sequence);
    }


    if (tree) {
        ti = proto_tree_add_item(tree, proto_csm_encaps, tvb, 0, -1, ENC_NA);
        csm_encaps_tree = proto_item_add_subtree(ti, ett_csm_encaps);




        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_opcode, tvb, 0, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_seq, tvb, 2, 1, ENC_BIG_ENDIAN);

        subitem = proto_tree_add_uint(csm_encaps_tree, hf_csm_encaps_ctrl, tvb, 3, 1, control);
        csm_encaps_control_tree = proto_item_add_subtree(subitem, ett_csm_encaps_control);

        proto_tree_add_boolean(csm_encaps_control_tree, hf_csm_encaps_ctrl_ack, tvb, 3, 1, control);
            proto_tree_add_boolean(csm_encaps_control_tree, hf_csm_encaps_ctrl_ack_suppress, tvb, 3, 1, control);
        proto_tree_add_boolean(csm_encaps_control_tree, hf_csm_encaps_ctrl_endian, tvb, 3, 1, control);

        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_channel, tvb, 4, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_length, tvb, 6, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_index, tvb, 7, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_class, tvb, 9, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_type, tvb, 8, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_function_code, tvb, 10, 2, ENC_LITTLE_ENDIAN);

        i=6;

        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_reserved, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length)
        {
            if (show_error_param)
                proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param_error, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN);
            else
                proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param1, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN);
            i+=2;
        }
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param2, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param3, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param4, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param5, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param6, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param7, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param8, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param9, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param10, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param11, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param12, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param13, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param14, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param15, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param16, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param17, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param18, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param19, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param20, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param21, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param22, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param23, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param24, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param25, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param26, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param27, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param28, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param29, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param30, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param31, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param32, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param33, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param34, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param35, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param36, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param37, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param38, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param39, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;
        if (i<length) proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param40, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN); i+=2;

        for (; i<length; i+=2)
            proto_tree_add_item(csm_encaps_tree, hf_csm_encaps_param, tvb, 12 + i-6, 2, ENC_LITTLE_ENDIAN);
    }
}
コード例 #9
0
static void
dissect_openvpn_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  gint           offset        = 0;
  gboolean       protocol_tcp;
  gboolean       tls_auth;
  guint          openvpn_keyid;
  guint          openvpn_opcode;
  guint32        msg_mpid      = -1;
  guint32        msg_sessionid = -1;
  guint8         openvpn_predict_tlsauth_arraylength;
  proto_item    *ti            = NULL;
  proto_item    *ti2;
  proto_item    *ti3;
  proto_tree    *openvpn_tree  = NULL;
  proto_tree    *packetarray_tree;
  proto_tree    *type_tree;
  guint32        msg_length_remaining;
  gboolean       msg_lastframe;
  fragment_head *frag_msg;
  tvbuff_t      *new_tvb;
  gboolean       save_fragmented;

  /* check whether we are dealing with tcp or udp encapsulation */
  protocol_tcp = (pinfo->ipproto == IP_PROTO_TCP ? TRUE : FALSE);

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

  /* we are being asked for details */
  if (tree) {
    ti = proto_tree_add_item(tree, proto_openvpn, tvb, 0, -1, ENC_NA);
    openvpn_tree = proto_item_add_subtree(ti, ett_openvpn);
  }

  /* openvpn packet length field is only present in tcp packets */
  if (protocol_tcp) {
    proto_tree_add_item(openvpn_tree, hf_openvpn_plen, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;
  }

  /* read opcode and write to info column */
  openvpn_opcode = tvb_get_bits8(tvb, offset*8, 5);
  col_append_fstr(pinfo->cinfo, COL_INFO, "MessageType: %s",
                  val_to_str_const(openvpn_opcode, openvpn_message_types, "Unknown Messagetype"));


  openvpn_keyid = tvb_get_bits8(tvb, offset*8 + 5, 3);
  proto_item_append_text(ti, ", Opcode: %s, Key ID: %d",
                         val_to_str(openvpn_opcode, openvpn_message_types, "Unknown (0x%02x)"),
                         openvpn_keyid);

  ti2 = proto_tree_add_item(openvpn_tree, hf_openvpn_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
  proto_item_append_text(ti2, " %s", "[opcode/key_id]");

  type_tree = proto_item_add_subtree(ti2, ett_openvpn_type);
  proto_tree_add_item(type_tree, hf_openvpn_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(type_tree, hf_openvpn_keyid, tvb, offset, 1, ENC_BIG_ENDIAN);
  offset += 1;

  /* if we have a P_CONTROL or P_ACK packet */
  if (openvpn_opcode != P_DATA_V1) {
    /* read sessionid */
    msg_sessionid = tvb_get_bits32(tvb, offset*8+32, 32, ENC_BIG_ENDIAN);
    proto_tree_add_item(openvpn_tree, hf_openvpn_sessionid, tvb, offset, 8, ENC_BIG_ENDIAN);
    offset += 8;

    /* tls-auth detection (this can be overridden by preferences */
    openvpn_predict_tlsauth_arraylength = tvb_get_guint8(tvb, offset);
    /* if the first 4 bytes that would, if tls-auth is used, contain part of the hmac,
       lack entropy, we asume no tls-auth is used */
    if (pref_tls_auth_override == FALSE) {
      if ((openvpn_opcode != P_DATA_V1)
          && (openvpn_predict_tlsauth_arraylength > 0)
          && check_for_valid_hmac(tvb_get_ntohl(tvb, offset))) {
        tls_auth = TRUE;
      } else {
        tls_auth = FALSE;
      }
    } else {
      tls_auth = pref_tls_auth;
    }

    if (tls_auth == TRUE) {
      proto_tree_add_item(openvpn_tree, hf_openvpn_hmac, tvb, offset, tls_auth_hmac_size, ENC_NA);
      offset += tls_auth_hmac_size;

      if (tvb_length_remaining(tvb, offset) >= 8) {
        proto_tree_add_item(openvpn_tree, hf_openvpn_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        if (pref_long_format) {
          proto_tree_add_item(openvpn_tree, hf_openvpn_net_time, tvb, offset, 4, ENC_BIG_ENDIAN);
          offset += 4;
        }
      }
    }

    if (tvb_length_remaining(tvb, offset) >= 1) {
      /* read P_ACK packet-id array length */
      gint pid_arraylength = tvb_get_guint8(tvb, offset);
      gint i;
      proto_tree_add_item(openvpn_tree, hf_openvpn_mpid_arraylength, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      if (pid_arraylength > 0) {

        ti3 = proto_tree_add_text(openvpn_tree, tvb, offset, 0, "Packet-ID Array");
        packetarray_tree = proto_item_add_subtree(ti3, ett_openvpn_packetarray);
        for (i = 0; i < pid_arraylength; i++) {
          proto_tree_add_item(packetarray_tree, hf_openvpn_mpid_arrayelement, tvb, offset, 4, ENC_BIG_ENDIAN);
          offset += 4;
        }

        if (tvb_length_remaining(tvb, offset) >= 8) {
          proto_tree_add_item(openvpn_tree, hf_openvpn_rsessionid, tvb, offset, 8, ENC_BIG_ENDIAN);
          offset += 8;
        }
      }
    }

    /* if we have a P_CONTROL packet */
    if (openvpn_opcode != P_ACK_V1) {
      /* read Message Packet-ID */
      if (tvb_length_remaining(tvb, offset) >= 4) {
        msg_mpid = tvb_get_bits32(tvb, offset*8, 32, ENC_BIG_ENDIAN);
        proto_tree_add_item(openvpn_tree, hf_openvpn_mpid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
      }
    }
  }

  /* if we have more data left, determine wht to do */
  msg_length_remaining = tvb_length_remaining(tvb, offset);

  if (msg_length_remaining == 0) {
    return;
  }

  if (openvpn_opcode != P_CONTROL_V1) {
    proto_tree *data_tree;
    ti2 = proto_tree_add_text(openvpn_tree, tvb, offset, -1, "Data (%d bytes)",
                              tvb_length_remaining(tvb, offset));

    data_tree = proto_item_add_subtree(ti2, ett_openvpn_data);
    proto_tree_add_item(data_tree, hf_openvpn_data, tvb, offset, -1, ENC_NA);
    return;
  }

  /* Try to reassemble */

  /* an ordinary openvpn control packet contains 100 bytes only if it is part of a
     fragmented message and is not the last fragment of the current transmission.
     Note that the tvb contains exactly one openvpn PDU:
     UDP: by definition;
     TCP: beacuse of the use of tcp_dissect_pdus().
  */
  if (msg_length_remaining == 100) {
    msg_lastframe = FALSE;
  } else {
    msg_lastframe = TRUE;
  }

  save_fragmented = pinfo->fragmented;
  pinfo->fragmented = TRUE;

  frag_msg = fragment_add_seq_next(
    &msg_reassembly_table,
    tvb,
    offset,
    pinfo,
    msg_sessionid,         /* ID for fragments belonging together */
    NULL,
    msg_length_remaining,  /* fragment length - to the end        */
    !(msg_lastframe));     /* More fragments ?                    */

  /* show "data" fragment on tree unless "reassembled" message has just one part.       */
  /* i.e., show if ("not reassembled") or ("reassembled" and "has multiple fragments")  */
  if ((frag_msg == NULL) || (frag_msg->next != NULL)) {
    proto_tree *data_tree;
    ti2 = proto_tree_add_text(openvpn_tree, tvb, offset, -1, "Message fragment (%d bytes)",
                              tvb_length_remaining(tvb, offset));

    data_tree = proto_item_add_subtree(ti2, ett_openvpn_data);
    proto_tree_add_item(data_tree, hf_openvpn_fragment_bytes, tvb, offset, -1, ENC_NA);
    }

  new_tvb = NULL;
  if (frag_msg) {
    if (msg_lastframe) { /* Reassembled */
      new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Message",
                                         frag_msg, &openvpn_frag_items, NULL, openvpn_tree);
      if (frag_msg->next != NULL) { /* multiple frags ? */
        col_append_fstr(pinfo->cinfo, COL_INFO, " (Message Reassembled "); /* overwritten by next dissector */
      }

    } else { /* Not last packet of reassembled Short Message */
      col_append_fstr(pinfo->cinfo, COL_INFO, " (Message fragment %d) ", msg_mpid);
      if (pinfo->fd->num != frag_msg->reassembled_in) {
        /* Add a "Reassembled in" link if not reassembled in this frame */
        proto_tree_add_uint(openvpn_tree, hf_openvpn_reassembled_in,
                            tvb, 0, 0, frag_msg->reassembled_in);
      }
    }
  } /* if (frag_msg) */

  pinfo->fragmented = save_fragmented;

  /* Now see if we need to call subdissector.
     new_tvb is non-null if we "reassembled* a message (even just one fragment) */

  if (new_tvb) {
    /* call SSL/TLS dissector if we just processed the last fragment */
    call_dissector(ssl_handle, new_tvb, pinfo, tree);
  }
}
コード例 #10
0
ファイル: packet-btsap.c プロジェクト: RayHightower/wireshark
static gint
dissect_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree,
        proto_tree *tree, gint offset, guint8 *parameter, gint *parameter_offset)
{
    proto_item  *parameter_item;
    proto_item  *pitem;
    proto_tree  *ptree;
    tvbuff_t    *next_tvb;
    guint        parameter_id;
    guint        parameter_length;
    guint        parameter_padding_length;
    guint        padding_length;
    guint        length;
    guint16      max_msg_size;
    guint8       connection_status;
    guint8       result_code;
    guint8       disconnection_type;
    guint8       status_change;
    guint8       transport_protocol;

    parameter_id = tvb_get_guint8(tvb, offset);
    parameter_length = tvb_get_ntohs(tvb, offset + 2);
    parameter_padding_length = parameter_length % 4;
    if (parameter_padding_length > 0)
        parameter_padding_length = 4 - parameter_padding_length;

    parameter_item = proto_tree_add_none_format(tree, hf_btsap_parameter, tvb, offset,
            2 + 2 + parameter_length + parameter_padding_length, "Parameter: %s: ",
            val_to_str_const(parameter_id, parameter_id_vals, "Unknown ParameterID"));
    ptree = proto_item_add_subtree(parameter_item, ett_btsap_parameter);

    proto_tree_add_item(ptree, hf_btsap_parameter_id, tvb, offset, 1, ENC_BIG_ENDIAN);

    col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(parameter_id, parameter_id_vals, "Unknown ParameterID"));
    offset += 1;

    proto_tree_add_item(ptree, hf_btsap_parameter_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    pitem = proto_tree_add_item(ptree, hf_btsap_parameter_length, tvb, offset, 2, ENC_BIG_ENDIAN);

    proto_item_append_text(pitem, " (in 4 bytes sections, padding length: %u)", parameter_padding_length);
    offset += 2;

    switch(parameter_id) {
        case 0x00: /* MaxMsgSize */
            proto_tree_add_item(ptree, hf_btsap_parameter_max_msg_size, tvb, offset, 2, ENC_BIG_ENDIAN);
            max_msg_size = tvb_get_ntohs(tvb, offset);
            proto_item_append_text(parameter_item, "%u", max_msg_size);
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", max_msg_size);
            length = 2;
            padding_length = 2;
            break;
        case 0x01: /* ConnectionStatus */
            proto_tree_add_item(ptree, hf_btsap_parameter_connection_status, tvb, offset, 1, ENC_BIG_ENDIAN);
            connection_status = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(connection_status, connection_status_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(connection_status, connection_status_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x02: /* ResultCode */
            proto_tree_add_item(ptree, hf_btsap_parameter_result_code, tvb, offset, 1, ENC_BIG_ENDIAN);
            result_code = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(result_code, result_code_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(result_code, result_code_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x03: /* DisconnectionType */
            proto_tree_add_item(ptree, hf_btsap_parameter_disconnection_type, tvb, offset, 1, ENC_BIG_ENDIAN);
            disconnection_type = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(disconnection_type, disconnection_type_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(disconnection_type, disconnection_type_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x04: /* CommandAPDU */
            /* GSM 11.11 */
            if (gsm_sim_cmd_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        case 0x05: /* ResponseAPDU */
            /* GSM 11.11 or ISO/IEC 7816-4; depend of TRANSFER_APDU_REQ */
            if (gsm_sim_resp_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(gsm_sim_resp_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(gsm_sim_resp_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        case 0x06: /* ATR */
            /* ISO/IEC 7816-3 */
            if (iso7816_atr_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(iso7816_atr_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(iso7816_atr_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        case 0x07: /* CardReaderStatus */
            /* 3GPP TS 11.14 */
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_powered, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_present, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_present_lower, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_present, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_removable, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_identity, tvb, offset, 1, ENC_BIG_ENDIAN);
            length = 1;
            padding_length = 3;
            break;
        case 0x08: /* StatusChange */
            proto_tree_add_item(ptree, hf_btsap_parameter_status_change, tvb, offset, 1, ENC_BIG_ENDIAN);
            status_change = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(status_change, status_change_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(status_change, status_change_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x09: /* TransportProtocol */
            proto_tree_add_item(ptree, hf_btsap_parameter_transport_protocol, tvb, offset, 1, ENC_BIG_ENDIAN);
            transport_protocol = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%u", transport_protocol);
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", transport_protocol);
            length = 1;
            padding_length = 3;
            break;
        case 0x10: /* CommandAPDU7816 */
            /* ISO/IEC 7816-4 */
            if (gsm_sim_cmd_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        default:
            proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            length = parameter_length;
            padding_length = parameter_padding_length;
    }

    *parameter = parameter_id;
    *parameter_offset = offset;

    if (length != parameter_length || padding_length != parameter_padding_length) {
        /* Malformed frame */
        expert_add_info_format(pinfo, pitem, &ei_btsap_parameter_error,
            "Parameter Length does not meet content length");
    }

    offset += parameter_length;

    if (parameter_padding_length > 0) {
        pitem = proto_tree_add_item(ptree, hf_btsap_parameter_padding, tvb, offset, parameter_padding_length, ENC_NA);
        proto_item_append_text(pitem, " (length %d)", parameter_padding_length);
        offset += parameter_padding_length;
    }

    return offset;
}
コード例 #11
0
ファイル: packet-hci_mon.c プロジェクト: DHODoS/wireshark
static gint
dissect_hci_mon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_tree       *hci_mon_item;
    proto_item       *hci_mon_tree;
    proto_item       *sub_item;
    gint              offset = 0;
    guint16           opcode;
    guint16           adapter_id;
    bluetooth_data_t *bluetooth_data;
    tvbuff_t         *next_tvb;
    guint32          *adapter_disconnect_in_frame;
    wmem_tree_t      *subtree;
    wmem_tree_key_t  key[4];
    guint32          k_interface_id;
    guint32          k_adapter_id;
    guint32          k_frame_number;

    bluetooth_data = (bluetooth_data_t *) data;

    DISSECTOR_ASSERT(bluetooth_data->previous_protocol_data_type == BT_PD_BTMON);
    adapter_id = bluetooth_data->previous_protocol_data.btmon->adapter_id;
    opcode = bluetooth_data->previous_protocol_data.btmon->opcode;

    if (opcode == 0x00 || opcode == 0x01)
        pinfo->p2p_dir = P2P_DIR_RECV;
    else if (opcode % 2)
        pinfo->p2p_dir = P2P_DIR_RECV;
    else
        pinfo->p2p_dir = P2P_DIR_SENT;

    hci_mon_item = proto_tree_add_item(tree, proto_hci_mon, tvb, offset, tvb_captured_length(tvb), ENC_NA);
    hci_mon_tree = proto_item_add_subtree(hci_mon_item, ett_hci_mon);

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

    if (opcode == 0x00 || opcode == 0x01)
        col_set_str(pinfo->cinfo, COL_INFO, "Info ");
    else switch (pinfo->p2p_dir) {

    case P2P_DIR_SENT:
        col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
        break;

    case P2P_DIR_RECV:
        col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
        break;

    default:
        col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
        break;
    }

    sub_item = proto_tree_add_uint(hci_mon_tree, hf_adapter_id,  tvb, offset, 0, adapter_id);
    PROTO_ITEM_SET_GENERATED(sub_item);

    sub_item = proto_tree_add_uint(hci_mon_tree, hf_opcode, tvb, offset, 0, opcode);
    PROTO_ITEM_SET_GENERATED(sub_item);

    col_append_fstr(pinfo->cinfo, COL_INFO, "Adapter Id: %u, Opcode: %s",
            adapter_id, val_to_str_ext_const(opcode, &hci_mon_opcode_vals_ext, "Unknown"));

    bluetooth_data->adapter_id = adapter_id;

    k_interface_id = bluetooth_data->interface_id;
    k_adapter_id   = adapter_id;
    k_frame_number = pinfo->num;

    key[0].length = 1;
    key[0].key    = &k_interface_id;
    key[1].length = 1;
    key[1].key    = &k_adapter_id;

    if (!pinfo->fd->flags.visited && opcode == 0x01) { /* Delete Index */
        guint32           *disconnect_in_frame;

        key[2].length = 1;
        key[2].key    = &k_frame_number;
        key[3].length = 0;
        key[3].key    = NULL;

        disconnect_in_frame = wmem_new(wmem_file_scope(), guint32);

        if (disconnect_in_frame) {
            *disconnect_in_frame = pinfo->num;

            wmem_tree_insert32_array(adapter_to_disconnect_in_frame, key, disconnect_in_frame);
        }
    }

    key[2].length = 0;
    key[2].key    = NULL;

    subtree = (wmem_tree_t *) wmem_tree_lookup32_array(adapter_to_disconnect_in_frame, key);
    adapter_disconnect_in_frame = (subtree) ? (guint32 *) wmem_tree_lookup32_le(subtree, k_frame_number) : NULL;
    if (adapter_disconnect_in_frame) {
        bluetooth_data->adapter_disconnect_in_frame = adapter_disconnect_in_frame;
    } else {
        bluetooth_data->adapter_disconnect_in_frame = &max_disconnect_in_frame;
    }

    pinfo->ptype = PT_BLUETOOTH;

    next_tvb = tvb_new_subset_remaining(tvb, offset);

    switch(opcode) {
    case 0x00: /* New Index */
        proto_tree_add_item(hci_mon_tree, hf_bus, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        proto_tree_add_item(hci_mon_tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        offset = dissect_bd_addr(hf_bd_addr, pinfo, hci_mon_tree, tvb, offset, TRUE, bluetooth_data->interface_id, bluetooth_data->adapter_id, NULL);

        proto_tree_add_item(hci_mon_tree, hf_name, tvb, offset, 8, ENC_NA | ENC_ASCII);
        offset += 8;

        break;
    case 0x01: /* Delete Index */
        /* No parameters */

        break;
    case 0x02: /* HCI Command Packet */
        call_dissector_with_data(bthci_cmd_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
   case 0x03:  /* HCI Event Packet */
        call_dissector_with_data(bthci_evt_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
   case 0x04:  /* ACL Tx Packet */
   case 0x05:  /* ACL Rx Packet */
        call_dissector_with_data(bthci_acl_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
   case 0x06:  /* SCO Tx Packet */
   case 0x07:  /* SCO Rx Packet */
        call_dissector_with_data(bthci_sco_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
    }

    if (tvb_reported_length_remaining(tvb, offset) > 0) {
        proto_tree_add_expert(hci_mon_tree, pinfo, &ei_unknown_data, tvb, offset, tvb_reported_length_remaining(tvb, offset));
        offset = tvb_reported_length(tvb);
    }

   /* NOTE: Oops... HCI_MON have special packet with length 0, but there is a pseudo-header with certain infos,
            mark it as dissected */
    if (opcode == 0x01)
        return 1;

    return offset;
}
コード例 #12
0
fragment_data *
force_reassemble_seq(packet_info *pinfo, guint32 id,
	     GHashTable *fragment_table)
{
	fragment_key key;
	fragment_data *fd_head;
	fragment_data *fd_i;
	fragment_data *last_fd;
	guint32 dfpos, size, packet_lost, burst_lost, seq_num;

	/* create key to search hash with */
	key.src = pinfo->src;
	key.dst = pinfo->dst;
	key.id  = id;

	fd_head = g_hash_table_lookup(fragment_table, &key);

	/* have we already seen this frame ?*/
	if (pinfo->fd->flags.visited) {
		if (fd_head != NULL && fd_head->flags & FD_DEFRAGMENTED) {
			return fd_head;
		} else {
			return NULL;
		}
	}

	if (fd_head==NULL){
		/* we must have it to continue */
		return NULL;
	}

	/* check for packet lost and count the burst of packet lost */
	packet_lost = 0;
	burst_lost = 0;
	seq_num = 0;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
		if (seq_num != fd_i->offset) {
			packet_lost += fd_i->offset - seq_num;
			if ( (fd_i->offset - seq_num) > burst_lost ) {
				burst_lost = fd_i->offset - seq_num;
			}
		}
		seq_num = fd_i->offset + 1;
	}

	/* we have received an entire packet, defragment it and
     * free all fragments
     */
	size=0;
	last_fd=NULL;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(!last_fd || last_fd->offset!=fd_i->offset){
	    size+=fd_i->len;
	  }
	  last_fd=fd_i;
	}
	fd_head->data = g_malloc(size);
	fd_head->len = size;		/* record size for caller	*/

	/* add all data fragments */
	dfpos = 0;
	last_fd=NULL;
	for (fd_i=fd_head->next;fd_i && fd_i->len + dfpos <= size;fd_i=fd_i->next) {
	  if (fd_i->len) {
	    if(!last_fd || last_fd->offset!=fd_i->offset){
	      memcpy(fd_head->data+dfpos,fd_i->data,fd_i->len);
	      dfpos += fd_i->len;
	    } else {
	      /* duplicate/retransmission/overlap */
	      fd_i->flags    |= FD_OVERLAP;
	      fd_head->flags |= FD_OVERLAP;
	      if( (last_fd->len!=fd_i->datalen)
		  || memcmp(last_fd->data, fd_i->data, last_fd->len) ){
			fd_i->flags    |= FD_OVERLAPCONFLICT;
			fd_head->flags |= FD_OVERLAPCONFLICT;
	      }
	    }
	  }
	  last_fd=fd_i;
	}

	/* we have defragmented the pdu, now free all fragments*/
	for (fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(fd_i->data){
	    g_free(fd_i->data);
	    fd_i->data=NULL;
	  }
	}

	/* mark this packet as defragmented */
	fd_head->flags |= FD_DEFRAGMENTED;
	fd_head->reassembled_in=pinfo->fd->num;

	col_append_fstr(pinfo->cinfo, COL_INFO, " (t4-data Reassembled: %d pack lost, %d pack burst lost)", packet_lost, burst_lost);

	p_t38_packet_conv_info->packet_lost = packet_lost;
	p_t38_packet_conv_info->burst_lost = burst_lost;

	return fd_head;
}
コード例 #13
0
ファイル: packet-rsh.c プロジェクト: danielwhite84/wireshark
static void
dissect_rsh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *ti;
    proto_tree *rsh_tree=NULL;

    /* Variables for extracting and displaying data from the packet */
    guchar *field_stringz; /* Temporary storage for each field we extract */

    gint length;
    guint offset = 0;
    conversation_t *conversation;
    rsh_hash_entry_t *hash_info;

    conversation = find_or_create_conversation(pinfo);

    /* Retrieve information from conversation
     * or add it if it isn't there yet
     */
    hash_info = (rsh_hash_entry_t *)conversation_get_proto_data(conversation, proto_rsh);
    if(!hash_info){
        hash_info = wmem_new(wmem_file_scope(), rsh_hash_entry_t);

        hash_info->first_packet_number = pinfo->fd->num;
        hash_info->second_packet_number = 0;
        hash_info->third_packet_number  = 0;
        hash_info->fourth_packet_number  = 0;

        hash_info->state = WAIT_FOR_STDERR_PORT; /* The first field we'll see */

        /* Start with empty username and command strings */
        hash_info->client_username=NULL;
        hash_info->server_username=NULL;
        hash_info->command=NULL;

        /* These will be set on the first pass by the first
         * four packets of the conversation
         */
        hash_info->first_packet_state  = NONE;
        hash_info->second_packet_state = NONE;
        hash_info->third_packet_state  = NONE;
        hash_info->fourth_packet_state  = NONE;

        conversation_add_proto_data(conversation, proto_rsh, hash_info);
    }

    /* Store the number of the first three packets of this conversation
     * as we reach them the first time */

    if(!hash_info->second_packet_number
            && pinfo->fd->num > hash_info->first_packet_number){
        /* We're on the second packet of the conversation */
        hash_info->second_packet_number = pinfo->fd->num;
    } else if(hash_info->second_packet_number
            && !hash_info->third_packet_number
            && pinfo->fd->num > hash_info->second_packet_number) {
        /* We're on the third packet of the conversation */
        hash_info->third_packet_number = pinfo->fd->num;
    } else if(hash_info->third_packet_number
            && !hash_info->fourth_packet_number
            && pinfo->fd->num > hash_info->third_packet_number) {
        /* We're on the fourth packet of the conversation */
        hash_info->fourth_packet_number = pinfo->fd->num;
    }

    /* Save this packet's state so we can retrieve it if this packet
     * is selected again later.  If the packet's state was already stored,
     * then retrieve it */
    if(pinfo->fd->num == hash_info->first_packet_number){
        if(hash_info->first_packet_state == NONE){
            hash_info->first_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->first_packet_state;
        }
    }

    if(pinfo->fd->num == hash_info->second_packet_number){
        if(hash_info->second_packet_state == NONE){
            hash_info->second_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->second_packet_state;
        }
    }

    if(pinfo->fd->num == hash_info->third_packet_number){
        if(hash_info->third_packet_state == NONE){
            hash_info->third_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->third_packet_state;
        }
    }

    if(pinfo->fd->num == hash_info->fourth_packet_number){
        if(hash_info->fourth_packet_state == NONE){
            hash_info->fourth_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->fourth_packet_state;
        }
    }

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

    /* First, clear the info column */
    col_clear(pinfo->cinfo, COL_INFO);

    /* Client username */
    if(hash_info->client_username && preference_info_show_client_username == TRUE){
        col_append_fstr(pinfo->cinfo, COL_INFO, "Client username:%s ", hash_info->client_username);
    }

    /* Server username */
    if(hash_info->server_username && preference_info_show_server_username == TRUE){
        col_append_fstr(pinfo->cinfo, COL_INFO, "Server username:%s ", hash_info->server_username);
    }

    /* Command */
    if(hash_info->command && preference_info_show_command == TRUE){
        col_append_fstr(pinfo->cinfo, COL_INFO, "Command:%s ", hash_info->command);
    }

    /* create display subtree for the protocol */
    ti = proto_tree_add_item(tree, proto_rsh, tvb, 0, -1, ENC_NA);
    rsh_tree = proto_item_add_subtree(ti, ett_rsh);

    /* If this packet doesn't end with a null terminated string,
     * then it must be session data only and we can skip looking
     * for the other fields.
     */
    if(tvb_find_guint8(tvb, tvb_length(tvb)-1, 1, '\0') == -1){
        hash_info->state = WAIT_FOR_DATA;
    }

    if(hash_info->state == WAIT_FOR_STDERR_PORT
            && tvb_length_remaining(tvb, offset)){
        field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);

        /* Check if this looks like the stderr_port field.
         * It is optional, so it may only be 1 character long
         * (the NULL)
         */
        if(length == 1 || (isdigit_string(field_stringz)
                    && length <= RSH_STDERR_PORT_LEN)){
            proto_tree_add_string(rsh_tree, hf_rsh_stderr_port, tvb, offset, length, (gchar*)field_stringz);
            /* Next field we need */
            hash_info->state = WAIT_FOR_CLIENT_USERNAME;
        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }

        /* Used if the next field is in the same packet */
        offset += length;
    }


    if(hash_info->state == WAIT_FOR_CLIENT_USERNAME
            && tvb_length_remaining(tvb, offset)){
        field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);

        /* Check if this looks like the username field */
        if(length != 1 && length <= RSH_CLIENT_USERNAME_LEN
                && isprint_string(field_stringz)){
            proto_tree_add_string(rsh_tree, hf_rsh_client_username, tvb, offset, length, (gchar*)field_stringz);

            /* Store the client username so we can display it in the
             * info column of the entire conversation
             */
            if(!hash_info->client_username){
                hash_info->client_username=wmem_strdup(wmem_file_scope(), (gchar*)field_stringz);
            }

            /* Next field we need */
            hash_info->state = WAIT_FOR_SERVER_USERNAME;
        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }

        /* Used if the next field is in the same packet */
        offset += length;
    }


    if(hash_info->state == WAIT_FOR_SERVER_USERNAME
            && tvb_length_remaining(tvb, offset)){
        field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);

        /* Check if this looks like the password field */
        if(length != 1 && length <= RSH_SERVER_USERNAME_LEN
                && isprint_string(field_stringz)){
            proto_tree_add_string(rsh_tree, hf_rsh_server_username, tvb, offset, length, (gchar*)field_stringz);

            /* Store the server username so we can display it in the
             * info column of the entire conversation
             */
            if(!hash_info->server_username){
                hash_info->server_username=wmem_strdup(wmem_file_scope(), (gchar*)field_stringz);
            }

            /* Next field we need */
            hash_info->state = WAIT_FOR_COMMAND;
        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }

        /* Used if the next field is in the same packet */
        offset += length;
        /* Next field we are looking for */
        hash_info->state = WAIT_FOR_COMMAND;
    }


    if(hash_info->state == WAIT_FOR_COMMAND
            && tvb_length_remaining(tvb, offset)){
        field_stringz = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);

        /* Check if this looks like the command field */
        if(length != 1 && length <= RSH_COMMAND_LEN
                && isprint_string(field_stringz)){
            proto_tree_add_string(rsh_tree, hf_rsh_command, tvb, offset, length, (gchar*)field_stringz);

            /* Store the command so we can display it in the
             * info column of the entire conversation
             */
            if(!hash_info->command){
                hash_info->command=wmem_strdup(wmem_file_scope(), (gchar*)field_stringz);
            }

        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }
    }


    if(hash_info->state == WAIT_FOR_DATA
            && tvb_length_remaining(tvb, offset)){
        if(pinfo->destport == RSH_PORT){
            /* Packet going to the server */
            /* offset = 0 since the whole packet is data */
            proto_tree_add_text(rsh_tree, tvb, 0, -1, "Client -> Server Data");

            col_append_str(pinfo->cinfo, COL_INFO, "Client -> Server data");
        } else {
            /* This packet must be going back to the client */
            /* offset = 0 since the whole packet is data */
            proto_tree_add_text(rsh_tree, tvb, 0, -1, "Server -> Client Data");

            col_append_str(pinfo->cinfo, COL_INFO, "Server -> Client Data");
        }
    }

    /* We haven't seen all of the fields yet */
    if(hash_info->state < WAIT_FOR_DATA){
        col_set_str(pinfo->cinfo, COL_INFO, "Session Establishment");
    }
}
コード例 #14
0
/* AU Header dissection */
static offset_struct* dissect_auheader( tvbuff_t *tvb, offset_struct *poffset, packet_info *pinfo, proto_tree *ismacryp_tree, guint set_version )
{
	proto_item *ismacryp_item;
	proto_tree *ismacryp_header_tree;
	proto_tree *ismacryp_header_byte_tree;
	
	guint16 header_len_bytes = 0; /* total length of non-first AU header in bytes (rounded up) */
	gint header_len = 0; /* length of AU headers in bits */
	gint cts_flag =0;
	gint dts_flag =0;
	gboolean first_au_flag=FALSE;
	gint bit_offset = 0;
	
	/*first determine total AU header length */
	/* calculate each AU header length in bits first */
	switch (set_version) {
		case V11:
			if (selective_encryption)
				header_len+=8; /* add one byte to header length */
			break;
		case V20:
			if (selective_encryption || slice_indication || padding_indication)
				header_len+=8; /* add one byte to header length */
			break;
		default:
			DISSECTOR_ASSERT_NOT_REACHED();
			break;
	}	/* end switch */
	header_len+=au_size_length; /* add au size length */
			
	if (poffset->offset_bytes==AU_HEADERS_LENGTH_SIZE){	/*first AU */
		header_len+=8*(iv_length);                      /* add IV length */
		header_len+=8*key_indicator_length;             /* add key indicator length */
		header_len+=au_index_length;                    /* add AU index length */
		first_au_flag = TRUE;
	}
	else { /* not the first AU */
		if (key_indicator_per_au_flag == TRUE) 
			header_len+=8*key_indicator_length; /* add key indicator length */
		header_len+=8*(delta_iv_length);                /* add delta IV length */
		header_len+=au_index_delta_length;              /* add AU delta index length */
	}
	/* CTS flag is present? */
	if (cts_delta_length != 0){    /* need to test whether cts_delta_flag is TRUE or FALSE */
		cts_flag=tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8+header_len, 1); /*fetch 1 bit CTS flag  */
		header_len+=1;         /* add CTS flag bit */
		if (cts_flag==1)
			header_len+=cts_delta_length; /* add CTS delta length bits if CTS flag SET */
	}
	/* DTS flag is present? */
	if (dts_delta_length != 0){ /* need to test whether dts_delta_flag is TRUE or FALSE */
		dts_flag=tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8+header_len, 1); /*fetch 1 bit DTS flag */
		header_len+=1;      /* add DTS flag bit */
		if (dts_flag==1)
			header_len+=dts_delta_length; /* add DTS delta length bits if DTS flag SET */
	}
	/* RAP flag present? */
	if (random_access_indication != FALSE)
		header_len+=1;      /* add 1 bit RAP flag */
	
	/* stream state indication present */
	if (stream_state_indication !=0)
		header_len+=stream_state_indication; /* add stream state indication bits */
	
	/* convert header_len to bytes (rounded up) */
	if (header_len% 8!=0)
	{
		header_len_bytes=((header_len)/8)+1; /*add 1 */
	}
	else
		header_len_bytes=((header_len)/8);
		
	/* add AU header tree  */
	ismacryp_item = proto_tree_add_item(ismacryp_tree, hf_ismacryp_header, tvb, poffset->offset_bytes, header_len_bytes, FALSE );
	proto_item_append_text(ismacryp_item, ": Length=%d bits", header_len); /* add text to Header tree indicating length */
	/* sanity check if actual AU header length is zero bits, which indicates an error */
	if ( header_len == 0) /* something wrong */
	{
		proto_item_append_text(ismacryp_item, " Error - zero bit AU header size - check parameters!");
	}
	ismacryp_header_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header);
					
	/* ismacryp header analysis */
	/* we are being asked for details  */
		
	/* Extra 1 Byte Header? */
	
	if ((set_version==V20 && (selective_encryption || slice_indication || padding_indication))
		|| (set_version==V11 && selective_encryption)){
							
		/* add  header byte tree	*/
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_header_byte,
						    tvb, poffset->offset_bytes, 1, FALSE );
		proto_item_append_text(ismacryp_item, ": Length=8 bits"); /* add text to Header byte tree indicating length */
		ismacryp_header_byte_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header_byte);
		
		/*ismacryp_header_byte_tree */ 
		/* we are being asked for details */
		/* tvb is network order, so get MSB bits first, so shift 8 bits and work "backwards" */
		add_bits(poffset,7);   /*shift 7 bits to get correct bit */
		/* AU_is_encrypted bit */
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */	
		if (selective_encryption){ /* bit used */
			ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_au_is_encrypted,
								 tvb, bit_offset, 1, FALSE); /*fetch 1 bit AU_is_encrypted */
		}
		else { /* bit unused */
			ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
								 tvb, bit_offset, 1, FALSE); /*fetch 1 bit unused */
		}
		switch (set_version){ /* ISMACryp version? */
			case V11:
				/* Reserved bits */
				add_bits(poffset, -7); /* move back 7 bits for reserved bits */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits,
									 tvb, bit_offset, 7, FALSE); /*fetch 7 bits reserved */
				add_bits(poffset,8);   /* offset to next byte */
				break;
			case V20:
				/* Slice_start bit */
				add_bits(poffset, -1); /* move back 1 bit for slice_start */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				if (slice_indication){
					ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_start,
										 tvb, bit_offset, 1, FALSE); /*fetch 1 bit slice_start */
				}
				else { /* bit unused */
					ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
										 tvb, bit_offset, 1, FALSE); /*fetch 1 bit unused */
				}
				add_bits(poffset, -1); /* move back 1 bit for slice_end */

				/* Slice_end bit */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				if (slice_indication){
					ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_end,
										 tvb, bit_offset, 1, FALSE); /*fetch 1 bit Slice_end */
				}
				else { /* bit unused */
					ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
										 tvb, bit_offset, 1, FALSE); /*fetch 1 bit unused */
				}
				add_bits(poffset, -3); /* move back 3 bits for padding_bitcount */

				/* Padding_bitcount bits */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				if (padding_indication){
					ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_padding_bitcount,
										 tvb, bit_offset, 3, FALSE); /*fetch 3 bits padding_bitcount */
				}
				else { /* bits unused */
					ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
										 tvb, bit_offset, 3, FALSE); /*fetch 3 bits unused */
				}
				add_bits(poffset, -2); /* move back 2 bits for reserved bits */
			
				/* Reserved bits */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				ismacryp_item = proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits,
									 tvb, bit_offset, 2, FALSE); /*fetch 2 bits reserved */
				add_bits(poffset,8); /* offset to next byte */
				break;
			default:
				DISSECTOR_ASSERT_NOT_REACHED();
				break;
		} /* end switch set_version */
	} /* end selective encryption */
	/* IV */
	if (first_au_flag == TRUE && iv_length != 0)
	{
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_iv, tvb, poffset->offset_bytes, iv_length, FALSE);
		proto_item_append_text(ismacryp_item, ": Length=%d bytes",iv_length); /* add IV info */
		if ( check_col( pinfo->cinfo, COL_INFO) ) {
			col_append_fstr( pinfo->cinfo, COL_INFO,
			", IV=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, iv_length,' '));
		}
		poffset->offset_bytes+=iv_length; /* add IV length to offset_bytes */
	}
	/*Delta  IV */
	if (first_au_flag == FALSE && delta_iv_length != 0)
	{
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_delta_iv,
						    tvb, poffset->offset_bytes, delta_iv_length, FALSE);
		proto_item_append_text(ismacryp_item, ": Length=%d bytes",delta_iv_length); /* add delta IV info */
		if ( check_col( pinfo->cinfo, COL_INFO) ) {
			col_append_fstr( pinfo->cinfo, COL_INFO,
			", Delta IV=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, delta_iv_length,' '));
		}
		poffset->offset_bytes+=iv_length; /* add IV length to offset_bytes */
	}				
	/* Key Indicator */
	if ( key_indicator_length != 0 && ( first_au_flag == TRUE || key_indicator_per_au_flag == TRUE) )
	{			
		/* (first AU or KI for each AU) and non-zero KeyIndicator size */
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_key_indicator, 
						    tvb, poffset->offset_bytes, key_indicator_length, FALSE);
		proto_item_append_text(ismacryp_item,": Length=%d bytes",key_indicator_length); /* add KI info */
		if ( check_col( pinfo->cinfo, COL_INFO) ) {
			col_append_fstr( pinfo->cinfo, COL_INFO,
					 ", KI=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, key_indicator_length,' '));
		}
		poffset->offset_bytes+=key_indicator_length; /* add KI length to offset_bytes */
	}		
	/* AU size */
	if (au_size_length != 0) /* in bits */
	{			
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_size,
							 tvb, bit_offset, au_size_length, FALSE);
		proto_item_append_text(ismacryp_item, " bytes: Length=%d bits",au_size_length); /* add AU size info */			
		bit_offset+=au_size_length;
		add_bits(poffset, au_size_length);	
	}					
	/* AU Index */
	if (first_au_flag == TRUE && au_index_length != 0) /* first AU and non-zero AU size */
	{	
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_index,
							 tvb, bit_offset, au_index_length, FALSE);
		proto_item_append_text(ismacryp_item, " bits: Length=%d bits",au_index_length); /* add AU index info */
		bit_offset+=au_index_length;
		add_bits(poffset, au_index_length);
	}			
	/* AU index delta */
	if (first_au_flag == FALSE && au_index_delta_length != 0) /* not first AU and non-zero AU delta size */
	{	
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_index_delta,
							 tvb, bit_offset, au_index_delta_length, FALSE);
		proto_item_append_text(ismacryp_item, ": Length=%d bits", au_index_delta_length); /* add AU index info */
		bit_offset+=au_index_delta_length;
		add_bits(poffset, au_index_delta_length);
	}	
	/* CTS delta value */
	if (cts_delta_length != 0)
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_flag,
							 tvb, bit_offset, 1, FALSE); /* read CTS flag */
		add_bits(poffset, 1);
		if (cts_flag==1)
		{
			/* now fetch CTS delta value (remember offset 1 bit due to CTS flag) */
			bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
			ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_delta,
								 tvb, bit_offset, cts_delta_length, FALSE); /* read CTS delta value */
			proto_item_append_text(ismacryp_item, ": Length=%d bits",cts_delta_length); /* add CTS delta info */
			add_bits(poffset, cts_delta_length);
		}
	}	
	/* DTS delta value */
	if (dts_delta_length != 0)
	{		
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_flag,
							 tvb, bit_offset, 1, FALSE); /* read DTS flag */
		add_bits(poffset, 1);
		
		/* now fetch DTS delta value (remember offset x bits due to DTS flag) */
		if (dts_flag ==1)
		{
			bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
			ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_delta,
								 tvb, bit_offset, dts_delta_length, FALSE); /* read DTS delta value */
			proto_item_append_text(ismacryp_item, ": Length=%d bits",dts_delta_length); /* add DTS delta info */
			add_bits(poffset, dts_delta_length);
		}
	}	
	/* RAP */
	if (random_access_indication != FALSE)
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_rap_flag,
							 tvb, bit_offset, 1, FALSE); /* read RAP flag */
		add_bits(poffset, 1);	
	}
	/*STREAM STATE */
	if (stream_state_indication != 0)
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_stream_state,
							 tvb, bit_offset, stream_state_indication, FALSE); /* read stream state */
		add_bits(poffset, stream_state_indication);
	}			
	/* end header details */
return poffset;
}
コード例 #15
0
ファイル: packet-ipx.c プロジェクト: SayCV/wireshark
static void
dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*spx_tree = NULL;
	proto_item	*ti;
	tvbuff_t	*next_tvb;
	guint8		conn_ctrl;
	proto_tree	*cc_tree;
	guint8		datastream_type;
	const char	*datastream_type_string;
	guint16         spx_seq;
	const char	*spx_msg_string;
	guint16		low_socket, high_socket;
	guint32		src;
	conversation_t	*conversation;
	spx_hash_value	*pkt_value;
	spx_rexmit_info	*spx_rexmit_info_p;
	spx_info	spx_infox;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SPX");
	col_set_str(pinfo->cinfo, COL_INFO, "SPX");

	if (tree) {
		ti = proto_tree_add_item(tree, proto_spx, tvb, 0, SPX_HEADER_LEN, ENC_NA);
		spx_tree = proto_item_add_subtree(ti, ett_spx);
	}

	conn_ctrl = tvb_get_guint8(tvb, 0);
	spx_msg_string = spx_conn_ctrl(conn_ctrl);
	if (check_col(pinfo->cinfo, COL_INFO))
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", spx_msg_string);
	if (tree) {
		ti = proto_tree_add_uint_format(spx_tree, hf_spx_connection_control, tvb,
						0, 1, conn_ctrl,
						"Connection Control: %s (0x%02X)",
						spx_msg_string, conn_ctrl);
		cc_tree = proto_item_add_subtree(ti, ett_spx_connctrl);
		proto_tree_add_boolean(cc_tree, hf_spx_connection_control_sys, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spx_connection_control_send_ack, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spx_connection_control_attn, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spx_connection_control_eom, tvb,
				       0, 1, conn_ctrl);
	}

	datastream_type = tvb_get_guint8(tvb, 1);
	datastream_type_string = spx_datastream(datastream_type);
	if (datastream_type_string != NULL) {
		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
			    datastream_type_string);
	}
	if (tree) {
		if (datastream_type_string != NULL) {
			proto_tree_add_uint_format(spx_tree, hf_spx_datastream_type, tvb,
						   1, 1, datastream_type,
						   "Datastream Type: %s (0x%02X)",
						   datastream_type_string,
						   datastream_type);
		} else {
			proto_tree_add_uint_format(spx_tree, hf_spx_datastream_type, tvb,
						   1, 1, datastream_type,
						   "Datastream Type: 0x%02X",
						   datastream_type);
		}
		proto_tree_add_item(spx_tree, hf_spx_src_id, tvb,  2, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(spx_tree, hf_spx_dst_id, tvb,  4, 2, ENC_BIG_ENDIAN);
	}
	spx_seq = tvb_get_ntohs(tvb, 6);
	if (tree) {
		proto_tree_add_uint(spx_tree, hf_spx_seq_nr, tvb,  6, 2, spx_seq);
		proto_tree_add_item(spx_tree, hf_spx_ack_nr, tvb,  8, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(spx_tree, hf_spx_all_nr, tvb, 10, 2, ENC_BIG_ENDIAN);
	}

	/*
	 * SPX is Connection Oriented and Delivery Guaranteed.
	 * On the first pass, we need to flag retransmissions by the SPX
	 * protocol, so that subdissectors know whether a packet was
	 * retransmitted.
	 *
	 * We start out by creating a conversation for this direction of the
	 * IPX session; we use "pinfo->srcport" twice, so that we have
	 * separate conversations for the two directions.
	 *
	 * XXX - that might not work correctly if there's more than one
	 * SPX session using that source port; can that happen?  If so,
	 * we should probably use the direction, as well as the conversation,
	 * as part of the hash key; if we do that, we can probably just
	 * use PT_IPX as the port type, and possibly get rid of PT_NCP.
	 *
	 * According to
	 *
	 *	http://developer.novell.com/research/appnotes/1995/december/03/apv.htm
	 *
	 * the sequence number is not incremented for system packets, so
	 * presumably that means there is no notion of a system packet
	 * being retransmitted; that document also says that system
	 * packets are used as "I'm still here" keepalives and as
	 * acknowledgements (presumably meaning ACK-only packets), which
	 * suggests that they might not be ACKed and thus might not
	 * be retransmitted.
	 */
	if (conn_ctrl & SPX_SYS_PACKET) {
		/*
		 * It's a system packet, so it isn't a retransmission.
		 */
		spx_rexmit_info_p = NULL;
	} else {
		/*
		 * Not a system packet - check for retransmissions.
		 */
		if (!pinfo->fd->flags.visited) {
			conversation = find_conversation(pinfo->fd->num, &pinfo->src,
			    &pinfo->dst, PT_NCP, pinfo->srcport,
			    pinfo->srcport, 0);
			if (conversation == NULL) {
				/*
				 * It's not part of any conversation - create
				 * a new one.
				 */
				conversation = conversation_new(pinfo->fd->num, &pinfo->src,
				    &pinfo->dst, PT_NCP, pinfo->srcport,
				    pinfo->srcport, 0);
			}

			/*
			 * Now we'll hash the SPX header and use the result
			 * of that, plus the conversation, as a hash key to
			 * identify this packet.
			 *
			 * If we don't find it in the hash table, it's not a
			 * retransmission, otherwise it is.  If we don't find
			 * it, we enter it into the hash table, with the
			 * frame number.
			 * If we do, we attach to this frame a structure giving
			 * the frame number of the original transmission, so
			 * that we, and subdissectors, know it's a
			 * retransmission.
			 */
			src = tvb_get_ntohs(tvb, 0)+tvb_get_ntohs(tvb, 2)+tvb_get_ntohs(tvb, 4)+tvb_get_ntohs(tvb, 6)+tvb_get_ntohs(tvb, 8);
			pkt_value = spx_hash_lookup(conversation, src, spx_seq);
			if (pkt_value == NULL) {
				/*
				 * Not found in the hash table.
				 * Enter it into the hash table.
				 */
				pkt_value = spx_hash_insert(conversation, src,
				    spx_seq);
				pkt_value->spx_ack = tvb_get_ntohs(tvb, 8);
				pkt_value->spx_all = tvb_get_ntohs(tvb, 10);
				pkt_value->num = pinfo->fd->num;

				/*
				 * This is not a retransmission, so we shouldn't
				 * have any retransmission indicator.
				 */
				spx_rexmit_info_p = NULL;
			} else {
				/*
				 * Found in the hash table.  Mark this frame as
				 * a retransmission.
				 */
				spx_rexmit_info_p = se_new(spx_rexmit_info);
				spx_rexmit_info_p->num = pkt_value->num;
				p_add_proto_data(pinfo->fd, proto_spx,
				    spx_rexmit_info_p);
			}
		} else {
			/*
			 * Do we have per-packet SPX data for this frame?
			 * If so, it's a retransmission, and the per-packet
			 * data indicates which frame had the original
			 * transmission.
			 */
			spx_rexmit_info_p = (spx_rexmit_info *)p_get_proto_data(pinfo->fd,
			    proto_spx);
		}
	}

	/*
	 * It's a retransmission if we have a retransmission indicator.
	 * Flag this as a retransmission, but don't pass it to the
	 * subdissector.
	 */
	if (spx_rexmit_info_p != NULL) {
		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_add_fstr(pinfo->cinfo, COL_INFO,
			    "[Retransmission] Original Packet %u",
			    spx_rexmit_info_p->num);
		}
		if (tree) {
			proto_tree_add_uint_format(spx_tree, hf_spx_rexmt_frame,
			    tvb, 0, 0, spx_rexmit_info_p->num,
			    "This is a retransmission of frame %u",
			    spx_rexmit_info_p->num);
			if (tvb_length_remaining(tvb, SPX_HEADER_LEN) > 0) {
				proto_tree_add_text(spx_tree, tvb,
				    SPX_HEADER_LEN, -1,
				    "Retransmitted data");
			}
		}
		return;
	}

	if (tvb_reported_length_remaining(tvb, SPX_HEADER_LEN) > 0) {
		void* pd_save;
		/*
		 * Call subdissectors based on the IPX socket numbers; a
		 * subdissector might have registered with our IPX socket
		 * dissector table rather than the IPX dissector's socket
		 * dissector table.
		 *
		 * Assume the lower-numbered socket number is more likely
		 * to be the right one, along the lines of what we do for
		 * TCP and UDP.  We've seen NCP packets with a type of NCP,
		 * a source socket of IPX_SOCKET_NCP, and a destination
		 * socket of IPX_SOCKET_IPX_MESSAGE, and we've seen NCP
		 * packets with a type of NCP, a source socket of
		 * IPX_SOCKET_IPX_MESSAGE, and a destination socket of
		 * IPX_SOCKET_NCP.
		 */
		if (pinfo->srcport > pinfo->destport) {
			low_socket = pinfo->destport;
			high_socket = pinfo->srcport;
		} else {
			low_socket = pinfo->srcport;
			high_socket = pinfo->destport;
		}

		/*
		 * Pass information to subdissectors.
		 */
		spx_infox.eom = conn_ctrl & SPX_EOM;
		spx_infox.datastream_type = datastream_type;
		pd_save = pinfo->private_data;
		pinfo->private_data = &spx_infox;

		next_tvb = tvb_new_subset_remaining(tvb, SPX_HEADER_LEN);
		if (dissector_try_uint(spx_socket_dissector_table, low_socket,
		    next_tvb, pinfo, tree))
		{
			pinfo->private_data = pd_save;
			return;
		}
		if (dissector_try_uint(spx_socket_dissector_table, high_socket,
		    next_tvb, pinfo, tree))
		{
			pinfo->private_data = pd_save;
			return;
		}
		call_dissector(data_handle, next_tvb, pinfo, tree);
		pinfo->private_data = pd_save;
	}
}
コード例 #16
0
ファイル: packet-dlm3.c プロジェクト: CharaD7/wireshark
/* Code to actually dissect the packets */
static void
dissect_dlm3_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                 guint length, int offset)
{
  guint32     m_type;

  m_type   = tvb_get_letohl(tvb, offset);
  proto_tree_add_uint(tree,
                      hf_dlm3_m_type, tvb, offset, 4, m_type);
  col_append_fstr(pinfo->cinfo, COL_INFO,
                ": %s",
                val_to_str_const(m_type,
                                 dlm3_msg,
                                 "Unknown"));

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_nodeid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_lkid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
  /* TODO: See `create_lkb'
     lkid has some structure. We dissect more. */

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_remid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_parent_lkid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_parent_remid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_exflags, ett_dlm3_m_exflags,
                         m_exflags_fields, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_sbflags, ett_dlm3_sbflags,
                         m_sbflags_fields, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_flags, ett_dlm3_m_flags,
                         m_flags_fields, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_lvbseq, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_hash, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_grmode, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_rqmode, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_bastmode, tvb, offset, 4, ENC_LITTLE_ENDIAN);


  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_asts, ett_dlm3_m_asts,
                         m_asts_fields, ENC_LITTLE_ENDIAN);
  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_result, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  if ((length - offset) > 0) {
    proto_tree_add_item(tree,
                        hf_dlm3_m_extra,
                        tvb,
                        offset,
                        -1,
                        ENC_NA);
  }
}
コード例 #17
0
void
dissect_sss_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, ncp_req_hash_value *request_value)
{
    guint8              /*func,*/ subfunc = 0;
    guint32             subverb=0;
    guint32             msg_length=0;
    guint32             foffset= 0;
    proto_tree          *atree;
    proto_item          *aitem;


    if (tvb_length_remaining(tvb, foffset)<4) {
        return;
    }
    foffset = 6;
    /*func = tvb_get_guint8(tvb, foffset);*/
    foffset += 1;
    subfunc = tvb_get_guint8(tvb, foffset);
    foffset += 1;

    /* Fill in the PROTOCOL & INFO  columns. */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS");
    col_add_fstr(pinfo->cinfo, COL_INFO, "C SecretStore - %s", val_to_str(subfunc, sss_func_enum, "Unknown (%d)"));

    switch (subfunc) {
    case 1:
        aitem = proto_tree_add_text(ncp_tree, tvb, foffset, tvb_length_remaining(tvb, foffset), "Packet Type: %s", val_to_str(subfunc, sss_func_enum, "Unknown (%d)"));
        atree = proto_item_add_subtree(aitem, ett_sss);
        proto_tree_add_item(atree, hf_ping_version, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
        foffset += 4;
        proto_tree_add_item(atree, hf_flags, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
        foffset += 4;
        break;
    case 2:
        proto_tree_add_item(ncp_tree, hf_frag_handle, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
        if (tvb_get_letohl(tvb, foffset)==0xffffffff) /* Fragment handle of -1 means no fragment. So process packet */
        {
            foffset += 4;
            proto_tree_add_item(ncp_tree, hf_buffer_size, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
            foffset += 4;
            proto_tree_add_item(ncp_tree, hf_length, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
            foffset += 4;
            foffset += 12; /* Blank Context */
            subverb = tvb_get_letohl(tvb, foffset);
            col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str(subverb, sss_verb_enum, "Unknown (%d)"));

            aitem = proto_tree_add_item(ncp_tree, hf_verb, tvb, foffset, 4, ENC_LITTLE_ENDIAN);
            atree = proto_item_add_subtree(aitem, ett_sss);
            if (request_value) {
                request_value->req_nds_flags=subverb;
            }
            foffset += 4;
            process_flags(atree, tvb, foffset);
            foffset += 4;
            proto_tree_add_item(atree, hf_context, tvb, foffset, 4, ENC_BIG_ENDIAN);
            foffset += 4;
            switch (subverb) {
            case 0:
                foffset += 4;
                foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
                break;
            case 1:
                foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
                msg_length = tvb_get_letohl(tvb, foffset);
                foffset += (msg_length+4);   /* Unsure of what this length and parameter are */
                /* A bad secret of length greater then 256 characters will cause frag
                   packets and then we will see these as malformed packets.
                   So check to make sure we still have data in the packet anytime
                   we read a secret. */
                if (tvb_length_remaining(tvb, foffset) > 4)
                {
                    foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
                }
                break;
            case 2:
                foffset += 4;
                foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
                if (tvb_length_remaining(tvb, foffset) > 4)
                {
                    msg_length = tvb_get_letohl(tvb, foffset);
                    foffset += 4;
                    if (tvb_length_remaining(tvb, foffset) < (gint) msg_length)
                    {
                        proto_tree_add_item(atree, hf_enc_data, tvb, foffset, -1, ENC_NA);
                    }
                    else
                    {
                        proto_tree_add_item(atree, hf_enc_data, tvb, foffset, msg_length, ENC_NA);
                    }
                }
                break;
            case 3:
            case 4:
                foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
                if (tvb_length_remaining(tvb, foffset) > 4)
                {
                    foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
                }
                break;
            case 5:
                break;
            case 6:
                foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, 0);
                if (tvb_length_remaining(tvb, foffset) > 4)
                {
                    foffset = sss_string(tvb, hf_user, atree, foffset, TRUE, 0);
                }
                break;
            case 7:
                msg_length = tvb_get_letohl(tvb, foffset);
                foffset += 4;
                proto_tree_add_item(atree, hf_enc_cred, tvb, foffset, msg_length, ENC_NA);
                break;
            case 8:
            case 9:
            default:
                break;
            }

        }
        else
        {
            col_set_str(pinfo->cinfo, COL_INFO, "C SecretStore - fragment");
            proto_tree_add_text(ncp_tree, tvb, foffset, 4, "Fragment");

            /* Fragments don't really carry a subverb so store 0xff as the subverb number */
            if (request_value) {
                request_value->req_nds_flags=255;
            }
            if (tvb_length_remaining(tvb, foffset) > 8)
            {
                foffset += 4;
                proto_tree_add_item(ncp_tree, hf_enc_data, tvb, foffset, tvb_length_remaining(tvb, foffset), ENC_NA);
            }
        }
        break;
    case 3:
        /* No Op */
        break;
    default:
        break;
    }
}
コード例 #18
0
ファイル: packet-dlm3.c プロジェクト: CharaD7/wireshark
static void
dissect_dlm3_rcom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                  guint length, int offset)
{
  guint32     rc_type;

  proto_item *sub_item;
  proto_tree *sub_tree;


  rc_type  = tvb_get_letohl(tvb, offset);
  proto_tree_add_uint(tree,
                      hf_dlm3_rc_type, tvb, offset, 4, rc_type);
  col_append_fstr(pinfo->cinfo, COL_INFO,
                  ": %s",
                  val_to_str_const(rc_type,
                                   dlm3_rcom,
                                   "Unknown"));

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_result, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);

  offset += 8;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_seq, tvb, offset, 8, ENC_LITTLE_ENDIAN);

  offset += 8;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_seq_reply, tvb, offset, 8, ENC_LITTLE_ENDIAN);

  offset += 8;
  if ((length - offset) == 0) {
    /* No rc_buf: Just return */
    return;
  }

  /* Decode rc_buf */
  sub_item = proto_tree_add_item(tree,
                                 hf_dlm3_rc_buf,
                                 tvb,
                                 offset,
                                 -1,
                                 ENC_NA);

  offset += 0;
  if (rc_type == DLM3_RCOM_LOCK) {
    sub_tree = proto_item_add_subtree(sub_item,
                                      ett_dlm3_rcom_lock);
    dissect_dlm3_rcom_lock(tvb, sub_tree, length, offset);
  } else if (rc_type == DLM3_RCOM_STATUS_REPLY) {
    sub_tree = proto_item_add_subtree(sub_item,
                                      ett_dlm3_rcom_config);
    dissect_dlm3_rcom_config(tvb, sub_tree, length, offset);
  }

}
コード例 #19
0
ファイル: packet-icep.c プロジェクト: MultipathDTLS/wireshark
static void dissect_icep_request_common(tvbuff_t *tvb, guint32 offset,
                    packet_info *pinfo, proto_tree *icep_sub_tree, proto_item* icep_sub_item, gint32 *total_consumed)
{
    /*  p. 613, chapter 23.3.3 and p. 612 chapter 23.3.2:
     *  Request and BatchRequest differ only in the first 4 bytes (requestID)
     *  so them share this part
     *
     *   Ice::Identity id;
     *   Ice::StringSeq facet;
     *   string operation;
     *   byte mode;
     *   Ice::Context context;
     *   Encapsulation params;
     *  }
     */

    gint32 consumed = 0;
    char *namestr = NULL;
    char *opstr = NULL;

    (*total_consumed) = 0;

    /* check common header (i.e. the batch request one)*/
    if ( !tvb_bytes_exist(tvb, offset, ICEP_MIN_COMMON_REQ_HEADER_SIZE) ) {

        expert_add_info_format(pinfo, icep_sub_item, &ei_icep_length, "too short header");
        col_append_str(pinfo->cinfo, COL_INFO, " (too short header)");

        goto error;
    }

    /* got at least 15 bytes */

    /*  "id" is a:
     *  struct Identity {
     *      string name;
     *  string category;
     *  }
     */

    dissect_ice_string(pinfo, icep_sub_tree, icep_sub_item, hf_icep_id_name, tvb, offset, &consumed, &namestr);

    if ( consumed == -1 )
        goto error;

    offset += consumed; DBG1("consumed --> %d\n", consumed);
    (*total_consumed) += consumed;


    dissect_ice_string(pinfo, icep_sub_tree, icep_sub_item, hf_icep_id_category, tvb, offset, &consumed, NULL);

    if ( consumed == -1 )
        goto error;

    offset += consumed; DBG1("consumed --> %d\n", consumed);
    (*total_consumed) += consumed;


    /*  "facet" is a:
     *  sequence<string> StringSeq
     *
     */

    dissect_ice_facet(pinfo, icep_sub_tree, icep_sub_item, hf_icep_facet, tvb, offset, &consumed);

    if ( consumed == -1 )
        goto error;

    offset += consumed; DBG1("consumed --> %d\n", consumed);
    (*total_consumed) += consumed;

    /*  "operation" is an ice_string
     *
     */

    dissect_ice_string(pinfo, icep_sub_tree, icep_sub_item, hf_icep_operation, tvb, offset, &consumed, &opstr);

    if ( consumed == -1 )
        goto error;
    else {
        offset += consumed; DBG1("consumed --> %d\n", consumed);
        (*total_consumed) += consumed;

        if ( opstr && namestr ) {
            DBG2("operation --> %s.%s()\n", namestr, opstr);
            col_append_fstr(pinfo->cinfo, COL_INFO, " %s.%s()",
                        namestr, opstr);
            opstr = NULL;
            namestr = NULL;
        }
    }

    /* check and get mode byte */
    if ( !tvb_bytes_exist(tvb, offset, 1) ) {

        expert_add_info(pinfo, icep_sub_item, &ei_icep_mode_missing);

        col_append_str(pinfo->cinfo, COL_INFO, " (mode field missing)");
        goto error;
    }

    proto_tree_add_item(icep_sub_tree, hf_icep_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN);

    offset++; DBG0("consumed --> 1\n");
    (*total_consumed)++;


    /*  "context" is a dictionary<string, string>
     *
     */

    dissect_ice_context(pinfo, icep_sub_tree, icep_sub_item, tvb, offset, &consumed);

    if ( consumed == -1 )
        goto error;

    offset += consumed; DBG1("consumed --> %d\n", consumed);
    (*total_consumed) += consumed;

    /*  "params" is a Encapsulation
     *
     */

    dissect_ice_params(pinfo, icep_sub_tree, icep_sub_item, tvb, offset, &consumed);

    if ( consumed == -1 )
        goto error;

    /*offset += consumed;*/
     DBG1("consumed --> %d\n", consumed);
    (*total_consumed) += consumed;

    return;

error:
    (*total_consumed) = -1;
}
コード例 #20
0
ファイル: packet-wtp.c プロジェクト: DHODoS/wireshark
/* Code to actually dissect the packets */
static void
dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    char          *szInfo;
    int            offCur        = 0;   /* current offset from start of WTP data */
    gint           returned_length, str_index = 0;

    unsigned char  b0;

    /* continuation flag */
    unsigned char  fCon;            /* Continue flag    */
    unsigned char  fRID;            /* Re-transmission indicator*/
    unsigned char  fTTR = '\0';        /* Transmission trailer    */
    guint          cbHeader       = 0;    /* Fixed header length    */
    guint          vHeader       = 0;    /* Variable header length*/
    int            abortType      = 0;

    /* Set up structures we'll need to add the protocol subtree and manage it */
    proto_item    *ti = NULL;
    proto_tree    *wtp_tree = NULL;

    char           pdut;
    char           clsTransaction = 3;
    int            numMissing = 0;        /* Number of missing packets in a negative ack */
    int            i;
    tvbuff_t      *wsp_tvb = NULL;
    guint8         psn = 0;        /* Packet sequence number*/
    guint16        TID = 0;        /* Transaction-Id    */
    int            dataOffset;
    gint           dataLen;

#define SZINFO_SIZE 256
    szInfo=(char *)wmem_alloc(wmem_packet_scope(), SZINFO_SIZE);

    b0 = tvb_get_guint8 (tvb, offCur + 0);
    /* Discover Concatenated PDUs */
    if (b0 == 0) {
        guint    c_fieldlen = 0;        /* Length of length-field    */
        guint    c_pdulen = 0;        /* Length of conc. PDU    */

        if (tree) {
            ti = proto_tree_add_item(tree, proto_wtp,
                    tvb, offCur, 1, ENC_NA);
            wtp_tree = proto_item_add_subtree(ti, ett_wtp_sub_pdu_tree);
            proto_item_append_text(ti, ", PDU concatenation");
        }
        offCur = 1;
        i = 1;
        while (offCur < (int) tvb_reported_length(tvb)) {
            tvbuff_t *wtp_tvb;
            /* The length of an embedded WTP PDU is coded as either:
             *    - a 7-bit value contained in one octet with highest bit == 0.
             *    - a 15-bit value contained in two octets (little endian)
             *      if the 1st octet has its highest bit == 1.
             * This means that this is NOT encoded as an uintvar-integer!!!
             */
            b0 = tvb_get_guint8(tvb, offCur + 0);
            if (b0 & 0x80) {
                c_fieldlen = 2;
                c_pdulen = ((b0 & 0x7f) << 8) | tvb_get_guint8(tvb, offCur + 1);
            } else {
                c_fieldlen = 1;
                c_pdulen = b0;
            }
            if (tree) {
                proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size,
                        tvb, offCur, c_fieldlen, c_pdulen);
            }
            if (i > 1) {
                col_append_str(pinfo->cinfo, COL_INFO, ", ");
            }
            /* Skip the length field for the WTP sub-tvb */
            wtp_tvb = tvb_new_subset_length(tvb, offCur + c_fieldlen, c_pdulen);
            dissect_wtp_common(wtp_tvb, pinfo, wtp_tree);
            offCur += c_fieldlen + c_pdulen;
            i++;
        }
        if (tree) {
            proto_item_append_text(ti, ", PDU count: %u", i);
        }
        return;
    }
    /* No concatenation */
    fCon = b0 & 0x80;
    fRID = retransmission_indicator(b0);
    pdut = pdu_type(b0);

#ifdef DEBUG
    proto_tree_add_debug_text(tree, "WTP packet %u: tree = %p, pdu = %s (%u) length: %u\n",
            pinfo->num, tree,
            val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"),
            pdut, tvb_captured_length(tvb));
#endif

    /* Develop the string to put in the Info column */
    returned_length =  g_snprintf(szInfo, SZINFO_SIZE, "WTP %s",
            val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"));
    str_index += MIN(returned_length, SZINFO_SIZE-str_index);

    switch (pdut) {
        case INVOKE:
            fTTR = transmission_trailer(b0);
            TID = tvb_get_ntohs(tvb, offCur + 1);
            psn = 0;
            clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3));
            returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index,
                    " Class %d", clsTransaction);
            str_index += MIN(returned_length, SZINFO_SIZE-str_index);
            cbHeader = 4;
            break;

        case SEGMENTED_INVOKE:
        case SEGMENTED_RESULT:
            fTTR = transmission_trailer(b0);
            TID = tvb_get_ntohs(tvb, offCur + 1);
            psn = tvb_get_guint8(tvb, offCur + 3);
            if (psn != 0) {
                returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index,
                        " (%u)", psn);
                str_index += MIN(returned_length, SZINFO_SIZE-str_index);
            }
            cbHeader = 4;
            break;

        case ABORT:
            cbHeader = 4;
            break;

        case RESULT:
            fTTR = transmission_trailer(b0);
            TID = tvb_get_ntohs(tvb, offCur + 1);
            psn = 0;
            cbHeader = 3;
            break;

        case ACK:
            cbHeader = 3;
            break;

        case NEGATIVE_ACK:
            /* Variable number of missing packets */
            numMissing = tvb_get_guint8(tvb, offCur + 3);
            cbHeader = numMissing + 4;
            break;

        default:
            break;
    };
    if (fRID) {
        /*returned_length =*/ g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " R" );
        /*str_index += MIN(returned_length, SZINFO_SIZE-str_index);*/
    };
    /* In the interest of speed, if "tree" is NULL, don't do any work not
       necessary to generate protocol tree items. */
    if (tree) {
#ifdef DEBUG
        fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader);
#endif
        /* NOTE - Length will be set when we process the TPI */
        ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 0, ENC_NA);
#ifdef DEBUG
        fprintf(stderr, "dissect_wtp: (7) Returned from proto_tree_add_item\n");
#endif
        wtp_tree = proto_item_add_subtree(ti, ett_wtp);

        /* Code to process the packet goes here */
#ifdef DEBUG
        fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader);
        fprintf(stderr, "dissect_wtp: offCur = %d\n", offCur);
#endif
        /* Add common items: only CON and PDU Type */
        proto_tree_add_item(
                wtp_tree,             /* tree */
                hf_wtp_header_flag_continue,     /* id */
                tvb,
                offCur,             /* start of highlight */
                1,                /* length of highlight*/
                b0                /* value */
                );
        proto_tree_add_item(wtp_tree, hf_wtp_header_pdu_type, tvb, offCur, 1, ENC_LITTLE_ENDIAN);

        switch(pdut) {
            case INVOKE:
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

                proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_version , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_TIDNew, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_UP, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_Reserved, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_TransactionClass, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                proto_item_append_text(ti,
                        ", PDU: Invoke (%u)"
                        ", Transaction Class: %s (%u)",
                        INVOKE,
                        val_to_str_const(clsTransaction, vals_transaction_classes, "Undefined"),
                        clsTransaction);
                break;

            case RESULT:
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_item_append_text(ti, ", PDU: Result (%u)", RESULT);
                break;

            case ACK:
                proto_tree_add_item(wtp_tree, hf_wtp_header_Ack_flag_TVETOK, tvb, offCur, 1, ENC_BIG_ENDIAN);

                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_item_append_text(ti, ", PDU: ACK (%u)", ACK);
                break;

            case ABORT:
                abortType = tvb_get_guint8 (tvb, offCur) & 0x07;
                proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_type , tvb, offCur , 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

                if (abortType == PROVIDER) {
                    guint8 reason = tvb_get_guint8(tvb, offCur + 3);
                    proto_tree_add_item( wtp_tree, hf_wtp_header_Abort_reason_provider , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti,
                            ", PDU: Abort (%u)"
                            ", Type: Provider (%u)"
                            ", Reason: %s (%u)",
                            ABORT,
                            PROVIDER,
                            val_to_str_const(reason, vals_abort_reason_provider, "Undefined"),
                            reason);
                }
                else if (abortType == USER) {
                    guint8 reason = tvb_get_guint8(tvb, offCur + 3);
                    proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_reason_user , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti,
                            ", PDU: Abort (%u)"
                            ", Type: User (%u)"
                            ", Reason: %s (%u)",
                            ABORT,
                            PROVIDER,
                            val_to_str_ext_const(reason, &vals_wsp_reason_codes_ext, "Undefined"),
                            reason);
                }
                break;

            case SEGMENTED_INVOKE:
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

                proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                proto_item_append_text(ti,
                        ", PDU: Segmented Invoke (%u)"
                        ", Packet Sequence Number: %u",
                        SEGMENTED_INVOKE, psn);
                break;

            case SEGMENTED_RESULT:
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

                proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                proto_item_append_text(ti,
                        ", PDU: Segmented Result (%u)"
                        ", Packet Sequence Number: %u",
                        SEGMENTED_RESULT, psn);
                break;

            case NEGATIVE_ACK:
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
                proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

                proto_tree_add_item(wtp_tree, hf_wtp_header_missing_packets , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
                /* Iterate through missing packets */
                for (i = 0; i < numMissing; i++)
                {
                    proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, ENC_LITTLE_ENDIAN);
                }
                proto_item_append_text(ti,
                        ", PDU: Negative Ack (%u)"
                        ", Missing Packets: %u",
                        NEGATIVE_ACK, numMissing);
                break;

            default:
                break;
        };
        if (fRID) {
            proto_item_append_text(ti, ", Retransmission");
        }
    } else { /* tree is NULL */
#ifdef DEBUG
        fprintf(stderr, "dissect_wtp: (4) tree was %p\n", tree);
#endif
    }
    /* Process the variable part */
    if (fCon) {            /* Now, analyze variable part    */
        guint8    tCon;
        guint8    tByte;
        guint     tpiLen;
        tvbuff_t *tmp_tvb;

        vHeader = 0;        /* Start scan all over    */

        do {
            tByte = tvb_get_guint8(tvb, offCur + cbHeader + vHeader);
            tCon = tByte & 0x80;
            if (tByte & 0x04)    /* Long TPI    */
                tpiLen = 2 + tvb_get_guint8(tvb, offCur + cbHeader + vHeader + 1);
            else
                tpiLen = 1 + (tByte & 0x03);
            if (tree)
            {
                tmp_tvb = tvb_new_subset_length(tvb, offCur + cbHeader + vHeader, tpiLen);
                wtp_handle_tpi(wtp_tree, tmp_tvb);
            }
            vHeader += tpiLen;
        } while (tCon);
    } else {
        /* There is no variable part */
    }    /* End of variable part of header */

    /* Set the length of the WTP protocol part now we know the length of the
     * fixed and variable WTP headers */
    if (tree)
        proto_item_set_len(ti, cbHeader + vHeader);

#ifdef DEBUG
    fprintf( stderr, "dissect_wtp: cbHeader = %d\n", cbHeader );
#endif

    /*
     * Any remaining data ought to be WSP data (if not WTP ACK, NACK
     * or ABORT pdu), so, if we have any remaining data, and it's
     * not an ACK, NACK, or ABORT PDU, hand it off (defragmented) to the
     * WSP dissector.
     * Note that the last packet of a fragmented WTP message needn't
     * contain any data, so we allow payloadless packets to be
     * reassembled.  (XXX - does the reassembly code handle this
     * for packets other than the last packet?)
     *
     * Try calling a subdissector only if:
     *    - The WTP payload is ressembled in this very packet,
     *    - The WTP payload is not fragmented across packets.
     */
    dataOffset = offCur + cbHeader + vHeader;
    dataLen = tvb_reported_length_remaining(tvb, dataOffset);
    if ((dataLen >= 0) &&
            ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT)))
    {
        /* Try to reassemble if needed, and hand over to WSP
         * A fragmented WTP packet is either:
         *    - An INVOKE with fTTR (transmission trailer) not set,
         *    - a SEGMENTED_INVOKE,
         *    - A RESULT with fTTR (transmission trailer) not set,
         *    - a SEGMENTED_RESULT.
         */
        if ( ( (pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT)
                    || ( ((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR) )
             ) && tvb_bytes_exist(tvb, dataOffset, dataLen) )
        {
            /* Try reassembling fragments */
            fragment_head *fd_wtp = NULL;
            guint32 reassembled_in = 0;
            gboolean save_fragmented = pinfo->fragmented;

            pinfo->fragmented = TRUE;
            fd_wtp = fragment_add_seq(&wtp_reassembly_table, tvb, dataOffset,
                    pinfo, TID, NULL, psn, dataLen, !fTTR, 0);
            /* XXX - fragment_add_seq() yields NULL unless Wireshark knows
             * that the packet is part of a reassembled whole. This means
             * that fd_wtp will be NULL as long as Wireshark did not encounter
             * (and process) the packet containing the last fragment.
             * This implies that Wireshark needs two passes over the data for
             * correct reassembly. At the first pass, a capture containing
             * three fragments plus a retransmssion of the last fragment
             * will progressively show:
             *
             *        Packet 1: (Unreassembled fragment 1)
             *        Packet 2: (Unreassembled fragment 2)
             *        Packet 3: (Reassembled WTP)
             *        Packet 4: (WTP payload reassembled in packet 3)
             *
             * However at subsequent evaluation (e.g., by applying a display
             * filter) the packet summary will show:
             *
             *        Packet 1: (WTP payload reassembled in packet 3)
             *        Packet 2: (WTP payload reassembled in packet 3)
             *        Packet 3: (Reassembled WTP)
             *        Packet 4: (WTP payload reassembled in packet 3)
             *
             * This is important to know, and also affects read filters!
             */
            wsp_tvb = process_reassembled_data(tvb, dataOffset, pinfo,
                    "Reassembled WTP", fd_wtp, &wtp_frag_items,
                    NULL, wtp_tree);
#ifdef DEBUG
            proto_tree_add_debug_text(tree, "WTP: Packet %u %s -> %d: wsp_tvb = %p, fd_wtp = %p, frame = %u\n",
                    pinfo->num,
                    fd_wtp ? "Reassembled" : "Not reassembled",
                    fd_wtp ? fd_wtp->reassembled_in : -1,
                    wsp_tvb,
                    fd_wtp
                  );
#endif
            if (fd_wtp) {
                /* Reassembled */
                reassembled_in = fd_wtp->reassembled_in;
                if (pinfo->num == reassembled_in) {
                    /* Reassembled in this very packet:
                     * We can safely hand the tvb to the WSP dissector */
                    call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
                } else {
                    /* Not reassembled in this packet */
                    col_append_fstr(pinfo->cinfo, COL_INFO,
                            "%s (WTP payload reassembled in packet %u)",
                            szInfo, fd_wtp->reassembled_in);

                    proto_tree_add_item(wtp_tree, hf_wtp_payload, tvb, dataOffset, -1, ENC_NA);
                }
            } else {
                /* Not reassembled yet, or not reassembled at all */
                col_append_fstr(pinfo->cinfo, COL_INFO,
                        "%s (Unreassembled fragment %u)",
                        szInfo, psn);
                proto_tree_add_item(wtp_tree, hf_wtp_payload, tvb, dataOffset, -1, ENC_NA);
            }
            /* Now reset fragmentation information in pinfo */
            pinfo->fragmented = save_fragmented;
        }
        else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) )
        {
            /* Non-fragmented payload */
            wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset);
            /* We can safely hand the tvb to the WSP dissector */
            call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
        }
        else
        {
            /* Nothing to hand to subdissector */
            col_append_str(pinfo->cinfo, COL_INFO, szInfo);
        }
    }
    else
    {
        /* Nothing to hand to subdissector */
        col_append_str(pinfo->cinfo, COL_INFO, szInfo);
    }
}
コード例 #21
0
ファイル: packet-icep.c プロジェクト: MultipathDTLS/wireshark
static void dissect_icep_reply(tvbuff_t *tvb, guint32 offset,
                               packet_info *pinfo, proto_tree *icep_tree, proto_item* icep_item)
{
    /*  p. 614, chapter 23.3.4:
     *
     *  struct ReplyData {
     *   int requestId;
     *   byte replyStatus;
     *   [... messageSize - 19 bytes ...  ]
     *  }
     */

    gint32 messageSize = 0;
    guint32 tvb_data_remained = 0;
    guint32 reported_reply_data = 0;
    proto_item *ti = NULL;
    proto_tree *icep_sub_tree = NULL;

    DBG0("dissect reply\n");

    /* get at least a full reply message header */

    if ( !tvb_bytes_exist(tvb, offset, ICEP_MIN_REPLY_SIZE) ) {

        expert_add_info_format(pinfo, icep_item, &ei_icep_length, "too short header");

        col_append_str(pinfo->cinfo, COL_INFO, " (too short header)");
        return;
    }

    /* got 5 bytes, then data */

    /* create display subtree for this message type */

    icep_sub_tree = proto_tree_add_subtree(icep_tree, tvb, offset, -1,
                     ett_icep_msg, &ti, "Reply Message Body");

    proto_tree_add_item(icep_sub_tree, hf_icep_request_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);

    col_append_fstr(pinfo->cinfo, COL_INFO, "(%d):", tvb_get_letohl(tvb, offset));

    offset += 4;

    proto_tree_add_item(icep_sub_tree, hf_icep_reply_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);

    col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
                val_to_str_const(tvb_get_guint8(tvb, offset),
                                                 icep_replystatus_vals,
                                                 "unknown reply status"));

    offset++;

    DBG1("consumed --> %d\n", 5);

    /* check if I got all reply data */
    tvb_data_remained = tvb_length_remaining(tvb, offset);
    messageSize = tvb_get_letohl(tvb, 10);
    reported_reply_data = messageSize - (ICEP_HEADER_SIZE + ICEP_MIN_REPLY_SIZE);

    /* no */
    if ( tvb_data_remained < reported_reply_data ) {

        expert_add_info_format(pinfo, ti, &ei_icep_reply_data, "Reply Data (missing %d bytes out of %d)", reported_reply_data - tvb_data_remained, reported_reply_data);

        col_append_fstr(pinfo->cinfo, COL_INFO,
                    " (missing reply data, %d bytes)",
                    reported_reply_data - tvb_data_remained);

        /*offset += tvb_data_remained;*/
        DBG1("consumed --> %d\n", tvb_data_remained);
        return;
    }

    /* yes (reported_reply_data can be 0) */

    proto_tree_add_item(icep_sub_tree, hf_icep_reply_data, tvb, offset, reported_reply_data, ENC_NA);

    /*offset += reported_reply_data;*/
    DBG1("consumed --> %d\n", reported_reply_data);
}
コード例 #22
0
static void
dissect_aodv_draft_01_v6_rreq(tvbuff_t *tvb, packet_info *pinfo,
			      proto_tree *aodv_tree, proto_item *ti)
{
    int                offset = 1;
    proto_item        *tj;
    proto_tree        *aodv_flags_tree;
    guint8             flags;
    guint8             hop_count;
    guint32            rreq_id;
    guint32            dest_seqno;
    guint32            orig_seqno;
    struct e_in6_addr  dest_addr_v6;
    struct e_in6_addr  orig_addr_v6;
    int                extlen;

    flags = tvb_get_guint8(tvb, offset);
    if (aodv_tree) {
	tj = proto_tree_add_text(aodv_tree, tvb, offset, 1, "Flags:");
	aodv_flags_tree = proto_item_add_subtree(tj, ett_aodv_flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_join,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_repair,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_gratuitous,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_destinationonly,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_unknown,
			       tvb, offset, 1, flags);
	if (flags & RREQ_JOIN)
	    proto_item_append_text(tj, " J");
	if (flags & RREQ_REP)
	    proto_item_append_text(tj, " R");
	if (flags & RREQ_GRATRREP)
	    proto_item_append_text(tj, " G");
	if (flags & RREQ_DESTONLY)
	    proto_item_append_text(tj, " D");
	if (flags & RREQ_UNKNSEQ)
	    proto_item_append_text(tj, " U");
    }
    offset += 2;	/* skip reserved byte */

    hop_count = tvb_get_guint8(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_hopcount, tvb, offset, 1,
			     hop_count);
    offset += 1;

    rreq_id = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_rreq_id, tvb, offset, 4,
			    rreq_id);
    offset += 4;

    dest_seqno = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_dest_seqno, tvb, offset, 4,
			    dest_seqno);
    offset += 4;

    orig_seqno = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_orig_seqno, tvb, offset, 4,
			    orig_seqno);
    offset += 4;

    tvb_get_ipv6(tvb, offset, &dest_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_dest_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&dest_addr_v6);
	proto_item_append_text(ti, ", Dest IP: %s",
			       ip6_to_str(&dest_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, ", D: %s",
			ip6_to_str(&dest_addr_v6));
    offset += INET6_ADDRLEN;

    tvb_get_ipv6(tvb, offset, &orig_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_orig_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&orig_addr_v6);
	proto_item_append_text(ti, ", Orig IP: %s",
			       ip6_to_str(&orig_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO,
			", O: %s Id=%u Hcnt=%u DSN=%u OSN=%u",
			ip6_to_str(&orig_addr_v6),
			rreq_id,
			hop_count,
			dest_seqno,
			orig_seqno);
    offset += INET6_ADDRLEN;

    if (aodv_tree) {
	extlen = tvb_reported_length_remaining(tvb, offset);
	if (extlen > 0)
	    dissect_aodv_ext(tvb, offset, aodv_tree);
    }
}
コード例 #23
0
/*
* Dissect RTSE PDUs inside a PPDU.
*/
static void
dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	int old_offset;
	proto_item *item=NULL;
	proto_tree *tree=NULL;
	proto_tree *next_tree=NULL;
	tvbuff_t *next_tvb = NULL;
	tvbuff_t *data_tvb = NULL;
	fragment_head *frag_msg = NULL;
	guint32 fragment_length;
	guint32 rtse_id = 0;
	gboolean data_handled = FALSE;
	conversation_t *conversation = NULL;
	asn1_ctx_t asn1_ctx;
	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);

	/* save parent_tree so subdissectors can create new top nodes */
	top_tree=parent_tree;

	/* do we have application context from the acse dissector?  */
	if( !pinfo->private_data ){
		if(parent_tree){
			proto_tree_add_text(parent_tree, tvb, offset, -1,
				"Internal error:can't get application context from ACSE dissector.");
		}
		return  ;
	} else {
		session  = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) );

	}

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSE");
  	col_clear(pinfo->cinfo, COL_INFO);

	if (rtse_reassemble &&
	    ((session->spdu_type == SES_DATA_TRANSFER) ||
	     (session->spdu_type == SES_MAJOR_SYNC_POINT))) {
		/* Use conversation index as fragment id */
		conversation  = find_conversation (pinfo->fd->num,
						   &pinfo->src, &pinfo->dst, pinfo->ptype,
						   pinfo->srcport, pinfo->destport, 0);
		if (conversation != NULL) {
			rtse_id = conversation->index;
		}
		session->rtse_reassemble = TRUE;
	}
	if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
		frag_msg = fragment_end_seq_next (&rtse_reassembly_table,
						  pinfo, rtse_id, NULL);
		next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE",
						     frag_msg, &rtse_frag_items, NULL, parent_tree);
	}
	if(parent_tree){
		item = proto_tree_add_item(parent_tree, proto_rtse, next_tvb ? next_tvb : tvb, 0, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_rtse);
	}
	if (rtse_reassemble && session->spdu_type == SES_DATA_TRANSFER) {
		/* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */
		dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hf_rtse_segment_data, &data_tvb);

		if (data_tvb) {
			fragment_length = tvb_length_remaining (data_tvb, 0);
			proto_item_append_text(asn1_ctx.created_item, " (%u byte%s)", fragment_length,
      	                              plurality(fragment_length, "", "s"));
			frag_msg = fragment_add_seq_next (&rtse_reassembly_table,
							  data_tvb, 0, pinfo,
							  rtse_id, NULL,
							  fragment_length, TRUE);
			if (frag_msg && pinfo->fd->num != frag_msg->reassembled_in) {
				/* Add a "Reassembled in" link if not reassembled in this frame */
				proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in),
						     data_tvb, 0, 0, frag_msg->reassembled_in);
			}
			pinfo->fragmented = TRUE;
			data_handled = TRUE;
		} else {
			fragment_length = tvb_length_remaining (tvb, offset);
		}

		col_append_fstr(pinfo->cinfo, COL_INFO, "[RTSE fragment, %u byte%s]",
					fragment_length, plurality(fragment_length, "", "s"));
	} else if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
		if (next_tvb) {
			/* ROS won't do this for us */
			session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT);
			offset=dissect_ber_external_type(FALSE, tree, next_tvb, 0, &asn1_ctx, -1, call_rtse_external_type_callback);
		} else {
			offset = tvb_length (tvb);
		}
		pinfo->fragmented = FALSE;
		data_handled = TRUE;
	}

	if (!data_handled) {
		while (tvb_reported_length_remaining(tvb, offset) > 0){
			old_offset=offset;
			offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1);
			if(offset == old_offset){
				item = proto_tree_add_text(tree, tvb, offset, -1, "Unknown RTSE PDU");

				expert_add_info (pinfo, item, &ei_rtse_unknown_rtse_pdu);
				next_tree=proto_item_add_subtree(item, ett_rtse_unknown);
				dissect_unknown_ber(pinfo, tvb, offset, next_tree);
				break;
			}
		}
	}

	top_tree = NULL;
}
コード例 #24
0
static void
dissect_aodv_draft_01_v6_rrep(tvbuff_t *tvb, packet_info *pinfo,
			      proto_tree *aodv_tree, proto_item *ti)
{
    int                offset = 1;
    proto_item        *tj;
    proto_tree        *aodv_flags_tree;
    guint8             flags;
    guint8             prefix_sz;
    guint8             hop_count;
    guint32            dest_seqno;
    struct e_in6_addr  dest_addr_v6;
    struct e_in6_addr  orig_addr_v6;
    guint32            lifetime;
    int                extlen;

    flags = tvb_get_guint8(tvb, offset);
    if (aodv_tree) {
	tj = proto_tree_add_text(aodv_tree, tvb, offset, 1, "Flags:");
	aodv_flags_tree = proto_item_add_subtree(tj, ett_aodv_flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rrep_repair,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rrep_ack, tvb,
			       offset, 1, flags);
	if (flags & RREP_REP)
	    proto_item_append_text(tj, " R");
	if (flags & RREP_ACK_REQ)
	    proto_item_append_text(tj, " A");
    }
    offset += 1;

    prefix_sz = tvb_get_guint8(tvb, offset) & 0x7F;
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_prefix_sz, tvb, offset, 1,
			    prefix_sz);
    offset += 1;

    hop_count = tvb_get_guint8(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_hopcount, tvb, offset, 1,
			    hop_count);
    offset += 1;

    dest_seqno = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_dest_seqno, tvb, offset, 4,
			    dest_seqno);
    offset += 4;

    tvb_get_ipv6(tvb, offset, &dest_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_dest_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&dest_addr_v6);
	proto_item_append_text(ti, ", Dest IP: %s",
			       ip6_to_str(&dest_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, ", D: %s",
			ip6_to_str(&dest_addr_v6));
    offset += INET6_ADDRLEN;

    tvb_get_ipv6(tvb, offset, &orig_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_orig_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&orig_addr_v6);
	proto_item_append_text(ti, ", Orig IP: %s",
			       ip6_to_str(&orig_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, ", O: %s",
			ip6_to_str(&orig_addr_v6));
    offset += INET6_ADDRLEN;

    lifetime = tvb_get_ntohl(tvb, offset);
    if (aodv_tree) {
	proto_tree_add_uint(aodv_tree, hf_aodv_lifetime, tvb, offset, 4,
			    lifetime);
	proto_item_append_text(ti, ", Lifetime=%u", lifetime);
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, " Hcnt=%u DSN=%u Lifetime=%u",
			hop_count,
			dest_seqno,
			lifetime);
    offset += 4;

    if (aodv_tree) {
	extlen = tvb_reported_length_remaining(tvb, offset);
	if (extlen > 0)
	    dissect_aodv_ext(tvb, offset, aodv_tree);
    }
}
コード例 #25
0
/*
 * XXX - this causes non-browser packets to have browser fields.
 */
int
dissect_smb_server_type_flags(tvbuff_t *tvb, int offset, packet_info *pinfo,
			      proto_tree *parent_tree, guint8 *drep,
			      gboolean infoflag)
{
	guint32 flags;
	int i;

	static const int * type_flags[] = {
		&hf_server_type_workstation,
		&hf_server_type_server,
		&hf_server_type_sql,
		&hf_server_type_domain,
		&hf_server_type_backup,
		&hf_server_type_time,
		&hf_server_type_apple,
		&hf_server_type_novell,
		&hf_server_type_member,
		&hf_server_type_print,
		&hf_server_type_dialin,
		&hf_server_type_xenix,
		&hf_server_type_ntw,
		&hf_server_type_wfw,
		&hf_server_type_nts,
		&hf_server_type_potentialb,
		&hf_server_type_backupb,
		&hf_server_type_masterb,
		&hf_server_type_domainmasterb,
		&hf_server_type_osf,
		&hf_server_type_vms,
		&hf_server_type_w95,
		&hf_server_type_dfs,
		&hf_server_type_local,
		&hf_server_type_domainenum,
		NULL
	};

	if (drep != NULL) {
		/*
		 * Called from a DCE RPC protocol dissector, for a
		 * protocol where a 32-bit NDR integer contains
		 * an server type mask; extract the server type mask
		 * with an NDR call (but don't put it into the
		 * protocol tree, as we can't get a pointer to the
		 * item it puts in, and thus can't put a tree below
		 * it with the values of the individual bits).
		 */
		offset = dissect_ndr_uint32(
			tvb, offset, pinfo, NULL, NULL, drep, hf_server_type, &flags);
	} else {
		/*
		 * Called from SMB browser or RAP, where the server type
		 * mask is just a 4-byte little-endian quantity with no
		 * special NDR alignment requirement; extract it with
		 * "tvb_get_letohl()".
		 */
		flags = tvb_get_letohl(tvb, offset);
		offset += 4;
	}

	if (infoflag) {
		/* Append the type(s) of the system to the COL_INFO line ... */
		for (i = 0; i < 32; i++) {
			if (flags & (1U<<i)) {
				col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
					val_to_str(i, server_types,
					"Unknown server type:%d"));
			}
		}
	}

	proto_tree_add_bitmask_value(parent_tree, tvb, offset-4,
		hf_server_type, ett_browse_flags, type_flags, flags);

	return offset;
}
コード例 #26
0
static void
dissect_socketcan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree *can_tree;
	proto_item *ti;
	guint8      frame_type;
	gint        frame_len;
	struct can_identifier can_id;
	tvbuff_t*   next_tvb;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "CAN");
	col_clear(pinfo->cinfo,COL_INFO);

	frame_len  = tvb_get_guint8( tvb, CAN_LEN_OFFSET);
	can_id.id  = tvb_get_ntohl(tvb, 0);

	if (can_id.id & CAN_RTR_FLAG)
	{
		frame_type = LINUX_CAN_RTR;
	}
	else if (can_id.id & CAN_ERR_FLAG)
	{
		frame_type = LINUX_CAN_ERR;
	}
	else if (can_id.id & CAN_EFF_FLAG)
	{
		frame_type = LINUX_CAN_EXT;
	}
	else
	{
		frame_type = LINUX_CAN_STD;
	}

	can_id.id &= CAN_EFF_MASK;

	col_add_fstr(pinfo->cinfo, COL_INFO, "%s: 0x%08x",
		     val_to_str(frame_type, frame_type_vals, "Unknown (0x%02x)"), can_id.id);
	col_append_fstr(pinfo->cinfo, COL_INFO, "   %s",
			tvb_bytes_to_ep_str_punct(tvb, CAN_DATA_OFFSET, frame_len, ' '));

	ti       = proto_tree_add_item(tree, proto_can, tvb, 0, -1, ENC_NA);
	can_tree = proto_item_add_subtree(ti, ett_can);

	proto_tree_add_item(can_tree, hf_can_ident,   tvb, 0, 4, ENC_BIG_ENDIAN);
	proto_tree_add_item(can_tree, hf_can_extflag, tvb, 0, 4, ENC_BIG_ENDIAN);
	proto_tree_add_item(can_tree, hf_can_rtrflag, tvb, 0, 4, ENC_BIG_ENDIAN);
	proto_tree_add_item(can_tree, hf_can_errflag, tvb, 0, 4, ENC_BIG_ENDIAN);

	proto_tree_add_item(can_tree, hf_can_len,     tvb, CAN_LEN_OFFSET, 1, ENC_BIG_ENDIAN);

	next_tvb = tvb_new_subset_length(tvb, CAN_DATA_OFFSET, frame_len);

	switch (can_high_level_protocol_dissector)
	{
		case CAN_DATA_DISSECTOR:
			call_dissector(data_handle, next_tvb, pinfo, tree);
			break;
		case CAN_CANOPEN_DISSECTOR:
			call_dissector_with_data(canopen_handle, next_tvb, pinfo, tree, &can_id);
			break;
		case CAN_DEVICENET_DISSECTOR:
			/* XXX - Not sure this is correct.  But the capture provided in
             * bug 8564 provides CAN ID in little endian format, so this makes it work */
			can_id.id = GUINT32_SWAP_LE_BE(can_id.id);

			call_dissector_with_data(devicenet_handle, next_tvb, pinfo, tree, &can_id);
			break;
		case CAN_J1939_DISSECTOR:
			call_dissector_with_data(j1939_handle, next_tvb, pinfo, tree, &can_id);
			break;
	}
}
コード例 #27
0
ファイル: packet-btobex.c プロジェクト: asriadi/wireshark
static void
dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item    *ti;
    proto_tree    *st;
    fragment_data *frag_msg       = NULL;
    gboolean       save_fragmented, complete;
    tvbuff_t*      new_tvb        = NULL;
    tvbuff_t*      next_tvb       = NULL;
    guint32        no_of_segments = 0;
    int            offset         = 0;

    save_fragmented = pinfo->fragmented;

    frag_msg = NULL;
    complete = FALSE;

    if (fragment_get(pinfo, pinfo->p2p_dir, fragment_table)) {
        /* not the first fragment */
        frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
                                fragment_table, reassembled_table, tvb_length(tvb), TRUE);

        new_tvb = process_reassembled_data(tvb, 0, pinfo,
                        "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);

        pinfo->fragmented = TRUE;
    }
    else    {
        if (tvb_length(tvb) < tvb_get_ntohs(tvb, offset+1)) {
            /* first fragment in a sequence */
            no_of_segments = tvb_get_ntohs(tvb, offset+1)/tvb_length(tvb);
            if (tvb_get_ntohs(tvb, offset+1) > (no_of_segments * tvb_length(tvb)))
                no_of_segments++;

            frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
                                fragment_table, reassembled_table, tvb_length(tvb), TRUE);

            fragment_set_tot_len(pinfo, pinfo->p2p_dir, fragment_table, no_of_segments-1);

            new_tvb = process_reassembled_data(tvb, 0, pinfo,
                        "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);

            pinfo->fragmented = TRUE;
            }
        else if (tvb_length(tvb) == tvb_get_ntohs(tvb, offset+1)) {
            /* non-fragmented */
            complete = TRUE;
            pinfo->fragmented = FALSE;
        }
    }

    if (new_tvb) { /* take it all */
        next_tvb = new_tvb;
        complete = TRUE;
    }
    else { /* make a new subset */
        next_tvb = tvb_new_subset_remaining(tvb, offset);
    }

    if (complete) {
        guint8 code, final_flag;

        /* fully dissectable packet ready */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBEX");

        ti = proto_tree_add_item(tree, proto_btobex, next_tvb, 0, -1, ENC_NA);
        st = proto_item_add_subtree(ti, ett_btobex);

        /* op/response code */
        code = tvb_get_guint8(next_tvb, offset) & BTOBEX_CODE_VALS_MASK;
        final_flag = tvb_get_guint8(next_tvb, offset) & 0x80;

        switch (pinfo->p2p_dir)
        {
        case P2P_DIR_SENT:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Sent ");
            break;

        case P2P_DIR_RECV:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;

        case P2P_DIR_UNKNOWN:
            break;

        default:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
                pinfo->p2p_dir);
            break;
        }

        col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
                        val_to_str_ext_const(code, &code_vals_ext, "Unknown"));

        if ((code < BTOBEX_CODE_VALS_CONTINUE) || (code == BTOBEX_CODE_VALS_ABORT)) {
            proto_tree_add_item(st, hf_opcode, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            if (pinfo->p2p_dir == P2P_DIR_SENT || pinfo->p2p_dir == P2P_DIR_RECV) {
                last_opcode[pinfo->p2p_dir] = code;
            }
            }
        else    {
            proto_tree_add_item(st, hf_response_code, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            }
        proto_tree_add_item(st, hf_final_flag, next_tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;

        /* length */
        proto_tree_add_item(st, hf_length, next_tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        switch(code)
        {
        case BTOBEX_CODE_VALS_CONNECT:
            proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
            break;

        case BTOBEX_CODE_VALS_PUT:
        case BTOBEX_CODE_VALS_GET:
            col_append_fstr(pinfo->cinfo, COL_INFO, " %s",  (final_flag == 0x80) ? "final" : "continue");
            break;

        case BTOBEX_CODE_VALS_SET_PATH:
            proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(st, hf_set_path_flags_0, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(st, hf_set_path_flags_1, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_constants, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;
            break;

        case BTOBEX_CODE_VALS_DISCONNECT:
        case BTOBEX_CODE_VALS_ABORT:
            break;

        default:
            {
                guint8 response_opcode = last_opcode[(pinfo->p2p_dir + 1) & 0x01];

                if (response_opcode == BTOBEX_CODE_VALS_CONNECT) {
                    proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset++;

                    proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset++;

                    proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;
                }
            }
            break;
        }

        dissect_headers(st, next_tvb, offset, pinfo);
    }
    else
    {
        /* packet fragment */
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s Obex fragment",
                     (pinfo->p2p_dir==P2P_DIR_SENT) ? "Sent" : "Rcvd");

        call_dissector(data_handle, next_tvb, pinfo, tree);
    }

    pinfo->fragmented = save_fragmented;
}
コード例 #28
0
/*
 * Dissect a standard (reliable) ts2 packet, reassembling if required.
 */
static void ts2_standard_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ts2_tree, ts2_conversation *conversation_data)
{
	guint8 save_fragmented;
	tvbuff_t *new_tvb, *next_tvb;
	fragment_data *frag_msg ;
	guint16 fragment_number;
	ts2_frag *frag;
	gboolean outoforder;

	guint16 type = tvb_get_letohs(tvb, 2);
	/*guint16 klass = tvb_get_letohs(tvb, 0);*/
	proto_tree_add_item(ts2_tree, hf_ts2_seqnum, tvb, 12, 4, TRUE);

	/* XXX: Following fragmentation stuff should be separate from the GUI stuff ??    */
	/* Get our stored fragmentation data or create one! */
	if ( ! ( frag = p_get_proto_data(pinfo->fd, proto_ts2) ) ) {
		frag = se_alloc(sizeof(ts2_frag));
		frag->frag_num=0;
	}

	/* decide if the packet is server to client or client to server
	 * then check its fragmentation
	 */
	if(!(pinfo->fd->flags.visited))
	{
		if(conversation_data->server_port == pinfo->srcport)
		{
			frag->fragmented = ts2_standard_find_fragments(tvb, &conversation_data->last_inorder_server_frame, &conversation_data->server_frag_size, &conversation_data->server_frag_num, &outoforder);
			frag->frag_num=conversation_data->server_frag_num;
			frag->frag_size=conversation_data->server_frag_size;
		}
		else
		{

			frag->fragmented = ts2_standard_find_fragments(tvb, &conversation_data->last_inorder_client_frame, &conversation_data->client_frag_size, &conversation_data->client_frag_num, &outoforder);
			frag->frag_num=conversation_data->client_frag_num;
			frag->frag_size=conversation_data->client_frag_size;
		}
		frag->outoforder=outoforder;
		p_add_proto_data(pinfo->fd, proto_ts2, frag);
	}

	/* Get our stored fragmentation data */
	frag = p_get_proto_data(pinfo->fd, proto_ts2);

	proto_tree_add_item(ts2_tree, hf_ts2_resend_count, tvb, 16, 2, TRUE);
	proto_tree_add_item(ts2_tree, hf_ts2_fragmentnumber, tvb, 18, 2, TRUE);
	ts2_add_checked_crc32(ts2_tree, hf_ts2_crc32, tvb, 20, tvb_get_letohl(tvb, 20));

	/* Reassemble the packet if its fragmented */
	new_tvb = NULL;
	if(frag->fragmented)
	{
		save_fragmented = pinfo->fragmented;
		frag_msg = NULL;
		pinfo->fragmented = TRUE;
		fragment_number = tvb_get_letohs(tvb, 18);
		frag_msg = fragment_add_seq_check(tvb, 24, pinfo, type,	msg_fragment_table, msg_reassembled_table, frag->frag_num, tvb_length_remaining(tvb, 24), fragment_number);
		new_tvb = process_reassembled_data(tvb, 24, pinfo,"Reassembled TeamSpeak2", frag_msg, &msg_frag_items, NULL, ts2_tree);
		if (frag_msg)
		{ /* Reassembled */
			col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled)");
		}
		else
		{ /* Not last packet of reassembled Short Message */
			if (check_col(pinfo->cinfo, COL_INFO))col_append_fstr(pinfo->cinfo, COL_INFO," (Message fragment %u)", frag->frag_num);
		}
		if (new_tvb)
			next_tvb = new_tvb;
		else
			next_tvb = tvb_new_subset_remaining(tvb, 24);
		pinfo->fragmented = save_fragmented;
	}
	else
		next_tvb = tvb_new_subset_remaining(tvb, 24);

	/* If we have a full packet now dissect it */
	if((new_tvb || !frag->fragmented) && !frag->outoforder)
	{
		switch(type)
		{
			case TS2T_LOGINPART2:
				ts2_parse_loginpart2(next_tvb, ts2_tree);
				break;
			case TS2T_CHANNELLIST:
				ts2_parse_channellist(next_tvb, ts2_tree);
				break;
			case TS2T_PLAYERLIST:
				ts2_parse_playerlist(next_tvb, ts2_tree);
				break;
			case TS2T_NEWPLAYERJOINED:
				ts2_parse_newplayerjoined(next_tvb, ts2_tree);
				break;
			case TS2T_KNOWNPLAYERUPDATE:
				ts2_parse_knownplayerupdate(next_tvb, ts2_tree);
				break;
			case TS2T_PLAYERLEFT:
				ts2_parse_playerleft(next_tvb, ts2_tree);
				break;
			case TS2T_PLAYERKICKED:
				ts2_parse_playerleft(next_tvb, ts2_tree);
				break;
			case TS2T_LOGINEND:
				ts2_parse_loginend(next_tvb, ts2_tree);
				break;
			case TS2T_CHANGESTATUS:
				ts2_parse_changestatus(next_tvb, ts2_tree);
				break;
			case TS2T_SWITCHCHANNEL:
				ts2_parse_switchchannel(next_tvb, ts2_tree);
				break;
			case TS2T_CHANNELCHANGE:
				ts2_parse_channelchange(next_tvb, ts2_tree);
				break;
		}
	}
	/* The packet is out of order, update the cinfo and ignore the packet */
	if(frag->outoforder)
		col_append_str(pinfo->cinfo, COL_INFO, " (Out Of Order, ignored)");
}
コード例 #29
0
	/* echo(4) */
	proto_tree_add_uint(xtp_subtree, hf_xtp_cntl_echo,
			tvb, offset, 4, cntl->echo);

	return;
}

static void
dissect_xtp_first(tvbuff_t *tvb, proto_tree *tree, guint32 offset) {

	if (!dissect_xtp_aseg(tvb, tree, offset))
		return;

	offset += XTP_IP_ADDR_SEG_LEN;
	dissect_xtp_tspec(tvb, tree, offset);

	return;
}

#define XTP_MAX_NSPANS 10000 /* Arbitrary. (Documentation link is dead.) */
static void
dissect_xtp_ecntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		guint32 offset) {
	guint32 len = tvb_length_remaining(tvb, offset);
	guint32 start = offset;
	proto_item *top_ti;
	proto_tree *xtp_subtree;
	struct xtp_ecntl ecntl[1];
	guint spans_len;
	guint i;

	top_ti = proto_tree_add_text(tree, tvb, offset, len,
				"Error Control Segment");
	xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_ecntl);

	if (len < MIN_XTP_ECNTL_PKT_LEN) {
		proto_item_append_text(top_ti,
				", bogus length (%u, must be at least %u)",
				len, MIN_XTP_ECNTL_PKT_LEN);
		return;
	}

	/** parse **/
	/* rseq(8) */
	ecntl->rseq = tvb_get_ntohl(tvb, offset);
	ecntl->rseq <<= 32;
	ecntl->rseq += tvb_get_ntohl(tvb, offset+4);
	offset += 8;
	/* alloc(8) */
	ecntl->alloc = tvb_get_ntohl(tvb, offset);
	ecntl->alloc <<= 32;
	ecntl->alloc += tvb_get_ntohl(tvb, offset+4);
	offset += 8;
	/* echo(4) */
	ecntl->echo = tvb_get_ntohl(tvb, offset);
	offset += 4;
	/* nspan(4) */
	ecntl->nspan = tvb_get_ntohl(tvb, offset);
	offset += 4;
	len = len + XTP_HEADER_LEN - offset;
	spans_len = 16 * ecntl->nspan;

	if (len != spans_len) {
		expert_add_info_format(pinfo, top_ti, &ei_xtp_spans_bad, "Number of spans (%u) incorrect. Should be %u.", ecntl->nspan, len);
		THROW(ReportedBoundsError);
	}

	if (ecntl->nspan > XTP_MAX_NSPANS) {
		expert_add_info_format(pinfo, top_ti, &ei_xtp_spans_bad, "Too many spans: %u", ecntl->nspan);
		THROW(ReportedBoundsError);
	}

	/** add summary **/
	col_append_fstr(pinfo->cinfo, COL_INFO,
				" Recv-Seq=%" G_GINT64_MODIFIER "u", ecntl->rseq);
	col_append_fstr(pinfo->cinfo, COL_INFO,
				" Alloc=%" G_GINT64_MODIFIER "u", ecntl->alloc);

	proto_item_append_text(top_ti,
				", Recv-Seq: %" G_GINT64_MODIFIER "u", ecntl->rseq);

	/** display **/
	offset = start;
	/* rseq(8) */
	proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_rseq,
				tvb, offset, 8, ecntl->rseq);
	offset += 8;
	/* alloc(8) */
	proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_alloc,
				tvb, offset, 8, ecntl->alloc);
	offset += 8;
	/* echo(4) */
	proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_echo,
				tvb, offset, 4, ecntl->echo);
	offset += 4;
	/* nspan(4) */
	proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_nspan,
				tvb, offset, 4, ecntl->nspan);
	offset += 4;
	/* spans(16n) */
	for (i = 0; i < ecntl->nspan; i++) {
		proto_tree_add_item(xtp_subtree, hf_xtp_ecntl_span_left,
				tvb, offset, 8, ENC_LITTLE_ENDIAN);
		offset += 8;
		proto_tree_add_item(xtp_subtree, hf_xtp_ecntl_span_right,
				tvb, offset, 8, ENC_LITTLE_ENDIAN);
		offset += 8;
	}

	return;
}
コード例 #30
0
ファイル: packet-ancp.c プロジェクト: CharaD7/wireshark
static void
dissect_ancp_adj_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ancp_tree,
                     gint offset, struct ancp_tap_t *ancp_info
)
{
    proto_item *sti;
    proto_tree *ancp_cap_tree;
    guint8      byte, numcaps, adjcode;
    guint16     tlv_len;

    sti = proto_tree_add_item(ancp_tree, hf_ancp_timer, tvb, offset, 1,
            ENC_BIG_ENDIAN);
    offset += 1;
    proto_item_append_text(sti, " msec");

    sti = proto_tree_add_item(ancp_tree, hf_ancp_adj_code, tvb, offset, 1,
            ENC_BIG_ENDIAN);
    byte = tvb_get_guint8(tvb, offset);
    offset += 1;
    adjcode = byte & ADJ_CODE_MASK;
    ancp_info->ancp_adjcode = adjcode; /* stats */
    proto_item_append_text(sti, " (%s, M Flag %s)",
            val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"),
            (byte >> 7) ? "Set" : "Unset");
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
            val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"));

    proto_tree_add_item(ancp_tree, hf_ancp_sender_name, tvb, offset, 6, ENC_NA);
    offset += 6;

    proto_tree_add_item(ancp_tree, hf_ancp_receiver_name, tvb,offset, 6, ENC_NA);
    offset += 6;

    proto_tree_add_item(ancp_tree, hf_ancp_sender_port, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    proto_tree_add_item(ancp_tree, hf_ancp_receiver_port, tvb,offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    sti = proto_tree_add_item(ancp_tree, hf_ancp_p_info, tvb,
            offset, 1, ENC_BIG_ENDIAN);
    byte = tvb_get_guint8(tvb, offset);
    offset += 1;
    proto_item_append_text(sti, " (Type = %d, Flag = %d)",
            byte >> 4, byte & 0x0F);

    proto_tree_add_item(ancp_tree, hf_ancp_sender_instance, tvb, offset, 3, ENC_BIG_ENDIAN);
    offset += 3;

    proto_tree_add_item(ancp_tree, hf_ancp_p_id, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    proto_tree_add_item(ancp_tree, hf_ancp_receiver_instance, tvb, offset, 3, ENC_BIG_ENDIAN);
    offset += 3;

    proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    sti = proto_tree_add_item(ancp_tree, hf_ancp_num_tlvs, tvb, offset, 1, ENC_BIG_ENDIAN);
    numcaps = tvb_get_guint8(tvb, offset);
    offset += 1;

    /* Start the capability subtree */
    ancp_cap_tree = proto_item_add_subtree(sti, ett_ancp_tot_len);

    proto_tree_add_item(ancp_cap_tree, hf_ancp_tot_len, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    for ( ;numcaps; numcaps--) {
        sti = proto_tree_add_item(ancp_cap_tree, hf_ancp_cap, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        tlv_len = tvb_get_ntohs(tvb, offset);
        offset += 2;
        proto_item_append_text(sti, " (%d bytes)", tlv_len);
        /* TODO - if there are non boolean caps, validate before use */
    }
}