我们可以将srp()函数用于第3层ICMP数据包吗?我看到当我们制作ICMP echo-request数据包并使用sr()发送/接收时,我们看不到它被发送出接口,因此没有来自目的地的响应。但是如果我们使用srp()函数,我们会看到相同的数据包响应。什么时候应该使用sr()和srp()?在文档中,它声明sr()将用于L3数据包,而srp()将用于L2?但在我的情况下,我不确定为什么sr()不适用于ICMP数据包?有些专家可以帮我理解吗?
也可以有人让我知道" iface"总是需要论证。没有它,scapy将如何知道它应该发送数据包的接口?
案例1:使用iface作为参数的sr()函数:
sr(icmp,iface="eth0")
开始发射:
WARNING: Mac address to reach destination not found. Using broadcast.
Finished to send 1 packets.
^C
Received 0 packets, got 0 answers, remaining 1 packets
(<Results: TCP:0 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:1 Other:0>)
上面我没有看到来自IP 192.168.25.1的任何ICMP响应
案例2:没有iface的sr()函数:
sr(icmp)
.Begin emission:
......WARNING: Mac address to reach destination not found. Using broadcast.
.Finished to send 1 packets.
...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C
Received 887 packets, got 0 answers, remaining 1 packets
(<Results: TCP:0 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:1 Other:0>)
如果您看到上面收到的数据包更多,但我没有看到任何ICMP响应。
案例3:使用srp()而不是sr()发送ICMP数据包:
srp(icmp,iface="eth0")
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
(<Results: TCP:0 UDP:0 ICMP:1 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)
这里我使用了srp()函数而不是sr()函数,现在我看到ICMP echo请求已正确发送,我也收到了响应。
>>> icmp.show2()
###[ Ethernet ]###
dst: 02:00:00:11:01:03
src: 02:00:20:ee:64:01
type: 0x800
###[ IP ]###
version: 4L
ihl: 5L
tos: 0x0
len: 28
id: 1
flags:
frag: 0L
ttl: 64
proto: icmp
chksum: 0xc78c
src: 192.168.25.2
dst: 192.168.25.1
\options\
###[ ICMP ]###
type: echo-request
code: 0
chksum: 0xf7ff
id: 0x0
seq: 0x0
>>>
答案 0 :(得分:4)
official API documentation的sr
函数:
sr(pkts, filter=None, iface=None, timeout=2, inter=0, verbose=None, chainCC=0, retry=0, multi=0)
使用
conf.L3socket
超级套接字在第3层发送和接收数据包。
srp
功能:
srp(pkts, filter=None, iface=None, timeout=2, inter=0, verbose=None, chainCC=0, retry=0, multi=0, iface hint=None)
与
srp
相同,但在第2层使用conf.L2socket
supersocket。
由于您的ICMP
数据包也填充了第2层字段,如ICMP.show2()
的输出所示,您应该使用srp
函数。如果你在this tutorial中完成了,你可以保持原状,你可以使用sr
函数。
现在,关于ICMP
分类为第2层协议或第3层协议的问题。许多人认为它是第3层协议,例如here,因为它使用IP
标头并且“坐在”它之上。但是,其他人认为它是第2层协议,例如here。 This is a question在这个问题上有一些很好的答案,但请注意它们是指OSI
模型,因此分层方案编号有点不同。这是我设法找到的最好的here:
编辑 - 我刚刚遇到this link,并认为值得一提:IP本身没有建立和维护连接的机制,甚至没有将数据作为直接有效载荷包含的机制。 Internet控制消息传递协议只是IP的一个补充,用于传输错误,路由和控制消息和数据,通常被视为网络层的协议。
ICMP是TCP / IP堆栈中的一种协议,主要用于提供控制,故障排除和错误消息。它运行在IP上,如TCP和UDP,但它是一种网络层协议,如IP,而不是TCP和UDP等传输层协议。 (是的,这有点奇怪,ICMP封装在IP中,与IP在同一层。但是,你也可以将IP封装在IP中。)
RFC 792也很明确:
ICMP使用IP的基本支持,就好像它是更高级别的协议一样,但ICMP实际上是IP的一个组成部分。
RFC 1122也是如此:
ICMP是一种控制协议,被认为是IP的一个组成部分,尽管它在体系结构上是基于IP的,即它使用IP来端到端地传输数据,就像TCP或UDP这样的传输协议确实。
...
尽管ICMP消息封装在IP数据报中,但ICMP处理被认为是(并且通常实现为)IP层的一部分。
关于明确指定界面的最后一个问题,请参阅scapy
's tutorial:
send()
函数将在第3层发送数据包。也就是说它将为您处理路由和第2层。sendp()
函数将在第2层工作。您可以选择正确的接口和正确的链路层协议。
官方API文档更详细一些:
启动Scapy时,其路由表将与主机的路由表同步。对于在第3层发送的数据包,目标IP确定要使用的输出接口,源地址和网关。对于第2层数据包,可以对输出接口进行精确处理,或者可以以IP的形式给出提示以确定输出接口。如果没有给出输出接口或提示,则使用
conf.iface
。
具体来说,iface
参数用于设置输入接口(但如果未使用iface_hint
则设置输出接口):
iface:仅在提供的界面上听取答案
对于output
界面上的提示,请使用iface_hint
作为第2层功能:
还有一个附加参数
iface_hint
,它提供了一个有助于选择正确输出接口的提示。默认情况下,如果iface
未指定,则会选择conf.iface
。该提示采用IP层的形式,第2层数据包可能被指定。 Scapy路由表(conf.route
)用于确定用于访问此IP的接口。