aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-mbtcp.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-04-26 20:11:46 -0400
committerMichael Mann <mmann78@netscape.net>2016-04-28 20:28:58 +0000
commit3eef66b2c259e4228d92c59140c60d4b59072814 (patch)
treead8793ea6eb410c6a9bcd856012924713c63c6f4 /epan/dissectors/packet-mbtcp.c
parent232b2de7bb008a2bc7c3e5eece04aab16215d24c (diff)
Add support for ModbusRTU over UDP.
Bug: 12374 Change-Id: I2df806c902b932d87e82f6f097f7acce814e5040 Reviewed-on: https://code.wireshark.org/review/15126 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Graham Bloice <graham.bloice@trihedral.com> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-mbtcp.c')
-rw-r--r--epan/dissectors/packet-mbtcp.c102
1 files changed, 56 insertions, 46 deletions
diff --git a/epan/dissectors/packet-mbtcp.c b/epan/dissectors/packet-mbtcp.c
index f04a6f14b4..c388a90c1a 100644
--- a/epan/dissectors/packet-mbtcp.c
+++ b/epan/dissectors/packet-mbtcp.c
@@ -215,59 +215,54 @@ classify_mbrtu_packet(packet_info *pinfo, tvbuff_t *tvb)
return QUERY_PACKET;
- /* Special case for serial-captured packets that don't have an Ethernet header */
+ /* We may not have an Ethernet header or unique ports. */
/* Dig into these a little deeper to try to guess the message type */
- if (!pinfo->srcport) {
- /* The 'exception' bit is set, so this is a response */
- if (func & 0x80) {
- return RESPONSE_PACKET;
- }
- switch (func) {
- case READ_COILS:
- case READ_DISCRETE_INPUTS:
- /* Only possible to get a response message of 8 bytes with Discrete or Coils */
- if (len == 8) {
- /* If this is, in fact, a response then the data byte count will be 3 */
- /* This will correctly identify all messages except for those that are discrete or coil polls */
- /* where the base address range happens to have 0x03 in the upper 16-bit address register */
- if (tvb_get_guint8(tvb, 2) == 3) {
- return RESPONSE_PACKET;
- }
- else {
- return QUERY_PACKET;
- }
- }
- else {
- return RESPONSE_PACKET;
- }
- break;
-
- case READ_HOLDING_REGS:
- case READ_INPUT_REGS:
- case WRITE_SINGLE_COIL:
- case WRITE_SINGLE_REG:
- if (len == 8) {
- return QUERY_PACKET;
- }
- else {
- return RESPONSE_PACKET;
- }
- break;
- case WRITE_MULT_REGS:
- case WRITE_MULT_COILS:
- if (len == 8) {
+ /* The 'exception' bit is set, so this is a response */
+ if (func & 0x80) {
+ return RESPONSE_PACKET;
+ }
+ switch (func) {
+ case READ_COILS:
+ case READ_DISCRETE_INPUTS:
+ /* Only possible to get a response message of 8 bytes with Discrete or Coils */
+ if (len == 8) {
+ /* If this is, in fact, a response then the data byte count will be 3 */
+ /* This will correctly identify all messages except for those that are discrete or coil polls */
+ /* where the base address range happens to have 0x03 in the upper 16-bit address register */
+ if (tvb_get_guint8(tvb, 2) == 3) {
return RESPONSE_PACKET;
}
else {
return QUERY_PACKET;
}
- break;
+ }
+ else {
+ return RESPONSE_PACKET;
+ }
+ break;
- default:
- return CANNOT_CLASSIFY;
- break;
- }
+ case READ_HOLDING_REGS:
+ case READ_INPUT_REGS:
+ case WRITE_SINGLE_COIL:
+ case WRITE_SINGLE_REG:
+ if (len == 8) {
+ return QUERY_PACKET;
+ }
+ else {
+ return RESPONSE_PACKET;
+ }
+ break;
+
+ case WRITE_MULT_REGS:
+ case WRITE_MULT_COILS:
+ if (len == 8) {
+ return RESPONSE_PACKET;
+ }
+ else {
+ return QUERY_PACKET;
+ }
+ break;
}
@@ -782,6 +777,18 @@ dissect_mbrtu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
return tvb_captured_length(tvb);
}
+static int
+dissect_mbrtu_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+
+ /* Make sure there's at least enough data to determine it's a Modbus packet */
+ /* 5 bytes is the smallest possible valid message (exception response) */
+ if (tvb_reported_length(tvb) < 5)
+ return 0;
+
+ return dissect_mbrtu_pdu(tvb, pinfo, tree, data);
+}
+
/* Code to allow further dissection of Modbus data payload */
/* Common to both Modbus/TCP and Modbus RTU dissectors */
@@ -1971,7 +1978,7 @@ proto_register_modbus(void)
/* 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 port for encapsulated Modbus RTU packets",
+ "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 */
@@ -2020,15 +2027,18 @@ 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;