Beispiel #1
0
static void
dissect_nflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    const int start_tlv_offset = 4;

    proto_tree *nflog_tree = NULL;
    proto_item *ti;

    int offset = 0;

    tvbuff_t *next_tvb = NULL;
    int aftype;

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

    aftype = tvb_get_guint8(tvb, 0);

    /* Header */
    if (proto_field_is_referenced(tree, hfi_nflog->id)) {
        ti = proto_tree_add_item(tree, hfi_nflog, tvb, 0, -1, ENC_NA);
        nflog_tree = proto_item_add_subtree(ti, ett_nflog);

        proto_tree_add_item(nflog_tree, &hfi_nflog_family, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item(nflog_tree, &hfi_nflog_version, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item(nflog_tree, &hfi_nflog_resid, tvb, offset, 2, ENC_BIG_ENDIAN);
        /*offset += 2;*/
    }

    offset = start_tlv_offset;
    /* TLVs */
    while (tvb_reported_length_remaining(tvb, offset) >= 4) {
        guint16 tlv_len = tvb_get_h_guint16(tvb, offset + 0);
        guint16 tlv_type;
        guint16 value_len;

        proto_tree *tlv_tree;

        /* malformed */
        if (tlv_len < 4)
            return;

        value_len = tlv_len - 4;
        tlv_type = (tvb_get_h_guint16(tvb, offset + 2) & 0x7fff);

        if (nflog_tree) {
            gboolean handled = FALSE;

            ti = proto_tree_add_bytes_format(nflog_tree, hfi_nflog_tlv.id,
                             tvb, offset, tlv_len, NULL,
                             "TLV Type: %s (%u), Length: %u",
                             val_to_str_const(tlv_type, nflog_tlv_vals, "Unknown"),
                             tlv_type, tlv_len);
            tlv_tree = proto_item_add_subtree(ti, ett_nflog_tlv);

            proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_length, tvb, offset + 0, 2, ENC_HOST_ENDIAN);
            proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_type, tvb, offset + 2, 2, ENC_HOST_ENDIAN);
            switch (tlv_type) {
                case WS_NFULA_PAYLOAD:
                    handled = TRUE;
                    break;

                case WS_NFULA_PREFIX:
                    if (value_len >= 1) {
                        proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_prefix,
                                    tvb, offset + 4, value_len, ENC_NA);
                        handled = TRUE;
                    }
                    break;

                case WS_NFULA_UID:
                    if (value_len == 4) {
                        proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_uid,
                                    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
                        handled = TRUE;
                    }
                    break;

                case WS_NFULA_GID:
                    if (value_len == 4) {
                        proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_gid,
                                    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
                        handled = TRUE;
                    }
                    break;

                case WS_NFULA_TIMESTAMP:
                    if (value_len == 16) {
                        nstime_t ts;

                        ts.secs  = (time_t)tvb_get_ntoh64(tvb, offset + 4);
                        /* XXX - add an "expert info" warning if this is >= 10^9? */
                        ts.nsecs = (int)tvb_get_ntoh64(tvb, offset + 12);
                        proto_tree_add_time(tlv_tree, &hfi_nflog_tlv_timestamp,
                                    tvb, offset + 4, value_len, &ts);
                        handled = TRUE;
                    }
                    break;
            }

            if (!handled)
                    proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_unknown,
                                        tvb, offset + 4, value_len, ENC_NA);
        }

        if (tlv_type == WS_NFULA_PAYLOAD)
            next_tvb = tvb_new_subset_length(tvb, offset + 4, value_len);

        offset += ((tlv_len + 3) & ~3); /* next TLV aligned to 4B */
    }

    if (next_tvb) {
        switch (aftype) {
            case LINUX_AF_INET:
                call_dissector(ip_handle, next_tvb, pinfo, tree);
                break;
            case LINUX_AF_INET6:
                call_dissector(ip6_handle, next_tvb, pinfo, tree);
                break;
            default:
                call_dissector(data_handle, next_tvb, pinfo, tree);
                break;
        }
    }
}
Beispiel #2
0
/* XXX - "packet comment" is passed into dissector as data, but currently doesn't have a use */
static int
dissect_file_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
	proto_item  *volatile ti = NULL;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile fh_tree = NULL;
	proto_tree  *volatile tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;
	const color_filter_t *color_filter;
	file_data_t *file_data = (file_data_t*)data;

	tree=parent_tree;

	pinfo->current_proto = "File";

	/* if FILE is not referenced from any filters we don't need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_file)) {
		tree=NULL;
	} else {
		/* Put in frame header information. */
		cap_len = tvb_captured_length(tvb);
		frame_len = tvb_reported_length(tvb);

		cap_plurality = plurality(cap_len, "", "s");
		frame_plurality = plurality(frame_len, "", "s");

		ti = proto_tree_add_protocol_format(tree, proto_file, tvb, 0, -1,
		    "File record %u: %u byte%s",
		    pinfo->num, frame_len, frame_plurality);
		proto_item_append_text(ti, ", %u byte%s",
		    cap_len, cap_plurality);

		fh_tree = proto_item_add_subtree(ti, ett_file);

		proto_tree_add_int(fh_tree, hf_file_ftap_encap, tvb, 0, 0, pinfo->pkt_encap);

		proto_tree_add_uint(fh_tree, hf_file_record_number, tvb, 0, 0, pinfo->num);

		proto_tree_add_uint_format(fh_tree, hf_file_record_len, tvb,
					   0, 0, frame_len, "Record Length: %u byte%s (%u bits)",
					   frame_len, frame_plurality, frame_len * 8);

		ti = proto_tree_add_boolean(fh_tree, hf_file_marked, tvb, 0, 0,pinfo->fd->flags.marked);
		PROTO_ITEM_SET_GENERATED(ti);

		ti = proto_tree_add_boolean(fh_tree, hf_file_ignored, tvb, 0, 0,pinfo->fd->flags.ignored);
		PROTO_ITEM_SET_GENERATED(ti);

		if(pinfo->fd->pfd != 0){
			proto_item *ppd_item;
			guint num_entries = g_slist_length(pinfo->fd->pfd);
			guint i;
			ppd_item = proto_tree_add_uint(fh_tree, hf_file_num_p_prot_data, tvb, 0, 0, num_entries);
			PROTO_ITEM_SET_GENERATED(ppd_item);
			for(i=0; i<num_entries; i++){
				gchar* str = p_get_proto_name_and_key(wmem_file_scope(), pinfo, i);
				proto_tree_add_string_format(fh_tree, hf_file_proto_name_and_key, tvb, 0, 0, str, "%s", str);
			}
		}

#if 0
		if (show_file_off) {
			proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}
#endif
	}

	if (pinfo->fd->flags.ignored) {
		/* Ignored package, stop handling here */
		col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
		proto_tree_add_boolean_format(tree, hf_file_ignored, tvb, 0, -1, TRUE, "This record is marked as ignored");
		return tvb_captured_length(tvb);
	}

	/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
		/* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
		   like memory access violations.
		   (a running debugger will be called before the except part below) */
		/* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
		   stack in an inconsistent state thus causing a crash at some point in the
		   handling of the exception.
		   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
		*/
		__try {
#endif
			if (!dissector_try_uint(file_encap_dissector_table, pinfo->pkt_encap,
						tvb, pinfo, parent_tree)) {

				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
				col_add_fstr(pinfo->cinfo, COL_INFO, "FTAP_ENCAP = %d",
					     pinfo->pkt_encap);
				call_data_dissector(tvb, pinfo, parent_tree);
			}
#ifdef _MSC_VER
		} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
			switch(GetExceptionCode()) {
			case(STATUS_ACCESS_VIOLATION):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
				break;
			case(STATUS_INTEGER_DIVIDE_BY_ZERO):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
				break;
			case(STATUS_STACK_OVERFLOW):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
				/* XXX - this will have probably corrupted the stack,
				   which makes problems later in the exception code */
				break;
				/* XXX - add other hardware exception codes as required */
			default:
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
			}
		}
#endif
	}
	CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if(proto_field_is_referenced(tree, hf_file_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), "");
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, wmem_strbuf_get_str(val));
		PROTO_ITEM_SET_GENERATED(ti);
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
		TRY {
#ifdef _MSC_VER
			/* Win32: Visual-C Structured Exception Handling (SEH)
			   to trap hardware exceptions like memory access violations */
			/* (a running debugger will be called before the except part below) */
			/* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
			   stack in an inconsistent state thus causing a crash at some point in the
			   handling of the exception.
			   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
			*/
			__try {
#endif
				call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
			} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
				switch(GetExceptionCode()) {
				case(STATUS_ACCESS_VIOLATION):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
					break;
				case(STATUS_INTEGER_DIVIDE_BY_ZERO):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
					break;
				case(STATUS_STACK_OVERFLOW):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
					/* XXX - this will have probably corrupted the stack,
					   which makes problems later in the exception code */
					break;
					/* XXX - add other hardware exception codes as required */
				default:
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
				}
			}
#endif
		}
		CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	/* Attempt to (re-)calculate color filters (if any). */
	if (pinfo->fd->flags.need_colorize) {
		color_filter = color_filters_colorize_packet(file_data->color_edt);
		pinfo->fd->color_filter = color_filter;
		pinfo->fd->flags.need_colorize = 0;
	} else {
		color_filter = pinfo->fd->color_filter;
	}
	if (color_filter) {
		pinfo->fd->color_filter = color_filter;
		item = proto_tree_add_string(fh_tree, hf_file_color_filter_name, tvb,
					     0, 0, color_filter->filter_name);
		PROTO_ITEM_SET_GENERATED(item);
		item = proto_tree_add_string(fh_tree, hf_file_color_filter_text, tvb,
					     0, 0, color_filter->filter_text);
		PROTO_ITEM_SET_GENERATED(item);
	}

	tap_queue_packet(file_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_file_record_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}

	return tvb_captured_length(tvb);
}
static void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_item	*volatile ti = NULL;
	nstime_t	ts;
	int		cap_len = 0, frame_len = 0;
	proto_tree	*volatile tree;
        proto_item  *item;
	guint32 frame_number;

	frame_number=pinfo->fd->num; /* dummy so that the buildbot crashdumps
					will show the packetnumber where the
					crash occurred.
				     */
	tree=parent_tree;

	pinfo->current_proto = "Frame";

	if (pinfo->pseudo_header != NULL) {
		switch (pinfo->fd->lnk_t) {

		case WTAP_ENCAP_WFLEET_HDLC:
		case WTAP_ENCAP_CHDLC_WITH_PHDR:
		case WTAP_ENCAP_PPP_WITH_PHDR:
		case WTAP_ENCAP_SDLC:
		case WTAP_ENCAP_BLUETOOTH_H4:
		case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_BLUETOOTH_HCI:
			pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent;
			break;

		case WTAP_ENCAP_LAPB:
		case WTAP_ENCAP_FRELAY_WITH_PHDR:
			pinfo->p2p_dir =
			    (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
			    P2P_DIR_RECV : P2P_DIR_SENT;
			break;

		case WTAP_ENCAP_ISDN:
			pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_LINUX_LAPD:
			pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
				pinfo->pseudo_header->lapd.pkttype == 4) ?
				P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_MTP2_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
			pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used;
			break;

		case WTAP_ENCAP_GSM_UM:
			pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		}
	}

	/* if FRAME is not referenced from any filters we dont need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_frame)) {
        tree=NULL;
        if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000)
            expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN,
                "Arrival Time: Fractional second out of range (0-1000000000)");
    } else {
	    proto_tree	*fh_tree;

	  /* Put in frame header information. */
	  cap_len = tvb_length(tvb);
	  frame_len = tvb_reported_length(tvb);

	  ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
	    "Frame %u (%u bytes on wire, %u bytes captured)", pinfo->fd->num, frame_len, cap_len);

	  fh_tree = proto_item_add_subtree(ti, ett_frame);

	  ts = pinfo->fd->abs_ts;

	  proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
		0, 0, &ts);
	  if(ts.nsecs < 0 || ts.nsecs >= 1000000000) {
	    item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb,
	  	  0, 0, "Arrival Time: Fractional second %09ld is invalid, the valid range is 0-1000000000", (long) ts.nsecs);
	    PROTO_ITEM_SET_GENERATED(item);
	    expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)");
	  }

	  ts = pinfo->fd->del_cap_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  ts = pinfo->fd->del_dis_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  ts = pinfo->fd->rel_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  if(pinfo->fd->flags.ref_time){
		ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, FALSE);
		PROTO_ITEM_SET_GENERATED(ti);
	  }

	  proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
		0, 0, pinfo->fd->num);

	  proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
		0, 0, frame_len, "Frame Length: %d byte%s", frame_len,
		plurality(frame_len, "", "s"));

	  proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
		0, 0, cap_len, "Capture Length: %d byte%s", cap_len,
		plurality(cap_len, "", "s"));

	  if (generate_md5_hash) {
		  const guint8 *cp;
		  md5_state_t md_ctx;
		  md5_byte_t digest[16];
		  gchar *digest_string;

		  cp = tvb_get_ptr(tvb, 0, cap_len);

		  md5_init(&md_ctx);
		  md5_append(&md_ctx, cp, cap_len);
		  md5_finish(&md_ctx, digest);

		  digest_string = bytestring_to_str(digest, 16, '\0');
		  ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
		  PROTO_ITEM_SET_GENERATED(ti);
	  }

	  ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
	  PROTO_ITEM_SET_GENERATED(ti);

	  /* we are going to be using proto_item_append_string() on
	   * hf_frame_protocols, and we must therefore disable the
	   * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
	   * setting it as visible.
	   *
	   * See proto.h for details.
	   */
	  proto_tree_set_visible(fh_tree, TRUE);

	  ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb,
	  	0, 0, "");
	  PROTO_ITEM_SET_GENERATED(ti);
	  pinfo->layer_names = g_string_new("");

	  /* Check for existences of P2P pseudo header */
	  if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
		  proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
				  0, 0, pinfo->p2p_dir);
	  }

	  /* Check for existences of MTP2 link number */
	  if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
		  proto_tree_add_uint(fh_tree, hf_link_number, tvb,
				  0, 0, pinfo->link_number);
	  }

	  if (show_file_off) {
		  proto_tree_add_int64_format(fh_tree, hf_frame_file_off, tvb,
				  0, 0, pinfo->fd->file_off,
				  "File Offset: %" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
				  pinfo->fd->file_off, pinfo->fd->file_off);
	  }

	  if(pinfo->fd->color_filter != NULL) {
	      color_filter_t *color_filter = pinfo->fd->color_filter;
	      item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
		    0, 0, color_filter->filter_name);
	      PROTO_ITEM_SET_GENERATED(item);
	      item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
		    0, 0, color_filter->filter_text);
	      PROTO_ITEM_SET_GENERATED(item);
	  }
    }

    /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */
    /* (a running debugger will be called before the except part below) */
    __try {
#endif
	if ((force_docsis_encap) && (docsis_handle)) {
	    call_dissector(docsis_handle, tvb, pinfo, parent_tree);
	} else {
            if (!dissector_try_port(wtap_encap_dissector_table, pinfo->fd->lnk_t,
                tvb, pinfo, parent_tree)) {

				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
				col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %u",
				    pinfo->fd->lnk_t);
			call_dissector(data_handle,tvb, pinfo, parent_tree);
		}
	}
#ifdef _MSC_VER
    } __except(TRUE /* handle all exceptions */) {
        switch(GetExceptionCode()) {
        case(STATUS_ACCESS_VIOLATION):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
            break;
        case(STATUS_INTEGER_DIVIDE_BY_ZERO):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
            break;
        case(STATUS_STACK_OVERFLOW):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
            /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */
            break;
        /* XXX - add other hardware exception codes as required */
        default:
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
        }
    }
#endif
	}
	CATCH(OutOfMemoryError) {
		RETHROW;
	}
	CATCH_ALL {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if (tree && pinfo->layer_names) {
		proto_item_append_string(ti, pinfo->layer_names->str);
		g_string_free(pinfo->layer_names, TRUE);
		pinfo->layer_names = NULL;
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
	    TRY {
#ifdef _MSC_VER
	    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */
	    /* (a running debugger will be called before the except part below) */
	    __try {
#endif
		call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
	    } __except(TRUE /* handle all exceptions */) {
		switch(GetExceptionCode()) {
		case(STATUS_ACCESS_VIOLATION):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
		    break;
		case(STATUS_INTEGER_DIVIDE_BY_ZERO):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
		    break;
		case(STATUS_STACK_OVERFLOW):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
		    /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */
		    break;
		/* XXX - add other hardware exception codes as required */
		default:
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
		}
	    }
#endif
	    }
	    CATCH(OutOfMemoryError) {
		    RETHROW;
	    }
	    CATCH_ALL {
		    show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	    }
	    ENDTRY;
	}

	tap_queue_packet(frame_tap, pinfo, NULL);


	if (frame_end_routines) {
		g_slist_foreach(frame_end_routines, &call_frame_end_routine, NULL);
		g_slist_free(frame_end_routines);
		frame_end_routines = NULL;
	}
}
Beispiel #4
0
static void
dissect_eth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
    int fcs_len)
{
  proto_item        *ti = NULL;
  eth_hdr           *ehdr;
  gboolean          is_802_2;
  proto_tree        *fh_tree = NULL;
  const guint8      *src_addr, *dst_addr;
  static eth_hdr    ehdrs[4];
  static int        ehdr_num=0;
  proto_tree        *tree;
  proto_item        *addr_item;
  proto_tree        *addr_tree=NULL;

  ehdr_num++;
  if(ehdr_num>=4){
     ehdr_num=0;
  }
  ehdr=&ehdrs[ehdr_num];

  tree=parent_tree;

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

  src_addr=tvb_get_ptr(tvb, 6, 6);
  SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src_addr);
  SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src_addr);
  SET_ADDRESS(&ehdr->src, AT_ETHER, 6, src_addr);
  dst_addr=tvb_get_ptr(tvb, 0, 6);
  SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst_addr);
  SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst_addr);
  SET_ADDRESS(&ehdr->dst, AT_ETHER, 6, dst_addr);

  ehdr->type = tvb_get_ntohs(tvb, 12);

  tap_queue_packet(eth_tap, pinfo, ehdr);

  /*
   * In case the packet is a non-Ethernet packet inside
   * Ethernet framing, allow heuristic dissectors to take
   * a first look before we assume that it's actually an
   * Ethernet packet.
   */
  if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, parent_tree, NULL))
    return;

  if (ehdr->type <= IEEE_802_3_MAX_LEN) {
    /* Oh, yuck.  Cisco ISL frames require special interpretation of the
       destination address field; fortunately, they can be recognized by
       checking the first 5 octets of the destination address, which are
       01-00-0C-00-00 for ISL frames. */
    if ((tvb_get_guint8(tvb, 0) == 0x01 ||
      tvb_get_guint8(tvb, 0) == 0x0C) &&
      tvb_get_guint8(tvb, 1) == 0x00 &&
      tvb_get_guint8(tvb, 2) == 0x0C &&
      tvb_get_guint8(tvb, 3) == 0x00 &&
      tvb_get_guint8(tvb, 4) == 0x00) {
      dissect_isl(tvb, pinfo, parent_tree, fcs_len);
      return;
    }
  }

  /*
   * If the type/length field is <= the maximum 802.3 length,
   * and is not zero, this is an 802.3 frame, and it's a length
   * field; it might be an Novell "raw 802.3" frame, with no
   * 802.2 LLC header, or it might be a frame with an 802.2 LLC
   * header.
   *
   * If the type/length field is >= the minimum Ethernet II length,
   * this is an Ethernet II frame, and it's a type field.
   *
   * If the type/length field is > maximum 802.3 length and < minimum
   * Ethernet II length, then this is an invalid packet.
   *
   * If the type/length field is zero (ETHERTYPE_UNK), this is
   * a frame used internally by the Cisco MDS switch to contain
   * Fibre Channel ("Vegas").  We treat that as an Ethernet II
   * frame; the dissector for those frames registers itself with
   * an ethernet type of ETHERTYPE_UNK.
   */
  if (ehdr->type > IEEE_802_3_MAX_LEN && ehdr->type < ETHERNET_II_MIN_LEN) {
    tvbuff_t *next_tvb;

    col_add_fstr(pinfo->cinfo, COL_INFO,
        "Ethernet Unknown: Invalid length/type: 0x%04x (%d)",
        ehdr->type, ehdr->type);
    ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
        "Ethernet Unknown, Src: %s (%s), Dst: %s (%s)",
        get_ether_name(src_addr), ether_to_str(src_addr),
        get_ether_name(dst_addr), ether_to_str(dst_addr));
    fh_tree = proto_item_add_subtree(ti, ett_ether);
    addr_item = proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst_addr);
    if (addr_item)
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 0, 6, dst_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 0, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 0, 3, ENC_BIG_ENDIAN);

    addr_item = proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src_addr);
    if (addr_item)
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 6, 6, src_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 6, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 6, 3, ENC_BIG_ENDIAN);

    ti = proto_tree_add_item(fh_tree, hf_eth_invalid_lentype, tvb, 12, 2, ENC_BIG_ENDIAN);
    expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
        "Invalid length/type: 0x%04x (%d)", ehdr->type, ehdr->type);
    next_tvb = tvb_new_subset_remaining(tvb, 14);
    call_dissector(data_handle, next_tvb, pinfo, parent_tree);
    return;
  }

  if (ehdr->type <= IEEE_802_3_MAX_LEN && ehdr->type != ETHERTYPE_UNK) {

    is_802_2 = check_is_802_2(tvb, fcs_len);

     col_add_fstr(pinfo->cinfo, COL_INFO, "IEEE 802.3 Ethernet %s",
        (is_802_2 ? "" : "Raw "));
    if (tree) {
      ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
        "IEEE 802.3 Ethernet %s", (is_802_2 ? "" : "Raw "));

      fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
    }

    /* if IP is not referenced from any filters we dont need to worry about
       generating any tree items.  We must do this after we created the actual
       protocol above so that proto hier stat still works though.
    */
    if(!proto_field_is_referenced(parent_tree, proto_eth)){
      tree=NULL;
      fh_tree=NULL;
    }

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 0, 6, dst_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 0, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 0, 3, ENC_BIG_ENDIAN);

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 6, 6, src_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 6, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 6, 3, ENC_BIG_ENDIAN);

    dissect_802_3(ehdr->type, is_802_2, tvb, ETH_HEADER_SIZE, pinfo,
        parent_tree, fh_tree, hf_eth_len, hf_eth_trailer, fcs_len);
  } else {
    if (eth_interpret_as_fw1_monitor) {
        if ((dst_addr[0] == 'i') || (dst_addr[0] == 'I') ||
            (dst_addr[0] == 'o') || (dst_addr[0] == 'O')) {
            call_dissector(fw1_handle, tvb, pinfo, parent_tree);
            return;
        }
    }

    col_set_str(pinfo->cinfo, COL_INFO, "Ethernet II");
    if (parent_tree) {
        if (PTREE_DATA(parent_tree)->visible) {
            ti = proto_tree_add_protocol_format(parent_tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
                "Ethernet II, Src: %s (%s), Dst: %s (%s)",
                get_ether_name(src_addr), ether_to_str(src_addr),
                get_ether_name(dst_addr), ether_to_str(dst_addr));
      }
      else {
            ti = proto_tree_add_item(parent_tree, proto_eth, tvb, 0, ETH_HEADER_SIZE, ENC_NA);
      }
      fh_tree = proto_item_add_subtree(ti, ett_ether2);
    }

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 0, 6, dst_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 0, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 0, 3, ENC_BIG_ENDIAN);

    addr_item=proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src_addr);
    if(addr_item){
        addr_tree = proto_item_add_subtree(addr_item, ett_addr);
        if (tvb_get_guint8(tvb, 6) & 0x01) {
            expert_add_info_format(pinfo, addr_item, PI_PROTOCOL, PI_WARN,
                "Source MAC must not be a group address: IEEE 802.3-2002, Section 3.2.3(b)");
        }
    }
    proto_tree_add_ether(addr_tree, hf_eth_addr, tvb, 6, 6, src_addr);
    proto_tree_add_item(addr_tree, hf_eth_lg, tvb, 6, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(addr_tree, hf_eth_ig, tvb, 6, 3, ENC_BIG_ENDIAN);

    ethertype(ehdr->type, tvb, ETH_HEADER_SIZE, pinfo, parent_tree, fh_tree, hf_eth_type,
          hf_eth_trailer, fcs_len);
  }
}
static void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_item  *volatile ti = NULL, *comment_item;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile tree;
	proto_tree  *comments_tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;

	tree=parent_tree;

	switch (pinfo->phdr->rec_type) {

	case REC_TYPE_PACKET:
		pinfo->current_proto = "Frame";
		if (pinfo->pseudo_header != NULL) {
			switch (pinfo->fd->lnk_t) {

			case WTAP_ENCAP_WFLEET_HDLC:
			case WTAP_ENCAP_CHDLC_WITH_PHDR:
			case WTAP_ENCAP_PPP_WITH_PHDR:
			case WTAP_ENCAP_SDLC:
			case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
				pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				break;

			case WTAP_ENCAP_BLUETOOTH_HCI:
				pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent;
				break;

			case WTAP_ENCAP_LAPB:
			case WTAP_ENCAP_FRELAY_WITH_PHDR:
				pinfo->p2p_dir =
				    (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
				    P2P_DIR_RECV : P2P_DIR_SENT;
				break;

			case WTAP_ENCAP_ISDN:
			case WTAP_ENCAP_V5_EF:
			case WTAP_ENCAP_DPNSS:
			case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR:
				pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				break;

			case WTAP_ENCAP_LINUX_LAPD:
				pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
					pinfo->pseudo_header->lapd.pkttype == 4) ?
					P2P_DIR_SENT : P2P_DIR_RECV;
				break;

			case WTAP_ENCAP_MTP2_WITH_PHDR:
				pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
				pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used;
				break;

			case WTAP_ENCAP_GSM_UM:
				pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				break;
			}
		}
		break;

	case REC_TYPE_FT_SPECIFIC_EVENT:
		pinfo->current_proto = "Event";
		break;

	case REC_TYPE_FT_SPECIFIC_REPORT:
		pinfo->current_proto = "Report";
		break;

	default:
		g_assert_not_reached();
		break;
	}

	if(pinfo->pkt_comment){
		item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, 0, ENC_NA);
		comments_tree = proto_item_add_subtree(item, ett_comments);
		comment_item = proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, 0,
							                   pinfo->pkt_comment, "%s",
							                   pinfo->pkt_comment);
		expert_add_info_format(pinfo, comment_item, &ei_comments_text,
					                       "%s",  pinfo->pkt_comment);


	}

	/* if FRAME is not referenced from any filters we don't need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_frame)) {
		tree=NULL;
		if(pinfo->fd->flags.has_ts) {
			if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000)
				expert_add_info(pinfo, NULL, &ei_arrive_time_out_of_range);
		}
	} else {
		proto_tree *fh_tree;
		gboolean old_visible;

		/* Put in frame header information. */
		cap_len = tvb_length(tvb);
		frame_len = tvb_reported_length(tvb);

		cap_plurality = plurality(cap_len, "", "s");
		frame_plurality = plurality(frame_len, "", "s");

		ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
		    "Frame %u: %u byte%s on wire",
		    pinfo->fd->num, frame_len, frame_plurality);
		if (generate_bits_field)
			proto_item_append_text(ti, " (%u bits)", frame_len * 8);
		proto_item_append_text(ti, ", %u byte%s captured",
		    cap_len, cap_plurality);
		if (generate_bits_field) {
			proto_item_append_text(ti, " (%u bits)",
			    cap_len * 8);
		}
		if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) {
			proto_item_append_text(ti, " on interface %u",
			    pinfo->phdr->interface_id);
		}
		if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
			if (pinfo->phdr->pack_flags & 0x00000001) {
				proto_item_append_text(ti, " (inbound)");
				pinfo->p2p_dir = P2P_DIR_RECV;
			}
			if (pinfo->phdr->pack_flags & 0x00000002) {
				proto_item_append_text(ti, " (outbound)");
				pinfo->p2p_dir = P2P_DIR_SENT;
			}
		}

		fh_tree = proto_item_add_subtree(ti, ett_frame);

		if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID && proto_field_is_referenced(tree, hf_frame_interface_id)) {
			const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id);

			if (interface_name)
				proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id, "%u (%s)", pinfo->phdr->interface_id, interface_name);
			else
				proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id);
		}

		if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
			proto_tree *flags_tree;
			proto_item *flags_item;

			flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pinfo->phdr->pack_flags);
			flags_tree = proto_item_add_subtree(flags_item, ett_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_direction, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->phdr->pack_flags);
		}

		if (pinfo->phdr->rec_type == REC_TYPE_PACKET)
			proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->fd->lnk_t);

		if (pinfo->fd->flags.has_ts) {
			proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
					    0, 0, &(pinfo->fd->abs_ts));
			if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) {
				expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range,
								  "Arrival Time: Fractional second %09ld is invalid,"
								  " the valid range is 0-1000000000",
								  (long) pinfo->fd->abs_ts.nsecs);
			}
			item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb,
					    0, 0, &(pinfo->fd->shift_offset));
			PROTO_ITEM_SET_GENERATED(item);

			if(generate_epoch_time) {
				proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb,
						    0, 0, &(pinfo->fd->abs_ts));
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta)) {
				nstime_t     del_cap_ts;

				frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->num - 1, &del_cap_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
							   0, 0, &(del_cap_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) {
				nstime_t del_dis_ts;

				frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->prev_dis_num, &del_dis_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
							   0, 0, &(del_dis_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
						   0, 0, &(pinfo->rel_ts));
			PROTO_ITEM_SET_GENERATED(item);

			if(pinfo->fd->flags.ref_time){
				ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA);
				PROTO_ITEM_SET_GENERATED(ti);
			}
		}

		proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
				    0, 0, pinfo->fd->num);

		proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
					   0, 0, frame_len, "Frame Length: %u byte%s (%u bits)",
					   frame_len, frame_plurality, frame_len * 8);

		proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
					   0, 0, cap_len, "Capture Length: %u byte%s (%u bits)",
					   cap_len, cap_plurality, cap_len * 8);

		if (generate_md5_hash) {
			const guint8 *cp;
			md5_state_t   md_ctx;
			md5_byte_t    digest[16];
			const gchar  *digest_string;

			cp = tvb_get_ptr(tvb, 0, cap_len);

			md5_init(&md_ctx);
			md5_append(&md_ctx, cp, cap_len);
			md5_finish(&md_ctx, digest);

			digest_string = bytestring_to_str(wmem_packet_scope(), digest, 16, '\0');
			ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
			PROTO_ITEM_SET_GENERATED(ti);
		}

		ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
		PROTO_ITEM_SET_GENERATED(ti);

		ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0,pinfo->fd->flags.ignored);
		PROTO_ITEM_SET_GENERATED(ti);

		if(proto_field_is_referenced(tree, hf_frame_protocols)) {
			/* we are going to be using proto_item_append_string() on
			 * hf_frame_protocols, and we must therefore disable the
			 * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
			 * setting it as visible.
			 *
			 * See proto.h for details.
			 */
			old_visible = proto_tree_set_visible(fh_tree, TRUE);
			ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, "");
			PROTO_ITEM_SET_GENERATED(ti);
			proto_tree_set_visible(fh_tree, old_visible);
		}

		/* Check for existences of P2P pseudo header */
		if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
			proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
					   0, 0, pinfo->p2p_dir);
		}

		/* Check for existences of MTP2 link number */
		if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
			proto_tree_add_uint(fh_tree, hf_link_number, tvb,
					    0, 0, pinfo->link_number);
		}

		if (show_file_off) {
			proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}

		if(pinfo->fd->color_filter != NULL) {
			const color_filter_t *color_filter = (const color_filter_t *)pinfo->fd->color_filter;
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
						     0, 0, color_filter->filter_name);
			PROTO_ITEM_SET_GENERATED(item);
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
						     0, 0, color_filter->filter_text);
			PROTO_ITEM_SET_GENERATED(item);
		}
	}

	if (pinfo->fd->flags.ignored) {
		/* Ignored package, stop handling here */
		col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
		proto_tree_add_text (tree, tvb, 0, 0, "This frame is marked as ignored");
		return;
	}

	/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
		/* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
		   like memory access violations.
		   (a running debugger will be called before the except part below) */
                /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                   stack in an inconsistent state thus causing a crash at some point in the
                   handling of the exception.
                   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                */
		__try {
#endif
			switch (pinfo->phdr->rec_type) {

			case REC_TYPE_PACKET:
				if ((force_docsis_encap) && (docsis_handle)) {
					call_dissector(docsis_handle, tvb, pinfo, parent_tree);
				} else {
					if (!dissector_try_uint(wtap_encap_dissector_table, pinfo->fd->lnk_t,
								tvb, pinfo, parent_tree)) {

						col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
						col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
							     pinfo->fd->lnk_t);
						call_dissector(data_handle,tvb, pinfo, parent_tree);
					}
				}
				break;

			case REC_TYPE_FT_SPECIFIC_EVENT:
			case REC_TYPE_FT_SPECIFIC_REPORT:
				if (!dissector_try_uint(wtap_fts_rec_dissector_table, pinfo->file_type_subtype,
							tvb, pinfo, parent_tree)) {

					col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
					col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
						     pinfo->file_type_subtype);
					call_dissector(data_handle,tvb, pinfo, parent_tree);
				}
				break;
			}
#ifdef _MSC_VER
		} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
			switch(GetExceptionCode()) {
			case(STATUS_ACCESS_VIOLATION):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
				break;
			case(STATUS_INTEGER_DIVIDE_BY_ZERO):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
				break;
			case(STATUS_STACK_OVERFLOW):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
				/* XXX - this will have probably corrupted the stack,
				   which makes problems later in the exception code */
				break;
				/* XXX - add other hardware exception codes as required */
			default:
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
			}
		}
#endif
	}
	CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

        if(proto_field_is_referenced(tree, hf_frame_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_sized_new(wmem_packet_scope(), 128, 0);
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		proto_item_append_string(ti, wmem_strbuf_get_str(val));
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
		TRY {
#ifdef _MSC_VER
			/* Win32: Visual-C Structured Exception Handling (SEH)
			   to trap hardware exceptions like memory access violations */
			/* (a running debugger will be called before the except part below) */
                        /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                           stack in an inconsistent state thus causing a crash at some point in the
                           handling of the exception.
                           See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                        */
			__try {
#endif
				call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
			} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
				switch(GetExceptionCode()) {
				case(STATUS_ACCESS_VIOLATION):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
					break;
				case(STATUS_INTEGER_DIVIDE_BY_ZERO):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
					break;
				case(STATUS_STACK_OVERFLOW):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
					/* XXX - this will have probably corrupted the stack,
					   which makes problems later in the exception code */
					break;
					/* XXX - add other hardware exception codes as required */
				default:
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
				}
			}
#endif
		}
		CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	tap_queue_packet(frame_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_frame_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}
}