Ask Your Question

Modbus/TCP decoding "func 3" seems wrong

asked 2021-01-06 17:33:48 +0000

Puzzled EE gravatar image

updated 2021-01-06 18:02:44 +0000

Hello. I am a novice WS user and I have an issue with the Modbus/TCP decoder that I can't figure out.

I send a function 3 (read holding registers), which gets transaction ID $0002 and asks for 24 bytes to be returned. send payload is: 00 02 00 00 00 06 01 03 03 84 00 0C

The response (per the decoder) is shown as function 24 (!), with transaction ID 512 ($0200).
It seems to ignore the first byte [00] and interprets as: [00] 02 00 00 00 1B 01 03 18 (followed by 12 data bytes)

If I mouseover data bytes in the sent transaction, it shows the first 00 as mbtcp.trans_id which is correct.

If I mouseover the data bytes in the response, it shows [00] as tcp.payload, but mbtcp.trans_id is not displayed until the 02 byte, which seems wrong; it has skipped the 00 in the transaction ID!

If I disable the decoder and look at the raw bytes, they appear correct.

If I hack my code to add a dummy byte of A5 as the first byte in the payload, the decoder then displays the func 3 query and reply correctly.

showing spurious function code 24:

with A5 byte added at start of payload, no spurious function 24:

Note: I am using the latest version of WS available from the Debian repo, but I see that is 2.6.8, which is not very new.

edit retag flag offensive close merge delete


Upload the capture file to a public share, e.g. Google Drive, DropBox etc. and post a link to the file back here.

grahamb gravatar imagegrahamb ( 2021-01-06 17:42:55 +0000 )edit

It would be helpful if that info was placed in the FAQs.

Puzzled EE gravatar imagePuzzled EE ( 2021-01-06 18:11:45 +0000 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2021-01-06 18:38:23 +0000

grahamb gravatar image

updated 2021-01-06 18:38:45 +0000

The remote device does not respond to the Read Holding Registers request.

Looking at the first capture and applying a display filter of "modbus" you can see that the Read was given transaction id 2. The transaction id allows the matching up of requests and responses and should be incremented for each new request from the client. The output of the info columns shows the transaction code and it can be observed that the the read request for the holding registers (frame 9) occurs after the first request to write registers (frame 6) and before the server could respond. The message in frame 10 is not a response to the read registers request but the response to the write registers request. In the rest of the capture there are no further responses from the server.

frame.number Info
6               Query: Trans:     1; Unit:   1, Func:  16: Write Multiple Registers
9               Query: Trans:     2; Unit:   1, Func:   3: Read Holding Registers
10           Response: Trans:     1; Unit:   1, Func:  16: Write Multiple Registers [TCP segment of a reassembled PDU]
11              Query: Trans:     3; Unit:   1, Func:  15: Write Multiple Coils
15              Query: Trans:     4; Unit:   1, Func:  16: Write Multiple Registers
18              Query: Trans:     5; Unit:   1, Func:   3: Read Holding Registers
21              Query: Trans:     6; Unit:   1, Func:  15: Write Multiple Coils
25              Query: Trans:     7; Unit:   1, Func:  16: Write Multiple Registers
edit flag offensive delete link more


I appreciate you taking a look.

Curiously, this is not at all what I see when I put on a display filter of modbus. My display shows a frame 7 reply to the first func 16, and frame 10 says its transaction ID is 512, and function code 24. If I look at the data bytes in frame 10, they are in fact correct (and unique) data to be the response to func 3!.

I agree after there there are no responses, because the transaction IDs are mismatched.

I will assume you are using the latest version, and maybe something changed in the decoder... unless there is some setting you can think of I might have wrong? I have not really changed anything from defaults, however.

Puzzled EE gravatar imagePuzzled EE ( 2021-01-06 19:00:30 +0000 )edit

Frame 7 contains a partial response to the Write registers request in frame 6. Frame 10 contains the final byte of this response and is reassembled by Wireshark. Note the info column for frame 10 has the text "[TCP segment of a reassembled PDU]".

There are a couple of options that affect reassembly, but I'm not sure if they are present in your older version. Have a look at the TCP and Modbus/TCP dissector preferences for the following options:

  • TCP - Allow subdissector to reassemble TCP streams
  • Modbus/TCP - Desegment all Modbus RTU packets spanning multiple segments
grahamb gravatar imagegrahamb ( 2021-01-06 19:21:51 +0000 )edit

It appears the first setting is what was goofing me up. By playing with the two settings, I can get it agree with debug info from the PC program, which is probably a good starting point to finding the real cause

Sure appreciate your time.

Puzzled EE gravatar imagePuzzled EE ( 2021-01-07 01:18:56 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2021-01-06 17:33:48 +0000

Seen: 370 times

Last updated: Jan 06 '21