예제 #1
0
/*
void
ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
	  packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
	  int etype_id, int trailer_id, int fcs_len)
*/
static int
dissect_ethertype(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
	const char	  *description;
	tvbuff_t	  *volatile next_tvb;
	guint		   length_before;
	gint		   captured_length, reported_length;
	volatile int  dissector_found = 0;
	const char	  *volatile saved_proto;
	ethertype_data_t  *ethertype_data;

	/* Reject the packet if data is NULL */
	if (data == NULL)
		return 0;
	ethertype_data = (ethertype_data_t*)data;

	/* Add the Ethernet type to the protocol tree */
	proto_tree_add_uint(ethertype_data->fh_tree, ethertype_data->etype_id, tvb,
				    ethertype_data->offset_after_ethertype - 2, 2, ethertype_data->etype);

	/* Get the captured length and reported length of the data
	   after the Ethernet type. */
	captured_length = tvb_captured_length_remaining(tvb, ethertype_data->offset_after_ethertype);
	reported_length = tvb_reported_length_remaining(tvb,
							ethertype_data->offset_after_ethertype);

	/* Remember how much data there is after the Ethernet type,
	   including any trailer and FCS. */
	length_before = reported_length;

	/* Construct a tvbuff for the payload after the Ethernet type.
	   If the FCS length is positive, remove the FCS.
	   (If it's zero, there's no FCS; if it's negative,
	   we don't know whether there's an FCS, so we'll
	   guess based on the length of the trailer.) */
	if (ethertype_data->fcs_len > 0) {
		if (captured_length >= 0 && reported_length >= 0) {
			if (reported_length >= ethertype_data->fcs_len)
				reported_length -= ethertype_data->fcs_len;
			if (captured_length > reported_length)
				captured_length = reported_length;
		}
	}
	next_tvb = tvb_new_subset(tvb, ethertype_data->offset_after_ethertype, captured_length,
				  reported_length);

	p_add_proto_data(pinfo->pool, pinfo, proto_ethertype, 0, GUINT_TO_POINTER((guint)ethertype_data->etype));

	/* Look for sub-dissector, and call it if found.
	   Catch exceptions, so that if the reported length of "next_tvb"
	   was reduced by some dissector before an exception was thrown,
	   we can still put in an item for the trailer. */
	saved_proto = pinfo->current_proto;
	TRY {
		dissector_found = dissector_try_uint(ethertype_dissector_table,
						     ethertype_data->etype, next_tvb, pinfo, tree);
	}
	CATCH_NONFATAL_ERRORS {
		/* Somebody threw an exception that means that there
		   was a problem dissecting the payload; that means
		   that a dissector was found, so we don't need to
		   dissect the payload as data or update the protocol
		   or info columns.

		   Just show the exception and then drive on to show
		   the trailer, after noting that a dissector was found
		   and restoring the protocol value that was in effect
		   before we called the subdissector. */
		show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);

		dissector_found = 1;
		pinfo->current_proto = saved_proto;
	}
	ENDTRY;

	if (!dissector_found) {
		/* No sub-dissector found.
		   Label rest of packet as "Data" */
		call_data_dissector(next_tvb, pinfo, tree);

		/* Label protocol */
		col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ethertype_data->etype);

		description = try_val_to_str(ethertype_data->etype, etype_vals);
		if (description) {
			col_add_str(pinfo->cinfo, COL_INFO, description);
		}
	}

	add_dix_trailer(pinfo, tree, ethertype_data->fh_tree, ethertype_data->trailer_id, tvb, next_tvb, ethertype_data->offset_after_ethertype,
			length_before, ethertype_data->fcs_len);

	return tvb_captured_length(tvb);
}
예제 #2
0
void
ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
	  packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
	  int etype_id, int trailer_id, int fcs_len)
{
	const char		*description;
	tvbuff_t		*volatile next_tvb;
	guint			length_before;
	gint			captured_length, reported_length;
	volatile gboolean	dissector_found = FALSE;
	const char		*volatile saved_proto;
	void			*pd_save;

	/* Add the Ethernet type to the protocol tree */
	if (tree) {
		proto_tree_add_uint(fh_tree, etype_id, tvb,
				    offset_after_etype - 2, 2, etype);
	}

	/* Get the captured length and reported length of the data
	   after the Ethernet type. */
	captured_length = tvb_length_remaining(tvb, offset_after_etype);
	reported_length = tvb_reported_length_remaining(tvb,
							offset_after_etype);

	/* Remember how much data there is after the Ethernet type,
	   including any trailer and FCS. */
	length_before = reported_length;

	/* Construct a tvbuff for the payload after the Ethernet type.
	   If the FCS length is positive, remove the FCS.
	   (If it's zero, there's no FCS; if it's negative,
	   we don't know whether there's an FCS, so we'll
	   guess based on the length of the trailer.) */
	if (fcs_len > 0) {
		if (captured_length >= 0 && reported_length >= 0) {
			if (reported_length >= fcs_len)
				reported_length -= fcs_len;
			if (captured_length > reported_length)
				captured_length = reported_length;
		}
	}
	next_tvb = tvb_new_subset(tvb, offset_after_etype, captured_length,
				  reported_length);

	pinfo->ethertype = etype;

	/* Look for sub-dissector, and call it if found.
	   Catch exceptions, so that if the reported length of "next_tvb"
	   was reduced by some dissector before an exception was thrown,
	   we can still put in an item for the trailer. */
	saved_proto = pinfo->current_proto;
	pd_save = pinfo->private_data;
	TRY {
		dissector_found = dissector_try_uint(ethertype_dissector_table,
						     etype, next_tvb, pinfo, tree);
	}
	CATCH(BoundsError) {
		/* Somebody threw BoundsError, which means that:

		   1) a dissector was found, so we don't need to
		   dissect the payload as data or update the
		   protocol or info columns;

		   2) dissecting the payload found that the packet was
		   cut off by a snapshot length before the end of
		   the payload.  The trailer comes after the payload,
		   so *all* of the trailer is cut off, and we'll
		   just get another BoundsError if we add the trailer.

		   Therefore, we just rethrow the exception so it gets
		   reported; we don't dissect the trailer or do anything
		   else. */
		RETHROW;
	}
	CATCH(OutOfMemoryError) {
		RETHROW;
	}
	CATCH_ALL {
		/* Somebody threw an exception other than BoundsError, which
		   means that a dissector was found, so we don't need to
		   dissect the payload as data or update the protocol or info
		   columns.  We just show the exception and then drive on
		   to show the trailer, after noting that a dissector was
		   found and restoring the protocol value that was in effect
		   before we called the subdissector. */
		show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);

		/*  Restore the private_data structure in case one of the
		 *  called dissectors modified it (and, due to the exception,
		 *  was unable to restore it).
		 */
		pinfo->private_data = pd_save;
		dissector_found = TRUE;
		pinfo->current_proto = saved_proto;
	}
	ENDTRY;

	if (!dissector_found) {
		/* No sub-dissector found.
		   Label rest of packet as "Data" */
		call_dissector(data_handle,next_tvb, pinfo, tree);

		/* Label protocol */
		col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", etype);

		description = match_strval(etype, etype_vals);
		if (description) {
			col_add_str(pinfo->cinfo, COL_INFO, description);
		}
	}

	add_dix_trailer(pinfo, tree, fh_tree, trailer_id, tvb, next_tvb, offset_after_etype,
			length_before, fcs_len);
}