Example #1
0
static gboolean IsDFP_Frame(tvbuff_t *tvb)
{
	guint16 u16SFCRC16;
	guint8  u8SFPosition;
	guint8  u8SFDataLength   = 255;
	int offset = 0;
	guint32 u32SubStart;
	guint16 crc;
    gint tvb_len =0;

    offset += 2;    /*Skip first crc because data is no more available */
    tvb_len = tvb_length(tvb);
    if(offset + 4 > tvb_len)
        return FALSE;
    while(1) {
        u32SubStart = offset;

        u8SFPosition = tvb_get_guint8(tvb, offset);
        offset += 1;

        u8SFDataLength = tvb_get_guint8(tvb, offset);
        offset += 1;

        if(u8SFDataLength == 0) {
            break;
        }

        offset += 1;

        offset += 1;

        offset += u8SFDataLength;
       if(offset > tvb_len)
           return /*TRUE; */FALSE;

        u16SFCRC16 = tvb_get_letohs(tvb, offset);
        if(u16SFCRC16 != 0){
            if(u8SFPosition & 0x80) {
                crc = crc16_plain_tvb_offset(tvb, u32SubStart, offset-u32SubStart);
                if(crc != u16SFCRC16) {
                    return FALSE;
                } else {
                }
            } else {
            }
        }
        offset += 2;
    }
    return TRUE;
}
/* possibly dissect a CSF_SDU related PN-RT packet */
static gboolean
dissect_CSF_SDU_heur(tvbuff_t *tvb,
	packet_info *pinfo, proto_tree *tree)
{
	guint16 u16FrameID;
	guint16 u16SFCRC16;
	guint8  u8SFPosition;
	guint8  u8SFDataLength = 255;
	guint8  u8SFCycleCounter;
	guint8  u8SFDataStatus;
	int offset = 0;
	guint32 u32SubStart;
    proto_item *sub_item;
    proto_tree *sub_tree;
    proto_item *item;
	guint16 crc;


    /* the sub tvb will NOT contain the frame_id here! */
    u16FrameID = GPOINTER_TO_UINT(pinfo->private_data);

	/* possible FrameID ranges for DFP */
	if ((u16FrameID >= 0x0500 && u16FrameID < 0x05ff) ||
	    (u16FrameID >= 0x0600 && u16FrameID < 0x07ff) ||
	    (u16FrameID >= 0x4800 && u16FrameID < 0x4fff) ||
	    (u16FrameID >= 0x5800 && u16FrameID < 0x5fff) ||
	    (u16FrameID >= 0x6800 && u16FrameID < 0x6fff) ||
	    (u16FrameID >= 0x7800 && u16FrameID < 0x7fff)) {
		/* can't check this CRC, as the checked data bytes are not available */
		u16SFCRC16 = tvb_get_letohs(tvb, offset);
		proto_tree_add_uint(tree, hf_pn_rt_sf_crc16, tvb, offset, 2, u16SFCRC16);
		offset += 2;

		while(1) {
			sub_item = proto_tree_add_item(tree, hf_pn_rt_sf, tvb, offset, 0, FALSE);
			sub_tree = proto_item_add_subtree(sub_item, ett_pn_rt_sf);
			u32SubStart = offset;

			u8SFPosition = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(sub_tree, hf_pn_rt_sf_position_control, tvb, offset, 1, u8SFPosition);
			proto_tree_add_uint(sub_tree, hf_pn_rt_sf_position, tvb, offset, 1, u8SFPosition);
			offset += 1;

			u8SFDataLength = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(sub_tree, hf_pn_rt_sf_data_length, tvb, offset, 1, u8SFDataLength);
			offset += 1;

			if(u8SFDataLength == 0) {
				proto_item_append_text(sub_item, ": Pos:%u, Length:%u", u8SFPosition, u8SFDataLength);
				proto_item_set_len(sub_item, offset - u32SubStart);
				break;
			}

			u8SFCycleCounter = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(sub_tree, hf_pn_rt_sf_cycle_counter, tvb, offset, 1, u8SFCycleCounter);
			offset += 1;

			u8SFDataStatus = tvb_get_guint8(tvb, offset);
			dissect_DataStatus(tvb, offset, sub_tree, u8SFDataStatus);
			offset += 1;

			offset = dissect_pn_user_data(tvb, offset, pinfo, sub_tree, u8SFDataLength, "DataItem");

			u16SFCRC16 = tvb_get_letohs(tvb, offset);
			item = proto_tree_add_uint(sub_tree, hf_pn_rt_sf_crc16, tvb, offset, 2, u16SFCRC16);

			if(u8SFPosition & 0x80) {
				crc = crc16_plain_tvb_offset(tvb, u32SubStart, offset-u32SubStart);
				if(crc != u16SFCRC16) {
					proto_item_append_text(item, " [Preliminary check: incorrect, should be: %u]", crc);
					expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
				} else {
					proto_item_append_text(item, " [Preliminary check: Correct]");
				}
			} else {
				proto_item_append_text(item, " [No preliminary check, Control bit not set]");
			}
			offset += 2;

			proto_item_append_text(sub_item, ": Pos:%u, Length:%u, Cycle:%u, Status: 0x%02x (%s,%s,%s,%s)",
				u8SFPosition, u8SFDataLength, u8SFCycleCounter, u8SFDataStatus,
				(u8SFDataStatus & 0x04) ? "Valid" : "Invalid",
				(u8SFDataStatus & 0x01) ? "Primary" : "Backup",
				(u8SFDataStatus & 0x20) ? "Ok" : "Problem",
				(u8SFDataStatus & 0x10) ? "Run" : "Stop");

			proto_item_set_len(sub_item, offset - u32SubStart);
		}

        return TRUE;
    }

    return FALSE;

}