forked from osmocom/wireshark
From Ryan Wamsley: Add Connection Configuration Object support to EtherNet/IP dissector
svn path=/trunk/; revision=20897
This commit is contained in:
parent
4fb922c2c8
commit
211cdda386
6
AUTHORS
6
AUTHORS
|
@ -2585,10 +2585,14 @@ Robin Seggelmann <seggelmann [AT] fh-muenster.de> {
|
|||
Support for SCTP reassembly.
|
||||
}
|
||||
|
||||
Chris Bontje <cbontje [AT] gmail.com {
|
||||
Chris Bontje <cbontje [AT] gmail.com> {
|
||||
Support for DNP3 Application Layer dissection
|
||||
}
|
||||
|
||||
Ryan Wamsley <wamslers [AT] sbcglobal.net> {
|
||||
Connection Configuration Object support in EtherNet/IP
|
||||
}
|
||||
|
||||
and by:
|
||||
|
||||
Pavel Roskin <proski [AT] gnu.org>
|
||||
|
|
|
@ -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, "") );
|
||||
}
|
||||
}
|
||||
|
||||
/* Add Service code */
|
||||
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 */
|
||||
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 */
|
||||
/* 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 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, ": ");
|
||||
|
||||
/* 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 );
|
||||
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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue