CIP Safety: Minor Refactoring, Part 1
This commit is contained in:
parent
3c25b69ff6
commit
943c38d606
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* This dissector includes items from:
|
||||
* CIP Volume 1: Common Industrial Protocol, Edition 3.24
|
||||
* CIP Volume 5: CIP Safety, Edition 2.17
|
||||
* CIP Volume 5: CIP Safety, Edition 2.22
|
||||
*
|
||||
* Copyright 2011
|
||||
* Michael Mann <mmann@pyramidsolutions.com>
|
||||
|
@ -1501,6 +1501,103 @@ dissect_mcast_byte( proto_tree *tree, tvbuff_t *tvb, int offset)
|
|||
proto_tree_add_bitmask(tree, tvb, offset, hf_cipsafety_mcast_byte, ett_cipsafety_mcast_byte, bits, ENC_LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
// Base Format Time Correction Message
|
||||
static void dissect_base_format_time_correction_message(proto_tree* tree, tvbuff_t* tvb, int offset)
|
||||
{
|
||||
dissect_mcast_byte(tree, tvb, offset);
|
||||
proto_tree_add_item(tree, hf_cipsafety_time_correction, tvb, offset + 1, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_mcast_byte2, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s3, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
|
||||
|
||||
// TODO: Validate CRC S3.
|
||||
}
|
||||
|
||||
// Extended Format Time Correction Message
|
||||
static void dissect_extended_format_time_correction_message(proto_tree* tree, tvbuff_t* tvb, int offset)
|
||||
{
|
||||
dissect_mcast_byte(tree, tvb, offset);
|
||||
proto_tree_add_item(tree, hf_cipsafety_time_correction, tvb, offset + 1, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_0, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_1, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_2, tvb, offset + 5, 1, ENC_LITTLE_ENDIAN);
|
||||
|
||||
// TODO: Validate CRC S5.
|
||||
}
|
||||
|
||||
// Base Format, Time Stamp Section Format
|
||||
static void dissect_base_format_time_stamp_section(packet_info* pinfo, proto_tree* tree, tvbuff_t* tvb, int offset,
|
||||
gboolean compute_crc, guint8 mode_byte, const cip_connection_triad_t* connection_triad)
|
||||
{
|
||||
proto_tree_add_item(tree, hf_cipsafety_timestamp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
guint16 timestamp = tvb_get_letohs(tvb, offset);
|
||||
|
||||
if (compute_crc)
|
||||
{
|
||||
guint8 computed_crc_s1 = compute_crc_s1_timestamp(compute_crc_s1_pid(connection_triad),
|
||||
(mode_byte & MODE_BYTE_CRC_S1_TIME_STAMP_MASK),
|
||||
timestamp);
|
||||
proto_tree_add_checksum(tree, tvb, offset + 2,
|
||||
hf_cipsafety_crc_s1, hf_cipsafety_crc_s1_status, &ei_cipsafety_crc_s1, pinfo,
|
||||
computed_crc_s1, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, offset + 2,
|
||||
hf_cipsafety_crc_s1, hf_cipsafety_crc_s1_status, &ei_cipsafety_crc_s1,
|
||||
pinfo, 0, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
// Base Format Time Coordination Message
|
||||
// Note: All data starts from the beginning of the tvb buffer.
|
||||
static void dissect_base_format_time_coordination_message(packet_info* pinfo, proto_tree* tree, tvbuff_t* tvb,
|
||||
gboolean compute_crc, const cip_connection_triad_t* connection_triad)
|
||||
{
|
||||
dissect_ack_byte(tree, tvb, 0);
|
||||
guint8 ack_byte = tvb_get_guint8(tvb, 0);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_consumer_time_value, tvb, 1, 2, ENC_LITTLE_ENDIAN);
|
||||
guint16 timestamp = tvb_get_letohs(tvb, 1);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_ack_byte2, tvb, 3, 1, ENC_LITTLE_ENDIAN);
|
||||
|
||||
if (compute_crc)
|
||||
{
|
||||
guint16 computed_crc_s3 = compute_crc_s3_time(compute_crc_s3_pid(connection_triad), ack_byte, timestamp);
|
||||
proto_tree_add_checksum(tree, tvb, 4,
|
||||
hf_cipsafety_crc_s3, hf_cipsafety_crc_s3_status, &ei_cipsafety_crc_s3, pinfo,
|
||||
computed_crc_s3, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, 4,
|
||||
hf_cipsafety_crc_s3, hf_cipsafety_crc_s3_status, &ei_cipsafety_crc_s3,
|
||||
pinfo, 0, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
// Extended Format Time Coordination Message
|
||||
// Note: All data starts from the beginning of the tvb buffer.
|
||||
static void dissect_extended_format_time_coordination_message(packet_info* pinfo, proto_tree* tree, tvbuff_t* tvb,
|
||||
gboolean compute_crc, const cip_connection_triad_t* connection_triad)
|
||||
{
|
||||
dissect_ack_byte(tree, tvb, 0);
|
||||
guint8 ack_byte = tvb_get_guint8(tvb, 0);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_consumer_time_value, tvb, 1, 2, ENC_LITTLE_ENDIAN);
|
||||
guint16 timestamp = tvb_get_letohs(tvb, 1);
|
||||
|
||||
guint32 crc_s5_0, crc_s5_1, crc_s5_2;
|
||||
proto_tree_add_item_ret_uint(tree, hf_cipsafety_crc_s5_0, tvb, 3, 1, ENC_LITTLE_ENDIAN, &crc_s5_0);
|
||||
proto_tree_add_item_ret_uint(tree, hf_cipsafety_crc_s5_1, tvb, 4, 1, ENC_LITTLE_ENDIAN, &crc_s5_1);
|
||||
proto_tree_add_item_ret_uint(tree, hf_cipsafety_crc_s5_2, tvb, 5, 1, ENC_LITTLE_ENDIAN, &crc_s5_2);
|
||||
|
||||
guint32 computed_crc_s5 = compute_crc_s5_time(compute_crc_s5_pid(connection_triad),
|
||||
ack_byte,
|
||||
timestamp);
|
||||
validate_crc_s5(pinfo, tree, tvb, compute_crc, crc_s5_0, crc_s5_1, crc_s5_2, computed_crc_s5);
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int item_length, packet_info *pinfo, cip_safety_info_t* safety_info)
|
||||
{
|
||||
|
@ -1552,45 +1649,16 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
|
|||
}
|
||||
|
||||
/* consumer data */
|
||||
dissect_ack_byte(tree, tvb, 0);
|
||||
proto_tree_add_item(tree, hf_cipsafety_consumer_time_value, tvb, 1, 2, ENC_LITTLE_ENDIAN);
|
||||
timestamp = tvb_get_letohs(tvb, 1);
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case CIP_SAFETY_BASE_FORMAT:
|
||||
proto_tree_add_item(tree, hf_cipsafety_ack_byte2, tvb, 3, 1, ENC_LITTLE_ENDIAN);
|
||||
if (compute_crc)
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, 4,
|
||||
hf_cipsafety_crc_s3, hf_cipsafety_crc_s3_status, &ei_cipsafety_crc_s3, pinfo,
|
||||
compute_crc_s3_time(compute_crc_s3_pid(&connection_triad),
|
||||
tvb_get_guint8(tvb, 0), /* ack byte */
|
||||
timestamp),
|
||||
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, 4,
|
||||
hf_cipsafety_crc_s3, hf_cipsafety_crc_s3_status, &ei_cipsafety_crc_s3,
|
||||
pinfo, 0, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
|
||||
}
|
||||
dissect_base_format_time_coordination_message(pinfo, tree, tvb, compute_crc, &connection_triad);
|
||||
break;
|
||||
case CIP_SAFETY_EXTENDED_FORMAT:
|
||||
{
|
||||
guint32 crc_s5_0, crc_s5_1, crc_s5_2;
|
||||
proto_tree_add_item_ret_uint(tree, hf_cipsafety_crc_s5_0, tvb, 3, 1, ENC_LITTLE_ENDIAN, &crc_s5_0);
|
||||
proto_tree_add_item_ret_uint(tree, hf_cipsafety_crc_s5_1, tvb, 4, 1, ENC_LITTLE_ENDIAN, &crc_s5_1);
|
||||
proto_tree_add_item_ret_uint(tree, hf_cipsafety_crc_s5_2, tvb, 5, 1, ENC_LITTLE_ENDIAN, &crc_s5_2);
|
||||
|
||||
guint32 computed_crc_s5 = compute_crc_s5_time(compute_crc_s5_pid(&connection_triad),
|
||||
tvb_get_guint8(tvb, 0), /* ack byte */
|
||||
timestamp);
|
||||
validate_crc_s5(pinfo, tree, tvb, compute_crc, crc_s5_0, crc_s5_1, crc_s5_2, computed_crc_s5);
|
||||
|
||||
dissect_extended_format_time_coordination_message(pinfo, tree, tvb, compute_crc, &connection_triad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (((conn_type == ECIDT_O2T) && (server_dir == TRUE)) ||
|
||||
((conn_type == ECIDT_T2O) && (server_dir == FALSE)))
|
||||
|
@ -1649,35 +1717,16 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
|
|||
hf_cipsafety_crc_s2, hf_cipsafety_crc_s2_status, &ei_cipsafety_crc_s2,
|
||||
pinfo, 0, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
|
||||
}
|
||||
proto_tree_add_item(tree, hf_cipsafety_timestamp, tvb, io_data_size+3, 2, ENC_LITTLE_ENDIAN);
|
||||
timestamp = tvb_get_letohs(tvb, io_data_size+3);
|
||||
if (compute_crc)
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, io_data_size+5,
|
||||
hf_cipsafety_crc_s1, hf_cipsafety_crc_s1_status, &ei_cipsafety_crc_s1, pinfo,
|
||||
compute_crc_s1_timestamp(compute_crc_s1_pid(&connection_triad),
|
||||
(mode_byte & MODE_BYTE_CRC_S1_TIME_STAMP_MASK),
|
||||
timestamp),
|
||||
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, io_data_size+5,
|
||||
hf_cipsafety_crc_s1, hf_cipsafety_crc_s1_status, &ei_cipsafety_crc_s1,
|
||||
pinfo, 0, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
|
||||
}
|
||||
dissect_base_format_time_stamp_section(pinfo, tree, tvb, io_data_size + 3, compute_crc, mode_byte, &connection_triad);
|
||||
|
||||
if (multicast)
|
||||
{
|
||||
dissect_mcast_byte(tree, tvb, item_length-6);
|
||||
proto_tree_add_item(tree, hf_cipsafety_time_correction, tvb, item_length-5, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_mcast_byte2, tvb, item_length-3, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s3, tvb, item_length-2, 2, ENC_LITTLE_ENDIAN);
|
||||
dissect_base_format_time_correction_message(tree, tvb, item_length - 6);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Long Format (3-250 bytes I/O data) */
|
||||
/* 3 to 250 Byte Data section, Base Format */
|
||||
if (item_length%2 == 1)
|
||||
{
|
||||
/* Malformed packet */
|
||||
|
@ -1725,34 +1774,16 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
|
|||
hf_cipsafety_complement_crc_s3, hf_cipsafety_complement_crc_s3_status, &ei_cipsafety_complement_crc_s3,
|
||||
pinfo, 0, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
|
||||
}
|
||||
proto_tree_add_item(tree, hf_cipsafety_timestamp, tvb, (io_data_size*2)+5, 2, ENC_LITTLE_ENDIAN);
|
||||
timestamp = tvb_get_letohs(tvb, (io_data_size*2)+5);
|
||||
if (compute_crc)
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, (io_data_size*2)+7,
|
||||
hf_cipsafety_crc_s1, hf_cipsafety_crc_s1_status, &ei_cipsafety_crc_s1, pinfo,
|
||||
compute_crc_s1_timestamp(compute_crc_s1_pid(&connection_triad),
|
||||
(mode_byte & MODE_BYTE_CRC_S1_TIME_STAMP_MASK),
|
||||
timestamp),
|
||||
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_checksum(tree, tvb, (io_data_size*2)+7,
|
||||
hf_cipsafety_crc_s1, hf_cipsafety_crc_s1_status, &ei_cipsafety_crc_s1,
|
||||
pinfo, 0, ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
|
||||
}
|
||||
dissect_base_format_time_stamp_section(pinfo, tree, tvb, (io_data_size * 2) + 5, compute_crc, mode_byte, &connection_triad);
|
||||
|
||||
if (multicast)
|
||||
{
|
||||
dissect_mcast_byte(tree, tvb, (io_data_size*2)+5);
|
||||
proto_tree_add_item(tree, hf_cipsafety_time_correction, tvb, (io_data_size*2)+6, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_mcast_byte2, tvb, (io_data_size*2)+8, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s3, tvb, (io_data_size*2)+9, 2, ENC_LITTLE_ENDIAN);
|
||||
dissect_base_format_time_correction_message(tree, tvb, (io_data_size * 2) + 5);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CIP_SAFETY_EXTENDED_FORMAT:
|
||||
{
|
||||
if (short_format)
|
||||
{
|
||||
io_data_size = item_length-base_length;
|
||||
|
@ -1815,16 +1846,12 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
|
|||
|
||||
if (multicast)
|
||||
{
|
||||
dissect_mcast_byte(tree, tvb, item_length-6);
|
||||
proto_tree_add_item(tree, hf_cipsafety_time_correction, tvb, item_length-5, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_0, tvb, item_length-3, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_1, tvb, item_length-2, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_2, tvb, item_length-1, 1, ENC_LITTLE_ENDIAN);
|
||||
dissect_extended_format_time_correction_message(tree, tvb, item_length - 6);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Long Format (3-250 bytes I/O data) */
|
||||
/* 3 to 250 Byte Data section, Extended Format */
|
||||
if (item_length%2 == 1)
|
||||
{
|
||||
/* Malformed packet */
|
||||
|
@ -1899,15 +1926,12 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
|
|||
|
||||
if (multicast)
|
||||
{
|
||||
dissect_mcast_byte(tree, tvb, (io_data_size*2)+8);
|
||||
proto_tree_add_item(tree, hf_cipsafety_time_correction, tvb, (io_data_size*2)+9, 2, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_0, tvb, (io_data_size*2)+11, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_1, tvb, (io_data_size*2)+12, 1, ENC_LITTLE_ENDIAN);
|
||||
proto_tree_add_item(tree, hf_cipsafety_crc_s5_2, tvb, (io_data_size*2)+13, 1, ENC_LITTLE_ENDIAN);
|
||||
dissect_extended_format_time_correction_message(tree, tvb, (io_data_size * 2) + 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // END case CIP_SAFETY_EXTENDED_FORMAT
|
||||
} // END switch
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue