52

Is there any port monitoring tool to watch the packets written on the port? I especially want to check if my program written in Java works so I need some kind of tool to see if my little application is writing the messages to the port. How do I do this?

2

10 Answers 10

45

is a tool to connect (nearly) everything to (nearly) everything, and can duplicate streams.
In your usecase you could connect your serial port /dev/ttyS0 to a PTY /tmp/ttyV0, then point your application to the PTY, and have socat tee out Input and Output somewhere for you to observe.

Googling "socat serial port pty tee debug" will point you to several "standard procedure" examples, one being:

socat /dev/ttyS0,raw,echo=0 \
SYSTEM:'tee in.txt |socat - "PTY,link=/tmp/ttyV0,raw,echo=0,waitslave" |tee out.txt'

The files in.txt and out.txt will then contain the captured data.

Updated after comments:

  • The socat syntax looks confusing at first, but in fact, it's just 2 nested statements.
    A small price to pay to such a powerful, versatile tool.
  • If you need to setup your serial port, or send other ioctls, do so before calling socat, as socat cannot proxy them.
  • The single-purpose-tool interceptty from 2006 has slightly simpler syntax, but can only intercept TTYs (while proxying ioctls), and is probably not in your package manager. (Most Linux distros never added it to their repos)
4
  • @peterh-ReinstateMonica What do you need to proxy the ioctl calls for? If it's just changing the baudrate, try stty -F /dev/ttyS0 19200. Technically, it should be possible by intercepting the system call using LD_PRELOAD, same as padsp.
    – hackerb9
    Mar 15 '20 at 9:55
  • @alex-stragies: I like socat, but the syntax is just too cumbersome. For this simple problem, I found the interceptty solution posted below to be much simpler: interceptty /dev/ttyS0 is all you need to create a PTY called /tmp/interceptty that can then be used by any program as a serial port.
    – hackerb9
    Mar 15 '20 at 9:59
  • 1
    @hackerb9 As of 03/2020, interceptty is not in debian package management, not even testing, so -for me and some others- not a viable solution for many situations. And the syntax is only cumbersome the first 5-8 times ;) Mar 15 '20 at 13:03
  • Fair enough. I also tend to stick with software that's been vetted by Debian. Interceptty, despite the author disappearing, seems to be well written. A simple ./configure && make && sudo make install worked for me.
    – hackerb9
    Mar 16 '20 at 22:06
21

I don't think the serial driver has any tracing functionality that would allow you to watch packets. You can use strace to observe all the reads and writes from your application:

strace -s9999 -o myapp.strace -eread,write,ioctl ./myapp
5
  • 1
    can is send packets to the port if nothign is connected ?
    – Deepak
    Apr 30 '11 at 12:53
  • strace will tell you if it tried to send characters to the port, and what the kernel responded with when it tried. depending on your flow control settings characters may arrive at the disconnected TXD pin or may not.
    – Jasen
    Jun 28 '18 at 5:19
  • Thanks, have a look at my dynamic strace, based on this answer!
    – F. Hauri
    Oct 29 '19 at 17:32
  • This works, but is an overkill in the sense that it'll monitor accesses to all files instead of the single /dev/tty* we're interested in.
    – Ruslan
    Jan 14 '20 at 9:31
  • This got me going in the direction I needed. I have a hardware widget with a serial interface that I can only find an ancient Windows-32 app to control, and I was looking to monitor all of it's traffic while running under wine to try and reverse-engineer it in hopes of making a new library. I found that adding the -P option limits strace to only my device, and I also needed -f to watch the child/fork processes: strace -o wine.strace -f -s 9999 -x -P /dev/ttyUSB0 wine start 'c:/Program Files (x86)/mydir/myapp.exe'
    – JustinB
    Apr 30 '20 at 17:45
17

I found projects called Linux Serial Sniffer, jpnevulator, and Moni. The first two look like they do exactly what you want. The last one calls itself a monitor, but it actually looks like a standard serial communication program.

7
  • 1
    thanks for that !! i will give it a try. by the way i solved the issue from my java side. i was missing a \r, so that prevented my message from writing on to the port. thanks for that anyways!!
    – Deepak
    Apr 30 '11 at 18:24
  • 4
    The «LInux Serial Sniffer» is buggy, it absolutely takes out incoming data, thus another application which is actually listen to serial see nothing. But, at least, the data that goes outside seems to go without problem.
    – Hi-Angel
    Mar 31 '15 at 11:12
  • 3
    From the jpnevulator FAQ: "Jpnevulator was never built to sit in between the kernel and your application."
    – Shelvacu
    Jun 12 '17 at 2:14
  • 1
    The link referring to Moni is dead.
    – Yaron
    Dec 12 '18 at 15:24
  • 2
    -1 because of 3 comments: LInux Serial Sniffer is buggy, then Jpnevulator was never built to sit in between kernel and app and finaly Moni is dead... This answer just point to 3 externals links and don't give a real solution. (3 fail on 3 link, left nothing!)
    – F. Hauri
    Sep 20 '19 at 11:49
8

interceptty does that job:

interceptty /dev/ttyACM0 /dev/ttyDUMMY

or, with a nice output format and with configuring the backend device, and with line buffering:

interceptty -s 'ispeed 19200 ospeed 19200' -l /dev/ttyACM0 /dev/ttyDUMMY | interceptty-nicedump

and then connect with your programme to /dev/ttyDUMMY.

4
  • 1
    @AlexStragies: I have it on my arch linux system. AUR page: aur.archlinux.org/packages/interceptty, copy of the sources: repo.j5lx.eu/archive/interceptty/interceptty-0.6.tar.gz Apr 3 '17 at 10:22
  • I had to download it (using wget since clicking on the .tar.gz file seemed to corrupt it somehow), install gcc and make, then run ./configure and make install. Does exactly what the OP and I want though. May 31 '17 at 23:18
  • 1
    Your answer is far the best.
    – peterh
    Jan 29 '19 at 15:35
  • Worked great on Debian GNU/Linux. Was able to intercept a Windows program (running in Wine) with a simple ln -s /tmp/interceptty ~/.wine/dosdevices/com5. Excellent answer.
    – hackerb9
    Mar 15 '20 at 9:33
6

This is the way I finally choose

Thanks to Gilles's answer!

strace -s 9999 -e read -ffp $(sed '/ttyUSB0/s/^.*proc.\([0-9]\+\).fd.*/\1/p;d' <(ls -l /proc/[1-9]*/fd/* 2>/dev/null)) 2>&1 | perl -e '$|=1;my %qa=('a'=>7,'b'=>10,'e'=>33,'f'=>14,'n'=>12,'r'=>15,'t'=>11);sub cnv { my $ch=$_[0];$ch=$qa[$1] if $ch=~/([abefnrt])/;return chr(oct($ch));  };while (<>) { /^read.\d+,\s+"(.*)",\s\d+.*$/ && do { $_=$1;s/\\(\d+|[abefnrt])/cnv($1)/eg;print; };};'

Sorry, I will explain...

#!/bin/bash

strace -s 9999 -e read -ffp $(
    sed "/tty${1:-USB0}/s/^.*proc.\([0-9]\+\).fd.*/\1/p;d" <(
        ls -l /proc/[1-9]*/fd/* 2>/dev/null
    )
) 2>&1 |
    perl -e '
        $|=1;
        my %qa=('a'=>7,'b'=>10,'e'=>33,'f'=>14,'n'=>12,'r'=>15,'t'=>11);
        sub cnv {
            my $ch=$_[0];
            $ch=$qa[$1] if $ch=~/([abefnrt])/;
            return chr(oct($ch));
        };
        while (<>) {
            /^read.\d+,\s+"(.*)",\s\d+.*$/ && do {
                $_=$1;
                s/\\(\d+|[abefnrt])/cnv($1)/eg;
                print;
            };
        };
    '
  • I use ls -l /proc/[0-9]*/fd/* | grep ttyUSB0 instead of lsof ttyUSB0 because I seen them sometime slow.
  • So strace will trace current program using ttyUSB0
  • Syntax: tty${1:-USB0} will permit, used as a script or function, to run them with serial device name as argument: ttySniff USB0 or ttySniff S0 and so on.
  • Perl script will unbackslash strings logged by strace -s 9999.
  • You could replace strace -e read by strace -e read,write or strace -e write depending on your need.

Note: I run them by using syntax:

 script -t ttySniff.log 2>ttySniff.tm -c "./ttySniff.sh USB0"

so I could replay the whole operation and trace timing executions.

2
  • There is no security consideration, about what could be comming by serial port!
    – F. Hauri
    Oct 29 '19 at 17:35
  • Awesome, work well, thanks!
    – techno
    Oct 31 '19 at 11:36
3

When I debug interaction of my application with a serial port, I use moserial.

1
  • 5
    What're you talking about, in the docs written it's just a terminal.
    – Hi-Angel
    Mar 31 '15 at 10:53
2

Try this:

screen /dev/tty.usbserial-blahblah 9600

works for me.

1
  • 27
    This opens the port and assumes control over it, so nothing else can use it. This does not "monitor" or "sniff" the traffic.
    – Ian M
    Jan 23 '15 at 7:12
1

Have a look at ttyUSBSpy. It is on alpha stage, but it works.

2
  • 2
    It doesn't. It is written in python, and the code does import some import pcopy, which is even Google gave up to find.
    – Hi-Angel
    Mar 31 '15 at 10:43
  • 2
    Software/Homepage looks abandoned. Is not in package managers. Apr 16 '17 at 16:28
1

minicom is missing from the list of tools to monitor serial ports. Use it as for example to listen to arduino device:

minicom --device /dev/ttyACM0 --baud 9600

1
  • 1
    OP wrote "monitor", but meant "sniffer" ( = is able to read traffic in transit), while minicom is a serial port "client", and as such is not an answer to this question. The answer below from mike made the same mistake, and the comment there explains the terminology problem as well. Mar 17 '19 at 21:03
0

I use Wireshark. Here you can find a complete how-to guide and here the USB filter reference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.