Scapy中的越野车行为

时间:2012-08-07 15:59:27

标签: python ip icmp scapy

我使用Scapy的函数send来发送将在路由器上生成ICMP数据包的数据包,并转储那些带有tcpdump的ICMP数据包,作为子进程启动。

然后,我将使用scapy的内置rdpcap函数将这些ICMP数据包读回我的程序。

嗯,事实证明rdpcap有时会弄乱某些内容,一旦我想查看我捕获的数据包,就会返回以下内容:

(InteractiveConsole)
>>> icmpPackets
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/scapy/plist.py", line 57, in __repr__
    if self._elt2pkt(r).haslayer(p):
AttributeError: 'NoneType' object has no attribute 'haslayer'

然后,我只需要在相同的参数上再次调用rdpcap,一切都将恢复正常:

>>> icmpPackets = rdpcap(tcpdumpFileName)
>>> icmpPackets
<icmpPackets.cap: TCP:0 UDP:0 ICMP:1428 Other:1>

这是一些错误,对吧?

编辑:好的,在我收到错误之前我做的一件事就是以下,这可能不是太正统,但我在伪造数据包时不需要以太网层。如果我删除这两行,我将不会收到任何此类错误:

for i in range(len(icmpPackets)):
        icmpPackets[i] = icmpPackets[i].getlayer(IP)

我之前在其他地方这样做过,从来没有遇到过问题。这里发生了什么?

1 个答案:

答案 0 :(得分:1)

您好,

我真的不明白为什么你用tcpdump而不是scapy来嗅探流量,但无论如何......你的问题不是Scapy中的错误,而是代码中的错误。您正在使用.getlayer(IP)替换每个数据包,如果数据包没有None层(例如,IP数据包),则返回ARP。因此,你获得后者的例外。

我认为你应该替换

icmpPackets = rdpcap(tcpdumpFileName)
for i in range(len(icmpPackets)):
    icmpPackets[i] = icmpPackets[i].getlayer(IP)

icmpPackets = PacketList([p[IP] for p in PcapReader(tcpdumpFileName) if IP in p])

首先,我认为它更像是“Pythonic”,而且它通过删除没有IP层的数据包来解决问题。或者你也可以使用,如果你想拥有没有Ether层的所有数据包:

icmpPackets = PacketList([p.payload for p in PcapReader(tcpdumpFileName)])

另外,如果您只想要icmp个数据包,可以在tcpdump(ICMP)中使用BPF过滤器进行过滤。