Beispiel #1
0
/**
 * dissect_content_length is a utility function which
 * calculates how long is the payload section of the message
 * in bytes. Used only by the UDP dissector.
 *
 * @see dissect_packetid()
 * @see dissect_reliable_message_index_base()
 * @see dissect_reliable_message_number()
 * @see dissect_messageid()
 * @see dissect_payload()
 * @param buffer the buffer to the data
 * @param offset the offset where to start reading the data
 * @param tree the parent tree where the dissected data is going to be inserted
 * @return int returns the content length of the packet
 *
 */
static int
dissect_content_length(tvbuff_t *buffer, int offset, proto_tree *tree)
{
    proto_item *msgflags_ti;
    proto_tree *msgflags_tree;
    guint32     length;

    length  = tvb_get_bits8(buffer, offset * 8 + 12, 4) << 8;
    length += tvb_get_bits8(buffer, offset * 8, 8);

    if(tree != NULL)
    {
        msgflags_ti   = proto_tree_add_item(tree, hf_knet_msg_flags, buffer, offset + 1, 1, ENC_NA);
        msgflags_tree = proto_item_add_subtree(msgflags_ti, ett_knet_message_flags);

        proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_fs, buffer, offset * 8 + 8, 1, ENC_LITTLE_ENDIAN); /* Fragment start flag */
        proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_ff, buffer, offset * 8 + 9, 1, ENC_LITTLE_ENDIAN);  /* Fragment flag */
        proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_inorder, buffer, offset * 8 + 10, 1, ENC_LITTLE_ENDIAN); /* Inorder flag */
        proto_tree_add_bits_item(msgflags_tree, hf_knet_msg_reliable, buffer, offset * 8 + 11, 1, ENC_LITTLE_ENDIAN); /* Reliable flag */

        proto_tree_add_uint(tree, hf_knet_content_length, buffer, offset, 2, length);
    }

    return length;
}
Beispiel #2
0
static gboolean
dissect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint8 flags;
	gboolean crcok, dir, encrypted, micok;
	gboolean bad_length 			= FALSE;
	gboolean bad_mic 			= FALSE;
	gboolean bad_crc 			= FALSE;
	proto_item *flags_item, *item;
	
	flags 			= 	tvb_get_guint8(tvb, get_flags_index());
	crcok 			= 	!!(flags & 1);
	dir 			= 		!!(flags & 2);	
	encrypted 		= !!(flags & 4);	
	micok 			= 	!!(flags & 8);	
	
	if (dir)
	{
		SET_ADDRESS(&pinfo->src, AT_STRINGZ, 7, "Master");
		SET_ADDRESS(&pinfo->dst, AT_STRINGZ, 6, "Slave");
	} 
	else 
	{
		SET_ADDRESS(&pinfo->src, AT_STRINGZ, 6, "Slave");
		SET_ADDRESS(&pinfo->dst, AT_STRINGZ, 7, "Master");
	}	
	

	flags_item 			= proto_tree_add_item(tree, hf_nordic_ble_flags, tvb, get_flags_index(), 1, ENC_BIG_ENDIAN);
	//flags_tree 			= proto_item_add_subtree(flags_item, ett_flags);
	if (encrypted) // if encrypted, add MIC status
	{
		item 			= proto_tree_add_bits_item(tree, hf_nordic_ble_micok, tvb, get_flags_index()*8+4, 1, ENC_LITTLE_ENDIAN);
		if (!micok)
		{
			// /* MIC is bad */
            #if IS_VERSION_1_11
                expert_add_info(pinfo, item, &ei_nordic_ble_bad_mic);
            #elif IS_VERSION_1_10
                expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_WARN, "MIC is bad");
                expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "Decryption failed (wrong key?)");
            #endif
			bad_mic 			= TRUE;
		}
	}
	proto_tree_add_bits_item(tree, hf_nordic_ble_encrypted, tvb, get_flags_index()*8+5, 1, ENC_LITTLE_ENDIAN);
	proto_tree_add_bits_item(tree, hf_nordic_ble_direction, tvb, get_flags_index()*8+6, 1, ENC_LITTLE_ENDIAN);
	item 			= proto_tree_add_bits_item(tree, hf_nordic_ble_crcok, tvb, get_flags_index()*8+7, 1, ENC_LITTLE_ENDIAN);
	if(!crcok)
	{
		/* CRC is bad */
        #if IS_VERSION_1_11
            expert_add_info(pinfo, item, &ei_nordic_ble_bad_crc);
        #elif IS_VERSION_1_10
            expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "CRC is bad");
        #endif
		bad_crc			=TRUE;
	}
	return bad_mic;
}
Beispiel #3
0
static void gcsna_message_GCSNAL2Ack(proto_item *item, tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
    proto_tree *subtree = NULL;

    item = proto_tree_add_item(tree, hf_gcsna_l2ack, tvb, *offset, 1, ENC_NA);
    subtree = proto_item_add_subtree(item, ett_gcsna_subtree);

    proto_tree_add_bits_item(subtree, hf_gcsna_ackSequence, tvb, *offset * 8, 6, ENC_BIG_ENDIAN);
    *offset += 1;
}
Beispiel #4
0
void
dissect_fhs(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset)
{
	proto_item *fhs_item, *psmode_item;
	proto_tree *fhs_tree;
    const gchar *description;
	guint8 psmode;

	if(tvb_reported_length_remaining(tvb, offset) != 20) {
		col_add_str(pinfo->cinfo, COL_INFO, "Encrypted or malformed payload data");
		return;
	}

	fhs_item = proto_tree_add_item(tree, hf_btbredr_payload, tvb, offset, -1, ENC_NA);
	fhs_tree = proto_item_add_subtree(fhs_item, ett_btbredr_payload);

	/* Use proto_tree_add_bits_item() to get around 32bit limit on bitmasks */
	proto_tree_add_bits_item(fhs_tree, hf_btbredr_fhs_parity, tvb, offset*8, 34, ENC_LITTLE_ENDIAN);
	/* proto_tree_add_item(fhs_tree, hf_btbredr_fhs_parity, tvb, offset, 5, ENC_LITTLE_ENDIAN); */
	offset += 4;

	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_lap, tvb, offset, 4, ENC_LITTLE_ENDIAN);
	offset += 3;

	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_eir, tvb, offset, 1, ENC_NA);
	/* skipping 1 undefined bit */
	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_sr, tvb, offset, 1, ENC_NA);
	/* skipping 2 reserved bits */
	offset += 1;

	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_uap, tvb, offset, 1, ENC_NA);
	offset += 1;

	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_nap, tvb, offset, 2, ENC_LITTLE_ENDIAN);
	offset += 2;

	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_class, tvb, offset, 3, ENC_LITTLE_ENDIAN);
	offset += 3;

	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_ltaddr, tvb, offset, 1, ENC_NA);
	proto_tree_add_item(fhs_tree, hf_btbredr_fhs_clk, tvb, offset, 4, ENC_LITTLE_ENDIAN);
	offset += 3;

	psmode = tvb_get_guint8(tvb, offset);
	description = try_rval_to_str(psmode, ps_modes);
	psmode_item = proto_tree_add_item(fhs_tree, hf_btbredr_fhs_psmode, tvb, offset, 1, ENC_NA);
	if (description)
        proto_item_append_text(psmode_item, " (%s)", description);
	offset += 1;

	proto_tree_add_item(fhs_tree, hf_btbredr_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
	offset += 2;
}
void
dissect_fhs(proto_tree *tree, tvbuff_t *tvb, int offset)
{
	proto_item *fhs_item, *psmode_item;
	proto_tree *fhs_tree;
    const gchar *description;
	guint8 psmode;

	DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) == 20);

	fhs_item = proto_tree_add_item(tree, hf_btbb_payload, tvb, offset, -1, ENC_NA);
	fhs_tree = proto_item_add_subtree(fhs_item, ett_btbb_payload);

	/* Use proto_tree_add_bits_item() to get around 32bit limit on bitmasks */
	proto_tree_add_bits_item(fhs_tree, hf_btbb_fhs_parity, tvb, offset*8, 34, ENC_LITTLE_ENDIAN);
	/* proto_tree_add_item(fhs_tree, hf_btbb_fhs_parity, tvb, offset, 5, ENC_LITTLE_ENDIAN); */
	offset += 4;

	proto_tree_add_item(fhs_tree, hf_btbb_fhs_lap, tvb, offset, 4, ENC_LITTLE_ENDIAN);
	offset += 3;

	proto_tree_add_item(fhs_tree, hf_btbb_fhs_eir, tvb, offset, 1, ENC_NA);
	/* skipping 1 undefined bit */
	proto_tree_add_item(fhs_tree, hf_btbb_fhs_sr, tvb, offset, 1, ENC_NA);
	/* skipping 2 reserved bits */
	offset += 1;

	proto_tree_add_item(fhs_tree, hf_btbb_fhs_uap, tvb, offset, 1, ENC_NA);
	offset += 1;

	proto_tree_add_item(fhs_tree, hf_btbb_fhs_nap, tvb, offset, 2, ENC_LITTLE_ENDIAN);
	offset += 2;

	proto_tree_add_item(fhs_tree, hf_btbb_fhs_class, tvb, offset, 3, ENC_LITTLE_ENDIAN);
	offset += 3;

	proto_tree_add_item(fhs_tree, hf_btbb_fhs_ltaddr, tvb, offset, 1, ENC_NA);
	proto_tree_add_item(fhs_tree, hf_btbb_fhs_clk, tvb, offset, 4, ENC_LITTLE_ENDIAN);
	offset += 3;

	psmode = tvb_get_guint8(tvb, offset);
	description = try_rval_to_str(psmode, ps_modes);
	psmode_item = proto_tree_add_item(fhs_tree, hf_btbb_fhs_psmode, tvb, offset, 1, ENC_NA);
	if (description)
        proto_item_append_text(psmode_item, " (%s)", description);
	offset += 1;

	proto_tree_add_item(fhs_tree, hf_btbb_crc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
	offset += 2;
}
int
dissect_h263_group_of_blocks_layer( tvbuff_t *tvb, proto_tree *tree, gint offset, gboolean is_rfc4626)
{

	unsigned int offset_in_bits		= offset << 3;

	if(is_rfc4626){
		/* GBSC 1xxx xxxx */
		proto_tree_add_bits_item(tree, hf_h263_gbsc, tvb, offset_in_bits, 1, FALSE);
		offset_in_bits++;
	}else{
		/* Group of Block Start Code (GBSC) (17 bits) 
		 * A word of 17 bits. Its value is 0000 0000 0000 0000 1.
		 */
		proto_tree_add_bits_item(tree, hf_h263_gbsc, tvb, offset_in_bits, 17, FALSE);
		offset_in_bits = offset_in_bits +17;
	}
	/* 
	 * Group Number (GN) (5 bits)
	 */
	proto_tree_add_bits_item(tree, hf_h263_GN, tvb, offset_in_bits, 5, FALSE);
	offset_in_bits = offset_in_bits +5;
	/* 5.2.4 GOB Sub-Bitstream Indicator (GSBI) (2 bits)
	 * A fixed length codeword of 2 bits that is only present if CPM is "1" in the picture header.
	 */
	/* 
	 * 5.2.5 GOB Frame ID (GFID) (2 bits)
	 */
	/*
	 * 5.2.6 Quantizer Information (GQUANT) (5 bits)
	 */
	/*
	 * 5.3 Macroblock layer
	 */

	return offset_in_bits>>3;
}
static void
dissect_ayiya(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree *ayiya_tree;
	int offset = 0;
	int idlen, siglen, ayiya_len;
	guint8 next_header, opcode;
	tvbuff_t *payload;

	idlen = 1 << tvb_get_bits8(tvb, 0, 4);
	siglen = tvb_get_bits8(tvb, 8, 4) * 4;
	opcode = tvb_get_bits8(tvb, 20, 4);
	next_header = tvb_get_guint8(tvb, 3);

	ayiya_len = 8+idlen+siglen;

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

	if (tree) {
		proto_item *ti;
		nstime_t tv;
		ti = proto_tree_add_protocol_format( tree, proto_ayiya, tvb,
											 offset, ayiya_len, "AYIYA" );
		ayiya_tree = proto_item_add_subtree(ti, ett_ayiya);

		proto_tree_add_bits_item(ayiya_tree, hf_id_len, tvb, 0, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_id_type, tvb, 4, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_sig_len, tvb, 8, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_hash_method, tvb, 12, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_auth_method, tvb, 16, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_opcode, tvb, 20, 4, ENC_BIG_ENDIAN);
		proto_tree_add_uint_format(ayiya_tree, hf_next_header, tvb,
								   3, 1, next_header,
								   "Next header: %s (0x%02x)",
								   ipprotostr(next_header), next_header);
		tv.secs = tvb_get_ntohl(tvb, 4);
		tv.nsecs = 0;
		proto_tree_add_time(ayiya_tree, hf_epoch, tvb, 4, 4, &tv);
		proto_tree_add_item(ayiya_tree, hf_identity, tvb, 8, idlen, ENC_NA);
		proto_tree_add_item(ayiya_tree, hf_signature, tvb, 8+idlen, siglen, ENC_NA);
	}
	offset = ayiya_len;
	switch (opcode) {
	case OPCODE_FORWARD:
		payload = tvb_new_subset_remaining(tvb, offset);
		dissector_try_uint(ip_dissector_table, next_header, payload, pinfo, tree);
		break;
	}
}
Beispiel #8
0
static void
dissect_pairing_request(tvbuff_t *tvb, proto_tree *tree)
{
    proto_item *auth_req_item;
    proto_tree *auth_req_tree;

    proto_tree_add_item(tree, hf_btsm_pairing_request_io_capability, tvb, 1, 1, TRUE);
    proto_tree_add_item(tree, hf_btsm_pairing_request_oob_data, tvb, 2, 1, TRUE);

    auth_req_item = proto_tree_add_item(tree, hf_btsm_pairing_request_auth_req, tvb, 3, 1, TRUE);
    auth_req_tree = proto_item_add_subtree(auth_req_item, ett_auth_req);
    proto_tree_add_item(auth_req_tree, hf_btsm_pairing_request_reserved, tvb, 3, 1, TRUE);
    proto_tree_add_bits_item(auth_req_tree, hf_btsm_pairing_request_mitm, tvb, 3 * 8 + 5, 1, TRUE);
    proto_tree_add_item(auth_req_tree, hf_btsm_pairing_request_bonding_flags, tvb, 3, 1, TRUE);

    // TODO: check that max key size iswithin [7,16]
    proto_tree_add_item(tree, hf_btsm_pairing_request_max_key_size, tvb, 4, 1, TRUE);
    proto_tree_add_item(tree, hf_btsm_pairing_request_initiator_key_distribution, tvb, 5, 1, TRUE);
    proto_tree_add_item(tree, hf_btsm_pairing_request_responder_key_distribution, tvb, 6, 1, TRUE);
}
/* add information for an LI to 'tree' */
static proto_tree *tree_add_li(struct rlc_li *li, guint8 li_idx, guint8 hdr_offs, tvbuff_t *tvb, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *li_tree;
	guint8 li_offs;
	
	if (!tree) return NULL;

	li_offs = hdr_offs + li_idx;

	ti = proto_tree_add_item(tree, hf_rlc_li, tvb, li_offs, 1, FALSE);
	li_tree = proto_item_add_subtree(ti, ett_rlc_frag);
	proto_tree_add_bits_item(li_tree, hf_rlc_li_value, tvb, li_offs*8, 7, FALSE);
	proto_tree_add_item(li_tree, hf_rlc_li_ext, tvb, li_offs, 1, FALSE);

	if (li->len > 0) {
		if (li->li > tvb_length_remaining(tvb, hdr_offs)) return li_tree;
		if (li->len > li->li) return li_tree; 
		proto_tree_add_item(li_tree, hf_rlc_li_data, tvb, hdr_offs + li->li - li->len, li->len, FALSE);
	}

	return li_tree;
}
/*
 * Length is used for the "Extra header" otherwise set to -1.
 */
int
dissect_h263_picture_layer( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint length _U_, gboolean is_rfc4626)
{
	proto_tree *h263_opptype_tree	= NULL;
	proto_item *opptype_item		= NULL;
	unsigned int offset_in_bits		= offset << 3;
	unsigned int saved_bit_offset;
	guint64 source_format;
	guint64 ufep;
	guint64 picture_coding_type;
	guint64 PB_frames_mode = 0;
	guint64 custom_pcf = 0;
	guint64 picture_type_code =0;
	guint64 cpm;
	guint64 pei;

	if(is_rfc4626){
		/* PC 1000 00xx */ 
		proto_tree_add_bits_item(tree, hf_h263_psc, tvb, offset_in_bits, 6, FALSE);
		offset_in_bits = offset_in_bits +6;

	}else{
	/* Check for PSC, PSC is a word of 22 bits. 
	 * Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx.
	 */
		proto_tree_add_bits_item(tree, hf_h263_psc, tvb, offset_in_bits, 22, FALSE);
		offset_in_bits = offset_in_bits +22;

	}
	proto_tree_add_bits_item(tree, hf_h263_TR, tvb, offset_in_bits, 8, FALSE);
	offset_in_bits = offset_in_bits +8;
	/*
	 * Bit 1: Always "1", in order to avoid start code emulation. 
	 * Bit 2: Always "0", for distinction with Recommendation H.261.
	 */
	offset_in_bits = offset_in_bits +2;
	/* Bit 3: Split screen indicator, "0" off, "1" on. */
	proto_tree_add_bits_item( tree, hf_h263_split_screen_indicator, tvb, offset_in_bits, 1, FALSE);
	offset_in_bits++;
	/* Bit 4: Document camera indicator, */
	proto_tree_add_bits_item( tree, hf_h263_document_camera_indicator, tvb, offset_in_bits, 1, FALSE);
	offset_in_bits++;
	/* Bit 5: Full Picture Freeze Release, "0" off, "1" on. */
	proto_tree_add_bits_item( tree, hf_h263_full_picture_freeze_release, tvb, offset_in_bits, 1, FALSE);
	offset_in_bits++;
	/* Bits 6-8: Source Format, "000" forbidden, "001" sub-QCIF, "010" QCIF, "011" CIF,
	 * "100" 4CIF, "101" 16CIF, "110" reserved, "111" extended PTYPE.
	 */
	proto_tree_add_bits_ret_val( tree, hf_h263_source_format, tvb, offset_in_bits, 3 ,&source_format, FALSE);
	offset_in_bits = offset_in_bits +3;
	if (source_format != H263_PLUSPTYPE){
		/* Not extended PTYPE */
		/* Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture). */
		proto_tree_add_bits_ret_val( tree, hf_h263_payload_picture_coding_type, tvb, offset_in_bits, 1, &picture_coding_type, FALSE);
		if ( check_col( pinfo->cinfo, COL_INFO) )
			col_append_str(pinfo->cinfo, COL_INFO, val_to_str((guint32)picture_coding_type, picture_coding_type_vals, "Unknown (%u)"));
		offset_in_bits++;
		/* Bit 10: Optional Unrestricted Motion Vector mode (see Annex D), "0" off, "1" on. */
		proto_tree_add_bits_item( tree, hf_h263_opt_unres_motion_vector_mode, tvb, offset_in_bits, 1, FALSE);
		offset_in_bits++;
		/* Bit 11: Optional Syntax-based Arithmetic Coding mode (see Annex E), "0" off, "1" on.*/
		proto_tree_add_bits_item( tree, hf_h263_syntax_based_arithmetic_coding_mode, tvb, offset_in_bits, 1, FALSE);
		offset_in_bits++;
		/* Bit 12: Optional Advanced Prediction mode (see Annex F), "0" off, "1" on.*/
		proto_tree_add_bits_item( tree, hf_h263_optional_advanced_prediction_mode, tvb, offset_in_bits, 1, FALSE);
		offset_in_bits++;
		/* Bit 13: Optional PB-frames mode (see Annex G), "0" normal I- or P-picture, "1" PB-frame.*/
		proto_tree_add_bits_ret_val( tree, hf_h263_PB_frames_mode, tvb, offset_in_bits, 1, &PB_frames_mode, FALSE);
		offset_in_bits++;
	}else{
		/* Extended PTYPE 
		 * Update Full Extended PTYPE (UFEP) (3 bits)
		 */
		/* .... ..xx x... .... */
		proto_tree_add_bits_ret_val( tree, hf_h263_UFEP, tvb, offset_in_bits, 3, &ufep, FALSE);
		offset_in_bits = offset_in_bits +3;
		if(ufep==1){
			/* The Optional Part of PLUSPTYPE (OPPTYPE) (18 bits) 
			 */
			 /*  .xxx xxxx  xxxx xxxx  xxx. .... */
			opptype_item = proto_tree_add_bits_item( tree, hf_h263_opptype, tvb, offset_in_bits, 18, FALSE);
			h263_opptype_tree = proto_item_add_subtree( opptype_item, ett_h263_optype );
			/*
			 * If UFEP is "001", then the following bits are present in PLUSPTYPE:
			 *  Bits 1-3 Source Format, "000" reserved, "001" sub-QCIF, "010" QCIF, "011" CIF,
			 * "100" 4CIF, "101" 16CIF, "110" custom source format, "111" reserved;
			 */
			proto_tree_add_bits_item( h263_opptype_tree, hf_h263_ext_source_format, tvb, offset_in_bits, 3, FALSE);
			offset_in_bits+=3;
			
			/*
			 *  Bit 4 Optional Custom PCF, "0" CIF PCF, "1" custom PCF;
			 */
			proto_tree_add_bits_ret_val( h263_opptype_tree, hf_h263_custom_pcf, tvb, offset_in_bits, 1, &custom_pcf, FALSE);
			offset_in_bits++;
			saved_bit_offset=offset_in_bits;
			/*
			 *  Bit 5 Optional Unrestricted Motion Vector (UMV) mode (see Annex D), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 6 Optional Syntax-based Arithmetic Coding (SAC) mode (see Annex E), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 7 Optional Advanced Prediction (AP) mode (see Annex F), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 8 Optional Advanced INTRA Coding (AIC) mode (see Annex I), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 9 Optional Deblocking Filter (DF) mode (see Annex J), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 10 Optional Slice Structured (SS) mode (see Annex K), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 11 Optional Reference Picture Selection (RPS) mode (see Annex N), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 12 Optional Independent Segment Decoding (ISD) mode (see Annex R), "0" off,"1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 13 Optional Alternative INTER VLC (AIV) mode (see Annex S), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 14 Optional Modified Quantization (MQ) mode (see Annex T), "0" off, "1" on;
			 */
			offset_in_bits++;
			/*
			 *  Bit 15 Equal to "1" to prevent start code emulation;
			 */
			offset_in_bits++;
			/*
			 *  Bit 16 Reserved, shall be equal to "0";
			 */
			offset_in_bits++;
			/*
			 *  Bit 17 Reserved, shall be equal to "0";
			 */
			offset_in_bits++;
			/*
			 *  Bit 18 Reserved, shall be equal to "0".
			 */
			offset_in_bits++;
			proto_tree_add_bits_item( h263_opptype_tree, hf_h263_not_dissected, tvb, saved_bit_offset, offset_in_bits-saved_bit_offset, FALSE);
			
		}
		/*
		 * 5.1.4.3 The mandatory part of PLUSPTYPE when PLUSPTYPE present (MPPTYPE) (9 bits)
		 * Regardless of the value of UFEP, the following 9 bits are also present in PLUSPTYPE:
		 * - Bits 1-3 Picture Type Code:
		 * "000" I-picture (INTRA);
		 * "001" P-picture (INTER);
		 * "010" Improved PB-frame (see Annex M);
		 * "011" B-picture (see Annex O);
		 * "100" EI-picture (see Annex O);
		 * "101" EP-picture (see Annex O);
		 * "110" Reserved;
		 * "111" Reserved;
		 */
		proto_tree_add_bits_ret_val( tree, hf_h263_picture_type_code, tvb, offset_in_bits, 3, &picture_type_code, FALSE);
		offset_in_bits+=3;
		saved_bit_offset=offset_in_bits;
		/*
		 *  Bit 4 Optional Reference Picture Resampling (RPR) mode (see Annex P), "0" off, "1" on;
		 */
		offset_in_bits++;
		/*
		 *  Bit 5 Optional Reduced-Resolution Update (RRU) mode (see Annex Q), "0" off, "1" on;
		 */
		offset_in_bits++;
		/*
		 *  Bit 6 Rounding Type (RTYPE) (see 6.1.2);
		 */
		offset_in_bits++;
		/*
		 *  Bit 7 Reserved, shall be equal to "0";
		 */
		offset_in_bits++;
		/*
		 *  Bit 8 Reserved, shall be equal to "0";
		 */
		offset_in_bits++;
		/*
		 *  Bit 9 Equal to "1" to prevent start code emulation.
		 */
		offset_in_bits++;
		proto_tree_add_bits_item( tree, hf_h263_not_dissected, tvb, saved_bit_offset, offset_in_bits-saved_bit_offset, FALSE);
		/* The picture header location of CPM (1 bit) and PSBI (2 bits)
		 * the picture header depends on whether or not PLUSPTYPE is present 
		 * (see 5.1.20 and 5.1.21). If PLUSPTYPE is present, then CPM follows
		 * immediately after PLUSPTYPE in the picture header.
		 */
		proto_tree_add_bits_ret_val( tree, hf_h263_cpm, tvb, offset_in_bits, 1, &cpm, FALSE);
		offset_in_bits++;
		/* 5.1.21 Picture Sub-Bitstream Indicator (PSBI) (2 bits)
		 * only present if Continuous Presence Multipoint and Video
		 * Multiplex mode is indicated by CPM.
		 */
		if(cpm==1){
			proto_tree_add_bits_item( tree, hf_h263_psbi, tvb, offset_in_bits, 2, FALSE);
			offset_in_bits+=2;
		}
		return offset_in_bits>>3;
		/* TODO Add the rest of the fields */
		/* 5.1.5 Custom Picture Format (CPFMT) (23 bits)
		 * present only if the use of a custom picture format is
		 * signalled in PLUSPTYPE and UFEP is '001'. When present, CPFMT consists of:
		 * Bits 1-4 Pixel Aspect Ratio Code: A 4-bit index to the PAR value in Table 5. For
		 * extended PAR, the exact pixel aspect ratio shall be specified in EPAR
		 * (see 5.1.6);
		 * Bits 5-13 Picture Width Indication: Range [0, ... , 511]; Number of pixels per
		 * line = (PWI + 1) * 4;
		 * Bit 14 Equal to "1" to prevent start code emulation;
		 * Bits 15-23 Picture Height Indication: Range [1, ... , 288]; Number of lines = PHI * 4.
		 */
		/* 5.1.6 Extended Pixel Aspect Ratio (EPAR) (16 bits)
		 * A fixed length codeword of 16 bits that is present only if CPFMT is present and extended PAR is
		 * indicated therein. When present, EPAR consists of:
		 *  Bits 1-8 PAR Width: "0" is forbidden. The natural binary representation of the PAR
		 * width;
		 *  Bits 9-16 PAR Height: "0" is forbidden. The natural binary representation of the PAR
		 * height.
		 */
		/* 5.1.7 Custom Picture Clock Frequency Code (CPCFC) (8 bits)
		 * A fixed length codeword of 8 bits that is present only if PLUSPTYPE is present and UFEP is 001
		 * and a custom picture clock frequency is signalled in PLUSPTYPE. When present, CPCFC consists of:
		 * Bit 1 Clock Conversion Code: "0" indicates a clock conversion factor of 1000 and
		 * "1" indicates 1001;
		 * Bits 2-8 Clock Divisor: "0" is forbidden. The natural binary representation of the value
		 * of the clock divisor.
		 */
		/* 5.1.8 Extended Temporal Reference (ETR) (2 bits)
		 * A fixed length codeword of 2 bits which is present only if a custom picture clock frequency is in
		 * use (regardless of the value of UFEP). It is the two MSBs of the 10-bit number defined in 5.1.2.
		 */
		/* 5.1.9 Unlimited Unrestricted Motion Vectors Indicator (UUI) (Variable length)
		 * A variable length codeword of 1 or 2 bits that is present only if the optional Unrestricted Motion
		 * Vector mode is indicated in PLUSPTYPE and UFEP is 001. When UUI is present it indicates the
		 * effective limitation of the range of the motion vectors being used.
		 *  UUI = "1" The motion vector range is limited according to Tables D.1 and D.2.
		 *  UUI = "01" The motion vector range is not limited except by the picture size.
		 */
		/*
		 *  5.1.10 Slice Structured Submode bits (SSS) (2 bits)
		 *  A fixed length codeword of 2 bits which is present only if the optional Slice Structured mode
		 *  (see Annex K) is indicated in PLUSPTYPE and UFEP is 001. If the Slice Structured mode is in use
		 *  but UFEP is not 001, the last values sent for SSS shall remain in effect.
		 *  - Bit 1 Rectangular Slices, "0" indicates free-running slices, "1" indicates rectangular
		 *  slices;
		 *  - Bit 2 Arbitrary Slice Ordering, "0" indicates sequential order, "1" indicates arbitrary
		 *  order.
		 *  5.1.11 Enhancement Layer Number (ELNUM) (4 bits)
		 *  A fixed length codeword of 4 bits which is present only if the optional Temporal, SNR, and Spatial
		 *  Scalability mode is in use (regardless of the value of UFEP). The particular enhancement layer is
		 *  identified by an enhancement layer number, ELNUM. Picture correspondence between layers is
		 *  achieved via the temporal reference. Picture size is either indicated within each enhancement layer
		 *  using the existing source format fields or is inferred by the relationship to the reference layer. The
		 *  first enhancement layer above the base layer is designated as Enhancement Layer Number 2, and
		 *  the base layer has number 1.
		 *  5.1.12 Reference Layer Number (RLNUM) (4 bits)
		 *  A fixed length codeword of 4 bits which is present only if the optional Temporal, SNR, and Spatial
		 *  Scalability mode is in use (see Annex O) and UFEP is 001. The layer number for the pictures used
		 *  as reference anchors is identified by a Reference Layer Number (RLNUM). Time correspondence
		 *  between layers is achieved via the temporal reference.
		 *  Note that for B-pictures in an enhancement layer having temporally surrounding EI- or EP-pictures
		 *  which are present in the same enhancement layer, RLNUM shall be equal to ELNUM
		 *  (see Annex O).
		 *  5.1.13 Reference Picture Selection Mode Flags (RPSMF) (3 bits)
		 *  A fixed length codeword of 3 bits that is present only if the Reference Picture Selection mode is in
		 *  use and UFEP is 001. When present, RPSMF indicates which type of back-channel messages are
		 *  needed by the encoder. If the Reference Picture Selection mode is in use but RPSMF is not present,
		 *  the last value of RPSMF that was sent shall remain in effect.
		 *  - 100: neither ACK nor NACK signals needed;
		 *  - 101: need ACK signals to be returned;
		 *  - 110: need NACK signals to be returned;
		 *  - 111: need both ACK and NACK signals to be returned;
		 *  - 000-011: Reserved.
		 *  5.1.14 Temporal Reference for Prediction Indication (TRPI) (1 bit)
		 *  A fixed length codeword of 1 bit that is present only if the optional Reference Picture Selection
		 *  mode is in use (regardless of the value of UFEP). When present, TRPI indicates the presence of the
		 *  following TRP field:
		 *  - 0: TRP field is not present;
		 *  - 1: TRP field is present.
		 *  TRPI shall be 0 whenever the picture header indicates an I- or EI-picture.
		 *  5.1.15 Temporal Reference for Prediction (TRP) (10 bits)
		 *  When present (as indicated in TRPI), TRP indicates the Temporal Reference which is used for
		 *  prediction of the encoding, except for in the case of B-pictures. For B-pictures, the picture having
		 *  the temporal reference TRP is used for the prediction in the forward direction. (Prediction in the
		 *  reverse-temporal direction always uses the immediately temporally subsequent picture.) TRP is a
		 *  ten-bit number. If a custom picture clock frequency was not in use for the reference picture, the two
		 *  MSBs of TRP are zero and the LSBs contain the eight-bit TR found in the picture header of the
		 *  reference picture. If a custom picture clock frequency was in use for the reference picture, TRP is a
		 *  ten-bit number consisting of the concatenation of ETR and TR from the reference picture header.
		 *  When TRP is not present, the most recent temporally previous anchor picture shall be used for
		 *  prediction, as when not in the Reference Picture Selection mode. TRP is valid until the next PSC,
		 *  GSC, or SSC.
		 *  5.1.16 Back-Channel message Indication (BCI) (Variable length)
		 *  A variable length field of one or two bits that is present only if the optional Reference Picture
		 *  Selection mode is in use. When set to "1", this signals the presence of the following optional video
		 *  Back-Channel Message (BCM) field. "01" indicates the absence or the end of the video backchannel
		 *  message field. Combinations of BCM and BCI may not be present, and may be repeated
		 *  when present. BCI shall be set to "01" if the videomux submode of the optional Reference Picture
		 *  Selection mode is not in use.
		 *  5.1.17 Back-Channel Message (BCM) (Variable length)
		 *  The Back-Channel message with syntax as specified in N.4.2, which is present only if the preceding
		 *  BCI field is present and is set to "1".
		 *  5.1.18 Reference Picture Resampling Parameters (RPRP) (Variable length)
		 *  A variable length field that is present only if the optional Reference Picture Resampling mode bit is
		 *  set in PLUSPTYPE. This field carries the parameters of the Reference Picture Resampling mode
		 *  (see Annex P). Note that the Reference Picture Resampling mode can also be invoked implicitly by
		 *  the occurrence of a picture header for an INTER coded picture having a picture size which differs
		 *  from that of the previous encoded picture, in which case the RPRP field is not present and the
		 *  Reference Picture Resampling mode bit is not set.
		 */
	}
	/* 5.1.19 Quantizer Information (PQUANT) (5 bits) */
	proto_tree_add_bits_item( tree, hf_h263_pquant, tvb, offset_in_bits, 5, FALSE);
	offset_in_bits = offset_in_bits +5;
	if (source_format != H263_PLUSPTYPE){
		proto_tree_add_bits_ret_val( tree, hf_h263_cpm, tvb, offset_in_bits, 1, &cpm, FALSE);
		offset_in_bits++;
		/* 5.1.21 Picture Sub-Bitstream Indicator (PSBI) (2 bits)
		 * only present if Continuous Presence Multipoint and Video
		 * Multiplex mode is indicated by CPM.
		 */
		if(cpm==1){
			proto_tree_add_bits_item( tree, hf_h263_psbi, tvb, offset_in_bits, 2, FALSE);
			offset_in_bits = offset_in_bits +2;
		}
	}
	/* 5.1.22 Temporal Reference for B-pictures in PB-frames (TRB) (3/5 bits)
	 * TRB is present if PTYPE or PLUSPTYPE indicates "PB-frame" or "Improved PB-frame"
	 * It is 3 bits long for standard CIF picture clock frequency and is
	 * extended to 5 bits when a custom picture clock frequency is in use.
	 */
	if((PB_frames_mode == 1)||(picture_type_code == 2 )){
		if(custom_pcf == 0){
			proto_tree_add_bits_item( tree, hf_h263_trb, tvb, offset_in_bits, 3, FALSE);
			offset_in_bits = offset_in_bits +3;
		}else{
			proto_tree_add_bits_item( tree, hf_h263_trb, tvb, offset_in_bits, 5, FALSE);
			offset_in_bits = offset_in_bits +5;
		}
	}
	/* 5.1.23 Quantization information for B-pictures in PB-frames (DBQUANT) (2 bits)
	 * DBQUANT is present if PTYPE or PLUSPTYPE indicates "PB-frame" or "Improved PB-frame"
	 */
	if((PB_frames_mode == 1)||(picture_type_code == 2 )){
		offset_in_bits = offset_in_bits +2;
	}
	/* 5.1.24 Extra Insertion Information (PEI) (1 bit)
	 * A bit which when set to "1" signals the presence of the following optional data field.
	 */
	proto_tree_add_bits_ret_val( tree, hf_h263_pei, tvb, offset_in_bits, 1, &pei, FALSE);
	offset_in_bits++;
	while(pei==1)
	{
		/*5.1.25 Supplemental Enhancement Information (PSUPP) (0/8/16 ... bits) 
		 * If PEI is set to "1", then 9 bits follow consisting of 8 bits of data (PSUPP) and then another PEI bit
		 * to indicate if a further 9 bits follow and so on. Encoders shall use PSUPP as specified in Annex L.
		 */
		proto_tree_add_bits_item( tree, hf_h263_psupp, tvb, offset_in_bits, 8, FALSE);
		offset_in_bits+=8;
		proto_tree_add_bits_ret_val( tree, hf_h263_pei, tvb, offset_in_bits, 1, &pei, FALSE);
		offset_in_bits++;
	}
	/* For the first GOB in each picture (with number 0), no GOB header shall be transmitted.
	 * For all other GOBs, the GOB header may be empty, depending on the encoder strategy.
	 */

	/*
	 * 5.3 Macroblock layer
	 * dissect_h263_macroblock_layer( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
	 */

	return offset_in_bits>>3;

}
Beispiel #11
0
static void gcsna_message_GCSNAServiceReject(proto_item *item, tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
    guint16 cause_val = -1, num_fields = -1, l_offset = -1;
    proto_tree *subtree = NULL;

    item = proto_tree_add_item(tree, hf_gcsna_servicereject, tvb, *offset, 1, ENC_NA);
    subtree = proto_item_add_subtree(item, ett_gcsna_subtree);

    l_offset = *offset * 8;
    proto_tree_add_bits_item(subtree, hf_gcsna_rejSequence, tvb, l_offset, 6, ENC_BIG_ENDIAN);
    l_offset += 6;
    proto_tree_add_bits_item(subtree, hf_gcsna_cause, tvb, l_offset, 8, ENC_BIG_ENDIAN);
    cause_val = tvb_get_bits8(tvb, *offset * 8 + 6, 8);
    l_offset += 8;

    switch (cause_val)
    {
    case 0:
    case 2:
    {
        num_fields = tvb_get_bits8(tvb, l_offset, 8);
        l_offset += 8;

        while (num_fields > 0)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClass, tvb, l_offset, 5, ENC_BIG_ENDIAN);
            l_offset += 5;
            proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClassRev, tvb, l_offset, 3, ENC_BIG_ENDIAN);
            l_offset += 3;
            num_fields--;
        }

        if (cause_val == 2)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_1xProtocolRevision, tvb, l_offset, 8, ENC_BIG_ENDIAN);
            l_offset += 8;
        }

        break;
    }

    case 1:
    {
        proto_tree_add_bits_item(subtree, hf_gcsna_1xProtocolRevision, tvb, l_offset, 8, ENC_BIG_ENDIAN);
        l_offset += 8;
        break;
    }

    case 3:
    {
        proto_tree_add_bits_item(subtree, hf_gcsna_invalidMessageId, tvb, l_offset, 8, ENC_BIG_ENDIAN);
        l_offset += 8;
        break;
    }

    /*This Cause Value is not supported in IWS Stack*/
    case 5:
    {
        num_fields = tvb_get_bits8(tvb, l_offset, 8);
        l_offset += 8;

        while (num_fields > 0)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_recordType, tvb, l_offset, 8, ENC_BIG_ENDIAN);
            l_offset += 8;
            num_fields--;
        }
        break;
    }

    default:
    {
        proto_tree_add_item(subtree, hf_gcsna_unsupported_reject_seq, tvb, l_offset, -1, ENC_NA);
        break;
    }
    }

    if (l_offset % 8 == 0)
    {
        *offset = (l_offset / 8);
    } else
    {
        *offset = (l_offset / 8) + 1;
    }

}
Beispiel #12
0
static void
gcsna_message_GCSNA1xCircuitService(proto_item *item, tvbuff_t *tvb, packet_info *pinfo, proto_tree *mainTree, proto_tree *tree, guint *offset)
{
    guint16 alt_gcsna_incl = 0, num_alt_gcsna_opt = -1, iws_incl = 0;
    guint8 num_res;
    guint bit_offset = *offset * 8;
    proto_tree *subtree = NULL;
    tvbuff_t *new_tvb;

    /* GCSNAOption 8 bits */
    item = proto_tree_add_item(tree, hf_gcsna_gcsna_option, tvb, *offset, 1, ENC_BIG_ENDIAN);
    subtree = proto_item_add_subtree(item, ett_gcsna_option);
    proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClass, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
    bit_offset += 5;
    proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClassRev, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
    bit_offset += 3;

    alt_gcsna_incl = tvb_get_bits8(tvb, bit_offset, 1);
    proto_tree_add_bits_item(subtree, hf_gcsna_altGCSNAOptionIncluded, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset += 1;
    if (alt_gcsna_incl)
    {
        num_alt_gcsna_opt = tvb_get_bits8(tvb, bit_offset, 8);
        proto_tree_add_bits_item(subtree, hf_gcsna_NumaltGCSNAOption, tvb, bit_offset, 8, ENC_BIG_ENDIAN);
        bit_offset += 8;

        while (num_alt_gcsna_opt != 0)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_altGCSNAOption, tvb, bit_offset, 8, ENC_BIG_ENDIAN);
            bit_offset += 8;
            num_alt_gcsna_opt--;
        }
    }

    iws_incl = tvb_get_bits8(tvb, bit_offset, 1);
    proto_tree_add_bits_item(subtree, hf_gcsna_iwsidIncluded, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset++;

    if (iws_incl)
    {
        proto_tree_add_bits_item(subtree, hf_gcsna_iwsidValue, tvb, bit_offset, 16, ENC_BIG_ENDIAN);
        bit_offset += 16;
    }

    proto_tree_add_bits_item(subtree, hf_gcsna_ackRequired, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset++;
    proto_tree_add_bits_item(subtree, hf_gcsna_stopDupDetect, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset++;
    proto_tree_add_bits_item(subtree, hf_gcsna_msgSequence, tvb, bit_offset, 6, ENC_BIG_ENDIAN);
    bit_offset += 6;

    proto_tree_add_bits_item(subtree, hf_gcsna_NumTLACEncapsulated1xL3PDU, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
    bit_offset += 2;

    /* The sender shall include reserved bits to make this message integral number of octets up to TLACEncapsulated1xL3PDU field.
     * The sender 5 shall set all bits in this field to '0'. The receiver shall ignore this field.
     */

     /* calculate number of reserved bits */
    num_res = 8 - (bit_offset & 0x3);
    proto_tree_add_bits_item(subtree, hf_gcsna_tlacReserved, tvb, bit_offset, num_res, ENC_BIG_ENDIAN);
    bit_offset = bit_offset + num_res;
    *offset = bit_offset >> 3;

    proto_tree_add_item(subtree, hf_gcsna_tlacEncapsulated, tvb, *offset, -1, ENC_NA);

    if (cdma2k_handle) {
        new_tvb = tvb_new_subset_length_caplen(tvb, *offset, -1, -1);
        call_dissector(cdma2k_handle, new_tvb, pinfo, mainTree);
    }
    /* set the offset to the end of the message */
    *offset += tvb_reported_length_remaining(tvb, *offset);

}
Beispiel #13
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, ENC_NA );
	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, ENC_NA );
		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 */
			proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_au_is_encrypted,
						 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit AU_is_encrypted */
		}
		else { /* bit unused */
			proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
						 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*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 */
				proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits,
							 tvb, bit_offset, 7, ENC_BIG_ENDIAN); /*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){
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_start,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit slice_start */
				}
				else { /* bit unused */
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*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){
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_end,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit Slice_end */
				}
				else { /* bit unused */
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*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){
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_padding_bitcount,
								 tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*fetch 3 bits padding_bitcount */
				}
				else { /* bits unused */
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
								 tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*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 */
				proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits,
							 tvb, bit_offset, 2, ENC_BIG_ENDIAN); /*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, ENC_NA);
		proto_item_append_text(ismacryp_item, ": Length=%d bytes",iv_length); /* add IV 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, ENC_NA);
		proto_item_append_text(ismacryp_item, ": Length=%d bytes",delta_iv_length); /* add delta IV 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, ENC_NA);
		proto_item_append_text(ismacryp_item,": Length=%d bytes",key_indicator_length); /* add KI 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, ENC_BIG_ENDIAN);
		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, ENC_BIG_ENDIAN);
		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, ENC_BIG_ENDIAN);
		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 */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_flag,
					 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* 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, ENC_BIG_ENDIAN); /* 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 */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_flag,
					 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* 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, ENC_BIG_ENDIAN); /* 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 */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_rap_flag,
					 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* 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 */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_stream_state,
					 tvb, bit_offset, stream_state_indication, ENC_BIG_ENDIAN); /* read stream state */
		add_bits(poffset, stream_state_indication);
	}
	/* end header details */
return poffset;
}
Beispiel #14
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 */
		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){
		col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_11);
		/* display mode */
		if (pref_user_mode == FALSE){
			col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",val_to_str_const(mode, modetypenames, "user mode"));
		} else {
			col_append_str(pinfo->cinfo, COL_INFO, ", user mode");
		}
		user_mode = pref_user_mode;
	}
	if (set_version == V20){
		col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_20);
		user_mode = TRUE;
		/* display mode */
		col_append_str(pinfo->cinfo, COL_INFO, ", 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, ENC_NA);
		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, ENC_BIG_ENDIAN );
		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 , ENC_BIG_ENDIAN); /* 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, ENC_NA );
		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 */
}
// content format
static void dissect_mysensors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  // your variable definitions go here
  int bitoffset = 0;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "mysensors");
  
  // Clear out stuff in the info column
  col_clear(pinfo->cinfo,COL_INFO);
  if (tree)
  {
    // in case that someone wants to know some details of our protocol
    // spawn a subtree and cut the sequence in readable parts
    proto_item *pi = NULL;
    proto_item *ti = NULL;
    proto_tree *mysensors_tree = NULL;
    tvbuff_t* tvb_next;
    guint8 payloadLen, dataType, type, sensor, sender, last, dest, reqack, isack;
    MySensors_Command commandType;
    gchar* info;
    
    ti = proto_tree_add_item(tree, proto_mysensors, tvb, 0 /*start*/, -1 /*to end*/, ENC_NA);
    mysensors_tree = proto_item_add_subtree(ti, ett_mysensors);
    
    proto_tree_add_item(mysensors_tree, hf_mysensors_last, tvb, bitoffset>>3, 1, encoding);
    last = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_sender, tvb, bitoffset>>3, 1, encoding);
    sender = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_dest, tvb, bitoffset>>3, 1, encoding);
    dest = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;

    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_length, tvb, bitoffset, 5, encoding);
    payloadLen = tvb_get_bits8(tvb, bitoffset, 5);
    bitoffset += 5;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_version, tvb, bitoffset, 3, encoding);
    bitoffset += 3;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_datatype, tvb, bitoffset, 3, encoding);
    dataType = tvb_get_bits8(tvb, bitoffset, 3);  // Type of payload
    bitoffset += 3;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_isack, tvb, bitoffset, 1, encoding);
    isack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1);
    bitoffset += 1;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_reqack, tvb, bitoffset, 1, encoding);
    reqack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1);
    bitoffset += 1;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_commandtype, tvb, bitoffset, 3, encoding);
    commandType = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 3);
    bitoffset += 3;

    type = tvb_get_guint8(tvb, bitoffset>>3);
    proto_tree_add_uint_format_value(mysensors_tree, hf_mysensors_type, tvb, bitoffset>>3, 1, type, "%s (%d)", typeToStr(commandType, type), (guint8)type);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_sensor, tvb, bitoffset>>3, 1, encoding);
    sensor = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;

    // Create tvb for the payload.
    tvb_next = tvb_new_subset(tvb, bitoffset>>3, payloadLen, payloadLen);

    info = buildColInfo( pinfo, payloadLen, dataType, commandType, reqack, isack, type, sensor, tvb_next );
    col_add_str(pinfo->cinfo, COL_INFO, info);
    proto_item_append_text(ti, " - %s", info);
    col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d", sender);
    col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d", dest);

    // Pass payload to generic data dissector
    call_dissector(data_handle, tvb_next, pinfo, mysensors_tree);
  }
}
Beispiel #16
0
/* common dissector function for dissecting TFP payloads */
static void
dissect_tfp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {

    gint   byte_offset = 0;
    gint   bit_offset  = 48;

    guint8 hv_tfp_len;
    guint8 hv_tfp_fid;
    guint8 hv_tfp_seq;

    gchar  tfp_uid_string[BASE58_MAX_STR_SIZE];

    base58_encode(tvb_get_letohl(tvb, 0), &tfp_uid_string[0]);

    hv_tfp_len = tvb_get_guint8(tvb, byte_offset_len);
    hv_tfp_fid = tvb_get_guint8(tvb, byte_offset_fid);
    hv_tfp_seq = tvb_get_bits8(tvb, bit_offset, bit_count_tfp_seq);

    col_add_fstr(pinfo->cinfo, COL_INFO,
                 "UID: %s, Len: %d, FID: %d, Seq: %d",
                 &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);

    /* call for details */
    if (tree) {
        proto_tree *tfp_tree;
        proto_item *ti;

        ti = proto_tree_add_protocol_format(tree, proto_tfp, tvb, 0, -1,
                                            "Tinkerforge Protocol, UID: %s, Len: %d, FID: %d, Seq: %d",
                                            &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);
        tfp_tree = proto_item_add_subtree(ti, ett_tfp);

        /* Use ...string_format_value() so we can show the complete generated string but specify */
        /*  the field length as being just the 4 bytes from which the string is generated.	 */
        ti = proto_tree_add_string_format_value(tfp_tree,
                                                hf_tfp_uid,
                                                tvb, byte_offset, byte_count_tfp_uid,
                                                &tfp_uid_string[0], "%s", &tfp_uid_string[0]);
        PROTO_ITEM_SET_GENERATED(ti);

        proto_tree_add_item(tfp_tree,
                            hf_tfp_uid_numeric,
                            tvb,
                            byte_offset,
                            byte_count_tfp_uid,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_uid;

        proto_tree_add_item(tfp_tree,
                            hf_tfp_len,
                            tvb,
                            byte_offset,
                            byte_count_tfp_len,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_len;

        proto_tree_add_item(tfp_tree,
                            hf_tfp_fid,
                            tvb,
                            byte_offset,
                            byte_count_tfp_fid,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_fid;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_seq,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_seq,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_seq;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_r,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_r,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_r;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_a,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_a,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_a;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_oo,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_oo,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_oo;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_e,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_e,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_e;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_future_use,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_future_use,
                                 ENC_LITTLE_ENDIAN);

        /*bit_offset += bit_count_tfp_future_use;*/

        if ((tvb_reported_length(tvb)) > 8) {

            byte_offset += byte_count_tfp_flags;

            proto_tree_add_item(tfp_tree, hf_tfp_payload, tvb, byte_offset, -1, ENC_NA);
        }
    }
}