summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-mbtcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-mbtcp.c')
-rw-r--r--epan/dissectors/packet-mbtcp.c111
1 files changed, 54 insertions, 57 deletions
diff --git a/epan/dissectors/packet-mbtcp.c b/epan/dissectors/packet-mbtcp.c
index da11c9f8f4..aaefcd4a7b 100644
--- a/epan/dissectors/packet-mbtcp.c
+++ b/epan/dissectors/packet-mbtcp.c
@@ -67,6 +67,7 @@
#include "packet-tcp.h"
#include "packet-mbtcp.h"
#include <epan/prefs.h>
+#include <epan/prefs-int.h>
#include <epan/expert.h>
#include <epan/crc16-tvb.h> /* For CRC verification */
#include <epan/proto_data.h>
@@ -174,17 +175,19 @@ static dissector_table_t modbus_dissector_table;
/* Globals for Modbus/TCP Preferences */
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 */
/* Globals for Modbus RTU over TCP Preferences */
static gboolean mbrtu_desegment = TRUE;
-static guint global_mbus_rtu_port = PORT_MBRTU; /* 0, by default */
+static guint global_mbus_tcp_rtu_port = PORT_MBRTU; /* 0, by default */
+static guint global_mbus_udp_rtu_port = PORT_MBRTU; /* 0, by default */
static gboolean mbrtu_crc = FALSE;
/* Globals for Modbus Preferences */
static gint global_mbus_register_format = MODBUS_PREF_REGISTER_FORMAT_UINT16;
static int
-classify_mbtcp_packet(packet_info *pinfo)
+classify_mbtcp_packet(packet_info *pinfo, guint port)
{
/* see if nature of packets can be derived from src/dst ports */
/* if so, return as found */
@@ -193,9 +196,9 @@ classify_mbtcp_packet(packet_info *pinfo)
/* the Modbus/TCP transaction ID for each pair of messages would allow for detection based on a new seq. number. */
/* Otherwise, we can stick with this method; a configurable port option has been added to allow for usage of */
/* user ports either than the default of 502. */
- if (( pinfo->srcport == global_mbus_tcp_port ) && ( pinfo->destport != global_mbus_tcp_port ))
+ if (( pinfo->srcport == port ) && ( pinfo->destport != port ))
return RESPONSE_PACKET;
- if (( pinfo->srcport != global_mbus_tcp_port ) && ( pinfo->destport == global_mbus_tcp_port ))
+ if (( pinfo->srcport != port ) && ( pinfo->destport == port ))
return QUERY_PACKET;
/* else, cannot classify */
@@ -203,7 +206,7 @@ classify_mbtcp_packet(packet_info *pinfo)
}
static int
-classify_mbrtu_packet(packet_info *pinfo, tvbuff_t *tvb)
+classify_mbrtu_packet(packet_info *pinfo, tvbuff_t *tvb, guint port)
{
guint8 func, len;
@@ -212,9 +215,9 @@ classify_mbrtu_packet(packet_info *pinfo, tvbuff_t *tvb)
/* see if nature of packets can be derived from src/dst ports */
/* if so, return as found */
- if (( pinfo->srcport == global_mbus_rtu_port ) && ( pinfo->destport != global_mbus_rtu_port ))
+ if (( pinfo->srcport == port ) && ( pinfo->destport != port ))
return RESPONSE_PACKET;
- if (( pinfo->srcport != global_mbus_rtu_port ) && ( pinfo->destport == global_mbus_rtu_port ))
+ if (( pinfo->srcport != port ) && ( pinfo->destport == port ))
return QUERY_PACKET;
@@ -393,7 +396,7 @@ static const enum_val_t mbus_register_format[] = {
/* Code to dissect Modbus/TCP packets */
static int
-dissect_mbtcp_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int proto)
+dissect_mbtcp_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int proto, guint port)
{
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *mi;
@@ -416,7 +419,7 @@ dissect_mbtcp_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
offset = 0;
/* "Request" or "Response" */
- packet_type = classify_mbtcp_packet(pinfo);
+ packet_type = classify_mbtcp_packet(pinfo, port);
switch ( packet_type ) {
case QUERY_PACKET :
@@ -517,12 +520,12 @@ dissect_mbtcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/TCP");
col_clear(pinfo->cinfo, COL_INFO);
- return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbtcp);
+ return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbtcp, global_mbus_tcp_port);
}
-/* Code to dissect Modbus RTU over TCP packets */
+/* Code to dissect Modbus RTU */
static int
-dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+dissect_mbrtu_pdu_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint port)
{
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *mi;
@@ -547,7 +550,7 @@ dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
offset = 0;
/* "Request" or "Response" */
- packet_type = classify_mbrtu_packet(pinfo, tvb);
+ packet_type = classify_mbrtu_packet(pinfo, tvb, port);
switch ( packet_type ) {
case QUERY_PACKET :
@@ -650,6 +653,12 @@ dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
return tvb_captured_length(tvb);
}
+/* Code to dissect Modbus RTU over TCP packets */
+static int
+dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ return dissect_mbrtu_pdu_common(tvb, pinfo, tree, global_mbus_tcp_rtu_port);
+}
/* Return length of Modbus/TCP message */
static guint
@@ -685,7 +694,7 @@ get_mbrtu_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
the rest can be added as pcap examples are made available */
/* Determine "Query" or "Response" */
- packet_type = classify_mbrtu_packet(pinfo, tvb);
+ packet_type = classify_mbrtu_packet(pinfo, tvb, global_mbus_tcp_rtu_port);
switch ( packet_type ) {
case QUERY_PACKET :
@@ -786,7 +795,7 @@ dissect_mbudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Modbus/UDP");
col_clear(pinfo->cinfo, COL_INFO);
- return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbudp);
+ return dissect_mbtcp_pdu_common(tvb, pinfo, tree, proto_mbudp, global_mbus_udp_port);
}
/* Code to dissect Modbus RTU over TCP messages */
@@ -812,7 +821,7 @@ dissect_mbrtu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
static int
-dissect_mbrtu_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+dissect_mbrtu_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
/* Make sure there's at least enough data to determine it's a Modbus packet */
@@ -820,7 +829,7 @@ dissect_mbrtu_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
if (tvb_reported_length(tvb) < 5)
return 0;
- return dissect_mbrtu_pdu(tvb, pinfo, tree, data);
+ return dissect_mbrtu_pdu_common(tvb, pinfo, tree, global_mbus_udp_rtu_port);
}
@@ -1573,6 +1582,28 @@ dissect_modbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
return tvb_captured_length(tvb);
}
+static void
+apply_mbtcp_prefs(void)
+{
+ /* Modbus/RTU uses the port preference to determine request/response */
+ pref_t *tcp_port = prefs_find_preference(prefs_find_module("mbtcp"), "tcp.port");
+ pref_t *udp_port = prefs_find_preference(prefs_find_module("mbudp"), "udp.port");
+
+ global_mbus_tcp_port = *tcp_port->varp.uint;
+ global_mbus_udp_port = *udp_port->varp.uint;
+}
+
+static void
+apply_mbrtu_prefs(void)
+{
+ /* Modbus/RTU uses the port preference to determine request/response */
+ pref_t *rtu_tcp_port = prefs_find_preference(prefs_find_module("mbrtu"), "tcp.port");
+ pref_t *rtu_udp_port = prefs_find_preference(prefs_find_module("mbrtu"), "udp.port");
+
+ global_mbus_tcp_rtu_port = *rtu_tcp_port->varp.uint;
+ global_mbus_udp_rtu_port = *rtu_udp_port->varp.uint;
+}
+
/* Register the protocol with Wireshark */
void
proto_register_modbus(void)
@@ -1989,8 +2020,8 @@ proto_register_modbus(void)
/* Register required preferences for Modbus Protocol variants */
- mbtcp_module = prefs_register_protocol(proto_mbtcp, proto_reg_handoff_mbtcp);
- mbrtu_module = prefs_register_protocol(proto_mbrtu, proto_reg_handoff_mbrtu);
+ mbtcp_module = prefs_register_protocol(proto_mbtcp, apply_mbtcp_prefs);
+ mbrtu_module = prefs_register_protocol(proto_mbrtu, apply_mbrtu_prefs);
modbus_module = prefs_register_protocol(proto_modbus, NULL);
/* Modbus RTU Preference - Desegment, defaults to TRUE for TCP desegmentation */
@@ -1999,12 +2030,6 @@ proto_register_modbus(void)
"Whether the Modbus RTU dissector should desegment all messages spanning multiple TCP segments",
&mbtcp_desegment);
- /* Modbus/TCP Preference - Default TCP Port, allows for "user" port either than 502. */
- prefs_register_uint_preference(mbtcp_module, "tcp.port", "Modbus/TCP Port",
- "Set the TCP port for Modbus/TCP packets (if other"
- " than the default of 502)",
- 10, &global_mbus_tcp_port);
-
/* Modbus RTU Preference - Desegment, defaults to TRUE for TCP desegmentation */
prefs_register_bool_preference(mbrtu_module, "desegment",
"Desegment all Modbus RTU packets spanning multiple TCP segments",
@@ -2017,11 +2042,6 @@ proto_register_modbus(void)
"Whether to validate the CRC",
&mbrtu_crc);
- /* Modbus RTU Preference - Default TCP Port, defaults to zero, allows custom user port. */
- prefs_register_uint_preference(mbrtu_module, "tcp.port", "Modbus RTU Port",
- "Set the TCP/UDP port for encapsulated Modbus RTU packets",
- 10, &global_mbus_rtu_port);
-
/* Modbus Preference - Holding/Input Register format, this allows for deeper dissection of response data */
prefs_register_enum_preference(modbus_module, "mbus_register_format",
"Holding/Input Register Format",
@@ -2046,20 +2066,8 @@ proto_register_modbus(void)
void
proto_reg_handoff_mbtcp(void)
{
- static unsigned int mbtcp_port;
-
- /* Make sure to use Modbus/TCP Preferences field to determine default TCP port */
- if(mbtcp_port != 0 && mbtcp_port != global_mbus_tcp_port){
- dissector_delete_uint("tcp.port", mbtcp_port, mbtcp_handle);
- dissector_delete_uint("udp.port", mbtcp_port, mbudp_handle);
- }
-
- if(global_mbus_tcp_port != 0 && mbtcp_port != global_mbus_tcp_port) {
- dissector_add_uint("tcp.port", global_mbus_tcp_port, mbtcp_handle);
- dissector_add_uint("udp.port", global_mbus_tcp_port, mbudp_handle);
- }
-
- mbtcp_port = global_mbus_tcp_port;
+ 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("mbtcp.prot_id", MODBUS_PROTOCOL_ID, modbus_handle);
@@ -2068,22 +2076,11 @@ proto_reg_handoff_mbtcp(void)
void
proto_reg_handoff_mbrtu(void)
{
- static unsigned int mbrtu_port = 0;
dissector_handle_t mbrtu_udp_handle = create_dissector_handle(dissect_mbrtu_udp, proto_mbrtu);
/* Make sure to use Modbus RTU Preferences field to determine default TCP port */
-
- if(mbrtu_port != 0 && mbrtu_port != global_mbus_rtu_port){
- dissector_delete_uint("tcp.port", mbrtu_port, mbrtu_handle);
- dissector_delete_uint("udp.port", mbrtu_port, mbrtu_udp_handle);
- }
-
- if(global_mbus_rtu_port != 0 && mbrtu_port != global_mbus_rtu_port) {
- dissector_add_uint("tcp.port", global_mbus_rtu_port, mbrtu_handle);
- dissector_add_uint("udp.port", global_mbus_rtu_port, mbrtu_udp_handle);
- }
-
- mbrtu_port = global_mbus_rtu_port;
+ dissector_add_for_decode_as_with_preference("udp.port", mbrtu_udp_handle);
+ dissector_add_for_decode_as_with_preference("tcp.port", mbrtu_handle);
dissector_add_uint("mbtcp.prot_id", MODBUS_PROTOCOL_ID, modbus_handle);
dissector_add_for_decode_as("rtacser.data", mbrtu_handle);