示例#1
0
/** Checksums the data. */
static tvbuff_t *
checksum_data(tvbuff_t *tvb, proto_tree *tree)
{
    proto_item *hidden_item;
    int len = tvb_length(tvb) - 2;
    if (len < 0)
        return tvb;
    if (tree) {
        guint16 actual_fcs = tvb_get_letohs(tvb, len);
        guint16 calculated_fcs = crc16_ccitt_tvb(tvb, len);
        if (calculated_fcs == actual_fcs) {
            proto_tree_add_uint_format(tree, hf_sir_fcs,
                                       tvb, len, 2, actual_fcs,
                                       "Frame check sequence: 0x%04x (correct)",
                                       actual_fcs);
        } else {
            hidden_item = proto_tree_add_boolean(tree,
                                                 hf_sir_fcs_bad, tvb, len, 2, TRUE);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
            proto_tree_add_uint_format(tree, hf_sir_fcs,
                                       tvb, len, 2, actual_fcs,
                                       "Frame check sequence: 0x%04x "
                                       "(incorrect, should be 0x%04x)",
                                       actual_fcs, calculated_fcs);
        }
    }
    return tvb_new_subset_length(tvb, 0, len);
}
示例#2
0
static void dissect_srp (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
    proto_item *srp_item = NULL;
    proto_tree *srp_tree = NULL;
    proto_item *hidden_item;

    guint8 header = tvb_get_guint8(tvb,0);

    /* add the 'srp' tree to the main tree */
    if (tree) {
	srp_item = proto_tree_add_item (tree, proto_srp, tvb, 0, -1, ENC_NA);
	srp_tree = proto_item_add_subtree (srp_item, ett_srp);
	proto_tree_add_uint(srp_tree,hf_srp_header,tvb,0,1,header);
    }

    switch( header ) {
	case SRP_SRP_COMMAND:
	    dissect_srp_command(tvb,pinfo,srp_tree);
	    break;

	case SRP_SRP_RESPONSE:
	    break;

	case SRP_NSRP_RESPONSE:
	    if( srp_tree )
		proto_tree_add_item(srp_tree,hf_srp_seqno,tvb,1,1,ENC_BIG_ENDIAN);
	    break;

	default:
	    break;
    }

    if( srp_tree ) {
	guint16 crc, calc_crc;
	guint crc_offset = tvb_reported_length(tvb)-2;
	crc = tvb_get_letohs(tvb,-2);

	/* crc includes the header */
	calc_crc = crc16_ccitt_tvb(tvb,crc_offset);

	if( crc == calc_crc ) {
	    proto_tree_add_uint_format(srp_tree, hf_srp_crc, tvb,
				       crc_offset, 2, crc,
				       "CRC: 0x%04x (correct)", crc);
	} else {
	    hidden_item = proto_tree_add_boolean(srp_tree, hf_srp_crc_bad, tvb,
					  crc_offset, 2, TRUE);
	    PROTO_ITEM_SET_HIDDEN(hidden_item);
	    proto_tree_add_uint_format(srp_tree, hf_srp_crc, tvb,
				       crc_offset, 2, crc,
				       "CRC: 0x%04x (incorrect, should be 0x%04x)",
				       crc,
				       calc_crc);
	}
    }

}
示例#3
0
/*
*******************************************************************************
* DETAILS : Calculate a new FCS-16 given the current FCS-16 and the new data.
*******************************************************************************
*/
static guint16
mtp2_fcs16(tvbuff_t * tvbuff)
{
    guint len = tvb_captured_length(tvbuff)-2;

    /* Check for Invalid Length */
    if (len == 0)
        return (0x0000);
    return crc16_ccitt_tvb(tvbuff, len);
}
示例#4
0
/** Checksums the data. */
static tvbuff_t *
checksum_data(tvbuff_t *tvb, proto_tree *tree)
{
	int len = tvb_reported_length(tvb) - 2;
	if (len < 0)
		return tvb;

	proto_tree_add_checksum(tree, tvb, len, hf_sir_fcs, hf_sir_fcs_status, NULL, NULL, crc16_ccitt_tvb(tvb, len),
								ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);

	return tvb_new_subset_length(tvb, 0, len);
}
示例#5
0
static void
dissect_v5dl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*v5dl_tree, *addr_tree;
	proto_item	*v5dl_ti, *addr_ti;
	int		direction;
	guint		v5dl_header_len;
	guint16		control;
#if 0
	proto_tree	*checksum_tree;
	proto_item	*checksum_ti;
	guint16		checksum, checksum_calculated;
	guint		checksum_offset;
#endif
	guint16		addr, cr, eah, eal, v5addr;
	gboolean	is_response = 0;
#if 0
	guint		length, reported_length;
#endif
	tvbuff_t	*next_tvb;
	const char	*srcname = "?";
	const char	*dstname = "?";

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

	addr = tvb_get_ntohs(tvb, 0);
	cr = addr & V5DL_CR;
	eal = (addr & V5DL_EAL) >> V5DL_EAL_SHIFT;
	eah = (addr & V5DL_EAH) >> V5DL_EAH_SHIFT;
	v5addr = (eah << 7) + eal;
	v5dl_header_len = 2;	/* addr */

	direction = pinfo->p2p_dir;
	if (pinfo->p2p_dir == P2P_DIR_RECV) {
	    is_response = cr ? FALSE : TRUE;
	    srcname = "Network";
	    dstname = "User";
	}
	else if (pinfo->p2p_dir == P2P_DIR_SENT) {
	    is_response = cr ? TRUE : FALSE;
	    srcname = "User";
	    dstname = "Network";
	}

	col_set_str(pinfo->cinfo, COL_RES_DL_SRC, srcname);
	col_set_str(pinfo->cinfo, COL_RES_DL_DST, dstname);

	if (tree) {
		proto_item *direction_ti;

		v5dl_ti = proto_tree_add_item(tree, proto_v5dl, tvb, 0, -1,
		    ENC_NA);
		v5dl_tree = proto_item_add_subtree(v5dl_ti, ett_v5dl);

		/*
		 * Don't show the direction if we don't know it.
		 */
		if (direction != P2P_DIR_UNKNOWN) {
			direction_ti = proto_tree_add_uint(v5dl_tree, hf_v5dl_direction,
			                                   tvb, 0, 0, pinfo->p2p_dir);
			PROTO_ITEM_SET_GENERATED(direction_ti);
		}

		addr_ti = proto_tree_add_uint(v5dl_tree, hf_v5dl_ef, tvb,
		    0, 2, v5addr);
		addr_tree = proto_item_add_subtree(addr_ti, ett_v5dl_address);
		proto_tree_add_uint(addr_tree, hf_v5dl_eah, tvb, 0, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_cr,  tvb, 0, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_ea1, tvb, 0, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_eal, tvb, 1, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_ea2, tvb, 1, 1, addr);
	}
	else {
		v5dl_ti = NULL;
		v5dl_tree = NULL;
	}

	control = dissect_xdlc_control(tvb, 2, pinfo, v5dl_tree, hf_v5dl_control,
	    ett_v5dl_control, &v5dl_cf_items, &v5dl_cf_items_ext, NULL, NULL,
	    is_response, TRUE, FALSE);
	v5dl_header_len += XDLC_CONTROL_LEN(control, TRUE);

	if (tree)
		proto_item_set_len(v5dl_ti, v5dl_header_len);

	/*
	 * XXX - the sample capture supplied with bug 7027 does not
	 * appear to include checksums in the packets.
	 */
#if 0
	/*
	 * Check the checksum, if available.
	 * The checksum is a CCITT CRC-16 at the end of the packet, so
	 * if we don't have the entire packet in the capture - i.e., if
	 * tvb_captured_length(tvb) != tvb_reported_length(tvb) we can't check it.
	 */
	length = tvb_captured_length(tvb);
	reported_length = tvb_reported_length(tvb);

	/*
	 * If the reported length isn't big enough for the V5DL header
	 * and 2 bytes of checksum, the packet is malformed, as the
	 * checksum overlaps the header.
	 */
	if (reported_length < v5dl_header_len + 2)
		THROW(ReportedBoundsError);

	if (length == reported_length) {
		/*
		 * There's no snapshot length cutting off any of the
		 * packet.
		 */
		checksum_offset = reported_length - 2;
		checksum = tvb_get_ntohs(tvb, checksum_offset);
		checksum_calculated = crc16_ccitt_tvb(tvb, checksum_offset);
		checksum_calculated = g_htons(checksum_calculated);  /* Note: g_htons() macro may eval arg multiple times */

		if (checksum == checksum_calculated) {
			checksum_ti = proto_tree_add_uint_format_value(v5dl_tree, hf_v5dl_checksum, tvb, checksum_offset,
								 2, 0,
								 "0x%04x [correct]",
								 checksum);
			checksum_tree = proto_item_add_subtree(checksum_ti, ett_v5dl_checksum);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_good, tvb, checksum_offset, 2, TRUE);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_bad, tvb, checksum_offset, 2, FALSE);
		} else {
			checksum_ti = proto_tree_add_uint_format_value(v5dl_tree, hf_v5dl_checksum, tvb, checksum_offset,
								 2, 0,
								 "0x%04x [incorrect, should be 0x%04x]",
								 checksum, checksum_calculated);
			checksum_tree = proto_item_add_subtree(checksum_ti, ett_v5dl_checksum);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_good, tvb, checksum_offset, 2, FALSE);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_bad, tvb, checksum_offset, 2, TRUE);
		}

		/*
		 * Remove the V5DL header *and* the checksum.
		 */
		next_tvb = tvb_new_subset(tvb, v5dl_header_len,
		    tvb_captured_length_remaining(tvb, v5dl_header_len) - 2,
		    tvb_reported_length_remaining(tvb, v5dl_header_len) - 2);
	} else {
		/*
		 * Some or all of the packet is cut off by a snapshot
		 * length.
		 */
		if (length == reported_length - 1) {
			/*
			 * One byte is cut off, so there's only one
			 * byte of checksum in the captured data.
			 * Remove that byte from the captured length
			 * and both bytes from the reported length.
			 */
			next_tvb = tvb_new_subset(tvb, v5dl_header_len,
			    tvb_captured_length_remaining(tvb, v5dl_header_len) - 1,
			    tvb_reported_length_remaining(tvb, v5dl_header_len) - 2);
		} else {
			/*
			 * Two or more bytes are cut off, so there are
			 * no bytes of checksum in the captured data.
			 * Just remove the checksum from the reported
			 * length.
			 */
			next_tvb = tvb_new_subset(tvb, v5dl_header_len,
			    tvb_captured_length_remaining(tvb, v5dl_header_len),
			    tvb_reported_length_remaining(tvb, v5dl_header_len) - 2);
		}
	}
#else
	next_tvb = tvb_new_subset_remaining(tvb, v5dl_header_len);
#endif

	if (XDLC_IS_INFORMATION(control)) {
		/* call V5.2 dissector */
	        call_dissector(v52_handle, next_tvb, pinfo, tree);
	}
}