Hey,
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
- Opening a capture file with Wireshark
- Reading tcpdump packet capture in realtime with Wireshark
- Closing thoughts
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)
while(1):
select(notification_fd)
print(read(fd))
tail
initializesinotify
to keep track of changes happening to a file (let’s say,file.txt
;- then it waits for a change on the underlying file;
- 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 - 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 --->
/tmp/capture.pcap
------>
wireshark
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)
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!
Cheers