Ask Your Question
0

Difference between Wireshark and tshark on InfiniBand dissection

asked 2024-06-28 19:51:19 +0000

zvonler gravatar image

Hello,

I wrote a heuristic LUA dissector for a protocol that uses UDP port 4791 and it works as expected in Wireshark. However, when I try to use the same dissector with tshark, the InfiniBand dissector tries and fails to decode the packet, preventing my heuristic dissector from operating, unless I disable it explicitly.

In the Wireshark prefs for IB there is a preference that is default true called “Try heuristic sub-dissectors first”. The same preference appears to be known to tshark:

tshark_ib % /Applications/Wireshark.app/Contents/MacOS/tshark -G currentprefs | grep -B 2 infiniband.try_heuristic_first
# Try to decode a packet using an heuristic sub-dissector before using Decode As
# TRUE or FALSE (case-insensitive)
#infiniband.try_heuristic_first: TRUE

but it doesn’t appear to have an effect, even if forced to TRUE with the -o command-line option. Attached is a script that demonstrates the tshark behavior with a minimal packet and dissector -- the LUA dissector is invoked only by the third way of calling tshark. The heuristic_dissector.lua file produced by the script can be loaded into Wireshark to confirm that it dissects the udp_packet.pcap file as PROP with default prefs.

Is it a bug for tshark not to invoke the heuristic dissector before the InfiniBand one?

#!/bin/bash

TEXT2PCAP=/Applications/Wireshark.app/Contents/MacOS/text2pcap
TSHARK=/Applications/Wireshark.app/Contents/MacOS/tshark
UDP_SRC_PORT=65432
UDP_DST_PORT=4791
PCAP_FN=udp_packet.pcap

cat <<EOF | ${TEXT2PCAP} -qu "${UDP_SRC_PORT},${UDP_DST_PORT}" - ${PCAP_FN}
0000    01 23 45 67 89 ab cd ef
EOF

cat >heuristic_dissector.lua <<EOF
-- This heuristic dissector works in Wireshark with the default preference of
-- infiniband.try_heuristic_first: TRUE
-- but it does not work in tshark without disabling the InfiniBand protocol.

local proto = Proto("prop", "PROP")

function proto.dissector(buffer, pinfo, root)
    print("prop dissector invoked")
    root:add(proto, buffer())
    pinfo.cols.protocol = proto.name
    return buffer:len()
end

local udp_dstport = Field.new("udp.dstport")
proto:register_heuristic("udp", function (buffer, pinfo, root)
    if udp_dstport()() == ${UDP_DST_PORT} then
        proto.dissector(buffer, pinfo, root)
        return true
    end
    return false
end)
EOF

echo "Heuristic dissector:"
${TSHARK} -X lua_script:heuristic_dissector.lua -r ${PCAP_FN}

echo "Heuristic dissector, overriding infiniband.try_heuristic_first to true:"
${TSHARK} -X lua_script:heuristic_dissector.lua -o infiniband.try_heuristic_first:TRUE -r ${PCAP_FN}

echo "Heuristic dissector, InfiniBand disabled:"
${TSHARK} -X lua_script:heuristic_dissector.lua --disable-protocol infiniband -r ${PCAP_FN}
edit retag flag offensive close merge delete

Comments

Should you be asking the UDP dissector to try heuristics first?

prefs_register_bool_preference(udp_module, "try_heuristic_first",
                     "Try heuristic sub-dissectors first",
                     "Try to decode a packet using an heuristic sub-dissector"
                     " before using a sub-dissector registered to a specific port",
                     &try_heuristic_first);
C:\Users\wireshark>"c:\Program Files\Wireshark\tshark.exe" -G currentprefs | findstr /I try_heuristic_first
#asam-cmp.try_heuristic_first: FALSE
#can.try_heuristic_first: FALSE
#acf-can.try_heuristic_first: FALSE
#dccp.try_heuristic_first: FALSE
#flexray.try_heuristic_first: FALSE
#infiniband.try_heuristic_first: TRUE
#ip.try_heuristic_first: FALSE
#ipv6.try_heuristic_first: FALSE
#mpls.try_heuristic_first: FALSE
#sctp.try_heuristic_first: FALSE
#tcp.try_heuristic_first: FALSE
#tecmp.try_heuristic_first: FALSE
#tipc.try_heuristic_first: FALSE
#udp.try_heuristic_first: FALSE
Chuckc gravatar imageChuckc ( 2024-06-28 21:03:26 +0000 )edit

Setting udp.try_heuristic_first to TRUE on the tshark command-line did get my dissector invoked. I'm still confused why Wireshark works differently, since checking the the UDP Preferences in it shows the pref is false, but my heuristic dissector works as expected.

zvonler gravatar imagezvonler ( 2024-06-28 21:31:02 +0000 )edit

This is for finding which heuristic is eating your data but might interesting to check the debug log.
LinkedIn: heuristic debug
6712: epan: ws_debug log for heuristic that claims frame (len != 0)
Without your setup (profiles, recent, others?) this would be hard to recreate.
If you can recreate it, run Wireshark from a console with debug logging on.

C:\>wireshark --log-level debug

 ** (wireshark:7756) 08:42:43.698629 [Epan DEBUG] C:\gitlab-builds\builds\MsQ3pox2\1\wireshark\wireshark\epan\packet.c:2961 -- dissector_try_heuristic(): Frame: 4 | Layers: frame:eth:ethertype:ip:tcp:websocket | Dissector: websocket_tcp


Excellent work on the submission including how to recreate the sample data.
I'm overdue to add/update an entry on the Wiki for how to "Ask" questions. Ok to copy over there?

Chuckc gravatar imageChuckc ( 2024-06-29 00:46:51 +0000 )edit

Thanks, sure you can use what I wrote as part of an example question.

I tried the --log-level debug and I get a lot of output but nothing about where the packets are going, neither with tshark or Wireshark. They're both version v4.2.5-0-g4aa814ac25a1.

zvonler gravatar imagezvonler ( 2024-07-01 13:54:46 +0000 )edit

2 Answers

Sort by » oldest newest most voted
0

answered 2024-06-29 19:18:35 +0000

Guy Harris gravatar image

With the script modified so that I can 1) have it run the programs from a build tree for main-branch Wireshark, 2) have it run TShark with -2, and 3) run it with Wireshark rather than TShark, I find that, when running from the main-branch build tree:

  1. with TShark and no -2, I get:

    Heuristic dissector:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, overriding infiniband.try_heuristic_first to true:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, InfiniBand disabled:
    prop dissector invoked
        1 0.000000000     10.1.1.1 → 10.2.2.2     PROP 60 65432 → 4791 Len=8
    
  2. with TShark and -2, I get:

    Heuristic dissector:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, overriding infiniband.try_heuristic_first to true:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, InfiniBand disabled:
    prop dissector invoked
    prop dissector invoked
        1 0.000000000     10.1.1.1 → 10.2.2.2     PROP 60 65432 → 4791 Len=8
    
  3. with Wireshark, I get:

    Heuristic dissector:
    1   2024-06-29 11:57:27.000001000   10.1.1.1    10.2.2.2    RRoCE   60  [Malformed Packet]
    Heuristic dissector, overriding infiniband.try_heuristic_first to true:
    1   2024-06-29 11:57:27.000001000   10.1.1.1    10.2.2.2    RRoCE   60  [Malformed Packet]
    Heuristic dissector, InfiniBand disabled:
    prop dissector invoked
    prop dissector invoked
    prop dissector invoked
    prop dissector invoked
    prop dissector invoked
    prop dissector invoked
    1   2024-06-29 11:57:27.000001000   10.1.1.1    10.2.2.2    PROP    60  65432 → 4791 Len=8
    

(the Wireshark is a mixture of stuff printed to the terminal and a summary line copied from the display, for each test).

With the Wireshark 4.2.5 installed on my machine:

  1. with TShark and no -2, I get:

    Heuristic dissector:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, overriding infiniband.try_heuristic_first to true:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, InfiniBand disabled:
    prop dissector invoked
        1 0.000000000     10.1.1.1 → 10.2.2.2     PROP 60 65432 → 4791 Len=8
    
  2. with TShark and -2, I get:

    Heuristic dissector:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, overriding infiniband.try_heuristic_first to true:
        1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
    Heuristic dissector, InfiniBand disabled:
    prop dissector invoked
    prop dissector invoked
        1 0.000000000     10.1.1.1 → 10.2.2.2     PROP 60 65432 → 4791 Len=8
    
  3. with Wireshark, I get:

    Heuristic dissector:
    1   2024-06-29 12:08:22.000001000   10.1.1.1    10.2.2.2    RRoCE   60  [Malformed Packet]
    Heuristic dissector, overriding infiniband.try_heuristic_first to true:
    1   2024-06-29 12:08:22.000001000   10.1.1.1    10.2.2.2    RRoCE ...
(more)
edit flag offensive delete link more

Comments

I am running v4.2.5-0-g4aa814ac25a1 on MacOS. The -2 switch does nothing for tshark on my machine at all -- in your output I see it triggers the print() call twice but I don't get that. Here's the output I get from my updated script:

Heuristic dissector:
    1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
Heuristic dissector, two passes:
    1 0.000000000     10.1.1.1 → 10.2.2.2     RRoCE 60 [Malformed Packet]
Heuristic dissector, forcing udp.try_heuristic_first to true:
prop dissector invoked
    1 0.000000000     10.1.1.1 → 10.2.2.2     PROP 60 65432 → 4791 Len=8
Heuristic dissector, two passes and forcing udp.try_heuristic_first to true:
prop dissector invoked
    1 0.000000000     10.1.1.1 → 10.2.2.2     PROP 60 65432 → 4791 Len=8
Heuristic dissector, InfiniBand disabled:
prop dissector invoked
    1 0.000000000 ...
(more)
zvonler gravatar imagezvonler ( 2024-07-01 14:19:11 +0000 )edit

Here is the updated script:

#!/bin/bash

set -e
set -u

TEXT2PCAP=/Applications/Wireshark.app/Contents/MacOS/text2pcap
TSHARK=/Applications/Wireshark.app/Contents/MacOS/tshark
UDP_SRC_PORT=65432
UDP_DST_PORT=4791
PCAP_FN=udp_packet.pcap

cat <<EOF | ${TEXT2PCAP} -qu "${UDP_SRC_PORT},${UDP_DST_PORT}" - ${PCAP_FN}
0000    01 23 45 67 89 ab cd ef
EOF

cat >heuristic_dissector.lua <<EOF
-- This heuristic dissector works in Wireshark with the default preference of
-- udp.try_heuristic_first: FALSE
-- but it does not work in tshark without setting that preference to TRUE or
-- disabling the InfiniBand protocol.

local proto = Proto("prop", "PROP")

function proto.dissector(buffer, pinfo, root)
    print("prop dissector invoked")
    root:add(proto, buffer())
    pinfo.cols.protocol = proto.name
    return buffer:len()
end

local udp_dstport = Field.new("udp.dstport")
proto:register_heuristic("udp", function (buffer, pinfo, root)
    if udp_dstport()() == ${UDP_DST_PORT} then
        proto.dissector(buffer, pinfo, root)
        return true
    end
    return false
end)
EOF

test_dissector () {
    echo "$1:"
    ${TSHARK} -X lua_script:heuristic_dissector.lua ...
(more)
zvonler gravatar imagezvonler ( 2024-07-01 14:19:31 +0000 )edit
0

answered 2024-06-28 21:07:20 +0000

johnthacker gravatar image

infiniband.try_heuristic_first means when dissecting payloads within Infiniband to try heuristic dissectors first. If you want the UDP dissector to try its heuristics first before calling Infiniband for the registered port, then you would want the udp.try_heuristic_first preference. (You may have that enabled in the Wireshark profile you are using; you can specify a non default profile on the tshark command line too.)

If your protocol always uses that port, though, perhaps it doesn't need to be a heuristic protocol but could be registered to that port instead and Infiniband disabled.

edit flag offensive delete link more

Comments

Thanks for the explanation. Setting udp.try_heuristic_first to TRUE on the tshark command-line did get my dissector invoked. I'm still confused why Wireshark works differently, since checking the the UDP Preferences in it shows the pref is false, but my heuristic dissector works as expected.

zvonler gravatar imagezvonler ( 2024-06-28 21:29:06 +0000 )edit

A general guideline is that when tshark and Wireshark produce different results, try running tshark in two-pass mode (-2) and see if that makes tshark output more closely match Wireshark.

Two pass mode can't work for live capture, but the GUI output always reflects dissecting frames a second time after the initial sequential pass.

johnthacker gravatar imagejohnthacker ( 2024-06-29 14:53:11 +0000 )edit

A general guideline is that when tshark and Wireshark produce different results, try running tshark in two-pass mode (-2) and see if that makes tshark output more closely match Wireshark.

As per my long answer, at least for me, in this case there appears to be no difference between the behavior of Wireshark, the behavior of TShark without -2, and the behavior of TShark with -2.

Guy Harris gravatar imageGuy Harris ( 2024-06-29 19:55:02 +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

1 follower

Stats

Asked: 2024-06-28 19:51:19 +0000

Seen: 90 times

Last updated: Jun 29