I’ve been doing some work in a Linux VM recently, and having to use secure copy (scp) every time just to copy a tcpdump capture to my MacOS machine to inspect it with Wireshark is not very fun.

        VM                              MACOS

tcpdump --> capture
                                scp linux --> /tmp/capture
                                wireshark /tmp/capture

Given that Wireshark can inspect packets flowing in real time, what if Wireshark perform the equivalent of a tail -f operation on a given packet file?

It turns out that this is possible and pretty simple.

tl;dr: wireshark -k -i <(tail -f -c +0 $PCAP_FILE)

What’s behind tail

While tail is pretty much just what it claims to be (a program that outputs the last part of a given fail), it has a pretty neat functionality of being able to “follow” a file (keep track of its status), and, whenever new things come (content gets appended to it), print to stdout these additions.

file_fd = open(/tmp/file.txt)
notification_fd = inotify(file_fd)

  1. tail initializes inotify to keep track of changes happening to a file (let’s say, file.txt;
  2. then it waits for a change on the underlying file;
  3. when the change occurs, tail then reads all that has not been read so far and then keeps track of the position where it was; then
  4. when a new change occurs, does the same thing: reads everything from the old position until the end (read(2) keeps track of the offset under the hood - seeking is only needed at the first time, assuming that arguments like -c and -n are specified).

If you’re curious to see this in practice, you can either check the source code or set up a simple test scenario where you can strace the execution of tail -f.

Opening a capture file with Wireshark

Having installed Wireshark on my MacOS using the regular procedure (downloading the package and then performing the regular installation), wireshark binary should already be in your $PATH.

Looking at the help (wireshark --help), we can see an interesting option to use (-r):

wireshark --help
Wireshark 2.6.2 (v2.6.2-0-g1b3cedbc)
Interactively dump and analyze network traffic.

Input file:
  -r <infile>   set the filename to read 
                from (no pipes or stdin!)

Reading tcpdump packet capture in realtime with Wireshark

While being able to read a packet capture in Wireshark is already interesting by itself, it doesn’t solve the problem stated at the beginning of the blog post.

Ideally, it’d be interesting if Wireshark was able to handle the result of a tail -f that could come to it either via stdin (we could pipe tail -f to wireshark), or via a pipe (we could provide the pipe to a flag).

while new_packets:
        tcpdump --->

Having no success with the first option (supplying stuff via stdin), I went with the second (supplying a pipe to -r, the option that makes Wireshark read from a file):

# Execute the `wireshark` binary with the result 
# of the bash process substitution as the argument 
# of `-r`.
# The process substitution creates a temporary
# pipe that takes the output of the `tail -f`
# process and makes it readable by `wireshark`.
wireshark \
        -r <(tail -f -c +0 /tmp/capture.pcap)
Wireshark complaining about file being a pipe
Wireshark not happy with file being a pipe

No success, but, a pretty clear direction: use -i.

Replace -r with -i and see it “not failing” (nothing starts):

wireshark \
        -i <(tail -f -c +0 /tmp/capture.pcap)

That’s because we’re missing an extra flag (-k): the one that tells Wireshark to start capturing the packets right away:

wireshark \
        -k \
        -i <(tail -f -c +0 /tmp/capture.pcap)

Closing thoughts

It’s great how we can combine something like bash process substitution with a program like Wireshark and achieve a much better result compared to what I had before.

As I’ve decided to go with a MacbookPro for personal use while I still do a bunch of Linux development, having these tricks under the belt helps a lot.

Do you have some that you use all the time as well?

Please let me know!

By the way, if you want to get in touch, I’m very open - reach me at @cirowrc on Twitter!