为什么scapy没有捕获VLAN标记信息?

时间:2013-09-25 00:22:55

标签: python networking raspberry-pi scapy

我一直在使用我的覆盆子pi作为嗅探器,并观察到tcpdump和scapy之间的一些有趣的差异。我看到以下内容:


流量生成器机器,带有scapy的Linux机箱:

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,来自' 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

即使我尝试:

>>> Dot1Q in pkt[0]
False


有谁知道为什么scapy无法捕获(解析?)vlan框架,但tcpdump认为它很好?

(PS我也嗤之以鼻,导出一个pcap文件,然后用tcpdump读取pcap文件...... vlan标签消失了......消失了......)

=======================

对于那些感兴趣的人,我现在的解决方法是使用tcpdump捕获到pcap文件,然后在scapy中使用rdpcap()来加载这些数据,这样我就可以使用scapy强大的解析功能来探索捕获 - 这引入了一层缓存,以及一个讨厌的系统调用我的程序,但获得可靠的vlan信息......

=======================

根据RyPeck的回答和GuyHarris的建议,我现在有一个更好的解决方法:

a)使用http://sourceforge.net/projects/pylibpcap/

import pcap
conf.use_pcap=True

b)使用pcappy - 可以安装:pip install pcappy

import pcappy as pcap
conf.use_pcap=True

现在scapy显示与tcpdump相同的vlan信息,所有它的解析功能都完好无损!

2 个答案:

答案 0 :(得分:4)

最近在Scapy邮件列表here中对此进行了讨论。

  

正如我所说,并指出,早些时候,vlan层被剥离了   在scapy之前的内核或tcpdump得到它。但是tcpdump现在已经得到了支持   把它加回来。因此,您可以为scapy创建一个支持此功能的票证   也是增强。 - Philippe Biondi(Scapy发明家)

这解释了为什么VLAN层正在消失。除了获取潜在的功能请求/票证之外,此时无需执行任何操作。随意在Scapy BitBucket创建一个。

@ GuyHarris offered a different potential solution,在tcpdump中具有上述功能将添加对Scapy的支持,如果您的Scapy安装使用libpcap来捕获数据包,这将适用于您。

答案 1 :(得分:2)

我试着做你说的但是没有用。 'conf.L2listen'仍然使用'PF_PACKETS'而不是libpcap。我开始查看代码并发现'conf.use_pcap'仅在'pcapdnet'模块中处理。这意味着如果你不导入它,'conf.use_pcap'将被丢弃并且'conf.L2listen'保持'PF_PACKETS'而不是更改为'L2pcapListenSocket'(这是绑定到libpcap的套接字)。

解决方案很简单:

conf.use_pcap = True
import scapy.arch.pcapdnet 

确保在更改配置后导入模块,否则无效。 如果你看一下,你可以检查它是否有效:

conf.L2listen

,值为:

 <L2pcapListenSocket: read packets at layer 2 using libpcap>

如果值为:

,则无效
<L2ListenSocket: read packets at layer 2 using Linux PF_PACKET sockets>