Saturday, 23 April 2011

How to capture VM network traffic using qemu -net dump

This post describes how to save a packet capture of the network traffic a QEMU
virtual machine sees. This feature is built into QEMU and works with any
emulated network card and any host network device except vhost-net.

It's relatively easy to use tcpdump(8) with tap networking. First the
tap device for the particular VM needs to be identified and then packets can be
# tcpdump -i vnet0 -s0 -w /tmp/vm0.pcap

The tcpdump(8) approach cannot be easily used with non-tap host network devices, including slirp and socket.

Using the dump net client

Packet capture is built into QEMU and can be done without tcpdump(8). There are some restrictions:
  1. The vhost-net host network device is not supported because traffic does not cross QEMU so interception is not possible.
  2. The old-style -net command-line option must be used instead of -netdev because the dump net client depends on the mis-named "vlan" feature (essentially a virtual network hub).

Without further ado, here is an example invocation:
$ qemu -net nic,model=e1000 -net dump,file=/tmp/vm0.pcap -net user
This presents the VM with an Intel e1000 network card using QEMU's userspace network stack (slirp). The packet capture will be written to /tmp/vm0.pcap. After shutting down the VM, either inspect the packet capture on the command-line:
$ /usr/sbin/tcpdump -nr /tmp/vm0.pcap

Or open the pcap file with Wireshark.


  1. where is the tmp directory

  2. Hi Stephan
    Thanks for the info. Your post seems to be one of the few that pointed me in the right direction. I'm using a setup where a network using Qemu/kvm and Virsh has networking using UDP encap on Most of the traffic I was interested in is not on a vnet interface but is multiplexed on the loopback interface with a UDP header. Initially with tcpdump on lo I got too many packets and it was not decoded by wireshark.

    In order to capture only what I wanted and decode the packets I had to do: virsh dumpxml 3 where 3 was the id of the VM I got from virsh list. Then I looked at the dumpxml output to find interface I wanted (swp1 in my case) to trace and find the corresponding UDP ports.
    source address='' port='20002'
    local address='' port='21002'
    target dev='swp1'
    model type='virtio'

    Using this info I could now filter the tcpdump by port with:
    sudo tcpdump port 21002 -i lo -s0 -w /tmp/lo.pcap
    where lo is the loopback and finally:

    editcap -C42 lo.pcap newlo.pcap
    to return the output to non UDP encap. (42 is of course the answer to everything and the size of the UDP header!)
    That newlo.pcap is then read correctly by Wireshark.

  3. Is there a way I can capture the packets if I am using a socket interface to send/receive packets between two qemu guests?

    1. Are you using -netdev socket? In that case, use tcpdump/Wireshark on the host to capture the traffic on that socket. Each guest packet consists of a 32-bit length field followed by the packet. I'm not sure if Wireshark has a dissector to decapsulate QEMU's -netdev socket protocol.

  4. Great tips, many thanks for sharing. I have traffic and mobile internet on the VM network traffic! I like this blog. For more details look at more info