diff options
author | Anders Broman <anders.broman@ericsson.com> | 2009-07-09 20:44:28 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2009-07-09 20:44:28 +0000 |
commit | 298feb719fa9a459a3e6620b3aab52d18b220571 (patch) | |
tree | 0730db7601deaadae6e3ad44de37feb811e45ae0 | |
parent | e10eb5770c03295887916a3a1573b3170215ead1 (diff) |
From Joakim Wiberg:
Device Level Ring protocol addition.
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3685
With some minor changes (blurb NULL whem text equal).
svn path=/trunk/; revision=29044
-rw-r--r-- | epan/dissectors/packet-enip.c | 351 | ||||
-rw-r--r-- | epan/dissectors/packet-enip.h | 51 | ||||
-rw-r--r-- | epan/dissectors/packet-ethertype.c | 3 | ||||
-rw-r--r-- | epan/etypes.h | 6 |
4 files changed, 409 insertions, 2 deletions
diff --git a/epan/dissectors/packet-enip.c b/epan/dissectors/packet-enip.c index b8a22bf07f..0beadb6fcb 100644 --- a/epan/dissectors/packet-enip.c +++ b/epan/dissectors/packet-enip.c @@ -45,6 +45,7 @@ #include <epan/emem.h> #include <epan/conversation.h> #include <epan/prefs.h> +#include <epan/etypes.h> #include "packet-tcp.h" #include "packet-enip.h" #include "packet-cip.h" @@ -140,6 +141,40 @@ static dissector_handle_t data_handle; static gboolean enip_desegment = TRUE; +static int proto_dlr = -1; + +static int hf_dlr_ringsubtype = -1; +static int hf_dlr_ringprotoversion = -1; +static int hf_dlr_frametype = -1; +static int hf_dlr_sourceport = -1; +static int hf_dlr_sourceip = -1; +static int hf_dlr_sequenceid = -1; + +static int hf_dlr_ringstate = -1; +static int hf_dlr_supervisorprecedence = -1; +static int hf_dlr_beaconinterval = -1; +static int hf_dlr_beacontimeout = -1; +static int hf_dlr_beaconreserved = -1; + +static int hf_dlr_nreqreserved = -1; + +static int hf_dlr_nressourceport = -1; +static int hf_dlr_nresreserved = -1; + +static int hf_dlr_lnknbrstatus = -1; +static int hf_dlr_lnknbrreserved = -1; + +static int hf_dlr_lfreserved = -1; + +static int hf_dlr_anreserved = -1; + +static int hf_dlr_sonumnodes = -1; +static int hf_dlr_somac = -1; +static int hf_dlr_soip = -1; +static int hf_dlr_soreserved = -1; + +static gint ett_dlr = -1; + /* Translate function to string - Encapsulation commands */ static const value_string encap_cmd_vals[] = { { NOP, "NOP" }, @@ -201,6 +236,46 @@ static const value_string enip_interface_handle_vals[] = { { 0, NULL } }; +/* Translate function to DLR Frame Type values */ +static const value_string dlr_frame_type_vals[] = { + { DLR_FT_BEACON, "Beacon" }, + { DLR_FT_NEIGHBOR_REQ, "Neighbor_Check_Request" }, + { DLR_FT_NEIGHBOR_RES, "Neighbor_Check_Response" }, + { DLR_FT_LINK_STAT, "Link_Status / Neighbor_Status" }, + { DLR_FT_LOCATE_FLT, "Locate_Fault" }, + { DLR_FT_ANNOUNCE, "Announce" }, + { DLR_FT_SIGN_ON, "Sign_On" }, + + { 0, NULL } +}; + +/* Translate function to DLR Source Port values */ +static const value_string dlr_source_port_vals[] = { + { 0, "Port 1 or Port 2" }, + { 1, "Port 1" }, + { 2, "Port 2" }, + + { 0, NULL } +}; + +/* Translate function to DLR Ring State values */ +static const value_string dlr_ring_state_vals[] = { + { 1, "RING_NORMAL_STATE" }, + { 2, "RING_FAULT_STATE" }, + + { 0, NULL } +}; + + +/* Translate function to DLR Link_Status/Neighbor_Status Status values */ +static const value_string dlr_lnk_nbr_status_vals[] = { + { 0x01, "PORT_1_UP" }, + { 0x02, "PORT_2_UP" }, + { 0x80, "NEIGHBOR_STATUS_FLAG" }, + + { 0, NULL } +}; + static GHashTable *enip_request_hashtable = NULL; /* Return codes of function classifying packets as query/response */ @@ -1206,6 +1281,127 @@ dissect_enipio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } /* end of dissect_enipio() */ +static gboolean +dissect_dlr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti; + proto_tree *dlr_tree = NULL; + guint8 dlr_subtype; + guint8 dlr_protover; + guint8 dlr_frametype; + + /* Make entries in Protocol column and Info column on summary display */ + if( check_col( pinfo->cinfo, COL_PROTOCOL ) ) + col_set_str( pinfo->cinfo, COL_PROTOCOL, "DLR" ); + + if (check_col( pinfo->cinfo, COL_INFO ) ) + col_clear( pinfo->cinfo, COL_INFO ); + + if( tree ) + { + /* Create display subtree for the protocol */ + ti = proto_tree_add_item(tree, proto_dlr, tvb, 0, -1, FALSE); + dlr_tree = proto_item_add_subtree( ti, ett_dlr ); + } + + /* Get values for the Common Frame Header Format */ + dlr_subtype = tvb_get_guint8(tvb, DLR_CFH_SUB_TYPE); + dlr_protover = tvb_get_guint8(tvb, DLR_CFH_PROTO_VERSION); + + /* Dissect the Common Frame Header Format */ + proto_tree_add_uint( dlr_tree, hf_dlr_ringsubtype, tvb, DLR_CFH_SUB_TYPE, 1, dlr_subtype ); + proto_tree_add_uint( dlr_tree, hf_dlr_ringprotoversion, tvb, DLR_CFH_PROTO_VERSION, 1, dlr_protover ); + + /* Get values for the DLR Message Payload Fields */ + dlr_frametype = tvb_get_guint8(tvb, DLR_MPF_FRAME_TYPE); + + /* Dissect the DLR Message Payload Fields */ + proto_tree_add_item( dlr_tree, hf_dlr_frametype, tvb, DLR_MPF_FRAME_TYPE, 1, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_sourceport, tvb, DLR_MPF_SOURCE_PORT, 1, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_sourceip, tvb, DLR_MPF_SOURCE_IP, 4, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_sequenceid, tvb, DLR_MPF_SEQUENCE_ID, 4, FALSE ); + + /* Add frame type to col info */ + if( check_col(pinfo->cinfo, COL_INFO) ) + { + col_add_fstr(pinfo->cinfo, COL_INFO, + "%s", val_to_str(dlr_frametype, dlr_frame_type_vals, "Unknown (0x%04x)") ); + } + + if( dlr_frametype == DLR_FT_BEACON ) + { + /* Beacon */ + proto_tree_add_item( dlr_tree, hf_dlr_ringstate, tvb, DLR_BE_RING_STATE, 1, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_supervisorprecedence, tvb, DLR_BE_SUPERVISOR_PRECEDENCE, 1, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_beaconinterval, tvb, DLR_BE_BEACON_INTERVAL, 4, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_beacontimeout, tvb, DLR_BE_BEACON_TIMEOUT, 4, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_beaconreserved, tvb, DLR_BE_RESERVED, 20, FALSE ); + } + else if( dlr_frametype == DLR_FT_NEIGHBOR_REQ ) + { + /* Neighbor_Check_Request */ + proto_tree_add_item( dlr_tree, hf_dlr_nreqreserved, tvb, DLR_NREQ_RESERVED, 30, FALSE ); + } + else if( dlr_frametype == DLR_FT_NEIGHBOR_RES ) + { + /* Neighbor_Check_Response */ + proto_tree_add_item( dlr_tree, hf_dlr_nressourceport, tvb, DLR_NRES_SOURCE_PORT, 1, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_nresreserved, tvb, DLR_NRES_RESERVED, 29, FALSE ); + } + else if( dlr_frametype == DLR_FT_LINK_STAT ) + { + /* Link_Status/Neighbor_Status */ + proto_tree_add_item( dlr_tree, hf_dlr_lnknbrstatus, tvb, DLR_LNS_SOURCE_PORT, 1, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_lnknbrreserved, tvb, DLR_LNS_RESERVED, 29, FALSE ); + } + else if( dlr_frametype == DLR_FT_LOCATE_FLT ) + { + /* Locate_Fault */ + proto_tree_add_item( dlr_tree, hf_dlr_lfreserved, tvb, DLR_LF_RESERVED, 30, FALSE ); + } + else if( dlr_frametype == DLR_FT_ANNOUNCE ) + { + /* Announce */ + proto_tree_add_item( dlr_tree, hf_dlr_ringstate, tvb, DLR_AN_RING_STATE, 1, FALSE ); + proto_tree_add_item( dlr_tree, hf_dlr_anreserved, tvb, DLR_AN_RESERVED, 29, FALSE ); + } + else if( dlr_frametype == DLR_FT_SIGN_ON ) + { + guint16 nCnt; + guint16 nNumNodes; + guint16 nOffset; + + + /* Sign_On */ + nNumNodes = tvb_get_ntohs(tvb, DLR_SO_NUM_NODES); + + proto_tree_add_uint( dlr_tree, hf_dlr_sonumnodes, tvb, DLR_SO_NUM_NODES, 2, nNumNodes ); + + /* Add each node in the list */ + for( nCnt = 0, nOffset = DLR_SO_NODE_1_MAC; nCnt < nNumNodes; nCnt++ ) + { + proto_tree_add_item( dlr_tree, hf_dlr_somac, tvb, nOffset, 6, FALSE ); + nOffset += 6; + proto_tree_add_item( dlr_tree, hf_dlr_soip, tvb, nOffset, 4, FALSE ); + nOffset += 4; + } + + if( nOffset < 42 ) + { + proto_tree_add_item( dlr_tree, hf_dlr_soreserved, tvb, nOffset, 42 - nOffset, FALSE ); + nOffset += (42 - nOffset); + } + } + else + { + /* Unknown Frame type */ + } + + return tvb_length(tvb); + +} /* end of dissect_dlr() */ + + /* Register the protocol with Wireshark */ /* this format is require because a script is used to build the C function @@ -1365,6 +1561,148 @@ proto_register_enip(void) &ett_sockadd, &ett_lsrcf, }; + + /* Setup list of header fields for DLR See Section 1.6.1 for details*/ + static hf_register_info hfdlr[] = { + /* Ring Sub-type */ + { &hf_dlr_ringsubtype, + { "Subtype", "enip.dlr.ringsubtype", + FT_UINT8, BASE_HEX, NULL, 0, + "Ring Sub-Type", HFILL } + }, + /* Ring Protocol Version */ + { &hf_dlr_ringprotoversion, + { "Version", "enip.dlr.protversion", + FT_UINT8, BASE_DEC, NULL, 0, + "Ring Protocol Version", HFILL } + }, + /* Frame Type */ + { &hf_dlr_frametype, + { "Frametype", "enip.dlr.frametype", + FT_UINT8, BASE_HEX, VALS(dlr_frame_type_vals), 0, + "Frame Type", HFILL } + }, + /* Source Port */ + { &hf_dlr_sourceport, + { "Sourceport", "enip.dlr.sourceport", + FT_UINT8, BASE_HEX, VALS(dlr_source_port_vals), 0, + "Source Port", HFILL } + }, + /* Source IP Address */ + { &hf_dlr_sourceip, + { "Source IP", "enip.dlr.sourceip", + FT_IPv4, BASE_HEX, NULL, 0, + "Source IP Address", HFILL } + }, + /* Sequence ID*/ + { &hf_dlr_sequenceid, + { "Sequence Id", "enip.dlr.seqid", + FT_UINT32, BASE_HEX, NULL, 0, + NULL, HFILL } + }, + /* Ring State */ + { &hf_dlr_ringstate, + { "Ring State", "enip.dlr.state", + FT_UINT8, BASE_HEX, VALS(dlr_ring_state_vals), 0, + NULL, HFILL } + }, + /* Supervisor Precedence */ + { &hf_dlr_supervisorprecedence, + { "Supervisor Precedence", "enip.dlr.supervisorprecedence", + FT_UINT8, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + /* Beacon Interval */ + { &hf_dlr_beaconinterval, + { "Beacon Interval", "enip.dlr.beaconinterval", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + /* Beacon Timeout */ + { &hf_dlr_beacontimeout, + { "Beacon Timeout", "enip.dlr.beacontimeout", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + /* Beacon Reserved */ + { &hf_dlr_beaconreserved, + { "Reserved", "enip.dlr.beaconreserved", + FT_BYTES, BASE_HEX, NULL, 0, + "Beacon Reserved", HFILL } + }, + /* Neighbor_Check_Request Reserved */ + { &hf_dlr_nreqreserved, + { "Reserved", "enip.dlr.nreqreserved", + FT_BYTES, BASE_HEX, NULL, 0, + "Neighbor_Check_Request Reserved", HFILL } + }, + /* Neighbor_Check_Response Source Port */ + { &hf_dlr_nressourceport, + { "Sourceport", "enip.dlr.nressourceport", + FT_UINT8, BASE_HEX, VALS(dlr_source_port_vals), 0, + "Neighbor_Check_Response Source Port", HFILL } + }, + /* Neighbor_Check_Response Reserved */ + { &hf_dlr_nresreserved, + { "Reserved", "enip.dlr.nresreserved", + FT_BYTES, BASE_HEX, NULL, 0, + "Neighbor_Check_Response Reserved", HFILL } + }, + /* Link_Status/Neighbor_Status Status */ + { &hf_dlr_lnknbrstatus, + { "Status", "enip.dlr.lnknbrstatus", + FT_UINT8, BASE_HEX, VALS(dlr_lnk_nbr_status_vals), 0, + "Link_Status/Neighbor_Status Status", HFILL } + }, + /* Link_Status/Neighbor_Status Reserved */ + { &hf_dlr_lnknbrreserved, + { "Reserved", "enip.dlr.lnknbrreserved", + FT_BYTES, BASE_HEX, NULL, 0, + "Link_Status/Neighbor_Status Reserved", HFILL } + }, + /* Locate_Fault Reserved */ + { &hf_dlr_lfreserved, + { "Reserved", "enip.dlr.lfreserved", + FT_BYTES, BASE_HEX, NULL, 0, + "Locate_Fault Reserved", HFILL } + }, + /* Announce Reserved */ + { &hf_dlr_anreserved, + { "Reserved", "enip.dlr.anreserved", + FT_BYTES, BASE_HEX, NULL, 0, + "Announce Reserved", HFILL } + }, + /* Number of Nodes in List */ + { &hf_dlr_sonumnodes, + { "Num nodes", "enip.dlr.sonumnodes", + FT_UINT16, BASE_DEC, NULL, 0, + "Number of Nodes in List", HFILL } + }, + /* Sign_On Node # MAC Address */ + { &hf_dlr_somac, + { "MAC Address", "enip.dlr.somac", + FT_ETHER, BASE_HEX, NULL, 0, + "Sign_On Node MAC Address", HFILL } + }, + /* Node # IP Address */ + { &hf_dlr_soip, + { "IP Address", "enip.dlr.soip", + FT_IPv4, BASE_HEX, NULL, 0, + "Sign_On Node IP Address", HFILL } + }, + /* Sign_On Reserved */ + { &hf_dlr_soreserved, + { "Reserved", "enip.dlr.soreserved", + FT_BYTES, BASE_HEX, NULL, 0, + "Sign_On Reserved", HFILL } + } + }; + + /* Setup protocol subtree array for DLR */ + static gint *ettdlr[] = { + &ett_dlr + }; + module_t *enip_module; /* Register the protocol name and description */ @@ -1388,6 +1726,14 @@ proto_register_enip(void) "SendRequestReplyData.Interface Handle", FT_UINT32, BASE_HEX); register_init_routine(&enip_init_protocol); + + /* Register the protocol name and description */ + proto_dlr = proto_register_protocol("Device Level Ring", "DLR", "dlr"); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_dlr, hfdlr, array_length(hfdlr)); + proto_register_subtree_array(ettdlr, array_length(ettdlr)); + } /* end of proto_register_enip() */ @@ -1400,6 +1746,7 @@ proto_reg_handoff_enip(void) { dissector_handle_t enip_udp_handle, enip_tcp_handle; dissector_handle_t enipio_handle; + dissector_handle_t dlr_handle; /* Register for EtherNet/IP, using TCP */ enip_tcp_handle = new_create_dissector_handle(dissect_enip_tcp, proto_enip); @@ -1416,4 +1763,8 @@ proto_reg_handoff_enip(void) /* Find dissector for data packet */ data_handle = find_dissector("data"); + /* Register for EtherNet/IP Device Level Ring protocol */ + dlr_handle = new_create_dissector_handle(dissect_dlr, proto_dlr); + dissector_add("ethertype", ETHERTYPE_DLR, dlr_handle); + } /* end of proto_reg_handoff_enip() */ diff --git a/epan/dissectors/packet-enip.h b/epan/dissectors/packet-enip.h index 018ca297ff..a16cda9821 100644 --- a/epan/dissectors/packet-enip.h +++ b/epan/dissectors/packet-enip.h @@ -27,6 +27,57 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Offsets of fields within the DLR Common Frame Header */ +#define DLR_CFH_SUB_TYPE 0 +#define DLR_CFH_PROTO_VERSION 1 + +/* Offsets (from beginning of the packet) of fields within the DLR Message + * Payload Fields + */ +#define DLR_MPF_FRAME_TYPE 2 +#define DLR_MPF_SOURCE_PORT 3 +#define DLR_MPF_SOURCE_IP 4 +#define DLR_MPF_SEQUENCE_ID 8 + +/* Offset for Beacon frames */ +#define DLR_BE_RING_STATE 12 +#define DLR_BE_SUPERVISOR_PRECEDENCE 13 +#define DLR_BE_BEACON_INTERVAL 14 +#define DLR_BE_BEACON_TIMEOUT 18 +#define DLR_BE_RESERVED 22 + +/* Offset for Neighbor_Check_Request frames */ +#define DLR_NREQ_RESERVED 12 + +/* Offset for Neighbor_Check_Response frames */ +#define DLR_NRES_SOURCE_PORT 12 +#define DLR_NRES_RESERVED 13 + +/* Offset for Link_Status/Neighbor_Status frames */ +#define DLR_LNS_SOURCE_PORT 12 +#define DLR_LNS_RESERVED 13 + +/* Offset for Locate_Fault frames */ +#define DLR_LF_RESERVED 12 + +/* Offset for Announce frames */ +#define DLR_AN_RING_STATE 12 +#define DLR_AN_RESERVED 13 + +/* Offset for Sign_On frames */ +#define DLR_SO_NUM_NODES 12 +#define DLR_SO_NODE_1_MAC 14 + +/* DLR commmands */ +#define DLR_FT_BEACON 1 +#define DLR_FT_NEIGHBOR_REQ 2 +#define DLR_FT_NEIGHBOR_RES 3 +#define DLR_FT_LINK_STAT 4 +#define DLR_FT_LOCATE_FLT 5 +#define DLR_FT_ANNOUNCE 6 +#define DLR_FT_SIGN_ON 7 + + typedef struct { guint32 req_num, rep_num; nstime_t req_time; diff --git a/epan/dissectors/packet-ethertype.c b/epan/dissectors/packet-ethertype.c index 318ea4a22c..1f1ac9d273 100644 --- a/epan/dissectors/packet-ethertype.c +++ b/epan/dissectors/packet-ethertype.c @@ -62,6 +62,7 @@ const value_string etype_vals[] = { {ETHERTYPE_DEC_LB, "DEC LanBridge" }, {ETHERTYPE_ATALK, "Appletalk" }, {ETHERTYPE_SNA, "SNA-over-Ethernet" }, + {ETHERTYPE_DLR, "EtherNet/IP Device Level Ring" }, {ETHERTYPE_AARP, "AARP" }, {ETHERTYPE_IPX, "Netware IPX/SPX" }, {ETHERTYPE_VINES_IP, "Vines IP" }, @@ -290,7 +291,7 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, if (check_col(pinfo->cinfo, COL_INFO)) { description = match_strval(etype, etype_vals); if (description) { - col_add_str(pinfo->cinfo, COL_INFO, + col_add_str(pinfo->cinfo, COL_INFO, description); } } diff --git a/epan/etypes.h b/epan/etypes.h index 3dfde8158a..ba1e9d11cf 100644 --- a/epan/etypes.h +++ b/epan/etypes.h @@ -170,6 +170,10 @@ #define ETHERTYPE_SNA 0x80d5 #endif +#ifndef ETHERTYPE_DLR +#define ETHERTYPE_DLR 0x80e1 /* Allen-Bradley Company, Inc. */ +#endif /* EtherNet/IP Device Level Ring */ + #ifndef ETHERTYPE_AARP #define ETHERTYPE_AARP 0x80f3 #endif @@ -304,7 +308,7 @@ #ifndef ETHERTYPE_XIMETA #define ETHERTYPE_XIMETA 0x88AD /* XiMeta Technology Americas Inc. */ -#endif /* proprietary communication protocol */ +#endif /* proprietary communication protocol */ #ifndef ETHERTYPE_BRDWALK #define ETHERTYPE_BRDWALK 0x88AE |