Scapy数据包嗅探器在每个嗅探到的数据包上触发一个动作

13
我正在使用pythonscapy来捕获实时网络流量。
capture=sniff(iface="<My Interface>", filter="tcp")

但是这个程序会嗅探每个网络数据包并将其添加到列表capture中,稍后可以处理这些数据包。

我想在嗅探到一个数据包后立即处理它并显示其中的一些字段。也就是说,在嗅探到一个数据包时,它将触发一个函数,我可以在该函数中分析该数据包。这将继续进行几次。

我已经准备好使用捕获的数据包列表使用的函数。但是我无法用它来处理每个实时数据包。

如何实现这一点?这是否可能通过scapy实现,还是我需要安装其他软件包?

2个回答

17

sniff函数的参数应该像下面的代码。

from scapy.all import *

def pkt_callback(pkt):
    pkt.show() # debug statement

sniff(iface="<My Interface>", prn=pkt_callback, filter="tcp", store=0)

store=0 表示不储存任何收到的数据包,而 prn 则表示将 pkt 发送给 pkt_callback

来源。

正如 Yoel 所提到的,如果只需要一个操作,可以使用 lambda 替代像这个例子中的新函数来处理 prn

sniff(iface="<My Interface>", prn = lambda x: x.show(), filter="tcp", store=0)

请阅读关于您在设置 store=0 上的声明的此答案 - Yoel
@Yoel 这不会对程序的执行产生任何影响。但是你觉得,在我们使用 prn 处理每个数据包时,将每个数据包附加到列表 (store=1) 中是否会增加额外的开销?我们真的需要存储这些数据包吗? - RatDon
这并不是你最初回答的陈述。我同意设置store = 0会略微提高空间和时间效率,我甚至在对我的回答的评论中进行了论证,当时你声称相反。现在你已经编辑了你的回答,它是正确的,尽管我没有看到它对讨论有什么补充,因为我的回答及其评论已经陈述了以上所有内容,而且早已发布。 - Yoel
我猜这个例子展示了通过调用函数来扩展使用 prn,并且删除了一些参数,如果缺少这些参数,则会采用默认值。我从未说过你的答案是错误的。上面那个更适合我的问题。 - RatDon

8
这可以通过sniff函数的prn参数完成。Scapy的教程提供了一个简单的示例,在这里。Scapy的官方API文档指定如下:

sniff(prn=None, lfilter=None, count=0, store=1, offline=None, L2socket=None, timeout=None)

...
prn: 应用于每个数据包的函数。如果返回了某些内容,则会显示出来。例如,您可以使用prn = lambda x: x.summary()
...


编辑:
被接受的答案声称必须将store参数设置为0才能调用prn回调函数。然而,将store=0并没有任何这样的效果。Scapy自己的示例不设置store=0,而官方API文档也没有提到任何这样的要求。事实上,检查Scapy的源代码会发现storeprn参数之间根本没有任何关联。下面是相关代码块的一部分:
...
if store:
    lst.append(p)
c += 1
if prn:
    r = prn(p)
    if r is not None:
        print r
...

执行一些简单的测试用例也支持这个发现。

谢谢。我已经找到了,并且我猜我需要将“store”参数设置为“0”来处理实时流量。但是无论在哪里都提到它很耗时间,因此我会尝试其他方法。无论如何,谢谢。 - RatDon
哦,这很令人惊讶。如果有的话,我会期望将store=0设置更有效率。你在哪里读到这个信息的? - Yoel
FTR,不设置store=1意味着您将每个数据包存储在一个巨大的列表中。通常这用于嗅探几个数据包,但是如果您永远不停止嗅探(这里:没有超时或数据包计数),当您使用ctrl^c时,您最终会拥有一个巨大的列表。 - Cukic0d
@Cukic0d,感谢您的建议。但是我认为您可能是想说“设置store=1”或者“不设置store=0”,而不是“不设置store=1”,对吗? - Yoel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接