I am parsing a log of a large number of Modbus/TCP transactions and want to grab the raw data that is returned for function code 4 (Read Input Registers). I can grab all the relevant fields for the Modbus/TCP packet except for the register value.
For example, here is the Modbus/TCP portion of a packet which requests a single register read on input register 401 (hex
And the corresponding slave response:
The actual value returned for register 401 is the final two bytes of the response:
However, running tshark on the packet doesn't output 268, but instead it outputs 0.
If I run a similar command on more than one register, the output is a sequential list of numbers starting with 0. For example, running it on a capture with a read request for 8 sequential registers starting at 401 whose contents are various 16-bit integer values:
It is clear that
I've uploaded a section of the capture here. The first three requests/responses only request a single register, while the last one requests 8 sequential input registers.
Here's the (abbreviated) output of
I have found a workaround using the pyshark library in Python (which itself issues calls to tshark on the backend). I believe that it just uses raw tshark calls to parse the packet data and store it in various data structures; in this case, it does appear to store the registers as a list of individual key/value pairs. Some example code in the interactive Python 3.5.1 shell:
This suits my needs, but it is definitely a workaround. Given sindy’s explanation, it is strange albeit understandable that this is not currently a feature of the dissector. That said, what I’m trying to do could be far enough outside the typical usage of Wireshark that a workaround in the form of an external script or library may be necessary. If it turns out that there truly is no way to do this with tshark, then I may submit an enhancement request at the provided bugzilla link.
asked 10 Feb ‘16, 10:18
edited 11 Feb ‘16, 08:29
Looking at that on a sample capture as you haven't provided the real one (the one with several registers requested in a single query would be the best), I'm afraid it is a bug of the dissector.
But it is even more complex, which version of Wireshark do you use? Because in your case, the dissector provides the index of the value rather than the value itself, while in Wireshark 2.0.1, it still does not provide the value but it provides the reference number of the register, i.e. you can use a display filter like
I understand the current (2.0.1) behaviour of the dissector in such a way that it does its best to display the reference number of the register and make it available for use in a display filter in the response packet where it does not exist as a protocol field. To do so, the dissector has to maintain state information and render this information taken from the query packet when dissecting the response.
If the assumption is correct, you would have to file an "enhancement" severity level bug at wireshark bugzilla, asking for another field like
edit: changed the register "addresses" and values in the example below to match the modbus reality.
However, it may still not be all that simple to use even if such enhancement would be implemented, as the display filter only chooses the whole packet, not a particular field in it, and it does not link together the individual expressions. So if the query would ask for registers 5, 6 and 7, and the values of these registers in the response would be 50, 600 and 7000 respectively, use of
answered 10 Feb '16, 16:46
edited 11 Feb '16, 08:39