aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2007-02-22 03:21:26 +0000
committerBill Meier <wmeier@newsguy.com>2007-02-22 03:21:26 +0000
commit211cdda3864dcfcd3ceb091cc48c047020cdf548 (patch)
tree9572ffec220e613b7b1927d1fb4f5758cfe547ff /epan
parent4fb922c2c8296e842c7888631a4f1d904f7a33b3 (diff)
From Ryan Wamsley: Add Connection Configuration Object support to EtherNet/IP dissector
svn path=/trunk/; revision=20897
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-cip.c204
-rw-r--r--epan/dissectors/packet-cip.h13
2 files changed, 152 insertions, 65 deletions
diff --git a/epan/dissectors/packet-cip.c b/epan/dissectors/packet-cip.c
index 0c9bb146e5..04acc83219 100644
--- a/epan/dissectors/packet-cip.c
+++ b/epan/dissectors/packet-cip.c
@@ -6,6 +6,9 @@
* Magnus Hansson <mah@hms.se>
* Joakim Wiberg <jow@hms.se>
*
+ * Added support for Connection Configuration Object
+ * ryan wamsley * Copyright 2007
+ *
* $Id$
*
* Wireshark - Network traffic analyzer
@@ -127,6 +130,23 @@ static const value_string cip_sc_vals[] = {
{ SC_FWD_OPEN, "Forward Open" },
{ SC_UNCON_SEND, "Unconnected Send" },
+ /* Connection Configuration Object services */
+ { SC_KICK_TIMER, "Kick Timer" },
+ { SC_OPEN_CONN, "Open Connection" },
+ { SC_CLOSE_CONN, "Close Connection" },
+ { SC_CHANGE_START, "Change Start" },
+ { SC_GET_STATUS, "Get Status" },
+ { SC_CHANGE_COMPLETE, "Change Complete" },
+
+ { 0, NULL }
+};
+
+/* Translate function to string - CIP Service codes that collide with cip_sc_vals */
+static const value_string cip_sc_vals_cco[] = {
+ /* Connection Configuration Object services */
+ { SC_STOP_CONN, "Stop Connection" }, /* collision with SC_UNCON_SEND */
+ { SC_AUDIT_CHANGE, "Audit Changes" }, /* collision with SC_UNCON_SEND */
+
{ 0, NULL }
};
@@ -976,7 +996,7 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_len
unsigned char gen_status;
unsigned char add_stat_size;
unsigned char temp_byte, route_path_size;
- unsigned char app_rep_size, i;
+ unsigned char app_rep_size, i, collision;
int msg_req_siz, num_services, serv_offset;
@@ -987,13 +1007,35 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_len
/* Add Request/Response */
proto_tree_add_item( rrsc_tree, hf_cip_rr, tvb, offset, 1, TRUE );
- proto_item_append_text( rrsc_item, "%s (%s)",
- val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x7F ),
- cip_sc_vals , "Unknown Service (%x)"),
- val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x80 )>>7,
- cip_sc_rr, "") );
+ /* watch for service collisions with CCO */
+ temp_byte = tvb_get_guint8( tvb, offset );
+ collision = 0;
+ if ( SC_STOP_CONN == temp_byte || SC_AUDIT_CHANGE == temp_byte )
+ {
+ /* check for CCO object in path... */
+ temp_data = tvb_get_guint8( tvb, offset+3 );
+ /* F3 is the CCO */
+ if ( temp_data == 0xF3 )
+ {
+ collision = 1;
+ proto_item_append_text( rrsc_item, "%s (%s)",
+ val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x7F ),
+ cip_sc_vals_cco , "Unknown Service (%x)"),
+ val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x80 )>>7,
+ cip_sc_rr, "") );
+ }
+ }
+
+ if (!collision)
+ {
+ proto_item_append_text( rrsc_item, "%s (%s)",
+ val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x7F ),
+ cip_sc_vals , "Unknown Service (%x)"),
+ val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x80 )>>7,
+ cip_sc_rr, "") );
+ }
- /* Add Service code */
+ /* Add Service code */
proto_tree_add_item(rrsc_tree, hf_cip_sc, tvb, offset, 1, TRUE );
if( tvb_get_guint8( tvb, offset ) & 0x80 )
@@ -1044,12 +1086,12 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_len
pi = proto_tree_add_text( item_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Command Specific data" );
cmd_data_tree = proto_item_add_subtree( pi, ett_cmd_data );
- if( gen_status == CI_GRC_SUCCESS )
- {
- /* Success responses */
-
- if( ( tvb_get_guint8( tvb, offset ) & 0x7F ) == SC_FWD_OPEN )
- {
+ if( gen_status == CI_GRC_SUCCESS )
+ {
+ /* Success responses */
+
+ if( ( tvb_get_guint8( tvb, offset ) & 0x7F ) == SC_FWD_OPEN )
+ {
/* Forward open Response (Success) */
/* Display originator to target connection ID */
@@ -1101,7 +1143,7 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_len
} /* End of if reply data */
} /* End of if forward open response */
- else if( ( tvb_get_guint8( tvb, offset ) & 0x7F ) == SC_FWD_CLOSE )
+ else if( ( tvb_get_guint8( tvb, offset ) & 0x7F ) == SC_FWD_CLOSE )
{
/* Forward close response (Success) */
@@ -1392,7 +1434,7 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_len
pi = proto_tree_add_text(cmd_data_tree, tvb, offset+2+req_path_size+36, conn_path_size, "Connection Path: ");
dissect_epath( tvb, pi, offset+2+req_path_size+36, conn_path_size );
}
- else if( tvb_get_guint8( tvb, offset ) == SC_FWD_CLOSE )
+ else if( tvb_get_guint8( tvb, offset ) == SC_FWD_CLOSE && ! collision)
{
/* Forward Close Request */
@@ -1434,56 +1476,74 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_len
} /* End of forward close */
else if( tvb_get_guint8( tvb, offset ) == SC_UNCON_SEND )
{
- /* Unconnected send */
-
- /* Display the priority/tick timer */
- temp_byte = tvb_get_guint8( tvb, offset+2+req_path_size );
- proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 1, "Priority/Time_tick: 0x%02X", temp_byte );
-
- /* Display the time-out ticks */
- temp_data = tvb_get_guint8( tvb, offset+2+req_path_size+1 );
- proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+1, 1, "Time-out_ticks: %d", temp_data );
-
- /* Display the actual time out */
- temp_data = ( 1 << ( temp_byte & 0x0F ) ) * temp_data;
- proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Actual Time Out: %dms", temp_data );
-
- /* Message request size */
- msg_req_siz = tvb_get_letohs( tvb, offset+2+req_path_size+2 );
- proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, 2, "Message Request Size: 0x%04X", msg_req_siz );
-
- /* Message Request */
- temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4, msg_req_siz, "Message Request" );
- temp_tree = proto_item_add_subtree(temp_item, ett_mes_req );
-
- /*
- ** We call our selves again to disect embedded packet
- */
-
- if(check_col(pinfo->cinfo, COL_INFO))
- col_append_fstr( pinfo->cinfo, COL_INFO, ": ");
-
- dissect_cip_data( temp_tree, tvb, offset+2+req_path_size+4, msg_req_siz, pinfo );
-
- if( msg_req_siz % 2 )
- {
- /* Pad byte */
- proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4+msg_req_siz, 1, "Pad Byte (0x%02X)",
- tvb_get_guint8( tvb, offset+2+req_path_size+4+msg_req_siz ) );
- msg_req_siz++; /* include the padding */
- }
-
- /* Route Path Size */
- route_path_size = tvb_get_guint8( tvb, offset+2+req_path_size+4+msg_req_siz )*2;
- proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4+msg_req_siz, 1, "Route Path Size: %d (words)", route_path_size/2 );
-
- /* Reserved */
- proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+5+msg_req_siz, 1, "Reserved (0x%02X)",
- tvb_get_guint8( tvb, offset+2+req_path_size+5+msg_req_siz ) );
-
- /* Route Path */
- temp_item = proto_tree_add_text(cmd_data_tree, tvb, offset+2+req_path_size+6+msg_req_siz, route_path_size, "Route Path: ");
- dissect_epath( tvb, temp_item, offset+2+req_path_size+6+msg_req_siz, route_path_size );
+ /* check for collision */
+ if ( collision )
+ {
+ /* Audit Change */
+
+ temp_data = tvb_get_letohs( tvb, offset+2+req_path_size );
+ temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Change Type: ");
+
+ if (temp_data == 0)
+ proto_item_append_text(temp_item, "Full" );
+ else if (temp_data == 1)
+ proto_item_append_text(temp_item, "Incremental" );
+ else
+ proto_item_append_text(temp_item, "Reserved" );
+ }
+ else
+ {
+ /* Unconnected send */
+
+ /* Display the priority/tick timer */
+ temp_byte = tvb_get_guint8( tvb, offset+2+req_path_size );
+ proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 1, "Priority/Time_tick: 0x%02X", temp_byte );
+
+ /* Display the time-out ticks */
+ temp_data = tvb_get_guint8( tvb, offset+2+req_path_size+1 );
+ proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+1, 1, "Time-out_ticks: %d", temp_data );
+
+ /* Display the actual time out */
+ temp_data = ( 1 << ( temp_byte & 0x0F ) ) * temp_data;
+ proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Actual Time Out: %dms", temp_data );
+
+ /* Message request size */
+ msg_req_siz = tvb_get_letohs( tvb, offset+2+req_path_size+2 );
+ proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, 2, "Message Request Size: 0x%04X", msg_req_siz );
+
+ /* Message Request */
+ temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4, msg_req_siz, "Message Request" );
+ temp_tree = proto_item_add_subtree(temp_item, ett_mes_req );
+
+ /*
+ ** We call our selves again to disect embedded packet
+ */
+
+ if(check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr( pinfo->cinfo, COL_INFO, ": ");
+
+ dissect_cip_data( temp_tree, tvb, offset+2+req_path_size+4, msg_req_siz, pinfo );
+
+ if( msg_req_siz % 2 )
+ {
+ /* Pad byte */
+ proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4+msg_req_siz, 1, "Pad Byte (0x%02X)",
+ tvb_get_guint8( tvb, offset+2+req_path_size+4+msg_req_siz ) );
+ msg_req_siz++; /* include the padding */
+ }
+
+ /* Route Path Size */
+ route_path_size = tvb_get_guint8( tvb, offset+2+req_path_size+4+msg_req_siz )*2;
+ proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4+msg_req_siz, 1, "Route Path Size: %d (words)", route_path_size/2 );
+
+ /* Reserved */
+ proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+5+msg_req_siz, 1, "Reserved (0x%02X)",
+ tvb_get_guint8( tvb, offset+2+req_path_size+5+msg_req_siz ) );
+
+ /* Route Path */
+ temp_item = proto_tree_add_text(cmd_data_tree, tvb, offset+2+req_path_size+6+msg_req_siz, route_path_size, "Route Path: ");
+ dissect_epath( tvb, temp_item, offset+2+req_path_size+6+msg_req_siz, route_path_size );
+ }
} /* End if unconnected send */
else if( tvb_get_guint8( tvb, offset ) == SC_MULT_SERV_PACK )
@@ -1550,6 +1610,20 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_len
}
} /* End of Get attribute list request */
+ else if ( tvb_get_guint8( tvb, offset ) == SC_CHANGE_COMPLETE )
+ {
+ /* Change complete request */
+
+ temp_data = tvb_get_letohs( tvb, offset+2+req_path_size );
+ temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Change Type: ");
+
+ if (temp_data == 0)
+ proto_item_append_text(temp_item, "Full" );
+ else if (temp_data == 1)
+ proto_item_append_text(temp_item, "Incremental" );
+ else
+ proto_item_append_text(temp_item, "Reserved" );
+ }
else
{
/* Add data */
diff --git a/epan/dissectors/packet-cip.h b/epan/dissectors/packet-cip.h
index 1345f376bb..666422f3d2 100644
--- a/epan/dissectors/packet-cip.h
+++ b/epan/dissectors/packet-cip.h
@@ -6,6 +6,9 @@
* Magnus Hansson <mah@hms.se>
* Joakim Wiberg <jow@hms.se>
*
+ * Added support for Connection Configuration Object
+ * ryan wamsley * Copyright 2007
+ *
* $Id$
*
* Wireshark - Network traffic analyzer
@@ -51,6 +54,16 @@
#define SC_FWD_CLOSE 0x4E
#define SC_UNCON_SEND 0x52
#define SC_FWD_OPEN 0x54
+/* Connection Configuration Object services */
+#define SC_KICK_TIMER 0x4B
+#define SC_OPEN_CONN 0x4C
+#define SC_CLOSE_CONN 0x4D
+#define SC_STOP_CONN 0x4E /* collision with SC_FWD_CLOSE */
+#define SC_CHANGE_START 0x4F
+#define SC_GET_STATUS 0x50
+#define SC_CHANGE_COMPLETE 0x51
+#define SC_AUDIT_CHANGE 0x52 /* collision with SC_UNCON_SEND */
+
/* CIP Genral status codes */
#define CI_GRC_SUCCESS 0x00