The task.

Let’s say that you need to capture traffic with tcpdump.

But you want to analyze it with wireshark.

Easy, you save a .pcap and read it.


Ok, not that fast!

Sometimes, saving and reading the file is limiting, maybe you want to view the packets in real time.

And maybe you want to do that with Wireshark, either because you have some extractors defined or just because you like the point-and-click interface (we don’t judge here).

Or maybe your tcpdump version is crappy and does not show all fields, or it must run in Docker container (cough Mellanox cough).

        On a side note, everything originated when I was trying to debug PTP and some RDMA applications.
        The NIC will digest some packets (that's why you spend more bucks on them!) and packet never appears to the end host.

Named pipes

Luckily, on Linux, you can use named pipes. They resemble a file, but they do not physically live in the disk, and could beused by two programs running on the same system to exchange data.

First, create the pipe:

mkfifo -m a+rw /tmp/tcpdump_pipe

Then, start our Wireshark instance reading from the pipe:

wireshark -k -i /tmp/tcpdump_pipe

Finally, tell tcpdump to write there:

tcpdump -i $IFACE -l -w - > /tmp/tcpdump_pipe

Or, as in my case, if you need to run tcpdump in a container, use this rather long command:

sudo docker run -it --rm \
        -v /dev/infiniband:/dev/infiniband  \
        -v /tmp/tcpdump_pipe:/tmp/tcpdump_pipe \
        --net=host --privileged \
        mellanox/tcpdump-rdma \
        sh -c "tcpdump -i $IFACE -l -w - > /tmp/tcpdump_pipe"

Packets should now magically appear in WireShark.


But what if tcpdump is running on a remote machine? Let’s say an embedded device? Or your router?

One trick (that introduce too much overhead w.r.t. to what is actually needed) is to send everything through a TCP or UDP socket. We’ll do it with netcat, and we assume you are in the same subnet (oh please don’t run this over the Internet!):

  • On the capture device: tcpdump -i whatever -U -l | netcat -u yourhost yourport
  • On the receiving side: netcat -l -u port | wireshark -k -i -

You can remove the -u in the netcat command to use TCP. You may need to allow incoming packets on your machine’s firewall.

Even over ssh

You can also pipe it over ssh. But are you sure you want to do that?

Use this oh-god-so-long-command:

ssh yourhost "tcpdump -i any -U -s0 -w - 'not port 22'" | wireshark -k -i -

Note that 1) you may need to use sudo depending on your server’s settings and 2) that may require some trickery to pass the password such as askpass.

I am rich: I have an OpenFlow switch!

Ok, if you are also so crazy to use a Python controller for it (because the webui is boring!), then jump [here(../openflow_mirror) to see a more elegant solution.