LLDP: Add CIP TLVs
This commit is contained in:
parent
bcb8558be2
commit
c758e9d9c0
|
@ -4833,6 +4833,40 @@ static int dissect_segment_ansi_extended_symbol(packet_info* pinfo, tvbuff_t* tv
|
|||
return 2 + seg_size;
|
||||
}
|
||||
|
||||
// offset - Starts with the 'Key Data' section of the Electronic Key Segment Format.
|
||||
int dissect_electronic_key_format(tvbuff_t* tvb, int offset, proto_tree* tree, gboolean generate, guint8 key_format)
|
||||
{
|
||||
int key_len;
|
||||
if (key_format == CI_E_KEY_FORMAT_VAL)
|
||||
{
|
||||
key_len = 8;
|
||||
}
|
||||
else // CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL
|
||||
{
|
||||
key_len = 12;
|
||||
}
|
||||
|
||||
if (generate)
|
||||
{
|
||||
dissect_deviceid(tvb, offset, tree,
|
||||
hf_cip_ekey_vendor, hf_cip_ekey_devtype, hf_cip_ekey_prodcode,
|
||||
hf_cip_ekey_compatibility, hf_cip_ekey_comp_bit, hf_cip_ekey_majorrev, hf_cip_ekey_minorrev, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
dissect_deviceid(tvb, offset, tree,
|
||||
hf_cip_ekey_vendor, hf_cip_ekey_devtype, hf_cip_ekey_prodcode,
|
||||
hf_cip_ekey_compatibility, hf_cip_ekey_comp_bit, hf_cip_ekey_majorrev, hf_cip_ekey_minorrev, FALSE);
|
||||
|
||||
if (key_format == CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL)
|
||||
{
|
||||
proto_tree_add_item(tree, hf_cip_ekey_serial_number, tvb, offset + 8, 4, ENC_LITTLE_ENDIAN);
|
||||
}
|
||||
}
|
||||
|
||||
return key_len;
|
||||
}
|
||||
|
||||
static int dissect_segment_logical_special(packet_info* pinfo, tvbuff_t* tvb, int offset,
|
||||
gboolean generate, proto_tree* path_seg_tree,
|
||||
proto_item* path_seg_item, proto_item* epath_item)
|
||||
|
@ -4847,40 +4881,20 @@ static int dissect_segment_logical_special(packet_info* pinfo, tvbuff_t* tvb, in
|
|||
guint8 key_format = tvb_get_guint8(tvb, offset + 1);
|
||||
if (key_format == CI_E_KEY_FORMAT_VAL || key_format == CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL)
|
||||
{
|
||||
if (key_format == CI_E_KEY_FORMAT_VAL)
|
||||
{
|
||||
segment_len = 10;
|
||||
}
|
||||
else // CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL
|
||||
{
|
||||
segment_len = 14;
|
||||
}
|
||||
|
||||
if (generate)
|
||||
{
|
||||
proto_item* it = proto_tree_add_uint(path_seg_tree, hf_cip_ekey_format, tvb, 0, 0, key_format);
|
||||
proto_item_set_generated(it);
|
||||
|
||||
dissect_deviceid(tvb, offset + 2, path_seg_tree,
|
||||
hf_cip_ekey_vendor, hf_cip_ekey_devtype, hf_cip_ekey_prodcode,
|
||||
hf_cip_ekey_compatibility, hf_cip_ekey_comp_bit, hf_cip_ekey_majorrev, hf_cip_ekey_minorrev, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_item(path_seg_tree, hf_cip_ekey_format, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
|
||||
|
||||
/* dissect the device ID */
|
||||
dissect_deviceid(tvb, offset + 2, path_seg_tree,
|
||||
hf_cip_ekey_vendor, hf_cip_ekey_devtype, hf_cip_ekey_prodcode,
|
||||
hf_cip_ekey_compatibility, hf_cip_ekey_comp_bit, hf_cip_ekey_majorrev, hf_cip_ekey_minorrev, FALSE);
|
||||
|
||||
if (key_format == CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL)
|
||||
{
|
||||
proto_tree_add_item(path_seg_tree, hf_cip_ekey_serial_number, tvb, offset + 12, 4, ENC_LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
proto_item_set_len(path_seg_item, segment_len);
|
||||
}
|
||||
segment_len = 2;
|
||||
|
||||
segment_len += dissect_electronic_key_format(tvb, offset + 2, path_seg_tree, generate, key_format);
|
||||
|
||||
proto_item_set_len(path_seg_item, segment_len);
|
||||
|
||||
/* Add "summary" information to parent item */
|
||||
guint16 vendor_id = tvb_get_letohs(tvb, offset + 2);
|
||||
|
|
|
@ -607,6 +607,7 @@ extern void dissect_deviceid(tvbuff_t *tvb, int offset, proto_tree *tree,
|
|||
int hf_vendor, int hf_devtype, int hf_prodcode,
|
||||
int hf_compatibility, int hf_comp_bit, int hf_majrev, int hf_minrev,
|
||||
gboolean generate);
|
||||
extern int dissect_electronic_key_format(tvbuff_t* tvb, int offset, proto_tree* tree, gboolean generate, guint8 key_format);
|
||||
extern int dissect_optional_attr_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
|
||||
int offset, int total_len);
|
||||
extern int dissect_optional_service_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* This dissector includes items from:
|
||||
* CIP Volume 1: Common Industrial Protocol, Edition 3.24
|
||||
* CIP Volume 2: EtherNet/IP Adaptation of CIP, Edition 1.27
|
||||
* CIP Volume 2: EtherNet/IP Adaptation of CIP, Edition 1.30
|
||||
* CIP Volume 8: CIP Security, Edition 1.13
|
||||
*
|
||||
* Copyright 2003-2004
|
||||
|
@ -368,6 +368,8 @@ static int hf_eip_cert_capflags_reserved = -1;
|
|||
static int hf_eip_cert_capability_flags = -1;
|
||||
static int hf_eip_cert_num_certs = -1;
|
||||
static int hf_eip_cert_cert_name = -1;
|
||||
static int hf_lldp_subtype = -1;
|
||||
static int hf_lldp_mac_address = -1;
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static gint ett_enip = -1;
|
||||
|
@ -4670,6 +4672,16 @@ proto_register_enip(void)
|
|||
{ "Certificate name", "cip.eip_cert.cert_name",
|
||||
FT_STRING, BASE_NONE, NULL, 0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_lldp_subtype,
|
||||
{ "ODVA LLDP Subtype", "cip.lldp.subtype",
|
||||
FT_UINT8, BASE_DEC, VALS(lldp_cip_subtypes), 0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
{ &hf_lldp_mac_address,
|
||||
{ "MAC Address", "cip.lldp.mac_address",
|
||||
FT_ETHER, BASE_NONE, NULL, 0,
|
||||
NULL, HFILL }},
|
||||
};
|
||||
|
||||
/* Setup protocol subtree array */
|
||||
|
@ -5020,6 +5032,53 @@ proto_register_enip(void)
|
|||
subdissector_decode_as_io_table = register_decode_as_next_proto(proto_enip, "cip.io", "CIP I/O Payload", enip_prompt);
|
||||
} /* end of proto_register_enip() */
|
||||
|
||||
const value_string lldp_cip_subtypes[] = {
|
||||
{ 1, "CIP Identification" },
|
||||
{ 2, "CIP MAC Address" },
|
||||
{ 3, "CIP Interface Label" },
|
||||
{ 4, "Position ID" },
|
||||
{ 5, "T1S PHY Data" },
|
||||
{ 6, "Commission Request" },
|
||||
{ 7, "Commission Response" },
|
||||
{ 8, "Discover Topology Response" },
|
||||
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
int dissect_lldp_cip_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
|
||||
{
|
||||
int total_len = tvb_reported_length_remaining(tvb, 0);
|
||||
int offset = 0;
|
||||
guint32 subtype;
|
||||
proto_tree_add_item_ret_uint(tree, hf_lldp_subtype, tvb, offset, 1, ENC_BIG_ENDIAN, &subtype);
|
||||
offset++;
|
||||
|
||||
switch (subtype)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
dissect_electronic_key_format(tvb, offset, tree, FALSE, CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
proto_tree_add_item(tree, hf_lldp_mac_address, tvb, offset, 6, ENC_NA);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
// The string is all the data, minus Subtype (1 byte).
|
||||
int string_len = total_len - 1;
|
||||
proto_tree_add_item(tree, hf_elink_interface_label, tvb, offset, string_len, ENC_ASCII | ENC_NA);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return tvb_reported_length(tvb);
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_enip(void)
|
||||
|
|
|
@ -109,6 +109,9 @@ void display_fwd_open_connection_path(cip_conn_info_t* conn_info, proto_tree* tr
|
|||
void enip_close_cip_connection(packet_info *pinfo, const cip_connection_triad_t* triad);
|
||||
void enip_mark_connection_triad(packet_info *pinfo, const cip_connection_triad_t* triad);
|
||||
|
||||
extern int dissect_lldp_cip_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
||||
extern const value_string lldp_cip_subtypes[];
|
||||
|
||||
extern attribute_info_t enip_attribute_vals[106];
|
||||
|
||||
#endif /* PACKET_ENIP_H */
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <epan/wmem_scopes.h>
|
||||
#include <epan/oui.h>
|
||||
|
||||
#include "packet-enip.h"
|
||||
|
||||
#define DEFAULT_COLUMN_INFO 1
|
||||
#define PROFINET_SPECIAL_COLUMN_INFO 2
|
||||
|
@ -4515,6 +4516,9 @@ dissect_organizational_specific_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tre
|
|||
case OUI_ONOS:
|
||||
subTypeStr = val_to_str(subType, onos_subtypes, "Unknown subtype (0x%x)");
|
||||
break;
|
||||
case OUI_ODVA:
|
||||
subTypeStr = val_to_str(subType, lldp_cip_subtypes, "Unknown subtype (0x%x)");
|
||||
break;
|
||||
default:
|
||||
subTypeStr = wmem_strdup_printf(pinfo->pool, "Unknown (%d)",subType);
|
||||
break;
|
||||
|
@ -4578,6 +4582,9 @@ dissect_organizational_specific_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tre
|
|||
case OUI_ONOS:
|
||||
dissect_onos_tlv(vendor_tvb, pinfo, org_tlv_tree);
|
||||
break;
|
||||
case OUI_ODVA:
|
||||
dissect_lldp_cip_tlv(vendor_tvb, pinfo, org_tlv_tree);
|
||||
break;
|
||||
default:
|
||||
dissect_oui_default_tlv(vendor_tvb, pinfo, org_tlv_tree);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#define OUI_IEEE_802_1QBG 0x001B3F /* IEEE 802.1 Qbg */
|
||||
#define OUI_NINTENDO 0x001F32
|
||||
#define OUI_TURBOCELL 0x0020F6 /* KarlNet, who brought you Turbocell */
|
||||
#define OUI_ODVA 0x00216C /* ODVA */
|
||||
#define OUI_AVAYA 0x00400D /* Avaya */
|
||||
#define OUI_CISCOWL 0x004096 /* Cisco Wireless (Aironet) */
|
||||
#define OUI_MARVELL 0x005043 /* Marvell Semiconductor */
|
||||
|
|
Loading…
Reference in New Issue