scapy-python中的'haslayer'函数无法工作
我正在尝试写一段简单的代码,用来检测 ICMP 数据包的源 IP 地址,使用的是 scapy
这个库。问题是 haslayer
这个函数似乎没有返回任何结果。
from scapy.all import *
while 1:
pkt = sniff ( iface="eth0" , count = 1 )
pkt.summary()
try:
if pkt.haslayer(IP):
ipsrc =pkt.getlayer(IP).src
print ipsrc
except:
pass
结果是
Ether / IP / ICMP 10.0.2.15 > 10.0.2.11 echo-request 0 / Raw
Ether / IP / ICMP 10.0.2.15 > 10.0.2.11 echo-request 0 / Raw
Ether / IP / ICMP 10.0.2.15 > 10.0.2.11 echo-request 0 / Raw
所以我无法获取 ICMP 请求的源 IP 地址。有没有什么想法?
2 个回答
1
@Hussam - 你不需要用循环,但如果你用语法 pkt = sniff(),那么它会返回一个数组。另一种写法是:
#!/usr/bin/env python
from scapy.all import *
pkt = sniff(count=1, filter="ip")
if pkt[0].haslayer(IP):
print pkt[0][IP].src
你也可以通过传递一个函数给sniff()来实现,这样每个数据包都会作为一个单独的数据包传递给这个函数,而不是作为一个数组。一个例子是:
#!/usr/bin/env python
from scapy.all import *
def print_ip_src(pkt):
if pkt.haslayer(IP):
print pkt[IP].src
sniff(prn=print_ip_src, filter="ip")
注意,这里没有循环,也没有从函数中赋值给变量。这个方法会一直运行,每个数据包都会被发送到我包含的print_ip_src()函数。
附注:我使用了BPF过滤器来只捕获IP数据包,但无论如何你还是应该包含haslayer()函数,作为一种安全措施。
1
你用的这个通用的 except
会掩盖你代码可能遇到的任何错误。把 pass
改成 raise
,然后去掉任何具体的错误信息。例如,我在你的代码中第一次遇到的问题是:
socket.error: [Errno 1] Operation not permitted
然后在以 root
身份运行后,我得到了:
AttributeError: 'list' object has no attribute 'haslayer'
这让我把代码改成了一个能正常工作的版本(以 root
身份运行):
from scapy.all import *
while 1:
pktl = sniff ( iface="eth0" , count = 1 )
pktl.summary()
for pkt in pktl:
try:
if pkt.haslayer(IP):
ipsrc =pkt.getlayer(IP).src
print ipsrc
except:
raise
所以你可能最好是干脆把 try - except 整个去掉。