diff options
author | Bill Meier <wmeier@newsguy.com> | 2007-02-22 03:21:26 +0000 |
---|---|---|
committer | Bill Meier <wmeier@newsguy.com> | 2007-02-22 03:21:26 +0000 |
commit | 211cdda3864dcfcd3ceb091cc48c047020cdf548 (patch) | |
tree | 9572ffec220e613b7b1927d1fb4f5758cfe547ff /epan | |
parent | 4fb922c2c8296e842c7888631a4f1d904f7a33b3 (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.c | 204 | ||||
-rw-r--r-- | epan/dissectors/packet-cip.h | 13 |
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 |