Wireshark-dev: Re: [Wireshark-dev] runtime error using plugin withprefs_register_enum_preferenc
Date: Thu, 23 Oct 2008 14:29:53 +0200
Hi again,

Thanks for your replies, I was hopeful you had provided the solution but I still can't get the thing to work either in plugin or dissector mode when using the prefs_register_enum_preference function. Code as is below with the function disabled works fine. As soon as I remove the comments, it compiles but gives me an error when I run wireshark.

Here's the code, I think it's now "Wireshark developer" compliant, but still wanted to check the bit decoding more closely with a colleague before formally submitting it.

Any ideas?

David

ps I would ideally add a 

if (version_type == 0 || rtp.p_type== "enc-mpeg4-generic") { decode as ISMACryp 11}
if (version_type == 1 || rtp.p_type== "enc-isoff-generic") { decode as ISMACryp 20}

in the tree dissection to allow a placeholder for TBD 2.0 parsing (unless I can find the time to do it). Not sure how to access the rtp.p_type info btw
================================
/* packet-ismacryp.c
* ISMACryp 1.1 protocol as defined in ISMA Encryption and Authentication see http://www.isma.tv
*
* David Castleford, Orange Labs / France Telecom R&D
* Oct 2008
 * $Id:
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxxx>
 * Copyright 1998 Gerald Combs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

/* 	TODO: handle ISMACryp 2.0
* 	TODO: get ISMACryp parameters automatically from SDP info, if present (typically sent via SAP/SDP), rather than having manual insertion via preferences
*	TODO: perhaps better check coherence of certain information?
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h> 
#include <epan/tvbuff.h>
#include <glib.h>
#include <epan/packet.h>
#include <epan/emem.h>
#include <epan/dissectors/packet-tcp.h>
#include <epan/prefs.h>

/* keeps track of current position in buffer in terms of bit and byte offset */
typedef struct Toffset_struct
{
	gint offset_bytes;
	guint8 offset_bits;
	
} offset_struct;

static void dissect_ismacryp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_ismacryp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static offset_struct* dissect_auheader( tvbuff_t *tvb, offset_struct *poffset, packet_info *pinfo _U_, proto_tree *tree ); 
static guint get_ismacryp_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
void proto_reg_handoff_ismacryp(void);
static void add_bits(offset_struct* poffset, gint len_bits);

#define PROTO_TAG_ISMACRYP_11	"ismacryp11"
#define PROTO_TAG_ISMACRYP_20	"ismacryp20"
#define DEFAULT_SELECTIVE_ENCRYPTION_FLAG	0
#define DEFAULT_IV_LENGTH					4
#define DEFAULT_DELTA_IV_LENGTH				0
#define DEFAULT_KEY_INDICATOR_LENGTH		0
#define DEFAULT_KEY_INDICATOR_PER_AU		0
#define AU_HEADERS_LENGTH_SIZE				2 /* size in bytes */
#define DEFAULT_AU_SIZE_LENGTH				0
#define DEFAULT_AU_INDEX_LENGTH				0
#define DEFAULT_AU_INDEX_DELTA_LENGTH		0
#define DEFAULT_CTS_DELTA_LENGTH			0
#define DEFAULT_DTS_DELTA_LENGTH			0
#define DEFAULT_RANDOM_ACCESS_INDICATION	1
#define DEFAULT_STREAM_STATE_INDICATION		0
#define CTS_FLAG_MASK						0x80 /* mask to take first (most significant) bit */

/* Wireshark ID of the ISMACRYP protocol */
static int proto_ismacryp = -1;

/* The dynamic payload type which will be dissected as ISMACRYP */
static guint dynamic_payload_type = 0;
static guint temp_dynamic_payload_type = 0;
/* The ISMACryp protocol version set in preferences menu */
static gint version_type = 0; /* ISMACryp 1.1 */

/* These are the handles of our subdissectors */
static dissector_handle_t data_handle=NULL;
static dissector_handle_t ismacryp_handle;

static int selective_encryption_flag = DEFAULT_SELECTIVE_ENCRYPTION_FLAG; /* default selective encryption flag */
static int iv_length = DEFAULT_IV_LENGTH; /* default IV length */
static int delta_iv_length = DEFAULT_DELTA_IV_LENGTH; /* default delta IV length */
static int key_indicator_length =DEFAULT_KEY_INDICATOR_LENGTH; /* default key indicator length */
static int key_indicator_per_au_flag =DEFAULT_KEY_INDICATOR_PER_AU; /* default key indicator per au */
static gint au_size_length =DEFAULT_AU_SIZE_LENGTH; /* default Au size length */
static int au_index_length =DEFAULT_AU_INDEX_LENGTH; /* default Au index length */
static int au_index_delta_length =DEFAULT_AU_INDEX_DELTA_LENGTH; /* default Au index delta length */
static int cts_delta_length =DEFAULT_CTS_DELTA_LENGTH; /* default CTS delta  length */
static int dts_delta_length =DEFAULT_DTS_DELTA_LENGTH; /* default DTS delta  length */
static int random_access_indication =DEFAULT_RANDOM_ACCESS_INDICATION; /* default random access indication */
static int stream_state_indication =DEFAULT_STREAM_STATE_INDICATION; /* default stream state indication */

/*static const value_string messagetypenames[] = {};	*/

/* ismacryp Parameter Types */
/*static const value_string parametertypenames[] = {}; */

/* The following hf_* variables are used to hold the Wireshark IDs of
* our header fields; they are filled out when we call
* proto_register_field_array() in proto_register_ismacryp()
*/
/** Kts attempt at defining the protocol */
static gint hf_ismacryp = -1;
static gint hf_ismacryp_header = -1;
static gint hf_ismacryp_au_headers_length = -1;
static gint hf_ismacryp_header_length = -1;
static gint hf_ismacryp_header_byte = -1;
static gint hf_ismacryp_version = -1;
static gint hf_ismacryp_length = -1;
static gint hf_ismacryp_message_type = -1;
static gint hf_ismacryp_message_length = -1;
static gint hf_ismacryp_message = -1;
static gint hf_ismacryp_parameter = -1;
static gint hf_ismacryp_parameter_type = -1;
static gint hf_ismacryp_parameter_length = -1;
static gint hf_ismacryp_parameter_value = -1;
static gint hf_ismacryp_iv = -1;
static gint hf_ismacryp_delta_iv = -1;
static gint hf_ismacryp_key_indicator = -1;
static gint hf_ismacryp_delta_iv_length = -1;
static gint hf_ismacryp_au_size = -1;
static gint hf_ismacryp_au_index = -1;
static gint hf_ismacryp_au_index_delta = -1;
static gint hf_ismacryp_cts_delta = -1;
static gint hf_ismacryp_cts_flag = -1;
static gint hf_ismacryp_dts_flag = -1;
static gint hf_ismacryp_dts_delta = -1;
static gint hf_ismacryp_rap_flag = -1;
static gint hf_ismacryp_au_is_encrypted = -1;
static gint hf_ismacryp_slice_start = -1;
static gint hf_ismacryp_slice_end = -1;
static gint hf_ismacryp_padding_bitcount = -1;
static gint hf_ismacryp_reserved_bits = -1;
static gint hf_ismacryp_stream_state = -1;

/* These are the ids of the subtrees that we may be creating */
static gint ett_ismacryp = -1;
static gint ett_ismacryp_header = -1;
static gint	ett_ismacryp_header_byte = -1;
static gint ett_ismacryp_header_length = -1;
static gint ett_ismacryp_au_headers_length = -1;
static gint ett_ismacryp_message = -1;

static guint udp_port = 0;

/* Informative tree structure is shown here:
* TREE 	-
*	AU Headers Length (2 bytes) - total length of AU header(s)
*	- HEADER1
*		Header Byte (if present - 1 byte)
*			-AU_is_encrypted (1 bit)
*			-Slice_start (1 bit)
*			-Slice_end (1 bit)
*			-Padding_bitcount (3 bits)
*			-Reserved (2 bits)
*		IV (variable length)
*		Key Indicator (variable length)
*		AU size (if present - variable length)
*		AU index (if present - variable length)
*		CTS delta (if present - variable length)
*		DTS delta (if present - variable length)
*		RAP flag (if present - 1 bit)
*		Stream State Indication (if present - variable length)
*	- HEADER2 if 2nd header present (depends on AU headers length)
*		Header Byte (if present - 1 byte)
*			-AU_is_encrypted (1 bit)
*			-Slice_start (1 bit)
*			-Slice_end (1 bit)
*			-Padding_bitcount (3 bits)
*			-Reserved (2 bits)
*		IV (variable length)
*		Key Indicator (variable length)
*		AU size (if present - variable length)
*		AU index delta(if present - variable length)
*		CTS delta (if present - variable length)
*		DTS delta (if present - variable length)
*		RAP flag (if present - 1 bit)
*		Stream State Indication (if present - variable length)
*	- more HEADERS if present
*	- MESSAGE
*		encrypted AU
* End informative tree structure
*/

/* Note that check coherence of total AU headers length and that calculated from size of parameters defined by default or preferences.
* These are found in SDP and vary e.g. between audio and video and depend on ISMACryp encoding parameters
* hence if these values are incorrect displayed values will be strange and can see errors
* this could be improved of course
*/

static void dissect_ismacryp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ismacryp_item = NULL;
	proto_tree *ismacryp_tree = NULL;
	proto_tree *ismacryp_parameter_tree = NULL;
	proto_tree *ismacryp_message_tree = NULL;
	/* not sure how to do this, try to display correct ismacryp version according to rtp payload type if defined	
	*rtp.p_type?
	*if (check_col(pinfo->cinfo, COL_PROTOCOL) & pinfo->cinfo->rtp.p_type== "enc-mpeg4-generic"))
	*	col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_11);
	*if (check_col(pinfo->cinfo, COL_PROTOCOL) & check_col(pinfo->rtp.p_type, "enc-isoff-generic"))
	*	col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_20);
	*/
	if (check_col(pinfo->cinfo, COL_PROTOCOL) )
	{
		col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_ISMACRYP_11);
	}
	/* Clear out stuff in the info column */
	if(check_col(pinfo->cinfo,COL_INFO))
	{
		col_clear(pinfo->cinfo,COL_INFO);
	}

	/* navigate through buffer */
	if (tree)
	{
		/* we are being asked for details */
		
		/*guint32 offset = 0;*/
		/*guint32 length = 0;*/
		guint16 au_headers_length = 0; /* total length of AU headers */
		int totalbits =0; /* keeps track of total number of AU header bits treated (used to determine end of AU headers) */
		offset_struct s_offset;
		offset_struct* poffset;
		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 */
		while((totalbits-8*AU_HEADERS_LENGTH_SIZE)<au_headers_length) /* subtract AU headers length bits*/
		{
			poffset=dissect_auheader( tvb, poffset, pinfo, ismacryp_tree);
			totalbits=(poffset->offset_bytes*8)+poffset->offset_bits;	
		}
		/* 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)
		{
			poffset->offset_bytes++; /* add 1 byte */
			poffset->offset_bits=0; /* set to O 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 */
		proto_item_append_text(ismacryp_item, ", Length= %d bytes", tvb_reported_length_remaining(tvb, poffset->offset_bytes)); /* add length of message */
	
		/* ismacryp message tree analysis (encrypted AUs) */
		if (ismacryp_message_tree)
		{	/* we are being asked for details */
			;	/* */
		}  /* end message details */	
		/* end ismacryp tree details */		
	} /* end if tree */
}	
/* AU Header dissection */
static offset_struct* dissect_auheader( tvbuff_t *tvb, offset_struct *poffset, packet_info *pinfo _U_, proto_tree *ismacryp_tree )
{
	proto_item *ismacryp_item = NULL;
	proto_tree *ismacryp_header_tree = NULL;
	proto_tree *ismacryp_header_byte_tree = NULL;
	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 */
	guint8 aByte=0;
	gint cts_flag =0;
	gint dts_flag =0;
	gint first_au_flag=0;
	gint bit_offset = 0;
	
	/*first determine total AU header length */
	/* calculate each AU header length in bits first */
	if (selective_encryption_flag)	header_len+=8; /* add one byte to header length */
	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 = 1;
	}
	else { /* not the first AU */
		if (key_indicator_per_au_flag == 1) 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 */
		aByte=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 (aByte==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 (aByte==1)	header_len+=dts_delta_length; /* add DTS delta length bits if DTS flag SET */
	}
	/* RAP flag present? */
	if (random_access_indication != 0)	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 */
	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 (selective_encryption_flag){
							
		/* 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=%d bits", 8); /* 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 */
		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 */
		add_bits(poffset, -1); /* move back 1 bit for slice_start */
		
		/* Slice_start bit */
		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_slice_start, tvb, bit_offset, 1, FALSE); /*fetch 1 bit slice_start */
		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 */
		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 */
		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 */
		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 */
		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 */
	
	} /* end selective encryption */
	/* IV */
	if (first_au_flag == 1 && 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_add_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 == 0 && 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_add_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 (first_au_flag == 1 && key_indicator_length != 0 || key_indicator_per_au_flag == 1) /* (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 == 1 && 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 == 0 && 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"); /* 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 != 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_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;
}

void proto_register_ismacryp (void)
{
	/* A header field is something you can search/filter on.
	* 
	* We create a structure to register our fields. It consists of an
	* array of hf_register_info structures, each of which are of the format
	* {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
	*/
	static hf_register_info hf[] =
	{
		{ &hf_ismacryp,
		{ "Data", "ismacryp.data", FT_NONE, BASE_NONE, NULL, 0x0,
		NULL, HFILL }},

		{ &hf_ismacryp_length,
		{ "Total Length", "ismacryp.len", FT_UINT16, BASE_DEC, NULL, 0x0,		/* length 2 bytes, print as decimal value */
		NULL, HFILL }},
		
		{ &hf_ismacryp_header,
		{ "AU Header", "ismacryp.header", FT_NONE, BASE_NONE, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_header_length,
		{ "Header Length", "ismacryp.header.length", FT_UINT16, BASE_DEC, NULL, 0x0,
		 NULL, HFILL }},
		 
		 { &hf_ismacryp_au_headers_length,
		{ "AU Headers Length", "ismacryp.au_headers.length", FT_UINT16, BASE_DEC, NULL, 0x0,
		 NULL, HFILL }},

		{ &hf_ismacryp_header_byte,
		{ "Header Byte", "ismacryp.header.byte", FT_UINT8, BASE_HEX, NULL, 0x0,
		 NULL, HFILL }},

		{ &hf_ismacryp_version,
		{ "Version", "ismacryp.version", FT_UINT8, BASE_HEX, NULL, 0x0, 	/* version 1 byte */
		NULL, HFILL }},

		{ &hf_ismacryp_message,
		{ "Message", "ismacryp.message", FT_NONE, BASE_NONE, NULL, 0x0,
		 NULL, HFILL }}, 
		 
		{ &hf_ismacryp_message_length,
		{ "Message Length", "ismacryp.message.len", FT_UINT16, BASE_DEC, NULL, 0x0,		/* length 2 bytes, print as decimal value */
		NULL, HFILL }},

		{ &hf_ismacryp_parameter,
		{ "Parameter", "ismacryp.parameter", FT_NONE, BASE_NONE, NULL, 0x0,
		 NULL, HFILL }}, 
		 
		{ &hf_ismacryp_parameter_length,
		{ "Parameter Length", "ismacryp.parameter.len", FT_UINT16, BASE_DEC, NULL, 0x0,		/* length 2 bytes, print as decimal value */
		NULL, HFILL }},
		
		{ &hf_ismacryp_iv,
		{ "IV", "ismacryp.iv", FT_BYTES, BASE_HEX, NULL, 0x0, /* variable length */
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_delta_iv,
		{ "Delta IV", "ismacryp.delta_iv", FT_BYTES, BASE_HEX, NULL, 0x0, /* variable length */
		 NULL, HFILL }},
		 
		 { &hf_ismacryp_key_indicator,
		{ "Key Indicator", "ismacryp.key_indicator", FT_BYTES, BASE_NONE, NULL, 0x0, /* variable length */
		 NULL, HFILL }}, 

		{ &hf_ismacryp_parameter_value,
		{ "Parameter Value", "ismacryp.parameter.value", FT_NONE, BASE_NONE, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_au_size,
		{ "AU size", "ismacryp.au.size", FT_UINT64, BASE_DEC, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_au_index,
		{ "AU index", "ismacryp.au.index", FT_UINT64, BASE_DEC, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_au_index_delta,
		{ "AU index delta", "ismacryp.au.index_delta", FT_UINT64, BASE_DEC, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_cts_delta,
		{ "CTS delta", "ismacryp.cts_delta", FT_NONE, BASE_NONE, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_cts_flag,
		{ "CTS flag", "ismacryp.cts_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_dts_delta,
		{ "DTS delta", "ismacryp.dts_delta", FT_NONE, BASE_NONE, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_dts_flag,
		{ "DTS flag", "ismacryp.dts_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }},
				 
		{ &hf_ismacryp_rap_flag,
		{ "RAP flag", "ismacryp.rap_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_stream_state,
		{ "Stream state", "ismacryp.stream_state", FT_NONE, BASE_NONE, NULL, 0x0,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_au_is_encrypted,
		{ "AU_is_encrypted flag", "ismacryp.au_is_encrypted", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }},
		
		{ &hf_ismacryp_slice_start,
		{ "Slice_start flag", "ismacryp.slice_start", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_slice_end,
		{ "Slice_end flag", "ismacryp.slice_end", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }},
		 
		{ &hf_ismacryp_padding_bitcount,
		{ "Padding_bitcount bits", "ismacryp.padding_bitcount", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }}, 
		
		{ &hf_ismacryp_reserved_bits,
		{ "Reserved bits", "ismacryp.reserved", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
		 NULL, HFILL }}
	};
	
	static gint *ett[] =
	{
		&ett_ismacryp,
		&ett_ismacryp_header,
		&ett_ismacryp_header_length,
		&ett_ismacryp_au_headers_length,
		&ett_ismacryp_header_byte,
		&ett_ismacryp_message	
	};
		
	static enum_val_t version_types[] = {
		/*{PROTO_TAG_ISMACRYP_11, PROTO_TAG_ISMACRYP_11, 0},
		{PROTO_TAG_ISMACRYP_20, PROTO_TAG_ISMACRYP_20, 1}, */
		{"version11", "version112222", 0},
		{"version20", "version2033333", 1},
		{NULL, NULL, -1}
	};

	module_t *ismacryp_module;
	
	/* execute protocol initialization only once */
	proto_ismacryp = proto_register_protocol ("ISMACryp Protocol", "ISMACRYP", "ismacryp");
	proto_register_field_array (proto_ismacryp, hf, array_length (hf));
	proto_register_subtree_array (ett, array_length (ett));
	
	register_dissector("ismacryp", dissect_ismacryp, proto_ismacryp);
	
	 /* Register our configuration options for ismacryp */
	/* this registers our preferences, function proto_reg_handoff_simulcrypt is called when preferences are applied */
	ismacryp_module = prefs_register_protocol(proto_ismacryp, proto_reg_handoff_ismacryp);
	
	prefs_register_uint_preference(ismacryp_module, "dynamic.payload.type",
							   "ISMACryp dynamic payload type",
							   "The dynamic payload type which will be interpreted as ISMACryp",
							   10,
							   &temp_dynamic_payload_type);

	/*prefs_register_enum_preference(ismacryp_module, "ismacryp.encoding",
					       "ismacryp version",
					       "ismacryp version",
					       &version_type, version_types, FALSE);
	*/
	prefs_register_bool_preference(ismacryp_module, "selective_encryption_flag","ISMACrypSelectiveEncryption (1/0)",
					"Indicates whether or not selective encryption is enabled (1/0)", &selective_encryption_flag);
	
	prefs_register_uint_preference(ismacryp_module, "iv_length","ISMACrypIVLength (bytes)",
					"Set the length of the IV in the ISMACryp AU Header in bytes", 10, &iv_length);
					
	prefs_register_uint_preference(ismacryp_module, "delta_iv_length","ISMACrypDeltaIVLength (bytes)",
					"Set the length of the Delta IV in the ISMACryp AU Header in bytes", 10, &delta_iv_length);
					
	prefs_register_uint_preference(ismacryp_module, "key_indicator_length","ISMACrypKeyIndicatorLength (bytes)",
					"Set the length of the Key Indicator in the ISMACryp AU Header in bytes", 10, &key_indicator_length);

	prefs_register_bool_preference(ismacryp_module, "key_indicator_per_au_flag","ISMACrypKeyIndicatorPerAU (1/0)",
					"Indicates whether or not the Key Indicator is present in all AU Headers (1/0)", &key_indicator_per_au_flag);
	
	prefs_register_uint_preference(ismacryp_module, "au_size_length","SizeLength (bits)",
					"Set the length of the AU size in the AU Header in bits", 10, &au_size_length);
					
	prefs_register_uint_preference(ismacryp_module, "au_index_length","IndexLength (bits)",
					"Set the length of the AU index in the AU Header in bits", 10, &au_index_length);
					
	prefs_register_uint_preference(ismacryp_module, "au_index_delta_length","IndexDeltaLength (bits)",
					"Set the length of the AU delta index in the AU Header in bits", 10, &au_index_delta_length);
					
	prefs_register_uint_preference(ismacryp_module, "cts_delta_length","CTSDeltaLength (bits)",
					"Set the length of the CTS delta field in the AU Header in bits", 10, &cts_delta_length);
					
	prefs_register_uint_preference(ismacryp_module, "dts_delta_length","DTSDeltaLength (bits)",
					"Set the length of the DTS delta field in the AU Header in bits", 10, &dts_delta_length);
					
	prefs_register_bool_preference(ismacryp_module, "random_access_indication","RandomAccessIndication (1/0)",
					"Indicates whether or not the RAP field is present in the AU Header (1/0)", &random_access_indication);
	
	prefs_register_uint_preference(ismacryp_module, "stream_state_indication","stream state indication (number of bits)",
					"Indicates the number of bits on which the stream state field is encoded in the AU Header (bits)", 10, &stream_state_indication);	
}
/* add len_bits to offset bits and  bytes, handling bits overflow */
static void add_bits(offset_struct* poffset, gint len_bits)
{
	gint nbbitstotal=0;
	nbbitstotal=poffset->offset_bytes*8+(poffset->offset_bits)+len_bits; /* total offset in bits */
	/* now calculate bytes and bit offsets */
	poffset->offset_bytes=(nbbitstotal / 8); /* add integer no. of bytes */
	poffset->offset_bits=(nbbitstotal % 8); /* add remaining bits */
}
void proto_reg_handoff_ismacryp(void)
{
	static gboolean ismacryp_prefs_initialized=FALSE;
	
	if (!ismacryp_prefs_initialized) {
		ismacryp_handle = create_dissector_handle(dissect_ismacryp, proto_ismacryp);
		ismacryp_prefs_initialized = TRUE;
		dynamic_payload_type=0;
	  }
	else { /* ismacryp_prefs_initialized = TRUE */
		/* delete existing association of ismacryp with payload_type */
		if ( dynamic_payload_type > 95 ){
			dissector_delete("rtp.pt", dynamic_payload_type, ismacryp_handle);
		}
	}
	/* always do the following */
	dynamic_payload_type = temp_dynamic_payload_type; /*update payload_type to new value */
	if ( dynamic_payload_type > 95 ){
		dissector_add("rtp.pt", dynamic_payload_type, ismacryp_handle);	
	}
	dissector_add_string("rtp_dyn_payload_type", "ISMACRYP", ismacryp_handle);
	dissector_add_string("rtp_dyn_payload_type", "enc-mpeg4-generic", ismacryp_handle);
	/*dissector_add_string("rtp_dyn_payload_type", "enc-isoff-generic", ismacryp_handle);*/
}
 


-----Message d'origine-----
De : wireshark-dev-bounces@xxxxxxxxxxxxx [mailto:wireshark-dev-bounces@xxxxxxxxxxxxx] De la part de Guy Harris
Envoyé : mercredi 22 octobre 2008 20:11
À : Developer support list for Wireshark
Objet : Re: [Wireshark-dev] runtime error using plugin withprefs_register_enum_preference


On Oct 22, 2008, at 9:13 AM, Jaap Keuter wrote:

> You can't have a space or caps in the preference name.

Preference value name, to be precise, in this case:

	/*
	 * Register a preference with an enumerated value.
	 */
	typedef struct {
		const char	*name;
		const char	*description;
		gint		value;
	} enum_val_t;

"name" is what's stored in the preferences file as the value; it should have neither capital letters nor spaces in it, e.g.  
"ismacrypt_1.1".

"description" is what shows up in the UI; it can have any printable ASCII characters in it.

_______________________________________________
Wireshark-dev mailing list
Wireshark-dev@xxxxxxxxxxxxx
https://wireshark.org/mailman/listinfo/wireshark-dev