scapy-python中的'haslayer'函数无法工作

3 投票
2 回答
9645 浏览
提问于 2025-04-17 19:55

我正在尝试写一段简单的代码,用来检测 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 整个去掉。

撰写回答