* Routines for Common Industrial Protocol (CIP) dissection
* CIP Home: www.odva.org
*
+ * This dissector includes items from:
+ * CIP Volume 1: Common Industrial Protocol
+ * CIP Volume 5: CIP Safety
+ *
* Copyright 2004
* Magnus Hansson <mah@hms.se>
* Joakim Wiberg <jow@hms.se>
proto_tree_add_uint(cmd_tree, hf_cip_cm_timeout, tvb, offset, 2, timeout);
}
+static void dissect_connection_triad(tvbuff_t *tvb, int offset, proto_tree *tree,
+ int hf_conn_serial, int hf_vendor, int hf_orig_serial,
+ cip_connection_triad_t *triad)
+{
+ guint32 ConnSerialNumber;
+ guint32 VendorID;
+ guint32 DeviceSerialNumber;
+
+ proto_tree_add_item_ret_uint(tree, hf_conn_serial, tvb, offset, 2, ENC_LITTLE_ENDIAN, &ConnSerialNumber);
+ proto_tree_add_item_ret_uint(tree, hf_vendor, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN, &VendorID);
+ proto_tree_add_item_ret_uint(tree, hf_orig_serial, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN, &DeviceSerialNumber);
+
+ if (triad)
+ {
+ triad->ConnSerialNumber = ConnSerialNumber;
+ triad->VendorID = VendorID;
+ triad->DeviceSerialNumber = DeviceSerialNumber;
+ }
+}
+
static void
dissect_cip_cm_fwd_open_req(cip_req_info_t *preq_info, proto_tree *cmd_tree, tvbuff_t *tvb, int offset, gboolean large_fwd_open, packet_info *pinfo)
{
proto_item *pi;
proto_tree *epath_tree;
int conn_path_size, rpi, net_param_offset = 0;
- guint32 O2TConnID, T2OConnID, DeviceSerialNumber;
- guint16 ConnSerialNumber, VendorID;
+ guint32 O2TConnID, T2OConnID;
guint8 TransportClass_trigger, O2TType, T2OType;
cip_simple_request_info_t connection_path;
cip_safety_epath_info_t safety_fwdopen;
proto_tree_add_item_ret_uint( cmd_tree, hf_cip_cm_ot_connid, tvb, offset+2, 4, ENC_LITTLE_ENDIAN, &O2TConnID);
proto_tree_add_item_ret_uint( cmd_tree, hf_cip_cm_to_connid, tvb, offset+6, 4, ENC_LITTLE_ENDIAN, &T2OConnID);
- ConnSerialNumber = tvb_get_letohs( tvb, offset+10 );
- proto_tree_add_item( cmd_tree, hf_cip_cm_conn_serial_num, tvb, offset+10, 2, ENC_LITTLE_ENDIAN);
- VendorID = tvb_get_letohs( tvb, offset+12 );
- proto_tree_add_item( cmd_tree, hf_cip_cm_vendor, tvb, offset+12, 2, ENC_LITTLE_ENDIAN);
+ cip_connection_triad_t conn_triad;
+ dissect_connection_triad(tvb, offset + 10, cmd_tree,
+ hf_cip_cm_conn_serial_num, hf_cip_cm_vendor, hf_cip_cm_orig_serial_num,
+ &conn_triad);
- proto_tree_add_item_ret_uint( cmd_tree, hf_cip_cm_orig_serial_num, tvb, offset+14, 4, ENC_LITTLE_ENDIAN, &DeviceSerialNumber);
proto_tree_add_item( cmd_tree, hf_cip_cm_timeout_multiplier, tvb, offset+18, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item( cmd_tree, hf_cip_reserved24, tvb, offset+19, 3, ENC_LITTLE_ENDIAN);
{
/* "Connection" is created during ForwardOpen reply (which will be after ForwardOpen request),
so ForwardOpen request can only be marked after the first pass */
- enip_mark_connection_triad(pinfo, ConnSerialNumber, VendorID, DeviceSerialNumber);
+ enip_mark_connection_triad(pinfo, &conn_triad);
}
else
{
DISSECTOR_ASSERT(preq_info->connInfo == NULL);
preq_info->connInfo = wmem_new0(wmem_file_scope(), cip_conn_info_t);
- preq_info->connInfo->ConnSerialNumber = ConnSerialNumber;
- preq_info->connInfo->VendorID = VendorID;
- preq_info->connInfo->DeviceSerialNumber = DeviceSerialNumber;
+ preq_info->connInfo->triad = conn_triad;
preq_info->connInfo->forward_open_frame = pinfo->num;
preq_info->connInfo->O2T.connID = O2TConnID;
preq_info->connInfo->T2O.connID = T2OConnID;
{
int temp_data;
unsigned char app_rep_size;
- guint32 O2TConnID, T2OConnID, DeviceSerialNumber, target_device_sn = 0;
- guint16 ConnSerialNumber, VendorID, init_rollover_value = 0, init_timestamp_value = 0,
- target_conn_sn = 0, target_vendorID = 0;
+ guint32 O2TConnID, T2OConnID;
+ guint16 init_rollover_value = 0, init_timestamp_value = 0;
proto_tree *pid_tree, *safety_tree;
+ cip_connection_triad_t target_triad;
+ memset(&target_triad, 0, sizeof(target_triad));
/* Display originator to target connection ID */
O2TConnID = tvb_get_letohl( tvb, offset );
T2OConnID = tvb_get_letohl( tvb, offset+4 );
proto_tree_add_item( tree, hf_cip_cm_to_connid, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
- /* Display connection serial number */
- ConnSerialNumber = tvb_get_letohs( tvb, offset+8 );
- proto_tree_add_item( tree, hf_cip_cm_conn_serial_num, tvb, offset+8, 2, ENC_LITTLE_ENDIAN);
-
- /* Display the originator vendor id */
- VendorID = tvb_get_letohs( tvb, offset+10 );
- proto_tree_add_item( tree, hf_cip_cm_vendor, tvb, offset+10, 2, ENC_LITTLE_ENDIAN);
-
- /* Display the originator serial number */
- DeviceSerialNumber = tvb_get_letohl( tvb, offset+12 );
- proto_tree_add_item( tree, hf_cip_cm_orig_serial_num, tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
+ cip_connection_triad_t conn_triad;
+ dissect_connection_triad(tvb, offset + 8, tree,
+ hf_cip_cm_conn_serial_num, hf_cip_cm_vendor, hf_cip_cm_orig_serial_num,
+ &conn_triad);
/* Display originator to target actual packet interval */
temp_data = tvb_get_letohl( tvb, offset+16 );
proto_tree_add_item( safety_tree, hf_cip_cm_consumer_number, tvb, offset+26, 2, ENC_LITTLE_ENDIAN);
pid_tree = proto_tree_add_subtree( safety_tree, tvb, offset+28, 8, ett_cip_cm_pid, NULL, "PID/CID");
proto_tree_add_item( pid_tree, hf_cip_cm_targ_vendor_id, tvb, offset+28, 2, ENC_LITTLE_ENDIAN);
- target_vendorID = tvb_get_letohs(tvb, offset+28);
- proto_tree_add_item_ret_uint( pid_tree, hf_cip_cm_targ_dev_serial_num, tvb, offset+30, 4, ENC_LITTLE_ENDIAN, &target_device_sn);
+ target_triad.VendorID = tvb_get_letohs(tvb, offset+28);
+
+ proto_tree_add_item_ret_uint( pid_tree, hf_cip_cm_targ_dev_serial_num, tvb, offset+30, 4, ENC_LITTLE_ENDIAN, &target_triad.DeviceSerialNumber);
+
proto_tree_add_item( pid_tree, hf_cip_cm_targ_conn_serial_num, tvb, offset+34, 2, ENC_LITTLE_ENDIAN);
- target_conn_sn = tvb_get_letohs(tvb, offset+34);
+ target_triad.ConnSerialNumber = tvb_get_letohs(tvb, offset+34);
if (app_rep_size > 10)
proto_tree_add_item(tree, hf_cip_cm_app_reply_data, tvb, offset+36, app_rep_size-10, ENC_NA );
proto_tree_add_item( safety_tree, hf_cip_cm_consumer_number, tvb, offset+26, 2, ENC_LITTLE_ENDIAN);
pid_tree = proto_tree_add_subtree( safety_tree, tvb, offset+28, 12, ett_cip_cm_pid, NULL, "PID/CID");
proto_tree_add_item( pid_tree, hf_cip_cm_targ_vendor_id, tvb, offset+28, 2, ENC_LITTLE_ENDIAN);
- target_vendorID = tvb_get_letohs(tvb, offset+28);
- proto_tree_add_item_ret_uint( pid_tree, hf_cip_cm_targ_dev_serial_num, tvb, offset+30, 4, ENC_LITTLE_ENDIAN, &target_device_sn);
+ target_triad.VendorID = tvb_get_letohs(tvb, offset+28);
+
+ proto_tree_add_item_ret_uint( pid_tree, hf_cip_cm_targ_dev_serial_num, tvb, offset+30, 4, ENC_LITTLE_ENDIAN, &target_triad.DeviceSerialNumber);
+
proto_tree_add_item( pid_tree, hf_cip_cm_targ_conn_serial_num, tvb, offset+34, 2, ENC_LITTLE_ENDIAN);
- target_conn_sn = tvb_get_letohs(tvb, offset+34);
+ target_triad.ConnSerialNumber = tvb_get_letohs(tvb, offset+34);
proto_tree_add_item( pid_tree, hf_cip_cm_initial_timestamp, tvb, offset+36, 2, ENC_LITTLE_ENDIAN);
init_timestamp_value = tvb_get_letohs(tvb, offset+36);
if ((preq_info != NULL) && (preq_info->connInfo != NULL))
{
/* Ensure the connection triad matches before updating the connection IDs */
- if ((preq_info->connInfo->ConnSerialNumber == ConnSerialNumber) &&
- (preq_info->connInfo->VendorID == VendorID) &&
- (preq_info->connInfo->DeviceSerialNumber == DeviceSerialNumber))
+ if ((preq_info->connInfo->triad.ConnSerialNumber == conn_triad.ConnSerialNumber) &&
+ (preq_info->connInfo->triad.VendorID == conn_triad.VendorID) &&
+ (preq_info->connInfo->triad.DeviceSerialNumber == conn_triad.DeviceSerialNumber))
{
/* Update the connection IDs as ForwardOpen reply is allowed to update them from
the ForwardOpen request */
{
preq_info->connInfo->safety.running_rollover_value = init_rollover_value;
preq_info->connInfo->safety.running_timestamp_value = init_timestamp_value;
- preq_info->connInfo->safety.target_conn_sn = target_conn_sn;
- preq_info->connInfo->safety.target_vendorID = target_vendorID;
- preq_info->connInfo->safety.target_device_sn = target_device_sn;
+ preq_info->connInfo->safety.target_triad = target_triad;
}
}
}
int i, msg_req_siz;
cip_req_info_t *preq_info;
cip_req_info_t *pembedded_req_info;
- guint16 ConnSerialNumber, VendorID;
- guint32 DeviceSerialNumber;
service = tvb_get_guint8( tvb, offset );
case SC_CM_FWD_CLOSE:
{
/* Forward close response (Success) */
-
- /* Display connection serial number */
- ConnSerialNumber = tvb_get_letohs( tvb, offset+4+add_stat_size );
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_conn_serial_num, tvb, offset+4+add_stat_size, 2, ENC_LITTLE_ENDIAN);
-
- /* Display the originator vendor id */
- VendorID = tvb_get_letohs( tvb, offset+4+add_stat_size+2 );
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+4+add_stat_size+2, 2, ENC_LITTLE_ENDIAN);
-
- /* Display the originator serial number */
- DeviceSerialNumber = tvb_get_letohl( tvb, offset+4+add_stat_size+4 );
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_orig_serial_num, tvb, offset+4+add_stat_size+4, 4, ENC_LITTLE_ENDIAN);
+ cip_connection_triad_t conn_triad;
+ dissect_connection_triad(tvb, offset + 4 + add_stat_size, cmd_data_tree,
+ hf_cip_cm_conn_serial_num, hf_cip_cm_vendor, hf_cip_cm_orig_serial_num,
+ &conn_triad);
/* Display the application reply size */
app_rep_size = tvb_get_guint8( tvb, offset+4+add_stat_size+8 ) * 2;
proto_tree_add_item(cmd_data_tree, hf_cip_cm_app_reply_data, tvb, offset+4+add_stat_size+10,app_rep_size, ENC_NA);
}
- enip_close_cip_connection( pinfo, ConnSerialNumber, VendorID, DeviceSerialNumber );
+ enip_close_cip_connection( pinfo, &conn_triad);
} /* End of if forward close response */
break;
proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_coo_conn, tvb, offset+4+add_stat_size+1, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_roo_conn, tvb, offset+4+add_stat_size+2, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_last_action, tvb, offset+4+add_stat_size+3, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_conn_serial_num, tvb, offset+4+add_stat_size+4, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+4+add_stat_size+6, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_orig_serial_num, tvb, offset+4+add_stat_size+8, 4, ENC_LITTLE_ENDIAN);
+
+ dissect_connection_triad(tvb, offset + 4 + add_stat_size + 4, cmd_data_tree,
+ hf_cip_cm_conn_serial_num, hf_cip_cm_vendor, hf_cip_cm_orig_serial_num,
+ NULL);
}
break;
default:
case SC_CM_FWD_OPEN:
case SC_CM_LARGE_FWD_OPEN:
case SC_CM_FWD_CLOSE:
-
+ {
/* Forward open and forward close error response look the same */
- ConnSerialNumber = tvb_get_letohs( tvb, offset+4+add_stat_size );
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_conn_serial_num, tvb, offset+4+add_stat_size, 2, ENC_LITTLE_ENDIAN);
- VendorID = tvb_get_letohs( tvb, offset+4+add_stat_size+2 );
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+4+add_stat_size+2, 2, ENC_LITTLE_ENDIAN);
- DeviceSerialNumber = tvb_get_letohl( tvb, offset+4+add_stat_size+4 );
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_orig_serial_num, tvb, offset+4+add_stat_size+4, 4, ENC_LITTLE_ENDIAN);
+ cip_connection_triad_t conn_triad;
+ dissect_connection_triad(tvb, offset + 4 + add_stat_size, cmd_data_tree,
+ hf_cip_cm_conn_serial_num, hf_cip_cm_vendor, hf_cip_cm_orig_serial_num,
+ &conn_triad);
+
proto_tree_add_item(cmd_data_tree, hf_cip_cm_remain_path_size, tvb, offset+4+add_stat_size+8, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+4+add_stat_size+9, 1, ENC_LITTLE_ENDIAN);
/* With an error reply the connection will either never be established or it has since already closed
That means the conversation should end too */
- enip_close_cip_connection(pinfo, ConnSerialNumber, VendorID, DeviceSerialNumber);
+ enip_close_cip_connection(pinfo, &conn_triad);
if (preq_info != NULL)
{
/* Remove any connection information */
preq_info->connInfo = NULL;
}
break;
+ }
case SC_CM_UNCON_SEND:
/* Unconnected send response (Unsuccess) */
proto_tree_add_item(cmd_data_tree, hf_cip_cm_remain_path_size, tvb, offset+4+add_stat_size, 1, ENC_LITTLE_ENDIAN);
/* Forward Close Request */
dissect_cip_cm_timeout( cmd_data_tree, tvb, offset+2+req_path_size);
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_conn_serial_num, tvb, offset+2+req_path_size+2, 2, ENC_LITTLE_ENDIAN);
- ConnSerialNumber = tvb_get_letohs( tvb, offset+2+req_path_size+2);
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+2+req_path_size+4, 2, ENC_LITTLE_ENDIAN);
- VendorID = tvb_get_letohs( tvb, offset+2+req_path_size+4 );
- proto_tree_add_item( cmd_data_tree, hf_cip_cm_orig_serial_num, tvb, offset+2+req_path_size+6, 4, ENC_LITTLE_ENDIAN);
- DeviceSerialNumber = tvb_get_letohl( tvb, offset+2+req_path_size+6 );
+
+ cip_connection_triad_t conn_triad;
+ dissect_connection_triad(tvb, offset + 2 + req_path_size + 2, cmd_data_tree,
+ hf_cip_cm_conn_serial_num, hf_cip_cm_vendor, hf_cip_cm_orig_serial_num,
+ &conn_triad);
if (!pinfo->fd->flags.visited)
- enip_mark_connection_triad(pinfo, ConnSerialNumber, VendorID, DeviceSerialNumber);
+ enip_mark_connection_triad(pinfo, &conn_triad);
/* Add the path size */
conn_path_size = tvb_get_guint8( tvb, offset+2+req_path_size+10 )*2;
* CRC handling
*
************************************************/
-static guint8 compute_crc_s1_pid(guint16 conn_serial_number, guint16 vendor_id, guint32 device_serial_number)
+static guint8 compute_crc_s1_pid(const cip_connection_triad_t* triad)
{
guint8 temp_buf[8];
- memcpy(temp_buf, &vendor_id, 2);
- memcpy(&temp_buf[2], &device_serial_number, 4);
- memcpy(&temp_buf[6], &conn_serial_number, 2);
+ memcpy(temp_buf, &triad->VendorID, 2);
+ memcpy(&temp_buf[2], &triad->DeviceSerialNumber, 4);
+ memcpy(&temp_buf[6], &triad->ConnSerialNumber, 2);
return crc8_0x37(temp_buf, 8, 0);
}
return crc8_0x3B(comp_buf, len, mode_byte_crc);
}
-static guint16 compute_crc_s3_pid(guint16 conn_serial_number, guint16 vendor_id, guint32 device_serial_number)
+static guint16 compute_crc_s3_pid(const cip_connection_triad_t* triad)
{
guint8 temp_buf[8];
- memcpy(temp_buf, &vendor_id, 2);
- memcpy(&temp_buf[2], &device_serial_number, 4);
- memcpy(&temp_buf[6], &conn_serial_number, 2);
+ memcpy(temp_buf, &triad->VendorID, 2);
+ memcpy(&temp_buf[2], &triad->DeviceSerialNumber, 4);
+ memcpy(&temp_buf[6], &triad->ConnSerialNumber, 2);
return crc16_0x080F_seed(temp_buf, 8, 0);
}
return timestamp_crc;
}
-static guint32 compute_crc_s5_pid(guint16 conn_serial_number, guint16 vendor_id, guint32 device_serial_number)
+static guint32 compute_crc_s5_pid(const cip_connection_triad_t* triad)
{
guint8 temp_buf[8];
- memcpy(temp_buf, &vendor_id, 2);
- memcpy(&temp_buf[2], &device_serial_number, 4);
- memcpy(&temp_buf[6], &conn_serial_number, 2);
+ memcpy(temp_buf, &triad->VendorID, 2);
+ memcpy(&temp_buf[2], &triad->DeviceSerialNumber, 4);
+ memcpy(&temp_buf[6], &triad->ConnSerialNumber, 2);
return crc32_0x5D6DCB_seed(temp_buf, 8, 0);
}
gboolean server_dir = FALSE;
enum enip_connid_type conn_type = ECIDT_UNKNOWN;
enum cip_safety_format_type format = CIP_SAFETY_BASE_FORMAT;
- guint16 timestamp, conn_sn = 0, vendorID = 0;
+ guint16 timestamp;
guint8 mode_byte;
- guint32 device_sn = 0;
cip_safety_packet_data_t* packet_data = NULL;
guint32 test_crc_c5, value_c5 = 0, tmp_c5;
proto_item *complement_item, *crc_s5_item, *crc_s5_status_item;
gboolean short_format = TRUE;
gboolean compute_crc = ((safety_info != NULL) && (safety_info->compute_crc == TRUE));
+ cip_connection_triad_t connection_triad;
+ memset(&connection_triad, 0, sizeof(connection_triad));
/* Make entries in Protocol column and Info column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "CIP Safety");
{
if ((conn_type == ECIDT_O2T) && (server_dir == FALSE))
{
- conn_sn = safety_info->eip_conn_info->ConnSerialNumber;
- vendorID = safety_info->eip_conn_info->VendorID;
- device_sn = safety_info->eip_conn_info->DeviceSerialNumber;
+ connection_triad = safety_info->eip_conn_info->triad;
}
else
{
- conn_sn = safety_info->eip_conn_info->safety.target_conn_sn;
- vendorID = safety_info->eip_conn_info->safety.target_vendorID;
- device_sn = safety_info->eip_conn_info->safety.target_device_sn;
+ connection_triad = safety_info->eip_conn_info->safety.target_triad;
}
}
{
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(conn_sn, vendorID, device_sn),
+ compute_crc_s3_time(compute_crc_s3_pid(&connection_triad),
tvb_get_guint8(tvb, 0), /* ack byte */
timestamp),
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
/* CRC-S5 doesn't use proto_tree_add_checksum because the checksum is broken up into multiple fields */
if (compute_crc)
{
- test_crc_c5 = compute_crc_s5_time(compute_crc_s5_pid(conn_sn, vendorID, device_sn),
+ test_crc_c5 = compute_crc_s5_time(compute_crc_s5_pid(&connection_triad),
tvb_get_guint8(tvb, 0), /* ack byte */
timestamp);
{
if ((conn_type == ECIDT_O2T) && (server_dir == TRUE))
{
- conn_sn = safety_info->eip_conn_info->ConnSerialNumber;
- vendorID = safety_info->eip_conn_info->VendorID;
- device_sn = safety_info->eip_conn_info->DeviceSerialNumber;
+ connection_triad = safety_info->eip_conn_info->triad;
}
else
{
- conn_sn = safety_info->eip_conn_info->safety.target_conn_sn;
- vendorID = safety_info->eip_conn_info->safety.target_vendorID;
- device_sn = safety_info->eip_conn_info->safety.target_device_sn;
+ connection_triad = safety_info->eip_conn_info->safety.target_triad;
}
}
{
proto_tree_add_checksum(tree, tvb, io_data_size+1,
hf_cipsafety_crc_s1, hf_cipsafety_crc_s1_status, &ei_cipsafety_crc_s1, pinfo,
- compute_crc_s1_data(compute_crc_s1_pid(conn_sn, vendorID, device_sn),
+ compute_crc_s1_data(compute_crc_s1_pid(&connection_triad),
(mode_byte & MODE_BYTE_CRC_S1_MASK),
tvb_get_ptr(tvb, 0, io_data_size), io_data_size),
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
proto_tree_add_checksum(tree, tvb, io_data_size+2,
hf_cipsafety_crc_s2, hf_cipsafety_crc_s2_status, &ei_cipsafety_crc_s2, pinfo,
- compute_crc_s2_data(compute_crc_s1_pid(conn_sn, vendorID, device_sn),
+ compute_crc_s2_data(compute_crc_s1_pid(&connection_triad),
((mode_byte ^ 0xFF) & MODE_BYTE_CRC_S1_MASK),
/* I/O data is duplicated because it will be complemented inline */
(guint8*)tvb_memdup(wmem_packet_scope(), tvb, 0, io_data_size), io_data_size),
{
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(conn_sn, vendorID, device_sn),
+ 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);
{
proto_tree_add_checksum(tree, tvb, io_data_size+1,
hf_cipsafety_crc_s3, hf_cipsafety_crc_s3_status, &ei_cipsafety_crc_s3, pinfo,
- compute_crc_s3_base_data(compute_crc_s3_pid(conn_sn, vendorID, device_sn),
+ compute_crc_s3_base_data(compute_crc_s3_pid(&connection_triad),
mode_byte & MODE_BYTE_CRC_S3_MASK, tvb_get_ptr(tvb, 0, io_data_size), io_data_size),
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
}
{
proto_tree_add_checksum(tree, tvb, (io_data_size*2)+3,
hf_cipsafety_complement_crc_s3, hf_cipsafety_complement_crc_s3_status, &ei_cipsafety_complement_crc_s3, pinfo,
- compute_crc_s3_base_data(compute_crc_s3_pid(conn_sn, vendorID, device_sn),
+ compute_crc_s3_base_data(compute_crc_s3_pid(&connection_triad),
((mode_byte ^ 0xFF) & MODE_BYTE_CRC_S3_MASK),
tvb_get_ptr(tvb, io_data_size+3, io_data_size), io_data_size),
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
{
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(conn_sn, vendorID, device_sn),
+ 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);
/* CRC-S5 doesn't use proto_tree_add_checksum because the checksum is broken up in non-consecutive bytes */
if (compute_crc && (packet_data != NULL))
{
- test_crc_c5 = compute_crc_s5_short_data(compute_crc_s5_pid(conn_sn, vendorID, device_sn),
+ test_crc_c5 = compute_crc_s5_short_data(compute_crc_s5_pid(&connection_triad),
((timestamp != 0) ? packet_data->rollover_value : 0), mode_byte & MODE_BYTE_CRC_S5_BASE_MASK, timestamp,
tvb_get_ptr(tvb, 0, io_data_size), io_data_size);
{
proto_tree_add_checksum(tree, tvb, io_data_size+1,
hf_cipsafety_crc_s3, hf_cipsafety_crc_s3_status, &ei_cipsafety_crc_s3, pinfo,
- compute_crc_s3_extended_data(compute_crc_s3_pid(conn_sn, vendorID, device_sn),
+ compute_crc_s3_extended_data(compute_crc_s3_pid(&connection_triad),
((timestamp != 0) ? packet_data->rollover_value : 0), mode_byte & MODE_BYTE_CRC_S3_MASK, tvb_get_ptr(tvb, 0, io_data_size), io_data_size),
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
}
/* CRC-S5 doesn't use proto_tree_add_checksum because the checksum is broken up in non-consecutive bytes */
if (compute_crc && (packet_data != NULL))
{
- test_crc_c5 = compute_crc_s5_long_data(compute_crc_s5_pid(conn_sn, vendorID, device_sn),
+ test_crc_c5 = compute_crc_s5_long_data(compute_crc_s5_pid(&connection_triad),
((timestamp != 0) ? packet_data->rollover_value : 0), mode_byte & MODE_BYTE_CRC_S5_EXTENDED_MASK, timestamp,
/* I/O data is duplicated because it will be complemented inline */
(guint8*)tvb_memdup(wmem_packet_scope(), tvb, 0, io_data_size), io_data_size);
}
typedef struct enip_conn_key {
- guint16 ConnSerialNumber;
- guint16 VendorID;
- guint32 DeviceSerialNumber;
+ cip_connection_triad_t triad;
guint32 O2TConnID;
guint32 T2OConnID;
} enip_conn_key_t;
"((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
conn->open_frame, conn->open_reply_frame, conn->close_frame,
conn->O2TConnID, conn->T2OConnID,
- conn->ConnSerialNumber, conn->VendorID, conn->DeviceSerialNumber);
+ conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
}
else
{
"((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
conn->open_frame, conn->open_reply_frame,
conn->O2TConnID, conn->T2OConnID,
- conn->ConnSerialNumber, conn->VendorID, conn->DeviceSerialNumber);
+ conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
}
return buf;
"((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
conn->open_frame, conn->open_reply_frame, conn->close_frame,
conn->O2TConnID, conn->T2OConnID,
- conn->ConnSerialNumber, conn->VendorID, conn->DeviceSerialNumber);
+ conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
}
else
{
"((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
conn->open_frame, conn->open_reply_frame,
conn->O2TConnID, conn->T2OConnID,
- conn->ConnSerialNumber, conn->VendorID, conn->DeviceSerialNumber);
+ conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
}
return buf;
}
const enip_conn_key_t *v1 = (const enip_conn_key_t *)v;
const enip_conn_key_t *v2 = (const enip_conn_key_t *)w;
- if ((v1->ConnSerialNumber == v2->ConnSerialNumber) &&
- (v1->VendorID == v2->VendorID) &&
- (v1->DeviceSerialNumber == v2->DeviceSerialNumber) &&
+ if ((v1->triad.ConnSerialNumber == v2->triad.ConnSerialNumber) &&
+ (v1->triad.VendorID == v2->triad.VendorID) &&
+ (v1->triad.DeviceSerialNumber == v2->triad.DeviceSerialNumber) &&
((v1->O2TConnID == 0) || (v2->O2TConnID == 0) || (v1->O2TConnID == v2->O2TConnID)) &&
((v1->T2OConnID == 0) || (v2->T2OConnID == 0) || (v1->T2OConnID == v2->T2OConnID)))
return 1;
const enip_conn_key_t *key = (const enip_conn_key_t *)v;
guint val;
- val = (guint)( key->ConnSerialNumber + key->VendorID + key->DeviceSerialNumber );
+ val = (guint)( key->triad.ConnSerialNumber + key->triad.VendorID + key->triad.DeviceSerialNumber );
return val;
}
}
conn_key = wmem_new(wmem_file_scope(), enip_conn_key_t);
- conn_key->ConnSerialNumber = connInfo->ConnSerialNumber;
- conn_key->VendorID = connInfo->VendorID;
- conn_key->DeviceSerialNumber = connInfo->DeviceSerialNumber;
+ conn_key->triad = connInfo->triad;
conn_key->O2TConnID = connInfo->O2T.connID;
conn_key->T2OConnID = connInfo->T2O.connID;
{
conn_val = wmem_new(wmem_file_scope(), enip_conn_val_t);
- conn_val->ConnSerialNumber = connInfo->ConnSerialNumber;
- conn_val->VendorID = connInfo->VendorID;
- conn_val->DeviceSerialNumber = connInfo->DeviceSerialNumber;
+ conn_val->triad = connInfo->triad;
conn_val->O2TConnID = connInfo->O2T.connID;
conn_val->T2OConnID = connInfo->T2O.connID;
conn_val->TransportClass_trigger = connInfo->TransportClass_trigger;
}
void
-enip_close_cip_connection(packet_info *pinfo, guint16 ConnSerialNumber,
- guint16 VendorID, guint32 DeviceSerialNumber )
+enip_close_cip_connection(packet_info *pinfo, const cip_connection_triad_t* triad)
{
enip_conn_key_t conn_key;
enip_conn_val_t *conn_val;
if (pinfo->fd->flags.visited)
return;
- conn_key.ConnSerialNumber = ConnSerialNumber;
- conn_key.VendorID = VendorID;
- conn_key.DeviceSerialNumber = DeviceSerialNumber;
+ conn_key.triad = *triad;
conn_key.O2TConnID = 0;
conn_key.T2OConnID = 0;
}
/* Save the connection info for the conversation filter */
-void enip_mark_connection_triad( packet_info *pinfo, guint16 ConnSerialNumber, guint16 VendorID, guint32 DeviceSerialNumber )
+void enip_mark_connection_triad(packet_info *pinfo, const cip_connection_triad_t* triad)
{
enip_conn_key_t conn_key;
enip_conn_val_t *conn_val;
- conn_key.ConnSerialNumber = ConnSerialNumber;
- conn_key.VendorID = VendorID;
- conn_key.DeviceSerialNumber = DeviceSerialNumber;
+ conn_key.triad = *triad;
conn_key.O2TConnID = 0;
conn_key.T2OConnID = 0;