I've been using my raspberry pi as a sniffer, and have observed some interesting differences between tcpdump and scapy. I am seeing the following:
Traffic Generator Machine, Linux Box with scapy:
sendp(Ether(dst='ff:ff:ff:ff:ff:ff',src="AA:00:00:00:00:00")/Dot1Q(vlan=10)/IP()/ICMP())
Raspberry Pi, ala 'tcpdump':
00:25:10.156830 aa:00:00:00:00:00 (oui Unknown) > Broadcast, ethertype 802.1Q (0x8100),length 60: vlan 10, p 0, ethertype IPv4, localhost > localhost: ICMP echo request, id 0, seq 0, length 8
Rasperry Pi, via 'scapy':
>>> pkt[0].show()
###[ Ethernet ]###
dst= ff:ff:ff:ff:ff:ff
src= aa:00:00:00:00:00
type= 0x800
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len=28
id= 1
flags=
frag= 0L
ttl= 64
proto= icmp
chksum= 0x7cde
src= 127.0.0.1
dst= 127.0.0.1
\options\
###[ ICMP ]###
type= echo-request
code= 0
chksum= 0xf7ff
id= 0x0
seq= 0x0
###[ Padding ]###
load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' None
Even when I try:
>>> Dot1Q in pkt[0]
False
Does anyone know why scapy is unable to capture (parse?) the vlan frame, but tcpdump sees it fine ?
(PS I also sniffed with scapy, and exported a pcap file, and then read the pcap file with tcpdump... the vlan tags are gone... disappeared... )
=======================
For those interested, my workaround for now is to use tcpdump to capture to a pcap file, and then use rdpcap() in scapy to load that data, so I can use scapy's powerful parsing features to explore the capture- this introduces a layer of caching, and a nasty system call into my program, but gets me reliable vlan information...
=======================
Based on RyPeck's answer and GuyHarris's advice, I now have a much better workaround:
a) Using http://sourceforge.net/projects/pylibpcap/
import pcap
conf.use_pcap=True
b) Using pcappy - which is can be installed with: pip install pcappy
import pcappy as pcap
conf.use_pcap=True
Now scapy shows the same vlan information as tcpdump, with all it's great parsing features intact!