CIP Safety: Improve Analysis
This commit is contained in:
parent
0d93782443
commit
2e41f52062
|
@ -682,6 +682,8 @@ static expert_field ei_cip_safety_open_type1;
|
|||
static expert_field ei_cip_safety_open_type2a;
|
||||
static expert_field ei_cip_safety_open_type2b;
|
||||
static expert_field ei_cip_no_fwd_close;
|
||||
static expert_field ei_cip_safety_input;
|
||||
static expert_field ei_cip_safety_output;
|
||||
|
||||
//// Concurrent Connections
|
||||
static int hf_cip_cm_cc_version;
|
||||
|
@ -3553,6 +3555,13 @@ static void add_cip_class_to_info_column(packet_info *pinfo, guint32 class_id, i
|
|||
return;
|
||||
}
|
||||
|
||||
// Don't show the Assembly class. It's a generic common class, and there are often multiple entries
|
||||
// which clutter the display.
|
||||
if (display_type == DISPLAY_CONNECTION_PATH && class_id == 4)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (display_type == DISPLAY_CONNECTION_PATH)
|
||||
{
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(class_id, cip_class_names_vals, "Class (0x%02x)"));
|
||||
|
@ -7352,6 +7361,15 @@ static void fwd_open_analysis_safety_open(packet_info* pinfo, proto_item* cmd_it
|
|||
{
|
||||
expert_add_info(pinfo, cmd_item, &ei_cip_safety_open_type2b);
|
||||
}
|
||||
|
||||
if (safety_fwdopen->originator_type == CIP_SAFETY_ORIGINATOR_PRODUCER)
|
||||
{
|
||||
expert_add_info(pinfo, cmd_item, &ei_cip_safety_output);
|
||||
}
|
||||
else if (safety_fwdopen->originator_type == CIP_SAFETY_ORIGINATOR_CONSUMER)
|
||||
{
|
||||
expert_add_info(pinfo, cmd_item, &ei_cip_safety_input);
|
||||
}
|
||||
}
|
||||
|
||||
static void display_previous_route_connection_path(cip_req_info_t* preq_info, proto_tree* item_tree, tvbuff_t* tvb, packet_info* pinfo, int hf_path, int display_type);
|
||||
|
@ -7379,6 +7397,8 @@ static void display_connection_information_fwd_open_req(packet_info* pinfo, tvbu
|
|||
|
||||
if (conn_info->safety.safety_seg)
|
||||
{
|
||||
add_safety_data_type_to_info_column(pinfo, ECIDT_O2T, &conn_info->safety);
|
||||
|
||||
pi = proto_tree_add_float(conn_info_tree, hf_cip_safety_nte_ms, tvb, 0, 0, conn_info->safety.nte_value_ms);
|
||||
proto_item_set_generated(pi);
|
||||
}
|
||||
|
@ -7405,6 +7425,11 @@ static void display_connection_information_fwd_open_rsp(packet_info* pinfo, tvbu
|
|||
mark_cip_connection(pinfo, tvb, conn_info_tree);
|
||||
|
||||
display_previous_route_connection_path(preq_info, conn_info_tree, tvb, pinfo, hf_cip_cm_conn_path_size, DISPLAY_CONNECTION_PATH);
|
||||
|
||||
if (preq_info && preq_info->connInfo && preq_info->connInfo->safety.safety_seg)
|
||||
{
|
||||
add_safety_data_type_to_info_column(pinfo, ECIDT_T2O, &preq_info->connInfo->safety);
|
||||
}
|
||||
}
|
||||
|
||||
static void display_connection_information_fwd_close_req(packet_info* pinfo, tvbuff_t* tvb, proto_tree* tree)
|
||||
|
@ -7452,6 +7477,7 @@ static void display_connection_information_fwd_close_req(packet_info* pinfo, tvb
|
|||
{
|
||||
// Make it obvious that the FwdClose is Safety, to match how the FwdOpen looks.
|
||||
col_append_str(pinfo->cinfo, COL_INFO, " [Safety]");
|
||||
add_safety_data_type_to_info_column(pinfo, ECIDT_O2T, &conn_info->safety);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7477,6 +7503,7 @@ static void display_connection_information_fwd_close_rsp(packet_info* pinfo, tvb
|
|||
{
|
||||
// Make it obvious that the FwdClose is Safety, to match how the FwdOpen looks.
|
||||
col_append_str(pinfo->cinfo, COL_INFO, " [Safety]");
|
||||
add_safety_data_type_to_info_column(pinfo, ECIDT_T2O, &conn_val->safety);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7759,6 +7786,19 @@ dissect_cip_cm_fwd_open_req(cip_req_info_t *preq_info, proto_tree *cmd_tree, tvb
|
|||
preq_info->connInfo->TransportClass_trigger = TransportClass_trigger;
|
||||
preq_info->connInfo->timeout_multiplier = timeout_multiplier;
|
||||
preq_info->connInfo->safety = safety_fwdopen;
|
||||
if (preq_info->connInfo->safety.safety_seg)
|
||||
{
|
||||
gboolean server_dir = (TransportClass_trigger & CI_PRODUCTION_DIR_MASK) ? TRUE : FALSE;
|
||||
if (server_dir)
|
||||
{
|
||||
preq_info->connInfo->safety.originator_type = CIP_SAFETY_ORIGINATOR_PRODUCER;
|
||||
}
|
||||
else
|
||||
{
|
||||
preq_info->connInfo->safety.originator_type = CIP_SAFETY_ORIGINATOR_CONSUMER;
|
||||
}
|
||||
}
|
||||
|
||||
preq_info->connInfo->connection_path = connection_path;
|
||||
|
||||
preq_info->connInfo->FwdOpenPathLenBytes = conn_path_size;
|
||||
|
@ -10129,6 +10169,8 @@ proto_register_cip(void)
|
|||
{ &ei_cip_safety_open_type1, { "cip.analysis.safety_open_type1", PI_PROTOCOL, PI_NOTE, "Type 1 - Safety Open with Data", EXPFILL } },
|
||||
{ &ei_cip_safety_open_type2a, { "cip.analysis.safety_open_type2a", PI_PROTOCOL, PI_NOTE, "Type 2a - Safety Open with SCID check", EXPFILL } },
|
||||
{ &ei_cip_safety_open_type2b, { "cip.analysis.safety_open_type2b", PI_PROTOCOL, PI_NOTE, "Type 2b - Safety Open without SCID check", EXPFILL } },
|
||||
{ &ei_cip_safety_input, { "cip.analysis.safety_input", PI_PROTOCOL, PI_NOTE, "Safety Input Connection", EXPFILL } },
|
||||
{ &ei_cip_safety_output, { "cip.analysis.safety_output", PI_PROTOCOL, PI_NOTE, "Safety Output Connection", EXPFILL } },
|
||||
{ &ei_cip_no_fwd_close, { "cip.analysis.no_fwd_close", PI_PROTOCOL, PI_NOTE, "No Forward Close seen for this CIP Connection", EXPFILL } },
|
||||
};
|
||||
|
||||
|
|
|
@ -512,6 +512,7 @@ typedef struct cip_connID_info {
|
|||
|
||||
enum cip_safety_format_type {CIP_SAFETY_BASE_FORMAT, CIP_SAFETY_EXTENDED_FORMAT};
|
||||
enum cip_safety_open_type {CIP_SAFETY_OPEN_UNKNOWN, CIP_SAFETY_OPEN_TYPE1, CIP_SAFETY_OPEN_TYPE2A, CIP_SAFETY_OPEN_TYPE2B};
|
||||
enum cip_safety_originator_type {CIP_SAFETY_ORIGINATOR_UNKNOWN, CIP_SAFETY_ORIGINATOR_CONSUMER, CIP_SAFETY_ORIGINATOR_PRODUCER};
|
||||
|
||||
typedef struct cip_connection_triad {
|
||||
guint16 ConnSerialNumber;
|
||||
|
@ -525,6 +526,8 @@ typedef struct cip_safety_epath_info {
|
|||
enum cip_safety_format_type format;
|
||||
enum cip_safety_open_type safety_open_type;
|
||||
|
||||
enum cip_safety_originator_type originator_type;
|
||||
|
||||
// These 3x variables are only used during a first pass calculation.
|
||||
guint16 running_rollover_value; /* Keep track of the rollover value over the course of the connection */
|
||||
guint16 running_timestamp_value; /* Keep track of the timestamp value over the course of the connection */
|
||||
|
|
|
@ -89,6 +89,7 @@ static int hf_cipsafety_crc_s5_1;
|
|||
static int hf_cipsafety_crc_s5_2;
|
||||
static int hf_cipsafety_crc_s5_status;
|
||||
static int hf_cipsafety_complement_data;
|
||||
static int hf_cip_safety_message_encoding;
|
||||
|
||||
/* CIP Safety header field identifiers */
|
||||
static int hf_cip_reqrsp;
|
||||
|
@ -457,6 +458,32 @@ const range_string safety_max_consumer_numbers[] = {
|
|||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
enum message_encoding_type {
|
||||
MSG_ENCODING_BASE_1_2_BYTE_DATA,
|
||||
MSG_ENCODING_EXTENDED_1_2_BYTE_DATA,
|
||||
MSG_ENCODING_BASE_3_250_BYTE_DATA,
|
||||
MSG_ENCODING_EXTENDED_3_250_BYTE_DATA,
|
||||
MSG_ENCODING_BASE_TIME_STAMP,
|
||||
MSG_ENCODING_BASE_TIME_COORDINATION,
|
||||
MSG_ENCODING_EXTENDED_TIME_COORDINATION,
|
||||
MSG_ENCODING_BASE_TIME_CORRECTION,
|
||||
MSG_ENCODING_EXTENDED_TIME_CORRECTION,
|
||||
};
|
||||
|
||||
static const value_string safety_message_encoding_vals[] = {
|
||||
{ MSG_ENCODING_BASE_1_2_BYTE_DATA, "Base Format, 1 or 2 Byte Data Section" },
|
||||
{ MSG_ENCODING_EXTENDED_1_2_BYTE_DATA, "Extended Format, 1 or 2 Byte Data Section" },
|
||||
{ MSG_ENCODING_BASE_3_250_BYTE_DATA, "Base Format, 3 to 250 Byte Data Section" },
|
||||
{ MSG_ENCODING_EXTENDED_3_250_BYTE_DATA, "Extended Format, 3 to 250 Byte Data Section" },
|
||||
{ MSG_ENCODING_BASE_TIME_STAMP, "Base Format, Time Stamp Section" },
|
||||
{ MSG_ENCODING_BASE_TIME_COORDINATION, "Base Format, Time Coordination Section" },
|
||||
{ MSG_ENCODING_EXTENDED_TIME_COORDINATION, "Extended Format, Time Coordination Section" },
|
||||
{ MSG_ENCODING_BASE_TIME_CORRECTION, "Base Format, Time Correction Section" },
|
||||
{ MSG_ENCODING_EXTENDED_TIME_CORRECTION, "Extended Format, Time Correction Section" },
|
||||
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
void cip_safety_128us_fmt(gchar *s, guint32 value)
|
||||
{
|
||||
// Each tick is 128us.
|
||||
|
@ -1527,6 +1554,9 @@ dissect_mcast_byte( proto_tree *tree, tvbuff_t *tvb, int offset)
|
|||
// Base Format Time Correction Message
|
||||
static void dissect_base_format_time_correction_message(proto_tree* tree, tvbuff_t* tvb, int offset)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_BASE_TIME_CORRECTION);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
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);
|
||||
|
@ -1536,6 +1566,9 @@ static void dissect_base_format_time_correction_message(proto_tree* tree, tvbuff
|
|||
// Extended Format Time Correction Message
|
||||
static void dissect_extended_format_time_correction_message(proto_tree* tree, tvbuff_t* tvb, int offset)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_EXTENDED_TIME_CORRECTION);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
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);
|
||||
|
@ -1549,6 +1582,9 @@ static void dissect_extended_format_time_correction_message(proto_tree* tree, tv
|
|||
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_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_BASE_TIME_STAMP);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_timestamp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
guint16 timestamp = tvb_get_letohs(tvb, offset);
|
||||
|
||||
|
@ -1574,6 +1610,9 @@ static void dissect_base_format_time_stamp_section(packet_info* pinfo, proto_tre
|
|||
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)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_BASE_TIME_COORDINATION);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
dissect_ack_byte(tree, tvb, 0);
|
||||
guint8 ack_byte = tvb_get_guint8(tvb, 0);
|
||||
|
||||
|
@ -1602,6 +1641,9 @@ static void dissect_base_format_time_coordination_message(packet_info* pinfo, pr
|
|||
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)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_EXTENDED_TIME_COORDINATION);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
dissect_ack_byte(tree, tvb, 0);
|
||||
guint8 ack_byte = tvb_get_guint8(tvb, 0);
|
||||
|
||||
|
@ -1624,6 +1666,9 @@ static void dissect_extended_format_time_coordination_message(packet_info* pinfo
|
|||
static void dissect_base_format_1_or_2_byte_data(packet_info* pinfo, proto_tree* tree, tvbuff_t* tvb, int io_data_size,
|
||||
gboolean compute_crc, const cip_connection_triad_t* connection_triad)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_BASE_1_2_BYTE_DATA);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_data, tvb, 0, io_data_size, ENC_NA);
|
||||
dissect_mode_byte(tree, tvb, io_data_size, pinfo);
|
||||
guint8 mode_byte = tvb_get_guint8(tvb, io_data_size);
|
||||
|
@ -1663,6 +1708,9 @@ static void dissect_base_format_1_or_2_byte_data(packet_info* pinfo, proto_tree*
|
|||
static void dissect_base_format_3_to_250_byte_data(packet_info* pinfo, proto_tree* tree, tvbuff_t* tvb, int io_data_size,
|
||||
gboolean compute_crc, const cip_connection_triad_t* connection_triad)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_BASE_3_250_BYTE_DATA);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_data, tvb, 0, io_data_size, ENC_NA);
|
||||
dissect_mode_byte(tree, tvb, io_data_size, pinfo);
|
||||
guint mode_byte = tvb_get_guint8(tvb, io_data_size);
|
||||
|
@ -1710,6 +1758,9 @@ static void dissect_base_format_3_to_250_byte_data(packet_info* pinfo, proto_tre
|
|||
static void dissect_extended_format_1_or_2_byte_data(packet_info* pinfo, proto_tree* tree, tvbuff_t* tvb, int io_data_size,
|
||||
gboolean compute_crc, const cip_connection_triad_t* connection_triad, const cip_safety_packet_data_t* packet_data)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_EXTENDED_1_2_BYTE_DATA);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_data, tvb, 0, io_data_size, ENC_NA);
|
||||
dissect_mode_byte(tree, tvb, io_data_size, pinfo);
|
||||
guint mode_byte = tvb_get_guint8(tvb, io_data_size);
|
||||
|
@ -1741,6 +1792,9 @@ static void dissect_extended_format_1_or_2_byte_data(packet_info* pinfo, proto_t
|
|||
static void dissect_extended_format_3_to_250_byte_data(packet_info* pinfo, proto_tree* tree, tvbuff_t* tvb, int io_data_size,
|
||||
gboolean compute_crc, const cip_connection_triad_t* connection_triad, const cip_safety_packet_data_t* packet_data)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(tree, hf_cip_safety_message_encoding, tvb, 0, 0, MSG_ENCODING_EXTENDED_3_250_BYTE_DATA);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
proto_tree_add_item(tree, hf_cipsafety_data, tvb, 0, io_data_size, ENC_NA);
|
||||
dissect_mode_byte(tree, tvb, io_data_size, pinfo);
|
||||
guint mode_byte = tvb_get_guint8(tvb, io_data_size);
|
||||
|
@ -1832,6 +1886,45 @@ static cip_safety_packet_data_t* get_timestamp_packet_data(packet_info* pinfo, c
|
|||
return packet_data;
|
||||
}
|
||||
|
||||
enum cip_safety_data_type {CIP_SAFETY_DATA_TYPE_UNKNOWN, CIP_SAFETY_PRODUCE, CIP_SAFETY_CONSUME};
|
||||
static enum cip_safety_data_type get_cip_safety_data_type(enum enip_connid_type conn_type, const cip_safety_epath_info_t* safety)
|
||||
{
|
||||
if (conn_type == ECIDT_O2T && safety->originator_type == CIP_SAFETY_ORIGINATOR_PRODUCER)
|
||||
{
|
||||
return CIP_SAFETY_PRODUCE;
|
||||
}
|
||||
else if (conn_type == ECIDT_O2T && safety->originator_type == CIP_SAFETY_ORIGINATOR_CONSUMER)
|
||||
{
|
||||
return CIP_SAFETY_CONSUME;
|
||||
}
|
||||
else if (conn_type == ECIDT_T2O && safety->originator_type == CIP_SAFETY_ORIGINATOR_PRODUCER)
|
||||
{
|
||||
return CIP_SAFETY_CONSUME;
|
||||
}
|
||||
else if (conn_type == ECIDT_T2O && safety->originator_type == CIP_SAFETY_ORIGINATOR_CONSUMER)
|
||||
{
|
||||
return CIP_SAFETY_PRODUCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CIP_SAFETY_DATA_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void add_safety_data_type_to_info_column(packet_info *pinfo, enum enip_connid_type conn_type, const cip_safety_epath_info_t* safety)
|
||||
{
|
||||
enum cip_safety_data_type data_type = get_cip_safety_data_type(conn_type, safety);
|
||||
|
||||
if (data_type == CIP_SAFETY_CONSUME)
|
||||
{
|
||||
col_append_str(pinfo->cinfo, COL_INFO, " [C->P]");
|
||||
}
|
||||
else // CIP_SAFETY_PRODUCE
|
||||
{
|
||||
col_append_str(pinfo->cinfo, COL_INFO, " [P->C]");
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1881,6 +1974,8 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
|
|||
}
|
||||
|
||||
/* consumer data */
|
||||
proto_item_append_text(item, " [Consume]");
|
||||
col_append_str(pinfo->cinfo, COL_INFO, " [C->P]");
|
||||
|
||||
switch (format)
|
||||
{
|
||||
|
@ -1911,6 +2006,9 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
|
|||
short_format = FALSE;
|
||||
|
||||
/* producer data */
|
||||
proto_item_append_text(item, " [Produce]");
|
||||
col_append_str(pinfo->cinfo, COL_INFO, " [P->C]");
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case CIP_SAFETY_BASE_FORMAT:
|
||||
|
@ -2266,7 +2364,7 @@ proto_register_cipsafety(void)
|
|||
},
|
||||
{ &hf_cipsafety_timestamp,
|
||||
{ "Timestamp", "cipsafety.timestamp",
|
||||
FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
|
||||
FT_UINT16, BASE_CUSTOM, CF_FUNC(cip_safety_128us_fmt), 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_cipsafety_ack_byte,
|
||||
{ "ACK Byte", "cipsafety.ack_byte",
|
||||
|
@ -2353,6 +2451,11 @@ proto_register_cipsafety(void)
|
|||
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
|
||||
{ &hf_cip_safety_message_encoding,
|
||||
{ "Safety Message Encoding", "cipsafety.message_encoding",
|
||||
FT_UINT32, BASE_DEC, VALS(safety_message_encoding_vals), 0, NULL, HFILL }
|
||||
},
|
||||
|
||||
{ &hf_cip_sercosiii_link_snn,
|
||||
{ "Data", "cipsafety.sercosiii_link.snn",
|
||||
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
|
||||
|
|
|
@ -50,6 +50,7 @@ extern void dissect_unid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_it
|
|||
int hf_snn_date, int hf_snn_time, int hf_macid, gint ett, gint ett_snn);
|
||||
extern void dissect_cipsafety_snn(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int hf_real_datetime, int hf_date, int hf_time);
|
||||
extern void cip_safety_128us_fmt(gchar *s, guint32 value);
|
||||
extern void add_safety_data_type_to_info_column(packet_info *pinfo, enum enip_connid_type conn_type, const cip_safety_epath_info_t* safety);
|
||||
|
||||
/*
|
||||
** Exported variables
|
||||
|
|
Loading…
Reference in New Issue