tcpdump can capture 802.1Q VLAN tagged traffic, but it requires a specific configuration to correctly identify and display the VLAN tags.
Let’s see tcpdump in action capturing VLAN tagged traffic. Imagine we have a network where traffic is tagged with VLAN ID 10. We want to capture this traffic on an interface, say eth0, and see the VLAN information.
sudo tcpdump -i eth0 -nn -Q -e vlan 10
Here’s what’s happening:
sudo tcpdump: We need root privileges to capture raw network traffic.-i eth0: This specifies the network interface to listen on. Replaceeth0with your actual interface name.-nn: This tellstcpdumpnot to resolve hostnames or port numbers. This is crucial for seeing the raw IP addresses and port numbers, which is often more useful when debugging network issues.-Q: This option is specific to some versions oftcpdumpand Linux kernels, and it tellstcpdumpto capture traffic with the VLAN tag. If this option doesn’t work for you, you might need to rely on thevlanfilter directly, or ensure your kernel supports it.-e: This option prints the link-level header, which is where the VLAN tag resides. Without this, you wouldn’t see the raw Ethernet frame structure, including the tag.vlan 10: This is the filter expression. It tellstcpdumpto only capture packets that are tagged with VLAN ID 10. You can use other VLAN IDs or even more complex filters.
When you run this command, you’ll see output similar to this:
09:15:30.123456 00:11:22:33:44:55 > 00:aa:bb:cc:dd:ee, ethertype 802.1Q (129), length 70: vlan 10, p 0, ethertype IPv4 (0x0800), broadcast 192.168.1.255 > 192.168.1.100: ICMP echo request, id 12345, seq 1, length 64
09:15:31.654321 00:11:22:33:44:55 > 00:aa:bb:cc:dd:ee, ethertype 802.1Q (129), length 70: vlan 10, p 0, ethertype IPv4 (0x0800), broadcast 192.168.1.255 > 192.168.1.100: ICMP echo reply, id 12345, seq 1, length 64
Notice the ethertype 802.1Q (129) and the vlan 10, p 0 fields. This clearly indicates that the packet is an 802.1Q tagged frame, and it belongs to VLAN 10. The p 0 refers to the priority code point (PCP) within the VLAN tag, which can be used for Quality of Service (QoS) prioritization.
The core problem tcpdump needs to solve is distinguishing between regular Ethernet frames and 802.1Q tagged frames. Standard Ethernet frames have an EtherType field that directly indicates the payload protocol (e.g., 0x0800 for IPv4, 0x86DD for IPv6). However, when VLAN tagging is used, the EtherType field is replaced with a special tag protocol identifier (TPID), which is 0x8100. Following the TPID is the Tag Control Information (TCI), which includes the VLAN ID and the PCP. tcpdump’s filtering mechanism needs to be aware of this structure.
The vlan <vlan_id> filter is the key here. It tells tcpdump to look for packets where the EtherType is 0x8100 and then inspect the following bytes to see if the VLAN ID matches the specified value. The -e option is essential because it displays the link-layer header, making the VLAN information visible in the output. Without -e, tcpdump might just show the IP packet and hide the underlying Ethernet frame details, including the VLAN tag.
If you don’t specify vlan <vlan_id>, tcpdump might still capture the tagged frames but will display them differently. For instance, it might show ethertype 802.1Q (129) followed by the actual payload EtherType (e.g., IPv4). The explicit vlan filter makes it much easier to isolate traffic for a specific VLAN.
The -Q option, if supported by your tcpdump and kernel, can sometimes be more efficient as it might allow the kernel to filter the VLAN traffic before it even reaches the tcpdump process. However, the vlan <vlan_id> filter is generally more portable and reliable.
One common pitfall is capturing on a trunk port that carries multiple VLANs. If you only specify vlan 10 and your interface is also carrying traffic for VLAN 20, you’ll only see the VLAN 10 traffic. To see all VLAN traffic, you would omit the vlan filter, and then you’d see output indicating ethertype 802.1Q (129) for all tagged frames, with the specific VLAN ID listed in the output line.
A more advanced scenario involves filtering by priority (PCP). You could use a filter like vlan and vlan_priority 3 to capture traffic tagged with VLAN ID 10 and a PCP of 3. This is useful for debugging QoS issues.
If you want to capture all VLAN-tagged traffic on an interface, regardless of the VLAN ID, you can simply use the vlan keyword:
sudo tcpdump -i eth0 -nn -e vlan
This will show you all packets with the 0x8100 EtherType. The output will then clearly indicate the specific VLAN ID for each captured frame.
The next challenge you’ll likely face is deciphering the output when multiple VLAN tags are present (Q-in-Q, IEEE 802.1ad). In such cases, tcpdump might display multiple vlan entries, and understanding which tag is the "outer" and which is the "inner" requires careful observation of the output format.