Ask Your Question
0

How to add a dissector below USB/FTDI?

asked 2024-04-10 12:06:27 +0000

updated 2024-04-10 12:06:55 +0000

I want to write a dissector for a serial protocol but modern PCs use USB/FTDI serial converters. The data appears "in" the FTDI messages broken out by existing Wireshark dissectors so could someone point me at an example of how to register a dissector such that it happens below the existing USB/FTDI dissector?

edit retag flag offensive close merge delete

Comments

Do you have a sample capture or is there one here (11743: Add FTDI USB dissector) for discussion?

Is the data always in the same FTDI field (Display Filter Reference: FTDI FT USB)?

Are you open to trying Lua? (05: Extending Wireshark with Lua | Learn Wireshark @ SF22US)

Chuckc gravatar imageChuckc ( 2024-04-10 12:44:54 +0000 )edit

The data appears "in" the FTDI messages broken out by existing Wireshark dissectors so could someone point me at an example of how to register a dissector such that it happens below the existing USB/FTDI dissector?

If the data appears in the FTDI message, then the dissector would be above the FTDI dissector. Why do you want it below the FTDI dissector?

Guy Harris gravatar imageGuy Harris ( 2024-04-10 21:52:37 +0000 )edit

Guy, I've never written a Wireshark dissector so perhaps my terminology is wrong. I had assumed that that FTDI dissector would pass "down" to my dissector which would then parse the FTDI representation. Chuckc, I can get a sample tonight. The data I want to interpret appear as "TX Transmit/RX Transmit" in the FTDI messages that cover the actual transmission and receipt of data. I could try LUA, it's not a language I've used before but I have work colleagues who have used it in the past (I'm a software engineer but this is part of a fun "at home" project)

papadeltasierra gravatar imagepapadeltasierra ( 2024-04-11 07:43:16 +0000 )edit

Got a capture - now how to I attached it to this question? I will attached a single dissected frame below (sorry the comment mangles the formatting!). I care about the last byte (0x7f) that is the TX (or RX) payload. These are what form the protocol I care about.

Frame 2950: 28 bytes on wire (224 bits), 28 bytes captured (224 bits) on interface \\.\USBPcap1, id 0
    Section number: 1
    Interface id: 0 (\\.\USBPcap1)
        Interface name: \\.\USBPcap1
        Interface description: USBPcap1
    Encapsulation type: USB packets with USBPcap header (152)
    Arrival Time: Apr 11, 2024 18:23:47.262265000 GMT Daylight Time
    UTC Arrival Time: Apr 11, 2024 17:23:47.262265000 UTC
    Epoch Arrival Time: 1712856227.262265000
    [Time shift for this packet: 0.000000000 seconds]
    [Time delta from previous captured frame: 0.009654000 seconds]
    [Time delta from previous displayed frame: 4.134574000 seconds]
    [Time since reference or first frame: 16.597388000 ...
(more)
papadeltasierra gravatar imagepapadeltasierra ( 2024-04-11 17:30:19 +0000 )edit

Please put it on a public file share (Google, Onedrive, Dropbox, ...) and update the question with a link to it.

Chuckc gravatar imageChuckc ( 2024-04-11 17:32:15 +0000 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2024-04-11 20:20:12 +0000

Chuckc gravatar image

updated 2024-04-16 15:44:27 +0000

Starting point is EASYPOST.luafound on wiki: https://wiki.wireshark.org/lua#examples
Use Help->About Wireshark:Folders to locate the Personal Lua Plugins folder and save code below to a .lua file.

-- EASYPOST.lua
-- Replace occurrences of "easypost/EASYPOST" with protocol/dissector name.
-- Grab and format fields as needed

-- Step 1 - document as you go. See header above and set_plugin_info().
local easypost_info =
{
    version = "1.0.0",
    author = "Good Coder",
    description = "Important EASYPOST stuff",
    repository = "Floppy in top drawer"
}

set_plugin_info(easypost_info)

-- Step 2 - create a protocol to attach new fields to
local easypost_p = Proto.new("easypost","Important EASYPOST Protocol")

-- Step 3 - add some field(s) to Step 2 protocol
local pf = {    rx_payload = ProtoField.bytes("easypost.rx_payload", "EASYPOST RX data"),
                tx_payload = ProtoField.bytes("easypost.tx_payload", "EASYPOST TX data") }

easypost_p.fields = pf

-- Step 4 - create a Field extractor to copy packet field data.
easypost_rx_payload_f = Field.new("ftdi-ft.if_a_rx_payload")
easypost_tx_payload_f = Field.new("ftdi-ft.if_a_tx_payload")

-- Step 5 - create the postdissector function that will run on each frame/packet
function easypost_p.dissector(tvb,pinfo,tree)
    local subtree = nil

    -- copy existing field(s) into table for processing
    finfo = { easypost_rx_payload_f() }

    if (#finfo > 0) then
        if not subtree then
            subtree = tree:add(easypost_p)
        end
        for k, v in pairs(finfo) do
            -- process data and add results to the tree
            subtree:add(pf.rx_payload, v.range)
        end
    end


    finfo = { easypost_tx_payload_f() }

    if (#finfo > 0) then
        if not subtree then
            subtree = tree:add(easypost_p)
        end
        for k, v in pairs(finfo) do
            -- process data and add results to the tree
            subtree:add(pf.tx_payload, v.range)
        end
    end


end

-- Step 6 - register the new protocol as a postdissector
register_postdissector(easypost_p)

Frame 3003: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on interface \\.\USBPcap1, id 0
USB URB
FTDI FT USB
    Modem Status: 0x01, Full Speed 64 byte MAX packet
    Line Status: 0x00
        .... ..0. = Receive Overflow Error: False
        .... .0.. = Parity Error: False
        .... 0... = Framing Error: False
        ...0 .... = Break Received: False
        ..0. .... = Transmitter Holding Register Empty: False
        .0.. .... = Transmitter Empty: False
    A RX payload: 1f1f1f1f1f1f1f
Important EASYPOST Protocol
    EASYPOST RX data: 1f1f1f1f1f1f1f

240416 Update: add screenshot for discussion in comments below.
image description

TX data column is actually both TX and RX - easypost.tx_payload or easypost.rx_payload

edit flag offensive delete link more

Comments

Looks good. Will this framework also allow me to reconstruct messages from multiple FTDI messages? One protocol message is often split across multiple FTDI in the same manner as large IP requests split across multiple ethernet frames.

papadeltasierra gravatar imagepapadeltasierra ( 2024-04-15 14:28:08 +0000 )edit

Do you have a capture with an example of ftdi fragments?

ft232h-scan.pcapng attached to 11743: Add FTDI USB dissector shows reassembled fragments which are then passed to ftdi-mpsse.

Chuckc gravatar imageChuckc ( 2024-04-15 15:33:41 +0000 )edit

I think the file I posted (which I can't see above so will link below again) has fragments in. The protocol is the the bootloader/IAP protocol for stm8s processors but I'm having trouble locating the definition right now. The exchanges are all "TX/Rx/TX/RX..." with each TX or RX being a single command or response split over multiple FTDI messages typically. https://1drv.ms/u/c/4310f5ad2aba2bee/...

papadeltasierra gravatar imagepapadeltasierra ( 2024-04-16 07:34:15 +0000 )edit

This is the STM32S protocol, which I think is the same: https://www.st.com/resource/en/applic...

papadeltasierra gravatar imagepapadeltasierra ( 2024-04-16 07:57:30 +0000 )edit

You mentioned "stm8s processors". The capture data looks more like:
STM8 bootloader: um0560-stm8-bootloader-stmicroelectronics

Have you looked at Serial bootloader for STM8?
There is a comment here (Bare metal programming: STM8 (Part 2)) where they mention:

Wireshark is the best tool for the job if you want to sniff USB.

Chuckc gravatar imageChuckc ( 2024-04-16 13:51:37 +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-04-10 12:06:27 +0000

Seen: 326 times

Last updated: Apr 16