Ryan Govostes

Serial Capture to PCAP

I am publishing serial2pcap, a humble toolbox of scripts to convert traces of serial device traffic into fake network packet captures that can be analyzed with more familiar tools like Wireshark or Scapy.

In my work in marine robotics, I regularly develop drivers to integrate sensors and instruments that communicate over serial into autonomous platforms. These instruments are typically built to run standalone with a vendor's GUI application, and since few customers do custom software integrations, these serial protocols are often underspecified, if they're documented at all.

Accordingly, driver development usually raises the need to be able to capture serial traffic, either from the first-party application to understand the protocol, or from an instrument in the field to troubleshoot our implementation. In one recent headscratcher, a capture was key to determining why our driver was rejecting 0.004% of messages: an off-by-one bug in the checksum calculation.

Unfortunately, tooling for capturing and analyzing serial traffic is not as convenient as network analysis tools like Wireshark or tcpdump. On Linux, I've sometimes gotten by with interposing traffic with pseudoterminals, or snooping read and write system calls with strace. On Windows, Portmon seems to be defunct, with one successor being Electronic Team Serial Port Monitor ($100).

Enter serial2pcap, which converts traces produced by strace or Serial Port Monitor into PCAP files:

strace -e read,write -s 65535 -tt -xx -o strace.log -- cmd
python3 strace2text.py --fd=3 < strace.log \
    | text2pcap -D -t iso -u 1234,1234 - - \
    | tshark -V -O data -r -

Each script is under 50 lines—it just needs to output in a format that text2pcap understands. The command above synthesizes UDP traffic between two devices from this ASCII hex dump:

I 06:48:47.728605
000000 2a 55 34 35 0d 0a
000006

O 06:48:47.732256
000000 2f 31 26 0d
000004

I 06:48:47.732456
000000 ff 2f 30 60 45 5a 53 65 72 76 6f 28 52 29 20 76
000010 32 2e 38 31 20 31 31 2d 33 30 2d 30 37 20 20 20
000020 20 20 03 0d 0a
000025

Note that these tools are only looking at data transmission, rather than configuration settings like baud rate or flow control, and they ignore signal line events like RTS, etc.

There's also no expectation that read or write system calls take place exactly on a data unit boundary, so one would need to reassemble the traffic into discrete packets. Conveniently, I've written about developing custom Wireshark dissectors for exactly this purpose.