Commit message: epan: Fix a memory leak.

Make sure _proto_tree_add_bits_ret_val allocates a bits array using the
packet scope, otherwise we leak memory. Fixes #17032.
CVE: CVE-2020-26419
CWE: CWE-401
Vulnerability description: Memory leak in the dissection engine in Wireshark 3.4.0 allows denial of service via packet injection or crafted capture file.

Project: wireshark

const char* proto_field_display_to_string(int field_display)
{
	return val_to_str_const(field_display, hf_display, "Unknown");
}

Project: wireshark

proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				   gint start, gint length, guint32 value,
				   const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
				   tvbuff_t *tvb, const gint start,
				   gint length, const guint encoding,
				   gint *lenretval)
{
	field_info        *new_fi;
	gint		  item_length;
	proto_item	 *item;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
	test_length(hfinfo, tvb, start, item_length, encoding);

	if (!tree) {
		/*
		 * We need to get the correct item length here.
		 * That's normally done by proto_tree_new_item(),
		 * but we won't be calling it.
		 */
		*lenretval = get_full_length(hfinfo, tvb, start, length,
		    item_length, encoding);
		return NULL;
	}

	TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
		/*
		 * Even if the tree item is not referenced (and thus faked),
		 * the caller must still be informed of the actual length.
		 */
		*lenretval = get_full_length(hfinfo, tvb, start, length,
		    item_length, encoding);
	});

	new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);

	item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
	*lenretval = new_fi->length;
	return item;
}

Project: wireshark

proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);

	pi = proto_tree_add_text_node(tree, tvb, start, length);

	TRY_TO_FAKE_THIS_REPR(pi);

	proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));

	return pi;
}

Project: wireshark

proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
{
	offset_search_t	offsearch;

	offsearch.offset = offset;
	offsearch.finfo  = NULL;
	offsearch.tvb    = tvb;

	proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);

	return offsearch.finfo;
}

Project: wireshark

proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
			      gpointer data)
{
	proto_node *pnode = tree;
	proto_node *child;
	proto_node *current;

	if (func(pnode, data))
		return TRUE;

	child = pnode->first_child;
	while (child != NULL) {
		/*
		 * The routine we call might modify the child, e.g. by
		 * freeing it, so we get the child's successor before
		 * calling that routine.
		 */
		current = child;
		child   = current->next;
		if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
			return TRUE;
	}

	return FALSE;
}

Project: wireshark

find_finfo(proto_node *node, gpointer data)
{
	field_info *fi = PNODE_FINFO(node);
	if (fi && fi->hfinfo) {
		if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
			g_ptr_array_add(((ffdata_t*)data)->array, fi);
		}
	}

	/* Don't stop traversing. */
	return FALSE;
}

Project: wireshark

proto_tree_set_visible(proto_tree *tree, gboolean visible)
{
	gboolean old_visible = PTREE_DATA(tree)->visible;

	PTREE_DATA(tree)->visible = visible;

	return old_visible;
}

Project: wireshark

proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		      gint length, const char* value)
{
	proto_item	  *pi;
	header_field_info *hfinfo;
	gint		  item_length;

	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
	get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
	/*
	 * Special case - if the length is 0, skip the test, so that
	 * we can have an empty string right after the end of the
	 * packet.  (This handles URL-encoded forms where the last field
	 * has no value so the form ends right after the =.)
	 */
	if (item_length != 0)
		test_length(hfinfo, tvb, start, item_length, ENC_NA);

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	DISSECTOR_ASSERT(length >= 0);
	proto_tree_set_string(PNODE_FINFO(pi), value);

	return pi;
}

Project: wireshark

proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
{
	protocol_t *protocol;
	header_field_info *hfinfo;

	/*
	 * Helper protocols don't need the strict rules as a "regular" protocol
	 * Just register it in a list and make a hf_ field from it
	 */
	if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
		g_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
	}

	if (parent_proto < 0) {
		g_error("Must have a valid parent protocol for helper protocol \"%s\"!"
			" This might be caused by an inappropriate plugin or a development error.", name);
	}

	check_valid_filter_name_or_fail(filter_name);

	/* Add this protocol to the list of helper protocols (just so it can be properly freed) */
	protocol = g_new(protocol_t, 1);
	protocol->name = name;
	protocol->short_name = short_name;
	protocol->filter_name = filter_name;
	protocol->fields = NULL; /* Delegate until actually needed */

	/* Enabling and toggling is really determined by parent protocol,
	   but provide default values here */
	protocol->is_enabled = TRUE;
	protocol->enabled_by_default = TRUE;
	protocol->can_toggle = TRUE;

	protocol->parent_proto_id = parent_proto;
	protocol->heur_list = NULL;

	/* List will be sorted later by name, when all protocols completed registering */
	protocols = g_list_prepend(protocols, protocol);

	/* Here we allocate a new header_field_info struct */
	hfinfo = g_slice_new(header_field_info);
	hfinfo->name = name;
	hfinfo->abbrev = filter_name;
	hfinfo->type = field_type;
	hfinfo->display = BASE_NONE;
	if (field_type == FT_BYTES) {
		hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
	}
	hfinfo->strings = protocol;
	hfinfo->bitmask = 0;
	hfinfo->ref_type = HF_REF_TYPE_NONE;
	hfinfo->blurb = NULL;
	hfinfo->parent = -1; /* This field differentiates protos and fields */

	protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
	return protocol->proto_id;
}

Project: wireshark

proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
				      tvbuff_t *tvb, const guint bit_offset,
				      const gint no_of_bits, guint64 value,
				      const char *format, ...)
{
	va_list ap;
	gchar  *dst;
	header_field_info *hf_field;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);

	switch (hf_field->type) {
		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
			break;

		default:
			REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
			    hf_field->abbrev);
			return NULL;
			break;
	}

	CREATE_VALUE_STRING(dst, format, ap);

	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
}

Project: wireshark

proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
{
	DISSECTOR_ASSERT(value_ptr != NULL);

	fvalue_set_time(&fi->value, value_ptr);
}

Project: wireshark

void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
{
	if (protocol == NULL)
		return;

	g_list_foreach(protocol->heur_list, func, user_data);
}

Project: wireshark

hfinfo_same_name_get_prev(const header_field_info *hfinfo)
{
	header_field_info *dup_hfinfo;

	if (hfinfo->same_name_prev_id == -1)
		return NULL;
	PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
	return dup_hfinfo;
}

Project: wireshark

proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
								const int len, int * const *fields, const guint64 value)
{
	if (tree) {
		proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
		    BMT_NO_APPEND, FALSE, TRUE, tree, value);
	}
}

Project: wireshark

proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
{
	GByteArray *bytes;

	DISSECTOR_ASSERT(value != NULL);

	bytes = byte_array_dup(value);

	fvalue_set_byte_array(&fi->value, bytes);
}

Project: wireshark

get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
    tvbuff_t *tvb, gint start, gint length, gint *ret_length,
    const guint encoding)
{
	guint32 n;
	const guint8 *value;

	/* I believe it's ok if this is called with a NULL tree */
	n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
	value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
	length += n;
	*ret_length = length;
	return value;
}

Project: wireshark

validate_proto_tree_add_bytes_ftype(const enum ftenum type)
{
	return (type == FT_BYTES      ||
		type == FT_UINT_BYTES ||
		type == FT_OID        ||
		type == FT_REL_OID    ||
		type == FT_SYSTEM_ID  );
}

Project: wireshark

new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
	       const gint start, const gint item_length)
{
	field_info *fi;

	FIELD_INFO_NEW(PNODE_POOL(tree), fi);

	fi->hfinfo     = hfinfo;
	fi->start      = start;
	fi->start     += (tvb)?tvb_raw_offset(tvb):0;
	fi->length     = item_length;
	fi->tree_type  = -1;
	fi->flags      = 0;
	if (!PTREE_DATA(tree)->visible)
		FI_SET_FLAG(fi, FI_HIDDEN);
	fvalue_init(&fi->value, fi->hfinfo->type);
	fi->rep        = NULL;

	/* add the data source tvbuff */
	fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;

	fi->appendix_start  = 0;
	fi->appendix_length = 0;

	return fi;
}

Project: wireshark

get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
    gint length, gint *ret_length, const guint encoding)
{
	/*
	 * XXX - currently, string values are null-
	 * terminated, so a "zero-truncated" string
	 * isn't special.  If we represent string
	 * values as something that includes a counted
	 * array of bytes, we'll need to strip everything
	 * starting with the terminating NUL.
	 */
	if (length == -1) {
		length = tvb_ensure_captured_length_remaining(tvb, start);
	}
	*ret_length = length;
	return tvb_get_string_enc(scope, tvb, start, length, encoding);
}

Project: wireshark

ptvcursor_advance(ptvcursor_t* ptvc, gint length)
{
	ptvc->offset += length;
}

Project: wireshark

hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
{
	const char *str = hf_try_val_to_str(value, hfinfo);

	return (str) ? str : unknown_str;
}

Project: wireshark

ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
{
	ptvc->tree = proto_item_add_subtree(it, ett_subtree);
	return ptvc->tree;
}

Project: wireshark

proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				 gint start, gint length,
				 const e_guid_t *value_ptr,
				 const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		      gint length, double value)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_double(PNODE_FINFO(pi), value);

	return pi;
}

Project: wireshark

proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
{
	int	    ret;	/*tmp return value */
	field_info *fi = PITEM_FINFO(pi);

	DISSECTOR_ASSERT(fi);

	if (!proto_item_is_hidden(pi)) {
		ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
		ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
				  format, ap);
		if (ret >= ITEM_LABEL_LENGTH) {
			/* Uh oh, we don't have enough room.  Tell the user
			 * that the field is truncated.
			 */
			LABEL_MARK_TRUNCATED_START(fi->rep->representation);
		}
	}
}

Project: wireshark

ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
{
	ptvc->tree = tree;
}

Project: wireshark

tmp_fld_check_assert(header_field_info *hfinfo)
{
	gchar* tmp_str;

	/* The field must have a name (with length > 0) */
	if (!hfinfo->name || !hfinfo->name[0]) {
		if (hfinfo->abbrev)
			/* Try to identify the field */
			g_error("Field (abbrev='%s') does not have a name\n",
				hfinfo->abbrev);
		else
			/* Hum, no luck */
			g_error("Field does not have a name (nor an abbreviation)\n");
	}

	/* fields with an empty string for an abbreviation aren't filterable */
	if (!hfinfo->abbrev || !hfinfo->abbrev[0])
		g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);

	/*  These types of fields are allowed to have value_strings,
	 *  true_false_strings or a protocol_t struct
	 */
	if (hfinfo->strings != NULL) {
		switch (hfinfo->type) {
		case FT_CHAR:
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
		case FT_BOOLEAN:
		case FT_PROTOCOL:
		case FT_FRAMENUM:
			break;
		case FT_FLOAT:
		case FT_DOUBLE:
			//allowed to support string if its a unit decsription
			if (hfinfo->display & BASE_UNIT_STRING)
				break;

			//fallthrough
		case FT_BYTES:
			//allowed to support string if its a protocol (for pinos)
			if (hfinfo->display & BASE_PROTOCOL_INFO)
				break;

			//fallthrough
		default:
			g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
				" (which is not allowed to have strings)\n",
				hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
		}
	}

	/* TODO: This check may slow down startup, and output quite a few warnings.
	   It would be good to be able to enable this (and possibly other checks?)
	   in non-release builds.   */
#ifdef ENABLE_CHECK_FILTER
	/* Check for duplicate value_string values.
	   There are lots that have the same value *and* string, so for now only
	   report those that have same value but different string. */
	if ((hfinfo->strings != NULL) &&
	    !(hfinfo->display & BASE_RANGE_STRING) &&
	    !(hfinfo->display & BASE_UNIT_STRING) &&
	    !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
	    (
		    (hfinfo->type == FT_CHAR)  ||
		    (hfinfo->type == FT_UINT8)  ||
		    (hfinfo->type == FT_UINT16) ||
		    (hfinfo->type == FT_UINT24) ||
		    (hfinfo->type == FT_UINT32) ||
		    (hfinfo->type == FT_INT8)   ||
		    (hfinfo->type == FT_INT16)  ||
		    (hfinfo->type == FT_INT24)  ||
		    (hfinfo->type == FT_INT32)  )) {

		if (hfinfo->display & BASE_EXT_STRING) {
			if (hfinfo->display & BASE_VAL64_STRING) {
				const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings);
				CHECK_HF_VALUE(val64_string, G_GINT64_MODIFIER, start_values);
			} else {
				const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings);
				CHECK_HF_VALUE(value_string, "", start_values);
			}
		} else {
			const value_string *start_values = (const value_string*)hfinfo->strings;
			CHECK_HF_VALUE(value_string, "", start_values);
		}
	}

	if (hfinfo->type == FT_BOOLEAN) {
		const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
		if (tfs) {
			if (strcmp(tfs->false_string, tfs->true_string) == 0) {
				g_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",
						   hfinfo->name, hfinfo->abbrev,
						   tfs->false_string, tfs->true_string);
			}
		}
	}

	if (hfinfo->display & BASE_RANGE_STRING) {
		const range_string *rs = (const range_string*)(hfinfo->strings);
		if (rs) {
			const range_string *this_it = rs;

			do {
				if (this_it->value_max < this_it->value_min) {
					g_warning("value_range_string error:  %s (%s) entry for \"%s\" - max(%u 0x%x) is less than min(%u 0x%x)",
							  hfinfo->name, hfinfo->abbrev,
							  this_it->strptr,
							  this_it->value_max, this_it->value_max,
							  this_it->value_min, this_it->value_min);
					++this_it;
					continue;
				}

				for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
					/* Not OK if this one is completely hidden by an earlier one! */
					if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
						g_warning("value_range_string error:  %s (%s) hidden by earlier entry "
								  "(prev=\"%s\":  %u 0x%x -> %u 0x%x)  (this=\"%s\":  %u 0x%x -> %u 0x%x)",
								  hfinfo->name, hfinfo->abbrev,
								  prev_it->strptr, prev_it->value_min, prev_it->value_min,
								  prev_it->value_max, prev_it->value_max,
								  this_it->strptr, this_it->value_min, this_it->value_min,
								  this_it->value_max, this_it->value_max);
					}
				}
				++this_it;
			} while (this_it->strptr);
		}
	}
#endif

	switch (hfinfo->type) {

		case FT_CHAR:
			/*  Require the char type to have BASE_HEX, BASE_OCT,
			 *  BASE_CUSTOM, or BASE_NONE as its base.
			 *
			 *  If the display value is BASE_NONE and there is a
			 *  strings conversion then the dissector writer is
			 *  telling us that the field's numerical value is
			 *  meaningless; we'll avoid showing the value to the
			 *  user.
			 */
			switch (FIELD_DISPLAY(hfinfo->display)) {
				case BASE_HEX:
				case BASE_OCT:
				case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
					break;
				case BASE_NONE:
					if (hfinfo->strings == NULL)
						g_error("Field '%s' (%s) is an integral value (%s)"
							" but is being displayed as BASE_NONE but"
							" without a strings conversion",
							hfinfo->name, hfinfo->abbrev,
							ftype_name(hfinfo->type));
					break;
				default:
					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
					g_error("Field '%s' (%s) is a character value (%s)"
						" but is being displayed as %s\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
					wmem_free(NULL, tmp_str);
			}
			if (hfinfo->display & BASE_UNIT_STRING) {
				g_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			}
			break;
		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
			/*	Hexadecimal and octal are, in printf() and everywhere
			 *	else, unsigned so don't allow dissectors to register a
			 *	signed field to be displayed unsigned.  (Else how would
			 *	we display negative values?)
			 */
			switch (FIELD_DISPLAY(hfinfo->display)) {
				case BASE_HEX:
				case BASE_OCT:
				case BASE_DEC_HEX:
				case BASE_HEX_DEC:
					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
					g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
					wmem_free(NULL, tmp_str);
			}
			/* FALL THROUGH */
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
			if (IS_BASE_PORT(hfinfo->display)) {
				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
				if (hfinfo->type != FT_UINT16) {
					g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
						hfinfo->name, hfinfo->abbrev,
						tmp_str, ftype_name(hfinfo->type));
				}
				if (hfinfo->strings != NULL) {
					g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
				}
				if (hfinfo->bitmask != 0) {
					g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
				}
				wmem_free(NULL, tmp_str);
				break;
			}

			if (hfinfo->display == BASE_OUI) {
				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
				if (hfinfo->type != FT_UINT24) {
					g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s\n",
						hfinfo->name, hfinfo->abbrev,
						tmp_str, ftype_name(hfinfo->type));
				}
				if (hfinfo->strings != NULL) {
					g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
				}
				if (hfinfo->bitmask != 0) {
					g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
				}
				wmem_free(NULL, tmp_str);
				break;
			}

			/*  Require integral types (other than frame number,
			 *  which is always displayed in decimal) to have a
			 *  number base.
			 *
			 *  If the display value is BASE_NONE and there is a
			 *  strings conversion then the dissector writer is
			 *  telling us that the field's numerical value is
			 *  meaningless; we'll avoid showing the value to the
			 *  user.
			 */
			switch (FIELD_DISPLAY(hfinfo->display)) {
				case BASE_DEC:
				case BASE_HEX:
				case BASE_OCT:
				case BASE_DEC_HEX:
				case BASE_HEX_DEC:
				case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
					break;
				case BASE_NONE:
					if (hfinfo->strings == NULL) {
						g_error("Field '%s' (%s) is an integral value (%s)"
							" but is being displayed as BASE_NONE but"
							" without a strings conversion",
							hfinfo->name, hfinfo->abbrev,
							ftype_name(hfinfo->type));
					}
					if (hfinfo->display & BASE_SPECIAL_VALS) {
						g_error("Field '%s' (%s) is an integral value (%s)"
							" that is being displayed as BASE_NONE but"
							" with BASE_SPECIAL_VALS",
							hfinfo->name, hfinfo->abbrev,
							ftype_name(hfinfo->type));
					}
					break;

				default:
					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
					g_error("Field '%s' (%s) is an integral value (%s)"
						" but is being displayed as %s\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
					wmem_free(NULL, tmp_str);
			}
			break;
		case FT_BYTES:
		case FT_UINT_BYTES:
			/*  Require bytes to have a "display type" that could
			 *  add a character between displayed bytes.
			 */
			switch (FIELD_DISPLAY(hfinfo->display)) {
				case BASE_NONE:
				case SEP_DOT:
				case SEP_DASH:
				case SEP_COLON:
				case SEP_SPACE:
					break;
				default:
					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
					g_error("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE\n",
						hfinfo->name, hfinfo->abbrev, tmp_str);
					wmem_free(NULL, tmp_str);
			}
			if (hfinfo->bitmask != 0)
				g_error("Field '%s' (%s) is an %s but has a bitmask\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			//allowed to support string if its a protocol (for pinos)
			if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
				g_error("Field '%s' (%s) is an %s but has a strings value\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			break;

		case FT_PROTOCOL:
		case FT_FRAMENUM:
			if (hfinfo->display != BASE_NONE) {
				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
				g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type), tmp_str);
				wmem_free(NULL, tmp_str);
			}
			if (hfinfo->bitmask != 0)
				g_error("Field '%s' (%s) is an %s but has a bitmask\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			break;

		case FT_BOOLEAN:
			break;

		case FT_ABSOLUTE_TIME:
			if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
			      hfinfo->display == ABSOLUTE_TIME_UTC   ||
			      hfinfo->display == ABSOLUTE_TIME_NTP_UTC   ||
			      hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
				g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
					hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
				wmem_free(NULL, tmp_str);
			}
			if (hfinfo->bitmask != 0)
				g_error("Field '%s' (%s) is an %s but has a bitmask\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			break;

		case FT_STRING:
		case FT_STRINGZ:
		case FT_UINT_STRING:
		case FT_STRINGZPAD:
		case FT_STRINGZTRUNC:
			switch (hfinfo->display) {
				case STR_ASCII:
				case STR_UNICODE:
					break;

				default:
					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
					g_error("Field '%s' (%s) is an string value (%s)"
						" but is being displayed as %s\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
					wmem_free(NULL, tmp_str);
			}

			if (hfinfo->bitmask != 0)
				g_error("Field '%s' (%s) is an %s but has a bitmask\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			if (hfinfo->strings != NULL)
				g_error("Field '%s' (%s) is an %s but has a strings value\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			break;

		case FT_IPv4:
			switch (hfinfo->display) {
				case BASE_NONE:
				case BASE_NETMASK:
					break;

				default:
					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
					g_error("Field '%s' (%s) is an IPv4 value (%s)"
						" but is being displayed as %s\n",
						hfinfo->name, hfinfo->abbrev,
						ftype_name(hfinfo->type), tmp_str);
					wmem_free(NULL, tmp_str);
					break;
			}
			break;
		case FT_FLOAT:
		case FT_DOUBLE:
			if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
				g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type),
					tmp_str);
				wmem_free(NULL, tmp_str);
			}
			if (hfinfo->bitmask != 0)
				g_error("Field '%s' (%s) is an %s but has a bitmask\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
				g_error("Field '%s' (%s) is an %s but has a strings value\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			break;
		default:
			if (hfinfo->display != BASE_NONE) {
				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
				g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type),
					tmp_str);
				wmem_free(NULL, tmp_str);
			}
			if (hfinfo->bitmask != 0)
				g_error("Field '%s' (%s) is an %s but has a bitmask\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			if (hfinfo->strings != NULL)
				g_error("Field '%s' (%s) is an %s but has a strings value\n",
					hfinfo->name, hfinfo->abbrev,
					ftype_name(hfinfo->type));
			break;
	}
}

Project: wireshark

proto_get_protocol_long_name(const protocol_t *protocol)
{
	if (protocol == NULL)
		return "(none)";
	return protocol->name;
}

Project: wireshark

ptvcursor_tvbuff(ptvcursor_t *ptvc)
{
	return ptvc->tvb;
}

Project: wireshark

proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
                             const gint start, gint length,
                             const guint encoding, ws_in4_addr *retval)
{
	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
	field_info	  *new_fi;
	ws_in4_addr	   value;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	switch (hfinfo->type) {
	case FT_IPv4:
		break;
	default:
		REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",
		    hfinfo->abbrev);
	}

	if (length != FT_IPv4_LEN)
		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",
			length);

	if (encoding & (ENC_STRING | ENC_VARIANT_MASK | ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
		REPORT_DISSECTOR_BUG("wrong encoding");
	}

	/*
	 * NOTE: to support code written when proto_tree_add_item() took
	 * a gboolean as its last argument, with FALSE meaning "big-endian"
	 * and TRUE meaning "little-endian", we treat any non-zero value
	 * of "encoding" as meaning "little-endian".
	 */
	value = tvb_get_ipv4(tvb, start);
	if (encoding)
		value = GUINT32_SWAP_LE_BE(value);

	if (retval) {
		*retval = value;
	}

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);

	new_fi = new_field_info(tree, hfinfo, tvb, start, length);

	proto_tree_set_ipv4(new_fi, value);

	new_fi->flags |= encoding ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
	return proto_tree_add_node(tree, new_fi);
}

Project: wireshark

proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				  gint start, gint length,
				  const guint8 *start_ptr,
				  const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	if (start_ptr == NULL)
		start_ptr = tvb_get_ptr(tvb, start, length);

	pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);

	TRY_TO_FAKE_THIS_REPR_NESTED(pi);

	va_start(ap, format);
	proto_tree_set_representation_value(pi, format, ap);
	va_end(ap);

	return pi;
}

Project: wireshark

proto_tree_set_ax25(field_info *fi, const guint8* value)
{
	fvalue_set_bytes(&fi->value, value);
}

Project: wireshark

prefix_hash (gconstpointer key) {
	/* end the string at the dot and compute its hash */
	gchar* copy = g_strdup((const gchar *)key);
	gchar* c    = copy;
	guint tmp;

	for (; *c; c++) {
		if (*c == '.') {
			*c = 0;
			break;
		}
	}

	tmp = g_str_hash(copy);
	g_free(copy);
	return tmp;
}

Project: wireshark

elastic_add_base_mapping(json_dumper *dumper)
{
	json_dumper_set_member_name(dumper, "index_patterns");
	json_dumper_value_string(dumper, "packets-*");

	json_dumper_set_member_name(dumper, "settings");
	json_dumper_begin_object(dumper);
	json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
	json_dumper_value_anyf(dumper, "%d", 1000000);
	json_dumper_end_object(dumper);
}

Project: wireshark

proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
{
	field_info *fi;

	if (!pi)
		return "";
	fi = PITEM_FINFO(pi);
	DISSECTOR_ASSERT(fi->hfinfo != NULL);
	return fvalue_to_string_repr(scope, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
}

Project: wireshark

call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_)
{
	proto_plugin *plug = (proto_plugin *)data;

	if (plug->register_protoinfo) {
		plug->register_protoinfo();
	}
}

Project: wireshark

display_to_port_type(field_display_e e)
{
	switch (e) {
	case BASE_PT_UDP:
		return PT_UDP;
	case BASE_PT_TCP:
		return PT_TCP;
	case BASE_PT_DCCP:
		return PT_DCCP;
	case BASE_PT_SCTP:
		return PT_SCTP;
	default:
		break;
	}
	return PT_NONE;
}

Project: wireshark

proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
			    const guint bit_offset, const gint no_of_bits,
			    guint64 *return_value, const guint encoding)
{
	proto_item *item;

	if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
						 bit_offset, no_of_bits,
						 return_value, encoding))) {
		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
	}
	return item;
}

Project: wireshark

every_finfo(proto_node *node, gpointer data)
{
	field_info *fi = PNODE_FINFO(node);
	if (fi && fi->hfinfo) {
		g_ptr_array_add(((ffdata_t*)data)->array, fi);
	}

	/* Don't stop traversing. */
	return FALSE;
}

Project: wireshark

proto_item_get_parent_nth(proto_item *ti, int gen) {
	if (!ti)
		return NULL;
	while (gen--) {
		ti = ti->parent;
		if (!ti)
			return NULL;
	}
	return ti;
}

Project: wireshark

proto_tree_set_uint64(field_info *fi, guint64 value)
{
	header_field_info *hfinfo;
	guint64		   integer;

	hfinfo = fi->hfinfo;
	integer = value;

	if (hfinfo->bitmask) {
		/* Mask out irrelevant portions */
		integer &= hfinfo->bitmask;

		/* Shift bits */
		integer >>= hfinfo_bitshift(hfinfo);

		FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
		FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
	}

	fvalue_set_uinteger64(&fi->value, integer);
}

Project: wireshark

proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				   gint start, gint length, const char* value,
				   const char *format,
				   ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		      gint length, guint64 value)
{
	proto_item	  *pi = NULL;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	switch (hfinfo->type) {
		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
		case FT_FRAMENUM:
			pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
			proto_tree_set_uint64(PNODE_FINFO(pi), value);
			break;

		default:
			REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
			    hfinfo->abbrev);
	}

	return pi;
}

Project: wireshark

free_deregistered_data (gpointer data, gpointer user_data _U_)
{
	g_free (data);
}

Project: wireshark

proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
	const gint start, gint length, const guint encoding, gint64 *retval)
{
	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
	field_info	  *new_fi;
	gint64		   value;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	switch (hfinfo->type) {
	case FT_INT40:
	case FT_INT48:
	case FT_INT56:
	case FT_INT64:
		break;
	default:
		REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
			hfinfo->abbrev);
	}

	/* length validation for native number encoding caught by get_uint64_value() */
	/* length has to be -1 or > 0 regardless of encoding */
	if (length < -1 || length == 0)
		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int64",
			length);

	if (encoding & ENC_STRING) {
		REPORT_DISSECTOR_BUG("wrong encoding");
	}
	/* I believe it's ok if this is called with a NULL tree */
	if (encoding & (ENC_VARIANT_MASK)) {
		tvb_get_varint(tvb, start, length, &value, encoding);
	}
	else {
		value = get_int64_value(tree, tvb, start, length, encoding);
	}

	if (retval) {
		*retval = value;
	}

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);

	new_fi = new_field_info(tree, hfinfo, tvb, start, length);

	proto_tree_set_int64(new_fi, value);

	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
	if (encoding & (ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
		new_fi->flags |= FI_VARINT;
	}

	return proto_tree_add_node(tree, new_fi);
}

Project: wireshark

proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		    gint length, const nstime_t *value_ptr)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_time(PNODE_FINFO(pi), value_ptr);

	return pi;
}

Project: wireshark

proto_item_fill_display_label(field_info *finfo, gchar *display_label_str, const int label_str_size)
{
	header_field_info *hfinfo = finfo->hfinfo;
	int label_len = 0;
	char *tmp_str;
	guint8 *bytes;
	guint32 number;
	guint64 number64;
	const true_false_string  *tfstring;
	const char *hf_str_val;
	char number_buf[48];
	const char *number_out;
	address addr;
	ws_in4_addr ipv4;
	ws_in6_addr *ipv6;

	switch (hfinfo->type) {

		case FT_NONE:
		case FT_PROTOCOL:
			/* prevent multiple check marks by setting result directly */
			return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK, label_str_size);
			break;

		case FT_UINT_BYTES:
		case FT_BYTES:
			tmp_str = hfinfo_format_bytes(NULL,
				hfinfo,
				(guint8 *)fvalue_get(&finfo->value),
				fvalue_length(&finfo->value));
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_ABSOLUTE_TIME:
			tmp_str = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_RELATIVE_TIME:
			tmp_str = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_BOOLEAN:
			number64 = fvalue_get_uinteger64(&finfo->value);
			tfstring = &tfs_true_false;
			if (hfinfo->strings) {
				tfstring = (const struct true_false_string*) hfinfo->strings;
			}
			label_len = protoo_strlcpy(display_label_str,
					tfs_get_string(!!number64, tfstring), label_str_size);
			break;

		case FT_CHAR:
			number = fvalue_get_uinteger(&finfo->value);

			if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
				gchar tmp[ITEM_LABEL_LENGTH];
				custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;

				DISSECTOR_ASSERT(fmtfunc);
				fmtfunc(tmp, number);

				label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);

			} else if (hfinfo->strings) {
				number_out = hf_try_val_to_str(number, hfinfo);

				if (!number_out) {
					number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
				}

				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);

			} else {
				number_out = hfinfo_char_value_format(hfinfo, number_buf, number);

				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
			}

			break;

		/* XXX - make these just FT_NUMBER? */
		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
		case FT_FRAMENUM:
			hf_str_val = NULL;
			number = IS_FT_INT(hfinfo->type) ?
				(guint32) fvalue_get_sinteger(&finfo->value) :
				fvalue_get_uinteger(&finfo->value);

			if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
				gchar tmp[ITEM_LABEL_LENGTH];
				custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;

				DISSECTOR_ASSERT(fmtfunc);
				fmtfunc(tmp, number);

				label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);

			} else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
				if (hfinfo->display & BASE_UNIT_STRING) {
					number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
					hf_str_val = hf_try_val_to_str(number, hfinfo);
					label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
				} else {
					number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);

					if (!number_out) {
						number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
					}

					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
				}
			} else {
				number_out = hfinfo_number_value_format(hfinfo, number_buf, number);

				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
			}

			break;

		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
			hf_str_val = NULL;
			number64 = IS_FT_INT(hfinfo->type) ?
				(guint64) fvalue_get_sinteger64(&finfo->value) :
				fvalue_get_uinteger64(&finfo->value);

			if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
				gchar tmp[ITEM_LABEL_LENGTH];
				custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;

				DISSECTOR_ASSERT(fmtfunc64);
				fmtfunc64(tmp, number64);

				label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
			} else if (hfinfo->strings) {
				if (hfinfo->display & BASE_UNIT_STRING) {
					number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
					hf_str_val = hf_try_val64_to_str(number64, hfinfo);
					label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
				} else {
					number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);

					if (!number_out)
						number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);

					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
				}
			} else {
				number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);

				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
			}

			break;

		case FT_EUI64:
			tmp_str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_IPv4:
			ipv4 = fvalue_get_uinteger(&finfo->value);
			set_address (&addr, AT_IPv4, 4, &ipv4);
			address_to_str_buf(&addr, display_label_str, label_str_size);
			label_len = (int)strlen(display_label_str);
			break;

		case FT_IPv6:
			ipv6 = (ws_in6_addr *)fvalue_get(&finfo->value);
			set_address (&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
			address_to_str_buf(&addr, display_label_str, label_str_size);
			label_len = (int)strlen(display_label_str);
			break;

		case FT_FCWWN:
			set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
			address_to_str_buf(&addr, display_label_str, label_str_size);
			label_len = (int)strlen(display_label_str);
			break;

		case FT_ETHER:
			set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
			address_to_str_buf(&addr, display_label_str, label_str_size);
			label_len = (int)strlen(display_label_str);
			break;

		case FT_GUID:
			tmp_str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_REL_OID:
			bytes = (guint8 *)fvalue_get(&finfo->value);
			tmp_str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_OID:
			bytes = (guint8 *)fvalue_get(&finfo->value);
			tmp_str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_SYSTEM_ID:
			bytes = (guint8 *)fvalue_get(&finfo->value);
			tmp_str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		case FT_FLOAT:
			if (hfinfo->display & BASE_UNIT_STRING) {
				double d_value = fvalue_get_floating(&finfo->value);
				g_snprintf(display_label_str, label_str_size,
						"%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
						unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
			} else {
				g_snprintf(display_label_str, label_str_size,
						"%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
			}
			label_len = (int)strlen(display_label_str);
			break;

		case FT_DOUBLE:
			if (hfinfo->display & BASE_UNIT_STRING) {
				double d_value = fvalue_get_floating(&finfo->value);
				g_snprintf(display_label_str, label_str_size,
						"%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
						unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
			} else {
				g_snprintf(display_label_str, label_str_size,
						"%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
			}
			label_len = (int)strlen(display_label_str);
			break;

		case FT_STRING:
		case FT_STRINGZ:
		case FT_UINT_STRING:
		case FT_STRINGZPAD:
		case FT_STRINGZTRUNC:
			bytes = (guint8 *)fvalue_get(&finfo->value);
			tmp_str = hfinfo_format_text(NULL, hfinfo, bytes);
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;

		default:
			/* First try ftype string representation */
			tmp_str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
			if (!tmp_str) {
				/* Default to show as bytes */
				bytes = (guint8 *)fvalue_get(&finfo->value);
				tmp_str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
			}
			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
			wmem_free(NULL, tmp_str);
			break;
	}
	return label_len;
}

Project: wireshark

_ftype_common(enum ftenum type)
{
	switch (type) {
		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
			return FT_INT32;

		case FT_CHAR:
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
		case FT_IPXNET:
		case FT_FRAMENUM:
			return FT_UINT32;

		case FT_UINT64:
		case FT_EUI64:
			return FT_UINT64;

		case FT_STRING:
		case FT_STRINGZ:
		case FT_UINT_STRING:
			return FT_STRING;

		case FT_FLOAT:
		case FT_DOUBLE:
			return FT_DOUBLE;

		case FT_BYTES:
		case FT_UINT_BYTES:
		case FT_ETHER:
		case FT_OID:
			return FT_BYTES;

		case FT_ABSOLUTE_TIME:
		case FT_RELATIVE_TIME:
			return FT_ABSOLUTE_TIME;

		default:
			return type;
	}
}

Project: wireshark

proto_tree_set_int(field_info *fi, gint32 value)
{
	header_field_info *hfinfo;
	guint32		   integer;
	gint		   no_of_bits;

	hfinfo = fi->hfinfo;
	integer = (guint32) value;

	if (hfinfo->bitmask) {
		/* Mask out irrelevant portions */
		integer &= (guint32)(hfinfo->bitmask);

		/* Shift bits */
		integer >>= hfinfo_bitshift(hfinfo);

		no_of_bits = ws_count_ones(hfinfo->bitmask);
		integer = ws_sign_ext32(integer, no_of_bits);

		FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
		FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
	}

	fvalue_set_sinteger(&fi->value, integer);
}

Project: wireshark

proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
			    const int len, const gint ett, int * const *fields,
			    const int flags, gboolean first,
			    gboolean use_parent_tree,
			    proto_tree* tree, guint64 value)
{
	guint64            available_bits = G_MAXUINT64;
	guint64            bitmask = 0;
	guint64            tmpval;
	header_field_info *hf;
	guint32            integer32;
	gint               bit_offset;
	gint               no_of_bits;

	if (len < 0 || len > 8)
		g_assert_not_reached();
	/**
	 * packet-frame.c uses len=0 since the value is taken from the packet
	 * metadata, not the packet bytes. In that case, assume that all bits
	 * in the provided value are valid.
	 */
	if (len > 0) {
		available_bits >>= (8 - (guint)len)*8;
	}

	if (use_parent_tree == FALSE)
		tree = proto_item_add_subtree(item, ett);

	while (*fields) {
		guint64 present_bits;
		PROTO_REGISTRAR_GET_NTH(**fields,hf);
		DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);

		bitmask |= hf->bitmask;

		/* Skip fields that aren't fully present */
		present_bits = available_bits & hf->bitmask;
		if (present_bits != hf->bitmask) {
			fields++;
			continue;
		}

		switch (hf->type) {
		case FT_CHAR:
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
			proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
			break;

		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
			proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
			break;

		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
			proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
			break;

		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
			proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
			break;

		case FT_BOOLEAN:
			proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
			break;

		default:
			REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
					     hf->abbrev,
					     hf->type,
					     ftype_name(hf->type));
			break;
		}
		if (flags & BMT_NO_APPEND) {
			fields++;
			continue;
		}
		tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);

		switch (hf->type) {
		case FT_CHAR:
			if (hf->display == BASE_CUSTOM) {
				gchar lbl[ITEM_LABEL_LENGTH];
				const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;

				DISSECTOR_ASSERT(fmtfunc);
				fmtfunc(lbl, (guint32) tmpval);
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, lbl);
				first = FALSE;
			}
			else if (hf->strings) {
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						       hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
				first = FALSE;
			}
			else if (!(flags & BMT_NO_INT)) {
				char buf[32];
				const char *out;

				if (!first) {
					proto_item_append_text(item, ", ");
				}

				out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
				proto_item_append_text(item, "%s: %s", hf->name, out);
				first = FALSE;
			}

			break;

		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
			if (hf->display == BASE_CUSTOM) {
				gchar lbl[ITEM_LABEL_LENGTH];
				const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;

				DISSECTOR_ASSERT(fmtfunc);
				fmtfunc(lbl, (guint32) tmpval);
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, lbl);
				first = FALSE;
			}
			else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
										hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
				first = FALSE;
			}
			else if (!(flags & BMT_NO_INT)) {
				char buf[32];
				const char *out;

				if (!first) {
					proto_item_append_text(item, ", ");
				}

				out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
				if (hf->display & BASE_UNIT_STRING) {
					proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
				} else {
					proto_item_append_text(item, "%s: %s", hf->name, out);
				}
				first = FALSE;
			}

			break;

		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
			integer32 = (guint32) tmpval;
			if (hf->bitmask) {
				no_of_bits = ws_count_ones(hf->bitmask);
				integer32 = ws_sign_ext32(integer32, no_of_bits);
			}
			if (hf->display == BASE_CUSTOM) {
				gchar lbl[ITEM_LABEL_LENGTH];
				const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;

				DISSECTOR_ASSERT(fmtfunc);
				fmtfunc(lbl, (gint32) integer32);
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, lbl);
				first = FALSE;
			}
			else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
				first = FALSE;
			}
			else if (!(flags & BMT_NO_INT)) {
				char buf[32];
				const char *out;

				if (!first) {
					proto_item_append_text(item, ", ");
				}

				out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
				if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
					proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
				} else {
					proto_item_append_text(item, "%s: %s", hf->name, out);
				}
				first = FALSE;
			}

			break;

		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
			if (hf->display == BASE_CUSTOM) {
				gchar lbl[ITEM_LABEL_LENGTH];
				const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;

				DISSECTOR_ASSERT(fmtfunc);
				fmtfunc(lbl, tmpval);
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, lbl);
				first = FALSE;
			}
			else if (hf->strings) {
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
				first = FALSE;
			}
			else if (!(flags & BMT_NO_INT)) {
				char buf[48];
				const char *out;

				if (!first) {
					proto_item_append_text(item, ", ");
				}

				out = hfinfo_number_value_format64(hf, buf, tmpval);
				proto_item_append_text(item, "%s: %s", hf->name, out);
				first = FALSE;
			}

			break;

		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
			if (hf->bitmask) {
				no_of_bits = ws_count_ones(hf->bitmask);
				tmpval = ws_sign_ext64(tmpval, no_of_bits);
			}
			if (hf->display == BASE_CUSTOM) {
				gchar lbl[ITEM_LABEL_LENGTH];
				const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;

				DISSECTOR_ASSERT(fmtfunc);
				fmtfunc(lbl, (gint64) tmpval);
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, lbl);
				first = FALSE;
			}
			else if (hf->strings) {
				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
						hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
				first = FALSE;
			}
			else if (!(flags & BMT_NO_INT)) {
				char buf[48];
				const char *out;

				if (!first) {
					proto_item_append_text(item, ", ");
				}

				out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
				proto_item_append_text(item, "%s: %s", hf->name, out);
				first = FALSE;
			}

			break;

		case FT_BOOLEAN:
			if (hf->strings && !(flags & BMT_NO_TFS)) {
				/* If we have true/false strings, emit full - otherwise messages
				   might look weird */
				const struct true_false_string *tfs =
					(const struct true_false_string *)hf->strings;

				if (tmpval) {
					proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
							hf->name, tfs->true_string);
					first = FALSE;
				} else if (!(flags & BMT_NO_FALSE)) {
					proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
							hf->name, tfs->false_string);
					first = FALSE;
				}
			} else if (hf->bitmask & value) {
				/* If the flag is set, show the name */
				proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
				first = FALSE;
			}
			break;
		default:
			REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
					     hf->abbrev,
					     hf->type,
					     ftype_name(hf->type));
			break;
		}

		fields++;
	}

	/* XXX: We don't pass the hfi into this function. Perhaps we should,
	 * but then again most dissectors don't set the bitmask field for
	 * the higher level bitmask hfi, so calculate the bitmask from the
	 * fields present. */
	if (item) {
		bit_offset = len*8 - 1 - ws_ilog2(bitmask);
		no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
	}
	return first;
}

Project: wireshark

proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
		 gchar *result, gchar *expr, const int size)
{
	guint32             number;
	guint64             number64;
	guint8             *bytes;

	int                 len, prev_len, last, i, offset_r = 0, offset_e = 0, label_len;
	GPtrArray          *finfos;
	field_info         *finfo         = NULL;
	header_field_info*  hfinfo;
	const gchar        *abbrev        = NULL;

	const char *hf_str_val;
	char number_buf[48];
	const char *number_out;
	char *str;
	int *field_idx;
	int field_id;
	int ii = 0;

	g_assert(field_ids != NULL);
	while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
		field_id = *field_idx;
		PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);

		/* do we need to rewind ? */
		if (!hfinfo)
			return "";

		if (occurrence < 0) {
			/* Search other direction */
			while (hfinfo->same_name_prev_id != -1) {
				PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
			}
		}

		prev_len = 0; /* Reset handled occurrences */

		while (hfinfo) {
			finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);

			if (!finfos || !(len = g_ptr_array_len(finfos))) {
				if (occurrence < 0) {
					hfinfo = hfinfo->same_name_next;
				} else {
					hfinfo = hfinfo_same_name_get_prev(hfinfo);
				}
				continue;
			}

			/* Are there enough occurrences of the field? */
			if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
				if (occurrence < 0) {
					hfinfo = hfinfo->same_name_next;
				} else {
					hfinfo = hfinfo_same_name_get_prev(hfinfo);
				}
				prev_len += len;
				continue;
			}

			/* Calculate single index or set outer bounderies */
			if (occurrence < 0) {
				i = occurrence + len + prev_len;
				last = i;
			} else if (occurrence > 0) {
				i = occurrence - 1 - prev_len;
				last = i;
			} else {
				i = 0;
				last = len - 1;
			}

			prev_len += len; /* Count handled occurrences */

			while (i <= last) {
				finfo = (field_info *)g_ptr_array_index(finfos, i);

				if (offset_r && (offset_r < (size - 2)))
					result[offset_r++] = ',';

				if (offset_e && (offset_e < (size - 2)))
					expr[offset_e++] = ',';

				switch (hfinfo->type) {

					case FT_BOOLEAN:
						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);

						number64 = fvalue_get_uinteger64(&finfo->value);
						offset_e += protoo_strlcpy(expr+offset_e,
								number64 ? "1" : "0", size-offset_e);
						break;

					case FT_CHAR:
						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);

						number = fvalue_get_uinteger(&finfo->value);

						if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
							hf_str_val = hf_try_val_to_str(number, hfinfo);
							g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
						} else {
							number_out = hfinfo_char_value_format(hfinfo, number_buf, number);

							g_strlcpy(expr+offset_e, number_out, size-offset_e);
						}

						offset_e = (int)strlen(expr);
						break;

						/* XXX - make these just FT_NUMBER? */
					case FT_INT8:
					case FT_INT16:
					case FT_INT24:
					case FT_INT32:
					case FT_UINT8:
					case FT_UINT16:
					case FT_UINT24:
					case FT_UINT32:
					case FT_FRAMENUM:
						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);

						hf_str_val = NULL;
						number = IS_FT_INT(hfinfo->type) ?
							(guint32) fvalue_get_sinteger(&finfo->value) :
							fvalue_get_uinteger(&finfo->value);

						if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
							hf_str_val = hf_try_val_to_str(number, hfinfo);
						}

						if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {

							hf_str_val = hf_try_val_to_str(number, hfinfo);
							g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
						} else {
							number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);

							g_strlcpy(expr+offset_e, number_out, size-offset_e);
						}

						offset_e = (int)strlen(expr);
						break;

					case FT_INT40:
					case FT_INT48:
					case FT_INT56:
					case FT_INT64:
					case FT_UINT40:
					case FT_UINT48:
					case FT_UINT56:
					case FT_UINT64:
						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);

						hf_str_val = NULL;
						number64 = IS_FT_INT(hfinfo->type) ?
							(guint64) fvalue_get_sinteger64(&finfo->value) :
							fvalue_get_uinteger64(&finfo->value);

						if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
							hf_str_val = hf_try_val64_to_str(number64, hfinfo);
						}

						if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
							g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
						} else {
							number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);

							g_strlcpy(expr+offset_e, number_out, size-offset_e);
						}

						offset_e = (int)strlen(expr);
						break;

					case FT_REL_OID:
						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);

						bytes = (guint8 *)fvalue_get(&finfo->value);
						str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
						offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
						wmem_free(NULL, str);
						break;

					case FT_OID:
						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);

						bytes = (guint8 *)fvalue_get(&finfo->value);
						str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
						offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
						wmem_free(NULL, str);
						break;

					case FT_SYSTEM_ID:
						label_len = proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);

						offset_e += protoo_strlcpy(expr+offset_e, result+offset_r, size-offset_e);

						offset_r += label_len;
						break;

					default:
						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
						break;
				}
				i++;
			}

			switch (hfinfo->type) {

				case FT_BOOLEAN:
				case FT_CHAR:
				case FT_UINT8:
				case FT_UINT16:
				case FT_UINT24:
				case FT_UINT32:
				case FT_UINT40:
				case FT_UINT48:
				case FT_UINT56:
				case FT_UINT64:
				case FT_FRAMENUM:
				case FT_INT8:
				case FT_INT16:
				case FT_INT24:
				case FT_INT32:
				case FT_INT40:
				case FT_INT48:
				case FT_INT56:
				case FT_INT64:
				case FT_OID:
				case FT_REL_OID:
				case FT_SYSTEM_ID:
					/* for these types, "expr" is filled in the loop above */
					break;

				default:
					/* for all others, just copy "result" to "expr" */
					g_strlcpy(expr, result, size);
					break;
			}

			if (!abbrev) {
				/* Store abbrev for return value */
				abbrev = hfinfo->abbrev;
			}

			if (occurrence == 0) {
				/* Fetch next hfinfo with same name (abbrev) */
				hfinfo = hfinfo_same_name_get_prev(hfinfo);
			} else {
				hfinfo = NULL;
			}
		}
	}

	return abbrev ? abbrev : "";
}

Project: wireshark

fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
{
	char       *p;
	int         bitfield_byte_length, bitwidth;
	guint64     unshifted_value;
	guint64     value;

	char        buf[48];
	const char *out;

	header_field_info *hfinfo = fi->hfinfo;

	/* Figure out the bit width */
	bitwidth = hfinfo_container_bitwidth(hfinfo);

	/* Un-shift bits */
	if (is_signed)
		value = fvalue_get_sinteger64(&fi->value);
	else
		value = fvalue_get_uinteger64(&fi->value);

	unshifted_value = value;
	if (hfinfo->bitmask) {
		unshifted_value <<= hfinfo_bitshift(hfinfo);
	}

	/* Create the bitfield first */
	p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
	bitfield_byte_length = (int) (p - label_str);

	/* Fill in the textual info using stored (shifted) value */
	if (hfinfo->display == BASE_CUSTOM) {
		gchar tmp[ITEM_LABEL_LENGTH];
		const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;

		DISSECTOR_ASSERT(fmtfunc64);
		fmtfunc64(tmp, value);
		label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
	}
	else if (hfinfo->strings) {
		const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");

		out = hfinfo_number_vals_format64(hfinfo, buf, value);
		if (out == NULL) /* BASE_NONE so don't put integer in descr */
			label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
		else
			label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
	}
	else {
		out = hfinfo_number_value_format64(hfinfo, buf, value);

		label_fill(label_str, bitfield_byte_length, hfinfo, out);
	}
}

Project: wireshark

proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				  gint start, gint length, float value,
				  const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
			  gboolean *is_tcp, gboolean *is_udp,
			  gboolean *is_sctp, gboolean *is_tls,
			  gboolean *is_rtp,
			  gboolean *is_lte_rlc)
{
	wmem_list_frame_t *protos = wmem_list_head(layers);
	int	    proto_id;
	const char *proto_name;

	/* Walk the list of a available protocols in the packet and
	   attempt to find "major" ones. */
	/* It might make more sense to assemble and return a bitfield. */
	while (protos != NULL)
	{
		proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
		proto_name = proto_get_protocol_filter_name(proto_id);

		if (is_ip && ((!strcmp(proto_name, "ip")) ||
			      (!strcmp(proto_name, "ipv6")))) {
			*is_ip = TRUE;
		} else if (is_tcp && !strcmp(proto_name, "tcp")) {
			*is_tcp = TRUE;
		} else if (is_udp && !strcmp(proto_name, "udp")) {
			*is_udp = TRUE;
		} else if (is_sctp && !strcmp(proto_name, "sctp")) {
			*is_sctp = TRUE;
		} else if (is_tls && !strcmp(proto_name, "tls")) {
			*is_tls = TRUE;
		} else if (is_rtp && !strcmp(proto_name, "rtp")) {
			*is_rtp = TRUE;
		} else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
			*is_lte_rlc = TRUE;
		}

		protos = wmem_list_frame_next(protos);
	}
}

Project: wireshark

proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		         gint length, guint64 value)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_boolean(PNODE_FINFO(pi), value);

	return pi;
}

Project: wireshark

construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
				char **filter)
{
	header_field_info *hfinfo;
	int		   abbrev_len;
	char		  *ptr;
	int		   buf_len;
	int		   dfilter_len, i;
	gint		   start, length, length_remaining;
	guint8		   c;
	gchar		   is_signed_num = FALSE;

	if (!finfo)
		return FALSE;

	hfinfo     = finfo->hfinfo;
	DISSECTOR_ASSERT(hfinfo);
	abbrev_len = (int) strlen(hfinfo->abbrev);

	if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
		const gchar *str = NULL;

		switch (hfinfo->type) {

		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
			str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
			break;

		case FT_CHAR:
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
			str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
			break;

		default:
			break;
		}

		if (str != NULL && filter != NULL) {
			*filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
			return TRUE;
		}
	}

	/*
	 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
	 * functions for FT_UINT and FT_INT types, as we choose the base in
	 * the string expression based on the display base of the field.
	 *
	 * Note that the base does matter, as this is also used for
	 * the protocolinfo tap.
	 *
	 * It might be nice to use them in "proto_item_fill_label()"
	 * as well, although, there, you'd have to deal with the base
	 * *and* with resolved values for addresses.
	 *
	 * Perhaps we need two different val_to_string routines, one
	 * to generate items for display filters and one to generate
	 * strings for display, and pass to both of them the
	 * "display" and "strings" values in the header_field_info
	 * structure for the field, so they can get the base and,
	 * if the field is Boolean or an enumerated integer type,
	 * the tables used to generate human-readable values.
	 */
	switch (hfinfo->type) {

		case FT_CHAR:
			if (filter != NULL) {
				guint32 number;

				char buf [48];
				const char *out;

				number = fvalue_get_uinteger(&finfo->value);

				out = hfinfo_char_value_format(hfinfo, buf, number);

				*filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
			}
			break;

		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
			is_signed_num = TRUE;
			/* FALLTHRU */
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
		case FT_FRAMENUM:
			if (filter != NULL) {
				guint32 number;

				char buf[32];
				const char *out;

				if (is_signed_num)
					number = fvalue_get_sinteger(&finfo->value);
				else
					number = fvalue_get_uinteger(&finfo->value);

				out = hfinfo_numeric_value_format(hfinfo, buf, number);

				*filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
			}
			break;

		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
			is_signed_num = TRUE;
			/* FALLTHRU */
		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:
			if (filter != NULL) {
				guint64 number;

				char buf [48];
				const char *out;

				if (is_signed_num)
					number = fvalue_get_sinteger64(&finfo->value);
				else
					number = fvalue_get_uinteger64(&finfo->value);

				out = hfinfo_numeric_value_format64(hfinfo, buf, number);

				*filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
			}
			break;

		case FT_PROTOCOL:
			if (filter != NULL)
				*filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
			break;

		case FT_NONE:
			/*
			 * If the length is 0, just match the name of the
			 * field.
			 *
			 * (Also check for negative values, just in case,
			 * as we'll cast it to an unsigned value later.)
			 */
			length = finfo->length;
			if (length == 0) {
				if (filter != NULL)
					*filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
				break;
			}
			if (length < 0)
				return FALSE;

			/*
			 * This doesn't have a value, so we'd match
			 * on the raw bytes at this address.
			 *
			 * Should we be allowed to access to the raw bytes?
			 * If "edt" is NULL, the answer is "no".
			 */
			if (edt == NULL)
				return FALSE;

			/*
			 * Is this field part of the raw frame tvbuff?
			 * If not, we can't use "frame[N:M]" to match
			 * it.
			 *
			 * XXX - should this be frame-relative, or
			 * protocol-relative?
			 *
			 * XXX - does this fallback for non-registered
			 * fields even make sense?
			 */
			if (finfo->ds_tvb != edt->tvb)
				return FALSE;	/* you lose */

			/*
			 * Don't go past the end of that tvbuff.
			 */
			length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
			if (length > length_remaining)
				length = length_remaining;
			if (length <= 0)
				return FALSE;

			if (filter != NULL) {
				start = finfo->start;
				buf_len = 32 + length * 3;
				*filter = (char *)wmem_alloc0(NULL, buf_len);
				ptr = *filter;

				ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
					"frame[%d:%d] == ", finfo->start, length);
				for (i=0; i<length; i++) {
					c = tvb_get_guint8(finfo->ds_tvb, start);
					start++;
					if (i == 0 ) {
						ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
					}
					else {
						ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
					}
				}
			}
			break;

		case FT_PCRE:
			/* FT_PCRE never appears as a type for a registered field. It is
			 * only used internally. */
			DISSECTOR_ASSERT_NOT_REACHED();
			break;

		/* By default, use the fvalue's "to_string_repr" method. */
		default:
			/* Figure out the string length needed.
			 *	The ft_repr length.
			 *	4 bytes for " == ".
			 *	1 byte for trailing NUL.
			 */
			if (filter != NULL) {
				char* str;
				dfilter_len = fvalue_string_repr_len(&finfo->value,
						FTREPR_DFILTER, finfo->hfinfo->display);
				dfilter_len += abbrev_len + 4 + 1;
				*filter = (char *)wmem_alloc0(NULL, dfilter_len);

				/* Create the string */
				str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
				g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
				wmem_free(NULL, str);
			}
			break;
	}

	return TRUE;
}

Project: wireshark

proto_get_id_by_short_name(const gchar *short_name)
{
	const protocol_t *protocol = NULL;

	DISSECTOR_ASSERT_HINT(short_name, "No short name present");

	protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);

	if (protocol == NULL)
		return -1;
	return protocol->proto_id;
}

Project: wireshark

decode_bitfield_varint_value(char *buf, const guint64 val, const guint64 mask, const int width)
{
	char *p;

	p = other_decode_bitfield_varint_value(buf, val, mask, width);
	p = g_stpcpy(p, " = ");

	return p;
}

Project: wireshark

proto_registrar_dump_protocols(void)
{
	protocol_t *protocol;
	int	    i;
	void	   *cookie = NULL;


	i = proto_get_first_protocol(&cookie);
	while (i != -1) {
		protocol = find_protocol_by_id(i);
		ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
			protocol->filter_name);
		i = proto_get_next_protocol(&cookie);
	}
}

Project: wireshark

proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			    gint start, gint length, const guint64 value,
			    const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		TRY_TO_FAKE_THIS_REPR(pi);

		va_start(ap, format);
		proto_tree_set_representation(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_item_get_parent(const proto_item *ti) {
	if (!ti)
		return NULL;
	return ti->parent;
}

Project: wireshark

other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const int width)
{
	int i = 0;
	guint64 bit;
	char *p;

	p = buf;
	bit = G_GUINT64_CONSTANT(1) << (width - 1);
	for (;;) {
		if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
			(mask & bit)) {
			/* This bit is part of the field.  Show its value. */
			if (val & bit)
				*p++ = '1';
			else
				*p++ = '0';
		} else {
			/* This bit is not part of the field. */
			*p++ = '.';
		}
		bit >>= 1;
		i++;
		if (i >= width)
			break;
		if (i % 4 == 0)
			*p++ = ' ';
	}

	*p = '\0';
	return p;
}

Project: wireshark

proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
					 tvbuff_t *tvb, const guint bit_offset,
					 const gint no_of_bits, guint64 value,
					 const char *format, ...)
{
	va_list ap;
	gchar  *dst;
	header_field_info *hf_field;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);

	DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);

	CREATE_VALUE_STRING(dst, format, ap);

	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
}

Project: wireshark

hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
{
	/* Get the underlying BASE_ value */
	int display = FIELD_DISPLAY(hfinfo->display);

	if (hfinfo->type == FT_FRAMENUM) {
		/*
		 * Frame numbers are always displayed in decimal.
		 */
		display = BASE_DEC;
	}

	switch (display) {
		case BASE_NONE:
		/* case BASE_DEC: */
		case BASE_DEC_HEX:
		case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
		case BASE_CUSTOM:
			display = BASE_DEC;
			break;

		/* case BASE_HEX: */
		case BASE_HEX_DEC:
			display = BASE_HEX;
			break;
	}

	return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
}

Project: wireshark

proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
			 const guint bit_offset, const gint no_of_bits,
			 const guint encoding)
{
	header_field_info *hfinfo;
	gint		   octet_length;
	gint		   octet_offset;

	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);

	octet_length = (no_of_bits + 7) >> 3;
	octet_offset = bit_offset >> 3;
	test_length(hfinfo, tvb, octet_offset, octet_length, encoding);

	/* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
	 * but only after doing a bunch more work (which we can, in the common
	 * case, shortcut here).
	 */
	CHECK_FOR_NULL_TREE(tree);
	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
}

Project: wireshark

proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
		       const guint offset,  const guint len, const int hf_hdr,
		       const gint ett, int * const *fields, struct expert_field* exp,
		       const guint encoding)
{
	proto_item        *item = NULL;
	header_field_info *hf;
	guint   decodable_len;
	guint   decodable_offset;
	guint32 decodable_value;
	guint64 value;

	PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
	DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);

	decodable_offset = offset;
	decodable_len = MIN(len, (guint) ftype_length(hf->type));

	/* If we are ftype_length-limited,
	 * make sure we decode as many LSBs as possible.
	 */
	if (encoding == ENC_BIG_ENDIAN) {
		decodable_offset += (len - decodable_len);
	}

	if (parent_tree) {
		decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
						 decodable_len, encoding);

		/* The root item covers all the bytes even if we can't decode them all */
		item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
					   decodable_value);
	}

	if (decodable_len < len) {
		/* Dissector likely requires updating for new protocol revision */
		expert_add_info_format(NULL, item, exp,
				       "Only least-significant %d of %d bytes decoded",
				       decodable_len, len);
	}

	if (item) {
		value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
		proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
		    ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
	}

	return item;
}

Project: wireshark

ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
{
	subtree_lvl *subtree;

	DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);

	subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
	subtree->it            = it;
	subtree->cursor_offset = ptvcursor_current_offset(ptvc);
}

Project: wireshark

proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		     gint length, float value)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_float(PNODE_FINFO(pi), value);

	return pi;
}

Project: wireshark

detect_trailing_stray_characters(guint encoding, const char *string, gint length, proto_item *pi)
{
	gboolean found_stray_character = FALSE;

	if (!string)
		return;

	switch (encoding & ENC_CHARENCODING_MASK) {
		case ENC_ASCII:
		case ENC_UTF_8:
			for (gint i = (gint)strlen(string); i < length; i++) {
				if (string[i] != '\0') {
					found_stray_character = TRUE;
					break;
				}
			}
			break;

		default:
			break;
	}

	if (found_stray_character) {
		expert_add_info(NULL, pi, &ei_string_trailing_characters);
	}
}

Project: wireshark

ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
{
	ptvc->pushed_tree       = NULL;
	ptvc->pushed_tree_max   = 0;
	DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
	ptvc->pushed_tree_index = 0;
}

Project: wireshark

proto_registrar_dump_fields(void)
{
	header_field_info *hfinfo, *parent_hfinfo;
	int		   i, len;
	const char	  *enum_name;
	const char	  *base_name;
	const char	  *blurb;
	char		   width[5];

	len = gpa_hfinfo.len;
	for (i = 0; i < len ; i++) {
		if (gpa_hfinfo.hfi[i] == NULL)
			continue; /* This is a deregistered protocol or header field */

		PROTO_REGISTRAR_GET_NTH(i, hfinfo);

		/*
		 * Skip the pseudo-field for "proto_tree_add_text()" since
		 * we don't want it in the list of filterable fields.
		 */
		if (hfinfo->id == hf_text_only)
			continue;

		/* format for protocols */
		if (proto_registrar_is_protocol(i)) {
			ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
		}
		/* format for header fields */
		else {
			/*
			 * If this field isn't at the head of the list of
			 * fields with this name, skip this field - all
			 * fields with the same name are really just versions
			 * of the same field stored in different bits, and
			 * should have the same type/radix/value list, and
			 * just differ in their bit masks.	(If a field isn't
			 * a bitfield, but can be, say, 1 or 2 bytes long,
			 * it can just be made FT_UINT16, meaning the
			 * *maximum* length is 2 bytes, and be used
			 * for all lengths.)
			 */
			if (hfinfo->same_name_prev_id != -1)
				continue;

			PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);

			enum_name = ftype_name(hfinfo->type);
			base_name = "";

			if (hfinfo->type == FT_CHAR  ||
			    hfinfo->type == FT_UINT8  ||
			    hfinfo->type == FT_UINT16 ||
			    hfinfo->type == FT_UINT24 ||
			    hfinfo->type == FT_UINT32 ||
			    hfinfo->type == FT_UINT40 ||
			    hfinfo->type == FT_UINT48 ||
			    hfinfo->type == FT_UINT56 ||
			    hfinfo->type == FT_UINT64 ||
			    hfinfo->type == FT_INT8   ||
			    hfinfo->type == FT_INT16  ||
			    hfinfo->type == FT_INT24  ||
			    hfinfo->type == FT_INT32  ||
			    hfinfo->type == FT_INT40 ||
			    hfinfo->type == FT_INT48 ||
			    hfinfo->type == FT_INT56 ||
			    hfinfo->type == FT_INT64) {

				switch (FIELD_DISPLAY(hfinfo->display)) {
					case BASE_NONE:
					case BASE_DEC:
					case BASE_HEX:
					case BASE_OCT:
					case BASE_DEC_HEX:
					case BASE_HEX_DEC:
					case BASE_CUSTOM:
					case BASE_PT_UDP:
					case BASE_PT_TCP:
					case BASE_PT_DCCP:
					case BASE_PT_SCTP:
					case BASE_OUI:
						base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
						break;
					default:
						base_name = "????";
						break;
				}
			} else if (hfinfo->type == FT_BOOLEAN) {
				/* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
				g_snprintf(width, sizeof(width), "%d", hfinfo->display);
				base_name = width;
			}

			blurb = hfinfo->blurb;
			if (blurb == NULL)
				blurb = "";
			else if (strlen(blurb) == 0)
				blurb = "\"\"";

			ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
				hfinfo->name, hfinfo->abbrev, enum_name,
				parent_hfinfo->abbrev, base_name,
				hfinfo->bitmask, blurb);
		}
	}
}

Project: wireshark

proto_reenable_all(void)
{
	protocol_t *protocol;
	GList      *list_item = protocols;

	if (protocols == NULL)
		return;

	while (list_item) {
		protocol = (protocol_t *)list_item->data;
		if (protocol->can_toggle && protocol->enabled_by_default)
			protocol->is_enabled = TRUE;
		list_item = g_list_next(list_item);
	}
}

Project: wireshark

initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
	((prefix_initializer_t)v)((const char *)k);
	return TRUE;
}

Project: wireshark

get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
    gint length, gint *ret_length, const guint encoding)
{
	if (length == -1) {
		length = tvb_ensure_captured_length_remaining(tvb, start);
	}
	*ret_length = length;
	return tvb_get_string_enc(scope, tvb, start, length, encoding);
}

Project: wireshark

proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
{
	proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
}

Project: wireshark

proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		     gint length, gint64 value)
{
	proto_item	  *pi = NULL;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	switch (hfinfo->type) {
		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
			pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
			proto_tree_set_int64(PNODE_FINFO(pi), value);
			break;

		default:
			REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
			    hfinfo->abbrev);
	}

	return pi;
}

Project: wireshark

proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
             gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
{
	proto_item    *pi;
	header_field_info *hfinfo;
	gint          item_length;

	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
	get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
	test_length(hfinfo, tvb, start, item_length, ENC_NA);

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
	proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);

	return pi;
}

Project: wireshark

proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				  gint start, gint length, gint64 value,
				  const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_registrar_get_byalias(const char *alias_name)
{
	if (!alias_name) {
		return NULL;
	}

	/* Find our aliased protocol. */
	char *an_copy = g_strdup(alias_name);
	char *dot = strchr(an_copy, '.');
	if (dot) {
		*dot = '\0';
	}
	const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
	if (!proto_pfx) {
		g_free(an_copy);
		return NULL;
	}

	/* Construct our aliased field and look it up. */
	GString *filter_name = g_string_new(proto_pfx);
	if (dot) {
		g_string_append_printf(filter_name, ".%s", dot+1);
	}
	header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
	g_free(an_copy);
	g_string_free(filter_name, TRUE);

	return hfinfo;
}

Project: wireshark

proto_tree_set_ipxnet(field_info *fi, guint32 value)
{
	fvalue_set_uinteger(&fi->value, value);
}

Project: wireshark

hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo,
    const guint8 *bytes, guint length)
{
	char *str = NULL;
	const guint8 *p;
	gboolean is_printable;

	if (bytes) {
		if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
			/*
			 * Check whether all bytes are printable.
			 */
			is_printable = TRUE;
			for (p = bytes; p < bytes+length; p++) {
				if (!g_ascii_isprint(*p)) {
					/* Not printable. */
					is_printable = FALSE;
					break;
				}
			}

			/*
			 * If all bytes are printable ASCII, show the bytes
			 * as a string - in quotes to indicate that it's
			 * a string.
			 */
			if (is_printable) {
				str = wmem_strdup_printf(scope, "\"%.*s\"",
				    (int)length, bytes);
				return str;
			}
		}

		/*
		 * Either it's not printable ASCII, or we don't care whether
		 * it's printable ASCII; show it as hex bytes.
		 */
		switch (FIELD_DISPLAY(hfinfo->display)) {
		case SEP_DOT:
			str = bytestring_to_str(scope, bytes, length, '.');
			break;
		case SEP_DASH:
			str = bytestring_to_str(scope, bytes, length, '-');
			break;
		case SEP_COLON:
			str = bytestring_to_str(scope, bytes, length, ':');
			break;
		case SEP_SPACE:
			str = bytestring_to_str(scope, bytes, length, ' ');
			break;
		case BASE_NONE:
		default:
			if (prefs.display_byte_fields_with_spaces) {
				str = bytestring_to_str(scope, bytes, length, ' ');
			} else {
				str = bytes_to_str(scope, bytes, length);
			}
			break;
		}
	}
	else {
		if (hfinfo->display & BASE_ALLOW_ZERO) {
			str = wmem_strdup(scope, "<none>");
		} else {
			str = wmem_strdup(scope, "<MISSING>");
		}
	}
	return str;
}

Project: wireshark

proto_registrar_get_name(const int n)
{
	header_field_info *hfinfo;

	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
	return hfinfo->name;
}

Project: wireshark

proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		       gint length, guint32 value)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_boolean(PNODE_FINFO(pi), value);

	return pi;
}

Project: wireshark

proto_tree_new_item(field_info *new_fi, proto_tree *tree,
		    tvbuff_t *tvb, gint start, gint length,
		    guint encoding)
{
	proto_item *pi;
	guint32	    value, n;
	guint64	    value64;
	ws_in4_addr ipv4_value;
	float	    floatval;
	double	    doubleval;
	const char *stringval = NULL;
	nstime_t    time_stamp;
	gboolean    length_error;

	switch (new_fi->hfinfo->type) {
		case FT_NONE:
			/* no value to set for FT_NONE */
			break;

		case FT_PROTOCOL:
			proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
			break;

		case FT_BYTES:
			proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
			break;

		case FT_UINT_BYTES:
			n = get_uint_value(tree, tvb, start, length, encoding);
			proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);

			/* Instead of calling proto_item_set_len(), since we don't yet
			 * have a proto_item, we set the field_info's length ourselves. */
			new_fi->length = n + length;
			break;

		case FT_BOOLEAN:
			/*
			 * Map all non-zero values to little-endian for
			 * backwards compatibility.
			 */
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			proto_tree_set_boolean(new_fi,
				get_uint64_value(tree, tvb, start, length, encoding));
			break;

		case FT_CHAR:
		/* XXX - make these just FT_UINT? */
		case FT_UINT8:
		case FT_UINT16:
		case FT_UINT24:
		case FT_UINT32:
			if (encoding & ENC_VARINT_PROTOBUF) {
				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
				new_fi->flags |= FI_VARINT;
				value = (guint32)value64;
			} else if (encoding & ENC_VARINT_QUIC) {
				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
				value = (guint32)value64;
			} else if (encoding & ENC_VARINT_ZIGZAG) {
				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
				new_fi->flags |= FI_VARINT;
				value = (guint32)value64;
			}
			else {
				/*
				 * Map all non-zero values to little-endian for
				 * backwards compatibility.
				 */
				if (encoding)
					encoding = ENC_LITTLE_ENDIAN;

				value = get_uint_value(tree, tvb, start, length, encoding);
			}
			proto_tree_set_uint(new_fi, value);
			break;

		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64:

			if (encoding & ENC_VARINT_PROTOBUF) {
				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
				new_fi->flags |= FI_VARINT;
			} else if (encoding & ENC_VARINT_QUIC) {
				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
			} else if (encoding & ENC_VARINT_ZIGZAG) {
				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
				new_fi->flags |= FI_VARINT;
			}
			else {
				/*
				 * Map all other non-zero values to little-endian for
				 * backwards compatibility.
				 */
				if (encoding)
					encoding = ENC_LITTLE_ENDIAN;

				value64 = get_uint64_value(tree, tvb, start, length, encoding);
			}
			proto_tree_set_uint64(new_fi, value64);
			break;

		/* XXX - make these just FT_INT? */
		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
			/*
			 * Map all non-zero values to little-endian for
			 * backwards compatibility.
			 */
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			proto_tree_set_int(new_fi,
				get_int_value(tree, tvb, start, length, encoding));
			break;

		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
			/*
			 * Map all non-zero values to little-endian for
			 * backwards compatibility.
			 */
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			proto_tree_set_int64(new_fi,
				get_int64_value(tree, tvb, start, length, encoding));
			break;

		case FT_IPv4:
			/*
			 * Map all non-zero values to little-endian for
			 * backwards compatibility.
			 */
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			if (length != FT_IPv4_LEN) {
				length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
			}
			ipv4_value = tvb_get_ipv4(tvb, start);
			/*
			 * NOTE: to support code written when
			 * proto_tree_add_item() took a gboolean as its
			 * last argument, with FALSE meaning "big-endian"
			 * and TRUE meaning "little-endian", we treat any
			 * non-zero value of "encoding" as meaning
			 * "little-endian".
			 */
			proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value) : ipv4_value);
			break;

		case FT_IPXNET:
			if (length != FT_IPXNET_LEN) {
				length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
			}
			proto_tree_set_ipxnet(new_fi,
				get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
			break;

		case FT_IPv6:
			if (length != FT_IPv6_LEN) {
				length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
			}
			proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
			break;

		case FT_FCWWN:
			if (length != FT_FCWWN_LEN) {
				length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
			}
			proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
			break;

		case FT_AX25:
			if (length != 7) {
				length_error = length < 7 ? TRUE : FALSE;
				report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
			}
			proto_tree_set_ax25_tvb(new_fi, tvb, start);
			break;

		case FT_VINES:
			if (length != VINES_ADDR_LEN) {
				length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "a Vines address", length, length_error);
			}
			proto_tree_set_vines_tvb(new_fi, tvb, start);
			break;

		case FT_ETHER:
			if (length != FT_ETHER_LEN) {
				length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "a MAC address", length, length_error);
			}
			proto_tree_set_ether_tvb(new_fi, tvb, start);
			break;

		case FT_EUI64:
			/*
			 * Map all non-zero values to little-endian for
			 * backwards compatibility.
			 */
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			if (length != FT_EUI64_LEN) {
				length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
			}
			proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
			break;
		case FT_GUID:
			/*
			 * Map all non-zero values to little-endian for
			 * backwards compatibility.
			 */
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			if (length != FT_GUID_LEN) {
				length_error = length < FT_GUID_LEN ? TRUE : FALSE;
				report_type_length_mismatch(tree, "a GUID", length, length_error);
			}
			proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
			break;

		case FT_OID:
		case FT_REL_OID:
			proto_tree_set_oid_tvb(new_fi, tvb, start, length);
			break;

		case FT_SYSTEM_ID:
			proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
			break;

		case FT_FLOAT:
			/*
			 * NOTE: to support code written when
			 * proto_tree_add_item() took a gboolean as its
			 * last argument, with FALSE meaning "big-endian"
			 * and TRUE meaning "little-endian", we treat any
			 * non-zero value of "encoding" as meaning
			 * "little-endian".
			 *
			 * At some point in the future, we might
			 * support non-IEEE-binary floating-point
			 * formats in the encoding as well
			 * (IEEE decimal, System/3x0, VAX).
			 */
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			if (length != 4) {
				length_error = length < 4 ? TRUE : FALSE;
				report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
			}
			if (encoding)
				floatval = tvb_get_letohieee_float(tvb, start);
			else
				floatval = tvb_get_ntohieee_float(tvb, start);
			proto_tree_set_float(new_fi, floatval);
			break;

		case FT_DOUBLE:
			/*
			 * NOTE: to support code written when
			 * proto_tree_add_item() took a gboolean as its
			 * last argument, with FALSE meaning "big-endian"
			 * and TRUE meaning "little-endian", we treat any
			 * non-zero value of "encoding" as meaning
			 * "little-endian".
			 *
			 * At some point in the future, we might
			 * support non-IEEE-binary floating-point
			 * formats in the encoding as well
			 * (IEEE decimal, System/3x0, VAX).
			 */
			if (encoding == TRUE)
				encoding = ENC_LITTLE_ENDIAN;
			if (length != 8) {
				length_error = length < 8 ? TRUE : FALSE;
				report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
			}
			if (encoding)
				doubleval = tvb_get_letohieee_double(tvb, start);
			else
				doubleval = tvb_get_ntohieee_double(tvb, start);
			proto_tree_set_double(new_fi, doubleval);
			break;

		case FT_STRING:
			stringval = get_string_value(wmem_packet_scope(),
			    tvb, start, length, &length, encoding);
			proto_tree_set_string(new_fi, stringval);

			/* Instead of calling proto_item_set_len(), since we
			 * don't yet have a proto_item, we set the
			 * field_info's length ourselves.
			 *
			 * XXX - our caller can't use that length to
			 * advance an offset unless they arrange that
			 * there always be a protocol tree into which
			 * we're putting this item.
			 */
			new_fi->length = length;
			break;

		case FT_STRINGZ:
			stringval = get_stringz_value(wmem_packet_scope(),
			    tree, tvb, start, length, &length, encoding);
			proto_tree_set_string(new_fi, stringval);

			/* Instead of calling proto_item_set_len(),
			 * since we don't yet have a proto_item, we
			 * set the field_info's length ourselves.
			 *
			 * XXX - our caller can't use that length to
			 * advance an offset unless they arrange that
			 * there always be a protocol tree into which
			 * we're putting this item.
			 */
			new_fi->length = length;
			break;

		case FT_UINT_STRING:
			/*
			 * NOTE: to support code written when
			 * proto_tree_add_item() took a gboolean as its
			 * last argument, with FALSE meaning "big-endian"
			 * and TRUE meaning "little-endian", if the
			 * encoding value is TRUE, treat that as
			 * ASCII with a little-endian length.
			 *
			 * This won't work for code that passes
			 * arbitrary non-zero values; that code
			 * will need to be fixed.
			 */
			if (encoding == TRUE)
				encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
			stringval = get_uint_string_value(wmem_packet_scope(),
			    tree, tvb, start, length, &length, encoding);
			proto_tree_set_string(new_fi, stringval);

			/* Instead of calling proto_item_set_len(), since we
			 * don't yet have a proto_item, we set the
			 * field_info's length ourselves.
			 *
			 * XXX - our caller can't use that length to
			 * advance an offset unless they arrange that
			 * there always be a protocol tree into which
			 * we're putting this item.
			 */
			new_fi->length = length;
			break;

		case FT_STRINGZPAD:
			stringval = get_stringzpad_value(wmem_packet_scope(),
			    tvb, start, length, &length, encoding);
			proto_tree_set_string(new_fi, stringval);

			/* Instead of calling proto_item_set_len(), since we
			 * don't yet have a proto_item, we set the
			 * field_info's length ourselves.
			 *
			 * XXX - our caller can't use that length to
			 * advance an offset unless they arrange that
			 * there always be a protocol tree into which
			 * we're putting this item.
			 */
			new_fi->length = length;
			break;

		case FT_STRINGZTRUNC:
			stringval = get_stringztrunc_value(wmem_packet_scope(),
			    tvb, start, length, &length, encoding);
			proto_tree_set_string(new_fi, stringval);

			/* Instead of calling proto_item_set_len(), since we
			 * don't yet have a proto_item, we set the
			 * field_info's length ourselves.
			 *
			 * XXX - our caller can't use that length to
			 * advance an offset unless they arrange that
			 * there always be a protocol tree into which
			 * we're putting this item.
			 */
			new_fi->length = length;
			break;

		case FT_ABSOLUTE_TIME:
			/*
			 * Absolute times can be in any of a number of
			 * formats, and they can be big-endian or
			 * little-endian.
			 *
			 * Historically FT_TIMEs were only timespecs;
			 * the only question was whether they were stored
			 * in big- or little-endian format.
			 *
			 * For backwards compatibility, we interpret an
			 * encoding of 1 as meaning "little-endian timespec",
			 * so that passing TRUE is interpreted as that.
			 */
			if (encoding == TRUE)
				encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;

			get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);

			proto_tree_set_time(new_fi, &time_stamp);
			break;

		case FT_RELATIVE_TIME:
			/*
			 * Relative times can be in any of a number of
			 * formats, and they can be big-endian or
			 * little-endian.
			 *
			 * Historically FT_TIMEs were only timespecs;
			 * the only question was whether they were stored
			 * in big- or little-endian format.
			 *
			 * For backwards compatibility, we interpret an
			 * encoding of 1 as meaning "little-endian timespec",
			 * so that passing TRUE is interpreted as that.
			 */
			if (encoding == TRUE)
				encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;

			get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);

			proto_tree_set_time(new_fi, &time_stamp);
			break;
		case FT_IEEE_11073_SFLOAT:
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			if (length != 2) {
				length_error = length < 2 ? TRUE : FALSE;
				report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
			}

			fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));

			break;
		case FT_IEEE_11073_FLOAT:
			if (encoding)
				encoding = ENC_LITTLE_ENDIAN;
			if (length != 4) {
				length_error = length < 4 ? TRUE : FALSE;
				report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
			}

			break;
		default:
			REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",
					     new_fi->hfinfo->abbrev,
					     new_fi->hfinfo->type,
					     ftype_name(new_fi->hfinfo->type));
			break;
	}
	FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);

	/* Don't add new node to proto_tree until now so that any exceptions
	 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
	/* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
	 *      to know which item caused exception? */
	pi = proto_tree_add_node(tree, new_fi);

	switch (new_fi->hfinfo->type) {

	case FT_STRING:
		detect_trailing_stray_characters(encoding, stringval, length, pi);
		break;

	default:
		break;
	}

	return pi;
}

Project: wireshark

proto_deregister_field (const int parent, gint hf_id)
{
	header_field_info *hfi;
	protocol_t       *proto;
	guint             i;

	g_free(last_field_name);
	last_field_name = NULL;

	if (hf_id == -1 || hf_id == 0)
		return;

	proto = find_protocol_by_id (parent);
	if (!proto || proto->fields == NULL) {
		return;
	}

	for (i = 0; i < proto->fields->len; i++) {
		hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
		if (hfi->id == hf_id) {
			/* Found the hf_id in this protocol */
			g_hash_table_steal(gpa_name_map, hfi->abbrev);
			g_ptr_array_remove_index_fast(proto->fields, i);
			g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
			return;
		}
	}
}

Project: wireshark

proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
{
	hf_register_info *ptr = hf;
	protocol_t	 *proto;
	int		  i;

	proto = find_protocol_by_id(parent);

	if (proto->fields == NULL) {
		proto->fields = g_ptr_array_sized_new(num_records);
	}

	for (i = 0; i < num_records; i++, ptr++) {
		/*
		 * Make sure we haven't registered this yet.
		 * Most fields have variables associated with them
		 * that are initialized to -1; some have array elements,
		 * or possibly uninitialized variables, so we also allow
		 * 0 (which is unlikely to be the field ID we get back
		 * from "proto_register_field_init()").
		 */
		if (*ptr->p_id != -1 && *ptr->p_id != 0) {
			fprintf(stderr,
				"Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
				ptr->hfinfo.abbrev);
			return;
		}

		*ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
	}
}

Project: wireshark

proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
{
	fvalue_set_uinteger(&fi->value, value);
}

Project: wireshark

hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
{
	/* Get the underlying BASE_ value */
	int display = FIELD_DISPLAY(hfinfo->display);

	return hfinfo_char_value_format_display(display, buf, value);
}

Project: wireshark

proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
{
	int		  i;
	protocol_t	 *proto;

	proto = find_protocol_by_id(parent);

	if (proto->fields == NULL) {
		proto->fields = g_ptr_array_sized_new(num_records);
	}

	for (i = 0; i < num_records; i++) {
		/*
		 * Make sure we haven't registered this yet.
		 */
		if (hfi[i].id != -1) {
			fprintf(stderr,
				"Duplicate field detected in call to proto_register_fields: %s is already registered\n",
				hfi[i].abbrev);
			return;
		}

		proto_register_field_common(proto, &hfi[i], parent);
	}
}

Project: wireshark

proto_tree_free(proto_tree *tree)
{
	tree_data_t *tree_data = PTREE_DATA(tree);

	proto_tree_children_foreach(tree, proto_tree_free_node, NULL);

	/* free tree data */
	if (tree_data->interesting_hfids) {
		/* Free all the GPtrArray's in the interesting_hfids hash. */
		g_hash_table_foreach(tree_data->interesting_hfids,
			free_GPtrArray_value, NULL);

		/* And then destroy the hash. */
		g_hash_table_destroy(tree_data->interesting_hfids);
	}

	g_slice_free(tree_data_t, tree_data);

	g_slice_free(proto_tree, tree);
}

Project: wireshark

proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
		const int hf_hdr, const gint ett, int * const *fields, const guint64 value, const int flags)
{
	proto_item        *item = NULL;
	header_field_info *hf;
	int                len;

	PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
	DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
	/* the proto_tree_add_uint/_uint64() calls below
	   will fail if tvb==NULL and len!=0 */
	len = tvb ? ftype_length(hf->type) : 0;

	if (parent_tree) {
		if (len <= 4)
			item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
		else
			item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);

		proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
		    flags, FALSE, FALSE, NULL, value);
	}

	return item;
}

Project: wireshark

free_deregistered_field (gpointer data, gpointer user_data _U_)
{
	header_field_info *hfi = (header_field_info *) data;
	gint hf_id = hfi->id;

	g_free((char *)hfi->name);
	g_free((char *)hfi->abbrev);
	g_free((char *)hfi->blurb);

	proto_free_field_strings(hfi->type, hfi->display, hfi->strings);

	if (hfi->parent == -1)
		g_slice_free(header_field_info, hfi);

	gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
}

Project: wireshark

proto_deregister_protocol(const char *short_name)
{
	protocol_t *protocol;
	header_field_info *hfinfo;
	int proto_id;
	guint i;

	proto_id = proto_get_id_by_short_name(short_name);
	protocol = find_protocol_by_id(proto_id);
	if (protocol == NULL)
		return FALSE;

	g_hash_table_remove(proto_names, protocol->name);
	g_hash_table_remove(proto_short_names, (gpointer)short_name);
	g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);

	if (protocol->fields) {
		for (i = 0; i < protocol->fields->len; i++) {
			hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
			hfinfo_remove_from_gpa_name_map(hfinfo);
			expert_deregister_expertinfo(hfinfo->abbrev);
			g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
		}
		g_ptr_array_free(protocol->fields, TRUE);
		protocol->fields = NULL;
	}

	g_list_free(protocol->heur_list);

	/* Remove this protocol from the list of known protocols */
	protocols = g_list_remove(protocols, protocol);

	g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
	g_hash_table_steal(gpa_name_map, protocol->filter_name);

	g_free(last_field_name);
	last_field_name = NULL;

	return TRUE;
}

Project: wireshark

proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			     gint start, gint length, guint64 value,
			     const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		TRY_TO_FAKE_THIS_REPR(pi);

		va_start(ap, format);
		proto_tree_set_representation(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
{
	if (hfinfo->display & BASE_RANGE_STRING)
		return try_rval_to_str(value, (const range_string *) hfinfo->strings);

	if (hfinfo->display & BASE_EXT_STRING) {
		if (hfinfo->display & BASE_VAL64_STRING)
			return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
		else
			return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
	}

	if (hfinfo->display & BASE_VAL64_STRING)
		return try_val64_to_str(value, (const val64_string *) hfinfo->strings);

	if (hfinfo->display & BASE_UNIT_STRING)
		return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);

	return try_val_to_str(value, (const value_string *) hfinfo->strings);
}

Project: wireshark

proto_tracking_interesting_fields(const proto_tree *tree)
{
	GHashTable *interesting_hfids;

	if (!tree)
		return FALSE;

	interesting_hfids = PTREE_DATA(tree)->interesting_hfids;

	return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
}

Project: wireshark

ws_type_to_elastic(guint type _U_)
{
	switch(type) {
		case FT_UINT16:
		case FT_INT16:
		case FT_INT32:
		case FT_UINT24:
		case FT_INT24:
			return "integer";
		case FT_INT8:
		case FT_UINT8:
			return "short";
		case FT_FRAMENUM:
		case FT_UINT32:
		case FT_UINT40:
		case FT_UINT48:
		case FT_UINT56:
		case FT_UINT64: // Actually it's not handled by 'long' elastic type.
		case FT_INT48:
		case FT_INT64:
			return "long";
		case FT_FLOAT:
		case FT_DOUBLE:
			return "float";
		case FT_IPv6:
		case FT_IPv4:
			return "ip";
		case FT_ABSOLUTE_TIME:
		case FT_RELATIVE_TIME:
			return "date";
		case FT_BYTES:
		case FT_UINT_BYTES:
			return "byte";
		case FT_BOOLEAN:
			return "boolean";
		default:
			return NULL;
	}
}

Project: wireshark

proto_find_finfo(proto_tree *tree, const int id)
{
	ffdata_t ffdata;

	ffdata.array = g_ptr_array_new();
	ffdata.id = id;

	proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);

	return ffdata.array;
}

Project: wireshark

hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
{
	int display = hfinfo->display;

	if (hfinfo->type == FT_FRAMENUM) {
		/*
		 * Frame numbers are always displayed in decimal.
		 */
		display = BASE_DEC;
	}

	return hfinfo_number_value_format_display(hfinfo, display, buf, value);
}

Project: wireshark

proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		     gint length, const guint8* value)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_ether(PNODE_FINFO(pi), value);

	return pi;
}

Project: wireshark

proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
				const crumb_spec_t *crumb_spec, guint16 crumb_index)
{
	header_field_info *hfinfo;

	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
	proto_tree_add_text_internal(tree, tvb,
			    bit_offset >> 3,
			    ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
			    "%s crumb %d of %s (decoded above)",
			    decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
						 tvb_get_bits(tvb,
							      bit_offset,
							      crumb_spec[crumb_index].crumb_bit_length,
							      ENC_BIG_ENDIAN)),
			    crumb_index,
			    hfinfo->name);
}

Project: wireshark

proto_get_protocol_name(const int proto_id)
{
	protocol_t *protocol;

	protocol = find_protocol_by_id(proto_id);

	if (protocol == NULL)
		return NULL;
	return protocol->name;
}

Project: wireshark

register_type_length_mismatch(void)
{
	static ei_register_info ei[] = {
		{ &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
		{ &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
	};

	expert_module_t* expert_type_length_mismatch;

	proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");

	expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
	expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));

	/* "Type Length Mismatch" isn't really a protocol, it's an error indication;
	   disabling them makes no sense. */
	proto_set_cant_toggle(proto_type_length_mismatch);
}

Project: wireshark

proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
{
	int		  i;
	protocol_t	 *proto;

	proto = find_protocol_by_id(parent);

	if (proto->fields == NULL) {
		proto->fields = g_ptr_array_sized_new(num_records);
	}


	for (i = 0; i < num_records; i++) {
		/*
		 * Make sure we haven't registered this yet.
		 */
		if (hfi[i]->id != -1) {
			fprintf(stderr,
				"Duplicate field detected in call to proto_register_fields: %s is already registered\n",
				hfi[i]->abbrev);
			return;
		}

		proto_register_field_common(proto, hfi[i], parent);
	}
}

Project: wireshark

proto_set_cant_toggle(const int proto_id)
{
	protocol_t *protocol;

	protocol = find_protocol_by_id(proto_id);
	protocol->can_toggle = FALSE;
}

Project: wireshark

hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
{
	/* Get the underlying BASE_ value */
	int display = FIELD_DISPLAY(hfinfo->display);

	if (hfinfo->type == FT_FRAMENUM) {
		/*
		 * Frame numbers are always displayed in decimal.
		 */
		display = BASE_DEC;
	}

	if (IS_BASE_PORT(display)) {
		display = BASE_DEC;
	} else if (display == BASE_OUI) {
		display = BASE_HEX;
	}

	switch (display) {
		case BASE_NONE:
		/* case BASE_DEC: */
		case BASE_DEC_HEX:
		case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
		case BASE_CUSTOM:
			display = BASE_DEC;
			break;

		/* case BASE_HEX: */
		case BASE_HEX_DEC:
			display = BASE_HEX;
			break;
	}

	return hfinfo_number_value_format_display(hfinfo, display, buf, value);
}

Project: wireshark

hfinfo_bitoffset(const header_field_info *hfinfo)
{
	if (!hfinfo->bitmask) {
		return 0;
	}

	/* ilog2 = first set bit, counting 0 as the last bit; we want 0
	 * as the first bit */
	return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
}

Project: wireshark

proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				gint start, gint length, gint32 value,
				const char *format, ...)
{
	proto_item  *pi;
	va_list	     ap;

	pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
{
	if (encoding)
	{
		proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
	} else {
		proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
	}
}

Project: wireshark

proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
	const guint bit_offset, const gint no_of_chars)
{
	proto_item	  *pi;
	header_field_info *hfinfo;
	gint		   byte_length;
	gint		   byte_offset;
	gchar		  *string;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);

	byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
	byte_offset = bit_offset >> 3;

	string = tvb_get_ts_23_038_7bits_string_packed(wmem_packet_scope(), tvb, bit_offset, no_of_chars);

	if (hfinfo->display == STR_UNICODE) {
		DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
	}

	pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
	DISSECTOR_ASSERT(byte_length >= 0);
	proto_tree_set_string(PNODE_FINFO(pi), string);

	return pi;
}

Project: wireshark

proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
			    gpointer data)
{
	proto_node *node = tree;
	proto_node *current;

	if (!node)
		return;

	node = node->first_child;
	while (node != NULL) {
		current = node;
		node    = current->next;
		func((proto_tree *)current, data);
	}
}

Project: wireshark

proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
{
	field_info *fi;
	gint length;

	TRY_TO_FAKE_THIS_REPR_VOID(pi);

	fi = PITEM_FINFO(pi);
	if (fi == NULL)
		return;

	end += tvb_raw_offset(tvb);
	DISSECTOR_ASSERT(end >= fi->start);
	length = end - fi->start;

	finfo_set_len(fi, length);
}

Project: wireshark

proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				gint start, gint length,
				const guint8* value_ptr,
				const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

hfinfo_type_bitwidth(enum ftenum type)
{
	int bitwidth = 0;

	switch (type) {
		case FT_CHAR:
		case FT_UINT8:
		case FT_INT8:
			bitwidth = 8;
			break;
		case FT_UINT16:
		case FT_INT16:
			bitwidth = 16;
			break;
		case FT_UINT24:
		case FT_INT24:
			bitwidth = 24;
			break;
		case FT_UINT32:
		case FT_INT32:
			bitwidth = 32;
			break;
		case FT_UINT40:
		case FT_INT40:
			bitwidth = 40;
			break;
		case FT_UINT48:
		case FT_INT48:
			bitwidth = 48;
			break;
		case FT_UINT56:
		case FT_INT56:
			bitwidth = 56;
			break;
		case FT_UINT64:
		case FT_INT64:
			bitwidth = 64;
			break;
		default:
			DISSECTOR_ASSERT_NOT_REACHED();
			;
	}
	return bitwidth;
}

Project: wireshark

proto_get_next_protocol(void **cookie)
{
	GList      *list_item = (GList *)*cookie;
	protocol_t *protocol;

	list_item = g_list_next(list_item);
	if (list_item == NULL)
		return -1;
	*cookie = list_item;
	protocol = (protocol_t *)list_item->data;
	return protocol->proto_id;
}

Project: wireshark

proto_tree_get_parent(proto_tree *tree) {
	if (!tree)
		return NULL;
	return (proto_item *)tree;
}

Project: wireshark

proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
{
	DISSECTOR_ASSERT(value_ptr != NULL);
	fvalue_set_bytes(&fi->value, value_ptr);
}

Project: wireshark

ptvcursor_pop_subtree(ptvcursor_t *ptvc)
{
	subtree_lvl *subtree;

	if (ptvc->pushed_tree_index <= 0)
		return;

	ptvc->pushed_tree_index--;
	subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
	if (subtree->it != NULL)
		proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);

	ptvc->tree = subtree->tree;
}

Project: wireshark

proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
{
	fvalue_set_protocol(&fi->value, tvb, field_data);
}

Project: wireshark

proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
                                          tvbuff_t *tvb,
                                          const gint start, gint length,
                                          const guint encoding,
                                          wmem_allocator_t *scope,
                                          const guint8 **retval,
                                          gint *lenretval)
{
	proto_item *pi;
	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
	field_info	  *new_fi;
	const guint8	  *value;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	switch (hfinfo->type) {
	case FT_STRING:
		value = get_string_value(scope, tvb, start, length, lenretval, encoding);
		break;
	case FT_STRINGZ:
		value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
		break;
	case FT_UINT_STRING:
		value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
		break;
	case FT_STRINGZPAD:
		value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
		break;
	case FT_STRINGZTRUNC:
		value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
		break;
	default:
		REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
		    hfinfo->abbrev);
	}

	if (retval)
		*retval = value;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);

	new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);

	proto_tree_set_string(new_fi, value);

	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;

	pi = proto_tree_add_node(tree, new_fi);

	switch (hfinfo->type) {

	case FT_STRINGZ:
	case FT_STRINGZPAD:
	case FT_STRINGZTRUNC:
	case FT_UINT_STRING:
		break;

	case FT_STRING:
		detect_trailing_stray_characters(encoding, value, length, pi);
		break;

	default:
		g_assert_not_reached();
	}

	return pi;
}

Project: wireshark

_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
			    const guint bit_offset, const gint no_of_bits,
			    guint64 *return_value, const guint encoding)
{
	gint     offset;
	guint    length;
	guint8   tot_no_bits;
	char    *bf_str;
	char     lbl_str[ITEM_LABEL_LENGTH];
	guint64  value = 0;
	guint8  *bytes = NULL;
	size_t bytes_length = 0;

	proto_item        *pi;
	header_field_info *hf_field;

	const true_false_string *tfstring;

	/* We can't fake it just yet. We have to fill in the 'return_value' parameter */
	PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);

	if (hf_field->bitmask != 0) {
		REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
				     " with field '%s' (%s) with bitmask != 0",
				     hf_field->abbrev, hf_field->name);
	}

	if (no_of_bits == 0) {
		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",
				     hf_field->abbrev);
	}

	/* Byte align offset */
	offset = bit_offset>>3;

	/*
	 * Calculate the number of octets used to hold the bits
	 */
	tot_no_bits = ((bit_offset&0x7) + no_of_bits);
	length = (tot_no_bits + 7) >> 3;

	if (no_of_bits < 65) {
		value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
	} else if (hf_field->type != FT_BYTES) {
		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65",
				     hf_field->abbrev, no_of_bits);
		return NULL;
	}

	/* Sign extend for signed types */
	switch (hf_field->type) {
		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
		case FT_INT40:
		case FT_INT48:
		case FT_INT56:
		case FT_INT64:
			value = ws_sign_ext64(value, no_of_bits);
			break;

		default:
			break;
	}

	if (return_value) {
		*return_value = value;
	}

	/* Coast clear. Try and fake it */
	CHECK_FOR_NULL_TREE(tree);
	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);

	bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);

	switch (hf_field->type) {
	case FT_BOOLEAN:
		/* Boolean field */
		tfstring = &tfs_true_false;
		if (hf_field->strings)
			tfstring = (const true_false_string *)hf_field->strings;
		return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
			"%s = %s: %s",
			bf_str, hf_field->name, tfs_get_string(!!value, tfstring));
		break;

	case FT_CHAR:
		pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
		fill_label_char(PITEM_FINFO(pi), lbl_str);
		break;

	case FT_UINT8:
	case FT_UINT16:
	case FT_UINT24:
	case FT_UINT32:
		pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
		fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
		break;

	case FT_INT8:
	case FT_INT16:
	case FT_INT24:
	case FT_INT32:
		pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
		fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
		break;

	case FT_UINT40:
	case FT_UINT48:
	case FT_UINT56:
	case FT_UINT64:
		pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
		fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
		break;

	case FT_INT40:
	case FT_INT48:
	case FT_INT56:
	case FT_INT64:
		pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
		fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
		break;

	case FT_BYTES:
		bytes = tvb_get_bits_array(wmem_packet_scope(), tvb, bit_offset, no_of_bits, &bytes_length);
		pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (gint) bytes_length);
		proto_item_fill_label(PITEM_FINFO(pi), lbl_str);
		proto_item_set_text(pi, "%s", lbl_str);
		return pi;
		break;

	default:
		REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",
				     hf_field->abbrev,
				     hf_field->type,
				     ftype_name(hf_field->type));
		return NULL;
		break;
	}

	proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
	return pi;
}

Project: wireshark

proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
{
	DISSECTOR_ASSERT(value_ptr != NULL);
	fvalue_set_bytes(&fi->value, value_ptr);
}

Project: wireshark

proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
			       gpointer data)
{
	proto_node *pnode = tree;
	proto_node *child;
	proto_node *current;

	child = pnode->first_child;
	while (child != NULL) {
		/*
		 * The routine we call might modify the child, e.g. by
		 * freeing it, so we get the child's successor before
		 * calling that routine.
		 */
		current = child;
		child   = current->next;
		if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
			return TRUE;
	}
	if (func(pnode, data))
		return TRUE;

	return FALSE;
}

Project: wireshark

free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
{
	GPtrArray         *ptrs = (GPtrArray *)value;
	gint               hfid = GPOINTER_TO_UINT(key);
	header_field_info *hfinfo;

	PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
	if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
		/* when a field is referenced by a filter this also
		   affects the refcount for the parent protocol so we need
		   to adjust the refcount for the parent as well
		*/
		if (hfinfo->parent != -1) {
			header_field_info *parent_hfinfo;
			PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
			parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
		}
		hfinfo->ref_type = HF_REF_TYPE_NONE;
	}

	g_ptr_array_free(ptrs, TRUE);
}

Project: wireshark

finfo_set_len(field_info *fi, const gint length)
{
	gint length_remaining;

	DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev);
	length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
	if (length > length_remaining)
		fi->length = length_remaining;
	else
		fi->length = length;

	/*
	 * You cannot just make the "len" field of a GByteArray
	 * larger, if there's no data to back that length;
	 * you can only make it smaller.
	 */
	if (fi->value.ftype->ftype == FT_BYTES && fi->length <= (gint)fi->value.value.bytes->len)
		fi->value.value.bytes->len = fi->length;
}

Project: wireshark

_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
				 tvbuff_t *tvb, const guint bit_offset,
				 const gint no_of_bits, void *value_ptr,
				 gchar *value_str)
{
	gint     offset;
	guint    length;
	guint8   tot_no_bits;
	char    *str;
	guint64  value = 0;
	header_field_info *hf_field;

	/* We do not have to return a value, try to fake it as soon as possible */
	CHECK_FOR_NULL_TREE(tree);
	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);

	if (hf_field->bitmask != 0) {
		REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
				     " with field '%s' (%s) with bitmask != 0",
				     hf_field->abbrev, hf_field->name);
	}

	if (no_of_bits == 0) {
		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",
				     hf_field->abbrev);
	}

	/* Byte align offset */
	offset = bit_offset>>3;

	/*
	 * Calculate the number of octets used to hold the bits
	 */
	tot_no_bits = ((bit_offset&0x7) + no_of_bits);
	length      = tot_no_bits>>3;
	/* If we are using part of the next octet, increase length by 1 */
	if (tot_no_bits & 0x07)
		length++;

	if (no_of_bits < 65) {
		value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
	} else {
		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",
				     hf_field->abbrev, no_of_bits);
		return NULL;
	}

	str = decode_bits_in_field(bit_offset, no_of_bits, value);

	g_strlcat(str, " = ", 256+64);
	g_strlcat(str, hf_field->name, 256+64);

	/*
	 * This function does not receive an actual value but a dimensionless pointer to that value.
	 * For this reason, the type of the header field is examined in order to determine
	 * what kind of value we should read from this address.
	 * The caller of this function must make sure that for the specific header field type the address of
	 * a compatible value is provided.
	 */
	switch (hf_field->type) {
	case FT_BOOLEAN:
		return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
						     "%s: %s", str, value_str);
		break;

	case FT_CHAR:
	case FT_UINT8:
	case FT_UINT16:
	case FT_UINT24:
	case FT_UINT32:
		return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
						  "%s: %s", str, value_str);
		break;

	case FT_UINT40:
	case FT_UINT48:
	case FT_UINT56:
	case FT_UINT64:
		return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
						    "%s: %s", str, value_str);
		break;

	case FT_INT8:
	case FT_INT16:
	case FT_INT24:
	case FT_INT32:
		return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
						 "%s: %s", str, value_str);
		break;

	case FT_INT40:
	case FT_INT48:
	case FT_INT56:
	case FT_INT64:
		return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
						   "%s: %s", str, value_str);
		break;

	case FT_FLOAT:
		return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
						   "%s: %s", str, value_str);
		break;

	default:
		REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",
				     hf_field->abbrev,
				     hf_field->type,
				     ftype_name(hf_field->type));
		return NULL;
		break;
	}
}

Project: wireshark

proto_check_field_name(const gchar *field_name)
{
	const char *p = field_name;
	guchar c = '.', lastc;

	do {
		lastc = c;
		c = *(p++);
		/* Leading '.' or substring ".." are disallowed. */
		if (c == '.' && lastc == '.') {
			break;
		}
	} while (fld_abbrev_chars[c]);

	/* Trailing '.' is disallowed. */
	if (lastc == '.') {
		return '.';
	}
	return c;
}

Project: wireshark

proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			      gint start, gint length, guint32 value,
			      const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		TRY_TO_FAKE_THIS_REPR(pi);

		va_start(ap, format);
		proto_tree_set_representation(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

register_string_errors(void)
{
	static ei_register_info ei[] = {
		{ &ei_string_trailing_characters,
			{ "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
		},
	};

	expert_module_t* expert_string_errors;

	proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");

	expert_string_errors = expert_register_protocol(proto_string_errors);
	expert_register_field_array(expert_string_errors, ei, array_length(ei));

	/* "String Errors" isn't really a protocol, it's an error indication;
	   disabling them makes no sense. */
	proto_set_cant_toggle(proto_string_errors);
}

Project: wireshark

proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
{
	proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
}

Project: wireshark

proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
{
	proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
}

Project: wireshark

proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
			    const guint offset, const guint len,
			    const char *name, const char *fallback,
			    const gint ett, int * const *fields,
			    const guint encoding, const int flags)
{
	proto_item *item = NULL;
	guint64     value;

	if (parent_tree) {
		item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
		value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
		if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
		    flags, TRUE, FALSE, NULL, value) && fallback) {
			/* Still at first item - append 'fallback' text if any */
			proto_item_append_text(item, "%s", fallback);
		}
	}

	return item;
}

Project: wireshark

proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
	tvbuff_t *tvb,
	const gint start, gint length, const guint encoding,
	wmem_allocator_t *scope, char **retval)
{
	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
	field_info	  *new_fi;
	nstime_t    time_stamp;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	switch (hfinfo->type) {
	case FT_ABSOLUTE_TIME:
		get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
		*retval = abs_time_to_str(scope, &time_stamp, (absolute_time_display_e)hfinfo->display, TRUE);
		break;
	case FT_RELATIVE_TIME:
		get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
		*retval = rel_time_to_secs_str(scope, &time_stamp);
		break;
	default:
		REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",
			hfinfo->abbrev);
	}

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);

	new_fi = new_field_info(tree, hfinfo, tvb, start, length);

	switch (hfinfo->type) {

	case FT_ABSOLUTE_TIME:
	case FT_RELATIVE_TIME:
		proto_tree_set_time(new_fi, &time_stamp);
		break;
	default:
		g_assert_not_reached();
	}

	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;

	return proto_tree_add_node(tree, new_fi);
}

Project: wireshark

proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
                                       tvbuff_t *tvb,
                                       const gint start, gint length,
                                       const guint encoding,
                                       wmem_allocator_t *scope,
                                       char **retval)
{
	return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
	    tvb, start, length, encoding, scope, retval, &length);
}

Project: wireshark

proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		    gint length, ws_in4_addr value)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_ipv4(PNODE_FINFO(pi), value);

	return pi;
}

Project: wireshark

proto_is_pino(const protocol_t *protocol)
{
	return (protocol->parent_proto_id != -1);
}

Project: wireshark

tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
{
	const header_field_info *hfinfo = fi->hfinfo;

	if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
		GPtrArray *ptrs = NULL;

		if (tree_data->interesting_hfids == NULL) {
			/* Initialize the hash because we now know that it is needed */
			tree_data->interesting_hfids =
				g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
		} else if (g_hash_table_size(tree_data->interesting_hfids)) {
			ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
					   GINT_TO_POINTER(hfinfo->id));
		}

		if (!ptrs) {
			/* First element triggers the creation of pointer array */
			ptrs = g_ptr_array_new();
			g_hash_table_insert(tree_data->interesting_hfids,
					    GINT_TO_POINTER(hfinfo->id), ptrs);
		}

		g_ptr_array_add(ptrs, fi);
	}
}

Project: wireshark

hfinfo_hex_digits(const header_field_info *hfinfo)
{
	int bitwidth;

	/* If we have a bitmask, hfinfo->type is the width of the container, so not
	 * appropriate to determine the number of hex digits for the field.
	 * So instead, we compute it from the bitmask.
	 */
	if (hfinfo->bitmask != 0) {
		bitwidth = hfinfo_mask_bitwidth(hfinfo);
	} else {
		bitwidth = hfinfo_type_bitwidth(hfinfo->type);
	}

	/* Divide by 4, rounding up, to get number of hex digits. */
	return (bitwidth + 3) / 4;
}

Project: wireshark

decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
{
	char *p;

	p = other_decode_bitfield_value(buf, val, mask, width);
	p = g_stpcpy(p, " = ");

	return p;
}

Project: wireshark

proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
{
	GByteArray *bytes;

	DISSECTOR_ASSERT(value_ptr != NULL || length == 0);

	bytes = g_byte_array_new();
	if (length > 0) {
		g_byte_array_append(bytes, value_ptr, length);
	}
	fvalue_set_byte_array(&fi->value, bytes);
}

Project: wireshark

proto_tree_set_uint(field_info *fi, guint32 value)
{
	header_field_info *hfinfo;
	guint32		   integer;

	hfinfo = fi->hfinfo;
	integer = value;

	if (hfinfo->bitmask) {
		/* Mask out irrelevant portions */
		integer &= (guint32)(hfinfo->bitmask);

		/* Shift bits */
		integer >>= hfinfo_bitshift(hfinfo);

		FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
		FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
	}

	fvalue_set_uinteger(&fi->value, integer);
}

Project: wireshark

proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
			const gint start, gint length, const guint encoding)
{
	field_info        *new_fi;
	gint		  item_length;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
	test_length(hfinfo, tvb, start, item_length, encoding);

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);

	new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);

	return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
}

Project: wireshark

proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				 gint start, gint length, ws_in4_addr value,
				 const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
				     tvbuff_t *tvb, const guint bit_offset,
				     const gint no_of_bits, gint32 value,
				     const char *format, ...)
{
	va_list ap;
	gchar  *dst;
	header_field_info *hf_field;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);

	switch (hf_field->type) {
		case FT_INT8:
		case FT_INT16:
		case FT_INT24:
		case FT_INT32:
			break;

		default:
			REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
			    hf_field->abbrev);
			return NULL;
			break;
	}

	CREATE_VALUE_STRING(dst, format, ap);

	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
}

Project: wireshark

report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error)
{
	if (is_error) {
		expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
	} else {
		expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
	}

	if (is_error) {
		THROW(ReportedBoundsError);
	}
}

Project: wireshark

proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
                             const gint start, gint length,
                             const guint encoding, guint32 *retval)
{
	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
	field_info	  *new_fi;
	guint32		   value;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	switch (hfinfo->type) {
	case FT_CHAR:
	case FT_UINT8:
	case FT_UINT16:
	case FT_UINT24:
	case FT_UINT32:
		break;
	default:
		REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
		    hfinfo->abbrev);
	}

	/* length validation for native number encoding caught by get_uint_value() */
	/* length has to be -1 or > 0 regardless of encoding */
	if (length < -1 || length == 0)
		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
			length);

	if (encoding & ENC_STRING) {
		REPORT_DISSECTOR_BUG("wrong encoding");
	}
	/* I believe it's ok if this is called with a NULL tree */
	/* XXX - modify if we ever support EBCDIC FT_CHAR */
	if (encoding & (ENC_VARIANT_MASK)) {
		guint64 temp64;
		tvb_get_varint(tvb, start, length, &temp64, encoding);
		value = (guint32)temp64;
	} else {
		value = get_uint_value(tree, tvb, start, length, encoding);
	}

	if (retval) {
		*retval = value;
		if (hfinfo->bitmask) {
			/* Mask out irrelevant portions */
			*retval &= (guint32)(hfinfo->bitmask);
			/* Shift bits */
			*retval >>= hfinfo_bitshift(hfinfo);
		}
	}

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);

	new_fi = new_field_info(tree, hfinfo, tvb, start, length);

	proto_tree_set_uint(new_fi, value);

	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
	if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
		new_fi->flags |= FI_VARINT;
	}
	return proto_tree_add_node(tree, new_fi);
}

Project: wireshark

proto_tree_set_boolean(field_info *fi, guint64 value)
{
	proto_tree_set_uint64(fi, value);
}

Project: wireshark

proto_can_toggle_protocol(const int proto_id)
{
	protocol_t *protocol;

	protocol = find_protocol_by_id(proto_id);
	//parent protocol determines toggling for helper dissectors
	if (proto_is_pino(protocol))
		return proto_can_toggle_protocol(protocol->parent_proto_id);

	return protocol->can_toggle;
}

Project: wireshark

proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			   gint start, gint length, ws_in4_addr value,
			   const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		TRY_TO_FAKE_THIS_REPR(pi);

		va_start(ap, format);
		proto_tree_set_representation(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			   const gint start, gint length, const guint encoding,
			   GByteArray *retval, gint *endoff, gint *err)
{
	field_info	  *new_fi;
	GByteArray	  *bytes = retval;
	GByteArray	  *created_bytes = NULL;
	gint		   saved_err = 0;
	guint32		   n = 0;
	header_field_info *hfinfo;
	gboolean	   generate = (bytes || tree) ? TRUE : FALSE;

	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
		"Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");

	/* length has to be -1 or > 0 regardless of encoding */
	/* invalid FT_UINT_BYTES length is caught in get_uint_value() */
	if (length < -1 || length == 0) {
		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_bytes_item for %s",
		    length, ftype_name(hfinfo->type));
	}

	if (encoding & ENC_STR_NUM) {
		REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
	}

	if (generate && (encoding & ENC_STR_HEX)) {
		if (hfinfo->type == FT_UINT_BYTES) {
			/* can't decode FT_UINT_BYTES from strings */
			REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
			    "FT_UINT_BYTES type, but as ENC_STR_HEX");
		}

		if (!bytes) {
			/* caller doesn't care about return value, but we need it to
			   call tvb_get_string_bytes() and set the tree later */
			bytes = created_bytes = g_byte_array_new();
		}

		/* bytes might be NULL after this, but can't add expert error until later */
		bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);

		/* grab the errno now before it gets overwritten */
		saved_err = errno;
	}
	else if (generate) {
		tvb_ensure_bytes_exist(tvb, start, length);

		if (!bytes) {
			/* caller doesn't care about return value, but we need it to
			   call tvb_get_string_bytes() and set the tree later */
			bytes = created_bytes = g_byte_array_new();
		}

		if (hfinfo->type == FT_UINT_BYTES) {
			n = length; /* n is now the "header" length */
			length = get_uint_value(tree, tvb, start, n, encoding);
			/* length is now the value's length; only store the value in the array */
			g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
		}
		else if (length > 0) {
			g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
		}

		if (endoff)
		    *endoff = start + n + length;
	}

	if (err) *err = saved_err;

	CHECK_FOR_NULL_TREE_AND_FREE(tree,
		{
		    if (created_bytes)
			g_byte_array_free(created_bytes, TRUE);
		    created_bytes = NULL;
		    bytes = NULL;
		} );

	TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
		{
		    if (created_bytes)
			g_byte_array_free(created_bytes, TRUE);
		    created_bytes = NULL;
		    bytes = NULL;
		} );

	/* n will be zero except when it's a FT_UINT_BYTES */
	new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);

	if (encoding & ENC_STRING) {
		if (saved_err == ERANGE)
		    expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
		else if (!bytes || saved_err != 0)
		    expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);

		if (bytes)
		    proto_tree_set_bytes_gbytearray(new_fi, bytes);
		else
		    proto_tree_set_bytes(new_fi, NULL, 0);

		if (created_bytes)
		    g_byte_array_free(created_bytes, TRUE);
	}
	else {
		/* n will be zero except when it's a FT_UINT_BYTES */
		proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);

		FI_SET_FLAG(new_fi,
			(encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
	}

	return proto_tree_add_node(tree, new_fi);
}

Project: wireshark

proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
{
	proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
}

Project: wireshark

label_concat(char *label_str, gsize pos, const char *str)
{
	if (pos < ITEM_LABEL_LENGTH)
		pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);

	return pos;
}

Project: wireshark

proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
		const int hf_hdr, const gint ett, int * const *fields, const guint64 value)
{
	return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
						hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
}

Project: wireshark

proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
{
	char *filter = NULL;

	if (!construct_match_selected_string(finfo, edt, &filter))
	{
		wmem_free(NULL, filter);
		return NULL;
	}
	return filter;
}

Project: wireshark

proto_item_set_text(proto_item *pi, const char *format, ...)
{
	field_info *fi = NULL;
	va_list     ap;

	TRY_TO_FAKE_THIS_REPR_VOID(pi);

	fi = PITEM_FINFO(pi);
	if (fi == NULL)
		return;

	if (fi->rep) {
		ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
		fi->rep = NULL;
	}

	va_start(ap, format);
	proto_tree_set_representation(pi, format, ap);
	va_end(ap);
}

Project: wireshark

ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
				gint ett_subtree, const char *format, ...)
{
	proto_item        *pi;
	va_list            ap;
	header_field_info *hfinfo;
	proto_tree        *tree;

	tree = ptvcursor_tree(ptvc);

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);

	pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
				      ptvcursor_current_offset(ptvc), length);

	TRY_TO_FAKE_THIS_REPR(pi);

	va_start(ap, format);
	proto_tree_set_representation(pi, format, ap);
	va_end(ap);

	return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
}

Project: wireshark

proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
		    const gint start, gint length, const guint encoding)
{
	register header_field_info *hfinfo;

	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
	return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
}

Project: wireshark

get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
		   gint *item_length, const guint encoding)
{
	gint length_remaining;

	/*
	 * We only allow a null tvbuff if the item has a zero length,
	 * i.e. if there's no data backing it.
	 */
	DISSECTOR_ASSERT(tvb != NULL || *length == 0);

	/*
	 * XXX - in some protocols, there are 32-bit unsigned length
	 * fields, so lengths in protocol tree and tvbuff routines
	 * should really be unsigned.  We should have, for those
	 * field types for which "to the end of the tvbuff" makes sense,
	 * additional routines that take no length argument and
	 * add fields that run to the end of the tvbuff.
	 */
	if (*length == -1) {
		/*
		 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
		 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
		 * of -1 means "set the length to what remains in the
		 * tvbuff".
		 *
		 * The assumption is either that
		 *
		 *	1) the length of the item can only be determined
		 *	   by dissection (typically true of items with
		 *	   subitems, which are probably FT_NONE or
		 *	   FT_PROTOCOL)
		 *
		 * or
		 *
		 *	2) if the tvbuff is "short" (either due to a short
		 *	   snapshot length or due to lack of reassembly of
		 *	   fragments/segments/whatever), we want to display
		 *	   what's available in the field (probably FT_BYTES
		 *	   or FT_STRING) and then throw an exception later
		 *
		 * or
		 *
		 *	3) the field is defined to be "what's left in the
		 *	   packet"
		 *
		 * so we set the length to what remains in the tvbuff so
		 * that, if we throw an exception while dissecting, it
		 * has what is probably the right value.
		 *
		 * For FT_STRINGZ, it means "the string is null-terminated,
		 * not null-padded; set the length to the actual length
		 * of the string", and if the tvbuff if short, we just
		 * throw an exception.
		 *
		 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG, it means "find the end of the string",
		 * and if the tvbuff if short, we just throw an exception.
		 *
		 * It's not valid for any other type of field.  For those
		 * fields, we treat -1 the same way we treat other
		 * negative values - we assume the length is a Really
		 * Big Positive Number, and throw a ReportedBoundsError
		 * exception, under the assumption that the Really Big
		 * Length would run past the end of the packet.
		 */
		if ((IS_FT_INT(hfinfo->type)) || (IS_FT_UINT(hfinfo->type))) {
			if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
				/*
				 * Leave the length as -1, so our caller knows
				 * it was -1.
				 */
				*item_length = *length;
				return;
			} else if (encoding & ENC_VARINT_QUIC) {
				switch (tvb_get_guint8(tvb, start) >> 6)
				{
				case 0: /* 0b00 => 1 byte length (6 bits Usable) */
					*item_length = 1;
					break;
				case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
					*item_length = 2;
					break;
				case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
					*item_length = 4;
					break;
				case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
					*item_length = 8;
					break;
				}
			}
		}

		switch (hfinfo->type) {

		case FT_PROTOCOL:
		case FT_NONE:
		case FT_BYTES:
		case FT_STRING:
		case FT_STRINGZPAD:
		case FT_STRINGZTRUNC:
			/*
			 * We allow FT_PROTOCOLs to be zero-length -
			 * for example, an ONC RPC NULL procedure has
			 * neither arguments nor reply, so the
			 * payload for that protocol is empty.
			 *
			 * We also allow the others to be zero-length -
			 * because that's the way the code has been for a
			 * long, long time.
			 *
			 * However, we want to ensure that the start
			 * offset is not *past* the byte past the end
			 * of the tvbuff: we throw an exception in that
			 * case.
			 */
			*length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
			DISSECTOR_ASSERT(*length >= 0);
			break;

		case FT_STRINGZ:
			/*
			 * Leave the length as -1, so our caller knows
			 * it was -1.
			 */
			break;

		default:
			THROW(ReportedBoundsError);
			DISSECTOR_ASSERT_NOT_REACHED();
		}
		*item_length = *length;
	} else {
		*item_length = *length;
		if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
			/*
			 * These types are for interior nodes of the
			 * tree, and don't have data associated with
			 * them; if the length is negative (XXX - see
			 * above) or goes past the end of the tvbuff,
			 * cut it short at the end of the tvbuff.
			 * That way, if this field is selected in
			 * Wireshark, we don't highlight stuff past
			 * the end of the data.
			 */
			/* XXX - what to do, if we don't have a tvb? */
			if (tvb) {
				length_remaining = tvb_captured_length_remaining(tvb, start);
				if (*item_length < 0 ||
					(*item_length > 0 &&
					  (length_remaining < *item_length)))
					*item_length = length_remaining;
			}
		}
		if (*item_length < 0) {
			THROW(ReportedBoundsError);
		}
	}
}

Project: wireshark

proto_get_protocol_short_name(const protocol_t *protocol)
{
	if (protocol == NULL)
		return "(none)";
	return protocol->short_name;
}

Project: wireshark

proto_tree_add_node(proto_tree *tree, field_info *fi)
{
	proto_node *pnode, *tnode, *sibling;
	field_info *tfi;
	guint depth = 1;

	/*
	 * Restrict our depth. proto_tree_traverse_pre_order and
	 * proto_tree_traverse_post_order (and possibly others) are recursive
	 * so we need to be mindful of our stack size.
	 */
	if (tree->first_child == NULL) {
		for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
			depth++;
			if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
				THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
						     "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
						     prefs.gui_max_tree_depth,
						     fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
			}
		}
	}

	/*
	 * Make sure "tree" is ready to have subtrees under it, by
	 * checking whether it's been given an ett_ value.
	 *
	 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
	 * node of the protocol tree.  That node is not displayed,
	 * so it doesn't need an ett_ value to remember whether it
	 * was expanded.
	 */
	tnode = tree;
	tfi = PNODE_FINFO(tnode);
	if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
		REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
				     fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
		/* XXX - is it safe to continue here? */
	}

	pnode = wmem_new(PNODE_POOL(tree), proto_node);
	PROTO_NODE_INIT(pnode);
	pnode->parent = tnode;
	PNODE_FINFO(pnode) = fi;
	pnode->tree_data = PTREE_DATA(tree);

	if (tnode->last_child != NULL) {
		sibling = tnode->last_child;
		DISSECTOR_ASSERT(sibling->next == NULL);
		sibling->next = pnode;
	} else
		tnode->first_child = pnode;
	tnode->last_child = pnode;

	tree_data_add_maybe_interesting_field(pnode->tree_data, fi);

	return (proto_item *)pnode;
}

Project: wireshark

ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
{
	ptvcursor_t *ptvc;

	ptvc                    = wmem_new(wmem_packet_scope(), ptvcursor_t);
	ptvc->tree              = tree;
	ptvc->tvb               = tvb;
	ptvc->offset            = offset;
	ptvc->pushed_tree       = NULL;
	ptvc->pushed_tree_max   = 0;
	ptvc->pushed_tree_index = 0;
	return ptvc;
}

Project: wireshark

proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
{
	proto_item *pi;

	if (tree == NULL)
		return NULL;

	pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);

	return pi;
}

Project: wireshark

proto_find_undecoded_data(proto_tree *tree, guint length)
{
	decoded_data_t decoded;
	decoded.length = length;
	decoded.buf = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);

	proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
	return decoded.buf;
}

Project: wireshark

proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
{
	const protocol_t *p1 = (const protocol_t *)p1_arg;
	const protocol_t *p2 = (const protocol_t *)p2_arg;

	return g_ascii_strcasecmp(p1->short_name, p2->short_name);
}

Project: wireshark

ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
			   const guint encoding, gint ett_subtree)
{
	proto_item *it;

	it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
	return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
}

Project: wireshark

proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			   gint start, gint length, guint32 value,
			   const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		TRY_TO_FAKE_THIS_REPR(pi);

		va_start(ap, format);
		proto_tree_set_representation(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
{
	wmem_list_frame_t *protos = wmem_list_head(layers);
	int	    proto_id;
	const char *name;

	/* Walk the list of a available protocols in the packet and
	   attempt to find the specified protocol. */
	while (protos != NULL)
	{
		proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
		name = proto_get_protocol_filter_name(proto_id);

		if (!strcmp(name, proto_name))
		{
			return TRUE;
		}

		protos = wmem_list_frame_next(protos);
	}

	return FALSE;
}

Project: wireshark

proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
{
	proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
}

Project: wireshark

proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
				   gint start, gint length, guint64 value,
				   const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		va_start(ap, format);
		proto_tree_set_representation_value(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_register_subtree_array(gint * const *indices, const int num_indices)
{
	int	i;
	gint	*const *ptr = indices;

	/*
	 * If we've already allocated the array of tree types, expand
	 * it; this lets plugins such as mate add tree types after
	 * the initial startup.  (If we haven't already allocated it,
	 * we don't allocate it; on the first pass, we just assign
	 * ett values and keep track of how many we've assigned, and
	 * when we're finished registering all dissectors we allocate
	 * the array, so that we do only one allocation rather than
	 * wasting CPU time and memory by growing the array for each
	 * dissector that registers ett values.)
	 */
	if (tree_is_expanded != NULL) {
		tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));

		/* set new items to 0 */
		/* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
		for (i = num_tree_types; i < num_tree_types + num_indices; i++)
			tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
	}

	/*
	 * Assign "num_indices" subtree numbers starting at "num_tree_types",
	 * returning the indices through the pointers in the array whose
	 * first element is pointed to by "indices", and update
	 * "num_tree_types" appropriately.
	 */
	for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
		if (**ptr != -1) {
			/* g_error will terminate the program */
			g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
				" This is a development error:"
				" Either the subtree item type has already been assigned or"
				" was not initialized to -1.");
		}
		**ptr = num_tree_types;
	}
}

Project: wireshark

proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
{
	GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);

	if (g_ptr_array_len(ptrs) > 0) {
		return TRUE;
	}
	else {
		return FALSE;
	}
}

Project: wireshark

proto_item_add_subtree(proto_item *pi,	const gint idx) {
	field_info *fi;

	if (!pi)
		return NULL;

	DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);

	fi = PITEM_FINFO(pi);
	if (!fi)
		return (proto_tree *)pi;

	fi->tree_type = idx;

	return (proto_tree *)pi;
}

Project: wireshark

get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
	       const gint length, const guint encoding, nstime_t *time_stamp,
	       const gboolean is_relative)
{
	guint32     tmpsecs;
	guint64     tmp64secs;
	guint64     todusecs;

	switch (encoding) {

		case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
			/*
			 * If the length is 16, 8-byte seconds, followed
			 * by 8-byte fractional time in nanoseconds,
			 * both big-endian.
			 *
			 * If the length is 12, 8-byte seconds, followed
			 * by 4-byte fractional time in nanoseconds,
			 * both big-endian.
			 *
			 * If the length is 8, 4-byte seconds, followed
			 * by 4-byte fractional time in nanoseconds,
			 * both big-endian.
			 *
			 * For absolute times, the seconds are seconds
			 * since the UN*X epoch.
			 */
			if (length == 16) {
				time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
				time_stamp->nsecs = (guint32)tvb_get_ntoh64(tvb, start+8);
			} else if (length == 12) {
				time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
				time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
			} else if (length == 8) {
				time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
				time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
			} else if (length == 4) {
				/*
				 * Backwards compatibility.
				 * ENC_TIME_SECS_NSECS is 0; using
				 * ENC_BIG_ENDIAN by itself with a 4-byte
				 * time-in-seconds value was done in the
				 * past.
				 */
				time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a timespec", length, (length < 4));
			}
			break;

		case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
			/*
			 * If the length is 16, 8-byte seconds, followed
			 * by 8-byte fractional time in nanoseconds,
			 * both little-endian.
			 *
			 * If the length is 12, 8-byte seconds, followed
			 * by 4-byte fractional time in nanoseconds,
			 * both little-endian.
			 *
			 * If the length is 8, 4-byte seconds, followed
			 * by 4-byte fractional time in nanoseconds,
			 * both little-endian.
			 *
			 * For absolute times, the seconds are seconds
			 * since the UN*X epoch.
			 */
			if (length == 16) {
				time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
				time_stamp->nsecs = (guint32)tvb_get_letoh64(tvb, start+8);
			} else if (length == 12) {
				time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
				time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
			} else if (length == 8) {
				time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
				time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
			} else if (length == 4) {
				/*
				 * Backwards compatibility.
				 * ENC_TIME_SECS_NSECS is 0; using
				 * ENC_LITTLE_ENDIAN by itself with a 4-byte
				 * time-in-seconds value was done in the
				 * past.
				 */
				time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a timespec", length, (length < 4));
			}
			break;

		case ENC_TIME_NTP|ENC_BIG_ENDIAN:
			/*
			 * NTP time stamp, big-endian.
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			/* We need a temporary variable here so the unsigned math
			 * works correctly (for years > 2036 according to RFC 2030
			 * chapter 3).
			 *
			 * If bit 0 is set, the UTC time is in the range 1968-2036 and
			 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
			 * If bit 0 is not set, the time is in the range 2036-2104 and
			 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
			 */
			tmpsecs  = tvb_get_ntohl(tvb, start);
			if ((tmpsecs & 0x80000000) != 0)
				time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
			else
				time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);

			if (length == 8) {
				/*
				 * Convert 1/2^32s of a second to nanoseconds.
				 */
				time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
				if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
					//This is "NULL" time
					time_stamp->secs = 0;
				}
			} else if (length == 4) {
				/*
				 * Backwards compatibility.
				 */
				if (tmpsecs == 0) {
					//This is "NULL" time
					time_stamp->secs = 0;
				}
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
			/*
			 * NTP time stamp, little-endian.
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			/* We need a temporary variable here so the unsigned math
			 * works correctly (for years > 2036 according to RFC 2030
			 * chapter 3).
			 *
			 * If bit 0 is set, the UTC time is in the range 1968-2036 and
			 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
			 * If bit 0 is not set, the time is in the range 2036-2104 and
			 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
			 */
			tmpsecs  = tvb_get_letohl(tvb, start);
			if ((tmpsecs & 0x80000000) != 0)
				time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
			else
				time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);

			if (length == 8) {
				/*
				 * Convert 1/2^32s of a second to nanoseconds.
				 */
				time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
				if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
					//This is "NULL" time
					time_stamp->secs = 0;
				}
			} else if (length == 4) {
				/*
				 * Backwards compatibility.
				 */
				if (tmpsecs == 0) {
					//This is "NULL" time
					time_stamp->secs = 0;
				}
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_TOD|ENC_BIG_ENDIAN:
			/*
			 * S/3x0 and z/Architecture TOD clock time stamp,
			 * big-endian.  The epoch is January 1, 1900,
			 * 00:00:00 (proleptic?) UTC.
			 *
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);
			DISSECTOR_ASSERT(length == 8);

			if (length == 8) {
				todusecs  = tvb_get_ntoh64(tvb, start) >> 12;
				time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
				time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
			/*
			 * S/3x0 and z/Architecture TOD clock time stamp,
			 * little-endian.  The epoch is January 1, 1900,
			 * 00:00:00 (proleptic?) UTC.
			 *
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			if (length == 8) {
				todusecs  = tvb_get_letoh64(tvb, start) >> 12 ;
				time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
				time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
			/*
			 * Time stamp using the same seconds/fraction format
			 * as NTP, but with the origin of the time stamp being
			 * the UNIX epoch rather than the NTP epoch; big-
			 * endian.
			 *
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			if (length == 8) {
				time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
				/*
				 * Convert 1/2^32s of a second to nanoseconds.
				 */
				time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
			/*
			 * Time stamp using the same seconds/fraction format
			 * as NTP, but with the origin of the time stamp being
			 * the UNIX epoch rather than the NTP epoch; little-
			 * endian.
			 *
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			if (length == 8) {
				time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
				/*
				 * Convert 1/2^32s of a second to nanoseconds.
				 */
				time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_MIP6 | ENC_BIG_ENDIAN:
			/*
			* MIP6 time stamp, big-endian.
			* A 64-bit unsigned integer field containing a timestamp.  The
			* value indicates the number of seconds since January 1, 1970,
			* 00:00 UTC, by using a fixed point format.  In this format, the
			* integer number of seconds is contained in the first 48 bits of
			* the field, and the remaining 16 bits indicate the number of
			* 1/65536 fractions of a second.

			* Only supported for absolute times.
			*/
			DISSECTOR_ASSERT(!is_relative);

			if (length == 8) {
				/* We need a temporary variable here so the casting and fractions
				* of a second work correctly.
				*/
				tmp64secs = tvb_get_ntoh48(tvb, start);
				tmpsecs = tvb_get_ntohs(tvb, start + 6);
				tmpsecs <<= 16;

				if ((tmp64secs == 0) && (tmpsecs == 0)) {
					//This is "NULL" time
					time_stamp->secs = 0;
					time_stamp->nsecs = 0;
				} else {
					time_stamp->secs = (time_t)tmp64secs;
					time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
				}
			} else {
				time_stamp->secs = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
			}
			break;

		case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
			/*
			 * 4-byte seconds, followed by 4-byte fractional
			 * time in microseconds, both big-endian.
			 * For absolute times, the seconds are seconds
			 * since the UN*X epoch.
			 */
			if (length == 8) {
				time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
				time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a timeval", length, (length < 4));
			}
			break;

		case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
			/*
			 * 4-byte seconds, followed by 4-byte fractional
			 * time in microseconds, both little-endian.
			 * For absolute times, the seconds are seconds
			 * since the UN*X epoch.
			 */
			if (length == 8) {
				time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
				time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a timeval", length, (length < 4));
			}
			break;

		case ENC_TIME_SECS|ENC_BIG_ENDIAN:
		case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
			/*
			 * Seconds, 1 to 8 bytes.
			 * For absolute times, it's seconds since the
			 * UN*X epoch.
			 */
			if (length >= 1 && length <= 8) {
				time_stamp->secs  = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
		case ENC_TIME_MSECS|ENC_LITTLE_ENDIAN:
			/*
			 * Milliseconds, 1 to 8 bytes.
			 * For absolute times, it's milliseconds since the
			 * UN*X epoch.
			 */
			if (length >= 1 && length <= 8) {
				guint64 msecs;

				msecs = get_uint64_value(tree, tvb, start, length, encoding);
				time_stamp->secs  = (time_t)(msecs / 1000);
				time_stamp->nsecs = (int)(msecs % 1000)*1000000;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
			/*
			 * 1/64ths of a second since the UN*X epoch,
			 * big-endian.
			 *
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			if (length == 8) {
				/*
				 * The upper 48 bits are seconds since the
				 * UN*X epoch.
				 */
				time_stamp->secs  = (time_t)tvb_get_ntoh48(tvb, start);
				/*
				 * The lower 16 bits are 1/2^16s of a second;
				 * convert them to nanoseconds.
				 *
				 * XXX - this may give the impression of higher
				 * precision than you actually get.
				 */
				time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
			/*
			 * 1/64ths of a second since the UN*X epoch,
			 * little-endian.
			 *
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			if (length == 8) {
				/*
				 * XXX - this is assuming that, if anybody
				 * were ever to use this format - RFC 3971
				 * doesn't, because that's an Internet
				 * protocol, and those use network byte
				 * order, i.e. big-endian - they'd treat it
				 * as a 64-bit count of 1/2^16s of a second,
				 * putting the upper 48 bits at the end.
				 *
				 * The lower 48 bits are seconds since the
				 * UN*X epoch.
				 */
				time_stamp->secs  = (time_t)tvb_get_letoh48(tvb, start+2);
				/*
				 * The upper 16 bits are 1/2^16s of a second;
				 * convert them to nanoseconds.
				 *
				 * XXX - this may give the impression of higher
				 * precision than you actually get.
				 */
				time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
			/*
			 * NTP time stamp, with 1-second resolution (i.e.,
			 * seconds since the NTP epoch), big-endian.
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			if (length == 4) {
				/*
				* We need a temporary variable here so the unsigned math
				* works correctly (for years > 2036 according to RFC 2030
				* chapter 3).
				*
				* If bit 0 is set, the UTC time is in the range 1968-2036 and
				* UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
				* If bit 0 is not set, the time is in the range 2036-2104 and
				* UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
				*/
				tmpsecs  = tvb_get_ntohl(tvb, start);
				if ((tmpsecs & 0x80000000) != 0)
					time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
				else
					time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
			/*
			 * NTP time stamp, with 1-second resolution (i.e.,
			 * seconds since the NTP epoch), little-endian.
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			/*
			 * We need a temporary variable here so the unsigned math
			 * works correctly (for years > 2036 according to RFC 2030
			 * chapter 3).
			 *
			 * If bit 0 is set, the UTC time is in the range 1968-2036 and
			 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
			 * If bit 0 is not set, the time is in the range 2036-2104 and
			 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
			 */
			if (length == 4) {
				tmpsecs  = tvb_get_letohl(tvb, start);
				if ((tmpsecs & 0x80000000) != 0)
					time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
				else
					time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
			}
			break;
		case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
			/*
			* Milliseconds, 1 to 8 bytes.
			* For absolute times, it's milliseconds since the
			* NTP epoch.
			*/
			if (length >= 1 && length <= 8) {
				guint64 msecs;

				msecs = get_uint64_value(tree, tvb, start, length, encoding);
				tmpsecs = (guint32)(msecs / 1000);
				/*
				* If bit 0 is set, the UTC time is in the range 1968-2036 and
				* UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
				* If bit 0 is not set, the time is in the range 2036-2104 and
				* UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
				*/
				if ((tmpsecs & 0x80000000) != 0)
					time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
				else
					time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
				time_stamp->nsecs = (int)(msecs % 1000)*1000000;
			}
			else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 4));
			}
			break;

		case ENC_TIME_CLASSIC_MAC_OS_SECS|ENC_BIG_ENDIAN:
			/*
			 * Classic Mac OS time stamps, big-endian.
			 * Only supported for absolute times.
			 */
			DISSECTOR_ASSERT(!is_relative);

			if (length == 8) {
				tmp64secs  = tvb_get_ntoh64(tvb, start);
				time_stamp->secs = (time_t)(gint64)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
				time_stamp->nsecs = 0;
			} else if (length == 4) {
				tmpsecs  = tvb_get_ntohl(tvb, start);
				time_stamp->secs = (time_t)(gint32)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
				time_stamp->nsecs = 0;
			} else {
				time_stamp->secs  = 0;
				time_stamp->nsecs = 0;
				report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
			}
			break;

		default:
			DISSECTOR_ASSERT_NOT_REACHED();
			break;
	}
}

Project: wireshark

proto_add_deregistered_data (void *data)
{
	g_ptr_array_add(deregistered_data, data);
}

Project: wireshark

proto_get_data_protocol(void *cookie)
{
	GList *list_item = (GList *)cookie;

	protocol_t *protocol = (protocol_t *)list_item->data;
	return protocol->proto_id;
}

Project: wireshark

proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
    const gint start, gint length, const guint encoding, guint64 *retval)
{
	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
	field_info	  *new_fi;
	guint64		   value;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	switch (hfinfo->type) {
	case FT_UINT40:
	case FT_UINT48:
	case FT_UINT56:
	case FT_UINT64:
		break;
	default:
		REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
		    hfinfo->abbrev);
	}

	/* length validation for native number encoding caught by get_uint64_value() */
	/* length has to be -1 or > 0 regardless of encoding */
	if (length < -1 || length == 0)
		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint64",
			length);

	if (encoding & ENC_STRING) {
		REPORT_DISSECTOR_BUG("wrong encoding");
	}
	/* I believe it's ok if this is called with a NULL tree */
	if (encoding & (ENC_VARIANT_MASK)) {
		tvb_get_varint(tvb, start, length, &value, encoding);
	} else {
		value = get_uint64_value(tree, tvb, start, length, encoding);
	}

	if (retval) {
		*retval = value;
		if (hfinfo->bitmask) {
			/* Mask out irrelevant portions */
			*retval &= hfinfo->bitmask;
			/* Shift bits */
			*retval >>= hfinfo_bitshift(hfinfo);
		}
	}

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);

	new_fi = new_field_info(tree, hfinfo, tvb, start, length);

	proto_tree_set_uint64(new_fi, value);

	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
	if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
		new_fi->flags |= FI_VARINT;
	}

	return proto_tree_add_node(tree, new_fi);
}

Project: wireshark

proto_initialize_all_prefixes(void) {
	g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
}

Project: wireshark

proto_item_get_len(const proto_item *pi)
{
	field_info *fi;

	if (!pi)
		return -1;
	fi = PITEM_FINFO(pi);
	return fi ? fi->length : -1;
}

Project: wireshark

hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
{
	char *ptr = &buf[31];
	gboolean isint = IS_FT_INT(hfinfo->type);

	*ptr = '\0';
	/* Properly format value */
	switch (FIELD_DISPLAY(display)) {
		case BASE_DEC:
			return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);

		case BASE_DEC_HEX:
			*(--ptr) = ')';
			ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
			*(--ptr) = '(';
			*(--ptr) = ' ';
			ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
			return ptr;

		case BASE_OCT:
			return oct_to_str_back(ptr, value);

		case BASE_HEX:
			return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);

		case BASE_HEX_DEC:
			*(--ptr) = ')';
			ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
			*(--ptr) = '(';
			*(--ptr) = ' ';
			ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
			return ptr;

		case BASE_PT_UDP:
		case BASE_PT_TCP:
		case BASE_PT_DCCP:
		case BASE_PT_SCTP:
			port_with_resolution_to_str_buf(buf, 32,
					display_to_port_type((field_display_e)display), value);
			return buf;
		case BASE_OUI:
			{
			guint8 p_oui[3];
			const gchar *manuf_name;

			p_oui[0] = value >> 16 & 0xFF;
			p_oui[1] = value >> 8 & 0xFF;
			p_oui[2] = value & 0xFF;

			/* Attempt an OUI lookup. */
			manuf_name = uint_get_manuf_name_if_known(value);
			if (manuf_name == NULL) {
				/* Could not find an OUI. */
				g_snprintf(buf, 32, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
			}
			else {
				/* Found an address string. */
				g_snprintf(buf, 32, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
			}
			return buf;
			}

		default:
			g_assert_not_reached();
	}
	return ptr;
}

Project: wireshark

proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			       gint start, gint length, const char *format, ...)
{
	proto_item	  *pi;
	tvbuff_t	  *protocol_tvb;
	va_list		   ap;
	header_field_info *hfinfo;
	gchar* protocol_rep;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);

	/*
	 * This can throw an exception, so do it before we allocate anything.
	 */
	protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);

	va_start(ap, format);
	protocol_rep = g_strdup_vprintf(format, ap);
	proto_tree_set_protocol_tvb(PNODE_FINFO(pi), protocol_tvb, protocol_rep);
	g_free(protocol_rep);
	va_end(ap);

	TRY_TO_FAKE_THIS_REPR(pi);

	va_start(ap, format);
	proto_tree_set_representation(pi, format, ap);
	va_end(ap);

	return pi;
}

Project: wireshark

get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
{
	guint64 value;
	gboolean length_error;

	switch (length) {

	case 1:
		value = tvb_get_guint8(tvb, offset);
		break;

	case 2:
		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
						       : tvb_get_ntohs(tvb, offset);
		break;

	case 3:
		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
						       : tvb_get_ntoh24(tvb, offset);
		break;

	case 4:
		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
						       : tvb_get_ntohl(tvb, offset);
		break;

	case 5:
		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
						       : tvb_get_ntoh40(tvb, offset);
		break;

	case 6:
		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
						       : tvb_get_ntoh48(tvb, offset);
		break;

	case 7:
		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
						       : tvb_get_ntoh56(tvb, offset);
		break;

	case 8:
		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
						       : tvb_get_ntoh64(tvb, offset);
		break;

	default:
		if (length < 1) {
			length_error = TRUE;
			value = 0;
		} else {
			length_error = FALSE;
			value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
							       : tvb_get_ntoh64(tvb, offset);
		}
		report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
		break;
	}
	return value;
}

Project: wireshark

proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
		const int hf_hdr, const gint ett, int * const *fields, const guint encoding, const int flags)
{
	proto_item        *item = NULL;
	header_field_info *hf;
	int                len;
	guint64            value;

	PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
	DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);

	if (parent_tree) {
		len = ftype_length(hf->type);
		item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
		value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
		proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
		    flags, FALSE, FALSE, NULL, value);
	}

	return item;
}

Project: wireshark

check_valid_filter_name_or_fail(const char *filter_name)
{
	gboolean found_invalid = proto_check_field_name(filter_name);

	/* Additionally forbid upper case characters. */
	if (!found_invalid) {
		for (guint i = 0; filter_name[i]; i++) {
			if (g_ascii_isupper(filter_name[i])) {
				found_invalid = TRUE;
				break;
			}
		}
	}

	if (found_invalid) {
		g_error("Protocol filter name \"%s\" has one or more invalid characters."
			" Allowed are lower characters, digits, '-', '_' and non-repeating '.'."
			" This might be caused by an inappropriate plugin or a development error.", filter_name);
	}
}

Project: wireshark

proto_tree_set_vines(field_info *fi, const guint8* value)
{
	fvalue_set_bytes(&fi->value, value);
}

Project: wireshark

proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
{
	return construct_match_selected_string(finfo, edt, NULL);
}

Project: wireshark

proto_registrar_get_abbrev(const int n)
{
	header_field_info *hfinfo;

	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
	return hfinfo->abbrev;
}

Project: wireshark

ptvcursor_free(ptvcursor_t *ptvc)
{
	ptvcursor_free_subtree_levels(ptvc);
	/*g_free(ptvc);*/
}

Project: wireshark

proto_is_protocol_enabled_by_default(const protocol_t *protocol)
{
	//parent protocol determines enable/disable for helper dissectors
	if (proto_is_pino(protocol))
		return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));

	return protocol->enabled_by_default;
}

Project: wireshark

proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			    gint start, gint length, const guint8* value,
			    const char *format, ...)
{
	proto_item	  *pi;
	va_list		   ap;

	pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
	if (pi != tree) {
		TRY_TO_FAKE_THIS_REPR(pi);

		va_start(ap, format);
		proto_tree_set_representation(pi, format, ap);
		va_end(ap);
	}

	return pi;
}

Project: wireshark

proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
{
	proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
}

Project: wireshark

proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
		    gint length, const e_guid_t *value_ptr)
{
	proto_item	  *pi;
	header_field_info *hfinfo;

	CHECK_FOR_NULL_TREE(tree);

	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);

	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);

	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
	proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);

	return pi;
}

Project: wireshark

proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
		const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
		packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
{
	header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
	guint32 checksum;
	guint32 len;
	proto_item* ti = NULL;
	proto_item* ti2;
	gboolean incorrect_checksum = TRUE;

	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");

	switch (hfinfo->type) {
	case FT_UINT8:
		len = 1;
		break;
	case FT_UINT16:
		len = 2;
		break;
	case FT_UINT24:
		len = 3;
		break;
	case FT_UINT32:
		len = 4;
		break;
	default:
		REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
		    hfinfo->abbrev);
	}

	if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
		ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
		proto_item_set_generated(ti);
		if (hf_checksum_status != -1) {
			ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
			proto_item_set_generated(ti2);
		}
		return ti;
	}

	if (flags & PROTO_CHECKSUM_GENERATED) {
		ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
		proto_item_set_generated(ti);
	} else {
		ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
		if (flags & PROTO_CHECKSUM_VERIFY) {
			if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
				if (computed_checksum == 0) {
					proto_item_append_text(ti, " [correct]");
					if (hf_checksum_status != -1) {
						ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
						proto_item_set_generated(ti2);
					}
					incorrect_checksum = FALSE;
				} else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
					computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
				}
			} else {
				if (checksum == computed_checksum) {
					proto_item_append_text(ti, " [correct]");
					if (hf_checksum_status != -1) {
						ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
						proto_item_set_generated(ti2);
					}
					incorrect_checksum = FALSE;
				}
			}

			if (incorrect_checksum) {
				if (hf_checksum_status != -1) {
					ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
					proto_item_set_generated(ti2);
				}
				if (flags & PROTO_CHECKSUM_ZERO) {
					proto_item_append_text(ti, " [incorrect]");
					if (bad_checksum_expert != NULL)
						expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
				} else {
					proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
					if (bad_checksum_expert != NULL)
						expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%0*x]", expert_get_summary(bad_checksum_expert), len * 2, computed_checksum);
				}
			}
		} else {
			if (hf_checksum_status != -1) {
				proto_item_append_text(ti, " [unverified]");
				ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
				proto_item_set_generated(ti2);
			}
		}
	}

	return ti;
}

Project: wireshark

hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
{
	char *ptr = &buf[6];
	static const gchar hex_digits[16] =
	{ '0', '1', '2', '3', '4', '5', '6', '7',
	  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	*ptr = '\0';
	*(--ptr) = '\'';
	/* Properly format value */
	if (g_ascii_isprint(value)) {
		/*
		 * Printable, so just show the character, and, if it needs
		 * to be escaped, escape it.
		 */
		*(--ptr) = value;
		if (value == '\\' || value == '\'')
			*(--ptr) = '\\';
	} else {
		/*
		 * Non-printable; show it as an escape sequence.
		 */
		switch (value) {

		case '\0':
			/*
			 * Show a NUL with only one digit.
			 */
			*(--ptr) = '0';
			break;

		case '\a':
			*(--ptr) = 'a';
			break;

		case '\b':
			*(--ptr) = 'b';
			break;

		case '\f':
			*(--ptr) = 'f';
			break;

		case '\n':
			*(--ptr) = 'n';
			break;

		case '\r':
			*(--ptr) = 'r';
			break;

		case '\t':
			*(--ptr) = 't';
			break;

		case '\v':
			*(--ptr) = 'v';
			break;

		default:
			switch (FIELD_DISPLAY(display)) {

			case BASE_OCT:
				*(--ptr) = (value & 0x7) + '0';
				value >>= 3;
				*(--ptr) = (value & 0x7) + '0';
				value >>= 3;
				*(--ptr) = (value & 0x7) + '0';
				break;

			case BASE_HEX:
				*(--ptr) = hex_digits[value & 0x0F];
				value >>= 4;
				*(--ptr) = hex_digits[value & 0x0F];
				*(--ptr) = 'x';
				break;

			default:
				g_assert_not_reached();
			}
		}
		*(--ptr) = '\\';
	}
	*(--ptr) = '\'';
	return ptr;
}

Project: wireshark

ptvcursor_tree(ptvcursor_t *ptvc)
{
	if (!ptvc)
		return NULL;

	return ptvc->tree;
}

Project: wireshark

proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
{
	DISSECTOR_ASSERT(value_ptr != NULL);
	fvalue_set_guid(&fi->value, value_ptr);
}

Project: wireshark

proto_register_alias(const int proto_id, const char *alias_name)
{
	protocol_t *protocol;

	protocol = find_protocol_by_id(proto_id);
	if (alias_name && protocol) {
		g_hash_table_insert(gpa_protocol_aliases, (gpointer) alias_name, (gpointer)protocol->filter_name);
	}
}

Project: wireshark

fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
{
	char       *p;
	int         bitfield_byte_length, bitwidth;
	guint32     unshifted_value;
	guint32     value;

	char        buf[32];
	const char *out;

	header_field_info *hfinfo = fi->hfinfo;

	/* Figure out the bit width */
	bitwidth = hfinfo_container_bitwidth(hfinfo);

	/* Un-shift bits */
	if (is_signed)
		value = fvalue_get_sinteger(&fi->value);
	else
		value = fvalue_get_uinteger(&fi->value);

	unshifted_value = value;
	if (hfinfo->bitmask) {
		unshifted_value <<= hfinfo_bitshift(hfinfo);
	}

	/* Create the bitfield first */
	p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
	bitfield_byte_length = (int) (p - label_str);

	/* Fill in the textual info using stored (shifted) value */
	if (hfinfo->display == BASE_CUSTOM) {
		gchar tmp[ITEM_LABEL_LENGTH];
		const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;

		DISSECTOR_ASSERT(fmtfunc);
		fmtfunc(tmp, value);
		label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
	}
	else if (hfinfo->strings) {
		const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");

		out = hfinfo_number_vals_format(hfinfo, buf, value);
		if (out == NULL) /* BASE_NONE so don't put integer in descr */
			label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
		else
			label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
	}
	else {
		out = hfinfo_number_value_format(hfinfo, buf, value);

		label_fill(label_str, bitfield_byte_length, hfinfo, out);
	}
}

Project: wireshark

static void save_same_name_hfinfo(gpointer data)
{
	same_name_hfinfo = (header_field_info*)data;
}

Project: wireshark

proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
			       const gint start, gint length,
			       const guint encoding, gint *lenretval)
{
	register header_field_info *hfinfo;

	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
	return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
}

Project: wireshark

proto_tree_reset(proto_tree *tree)
{
	tree_data_t *tree_data = PTREE_DATA(tree);

	proto_tree_children_foreach(tree, proto_tree_free_node, NULL);

	/* free tree data */
	if (tree_data->interesting_hfids) {
		/* Free all the GPtrArray's in the interesting_hfids hash. */
		g_hash_table_foreach(tree_data->interesting_hfids,
			free_GPtrArray_value, NULL);

		/* And then remove all values. */
		g_hash_table_remove_all(tree_data->interesting_hfids);
	}

	/* Reset track of the number of children */
	tree_data->count = 0;

	PROTO_NODE_INIT(tree);
}

Project: wireshark

proto_cleanup(void)
{
	proto_free_deregistered_fields();
	proto_cleanup_base();

#ifdef HAVE_PLUGINS
	g_slist_free(dissector_plugins);
	dissector_plugins = NULL;
#endif
}

Project: wireshark

proto_set_decoding(const int proto_id, const gboolean enabled)
{
	protocol_t *protocol;

	protocol = find_protocol_by_id(proto_id);
	DISSECTOR_ASSERT(protocol->can_toggle);
	DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
	protocol->is_enabled = enabled;
}