Modbus/TCP: Add TLS dissector

In 2018 Modbus Organization published a document named
"Modbus/TCP Security"[1] that specifies the use of Modbus/TCP over TLS.
This commit register a new dissector, "mbtls", reusing "mbtcp" proto. A
new option is added to define the Modbus/TLS port to be use in
`classify_mbtcp_packet`.

[1] https://modbus.org/docs/MB-TCP-Security-v21_2018-07-24.pdf
This commit is contained in:
ferst 2021-01-28 11:13:06 -03:00 committed by Wireshark GitLab Utility
parent afeb15d4d8
commit 8037be0ef6
2 changed files with 32 additions and 2 deletions

View File

@ -58,6 +58,7 @@
#include <epan/expert.h>
#include <epan/crc16-tvb.h> /* For CRC verification */
#include <epan/proto_data.h>
#include "packet-tls.h"
void proto_register_modbus(void);
void proto_reg_handoff_mbtcp(void);
@ -163,6 +164,7 @@ static expert_field ei_mbtcp_cannot_classify = EI_INIT;
static dissector_handle_t modbus_handle;
static dissector_handle_t mbtcp_handle;
static dissector_handle_t mbtls_handle;
static dissector_handle_t mbudp_handle;
static dissector_handle_t mbrtu_handle;
@ -174,6 +176,7 @@ static dissector_table_t modbus_dissector_table;
static gboolean mbtcp_desegment = TRUE;
static guint global_mbus_tcp_port = PORT_MBTCP; /* Port 502, by default */
static guint global_mbus_udp_port = PORT_MBTCP; /* Port 502, by default */
static guint global_mbus_tls_port = PORT_MBTLS; /* Port 802, by default */
/* Globals for Modbus RTU over TCP Preferences */
static gboolean mbrtu_desegment = TRUE;
@ -538,6 +541,16 @@ dissect_mbtcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbtcp, global_mbus_tcp_port);
}
static int
dissect_mbtls_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
/* Make entries in Protocol column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/TCP Security");
col_clear(pinfo->cinfo, COL_INFO);
return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbtcp, global_mbus_tls_port);
}
/* Code to dissect Modbus RTU */
static int
dissect_mbrtu_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint port)
@ -768,7 +781,7 @@ get_mbrtu_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
/* Code to dissect Modbus/TCP messages */
static int
dissect_mbtcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
dissect_mbtcp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data, dissector_t dissect_pdu)
{
/* Make sure there's at least enough data to determine it's a Modbus TCP packet */
@ -787,11 +800,23 @@ dissect_mbtcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
/* build up protocol tree and iterate over multiple packets */
tcp_dissect_pdus(tvb, pinfo, tree, mbtcp_desegment, 6,
get_mbtcp_pdu_len, dissect_mbtcp_pdu, data);
get_mbtcp_pdu_len, dissect_pdu, data);
return tvb_captured_length(tvb);
}
static int
dissect_mbtcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
return dissect_mbtcp_common(tvb, pinfo, tree, data, dissect_mbtcp_pdu);
}
static int
dissect_mbtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
return dissect_mbtcp_common(tvb, pinfo, tree, data, dissect_mbtls_pdu);
}
static int
dissect_mbudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
@ -1677,6 +1702,7 @@ apply_mbtcp_prefs(void)
/* Modbus/RTU uses the port preference to determine request/response */
global_mbus_tcp_port = prefs_get_uint_value("mbtcp", "tcp.port");
global_mbus_udp_port = prefs_get_uint_value("mbudp", "udp.port");
global_mbus_tls_port = prefs_get_uint_value("mbtcp", "tls.port");
}
static void
@ -2130,6 +2156,7 @@ proto_register_modbus(void)
/* Registering protocol to be called by another dissector */
modbus_handle = register_dissector("modbus", dissect_modbus, proto_modbus);
mbtcp_handle = register_dissector("mbtcp", dissect_mbtcp, proto_mbtcp);
mbtls_handle = register_dissector("mbtls", dissect_mbtls, proto_mbtcp);
mbrtu_handle = register_dissector("mbrtu", dissect_mbrtu, proto_mbrtu);
mbudp_handle = register_dissector("mbudp", dissect_mbudp, proto_mbudp);
@ -2199,10 +2226,12 @@ proto_reg_handoff_mbtcp(void)
{
dissector_add_uint_with_preference("tcp.port", PORT_MBTCP, mbtcp_handle);
dissector_add_uint_with_preference("udp.port", PORT_MBTCP, mbudp_handle);
dissector_add_uint_with_preference("tls.port", PORT_MBTLS, mbtls_handle);
apply_mbtcp_prefs();
dissector_add_uint("mbtcp.prot_id", MODBUS_PROTOCOL_ID, modbus_handle);
ssl_dissector_add(PORT_MBTLS, mbtls_handle);
}
void

View File

@ -14,6 +14,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#define PORT_MBTCP 502 /* Modbus/TCP located on port 502, with IANA registration */
#define PORT_MBTLS 802 /* Modbus/TCP Security protocol (Modbus/TCP over TLS) is registered on port 802 */
#define PORT_MBRTU 0 /* Modbus RTU over TCP does not have a standard port, default to zero */
/* Modbus protocol function codes */