在scapy中发送ICMP数据包并选择正确的接口

时间:2014-10-09 09:09:50

标签: python scapy

我们可以将srp()函数用于第3层ICMP数据包吗?我看到当我们制作ICMP echo-r​​equest数据包并使用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
>>>                  

1 个答案:

答案 0 :(得分:4)

official API documentationsr函数:

  

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层协议,例如hereThis is a question在这个问题上有一些很好的答案,但请注意它们是指OSI模型,因此分层方案编号有点不同。这是我设法找到的最好的here

  

IP本身没有建立和维护连接的机制,甚至没有将数据作为直接有效载荷包含的机制。 Internet控制消息传递协议只是IP的一个补充,用于传输错误,路由和控制消息和数据,通常被视为网络层的协议。

编辑 - 我刚刚遇到this link,并认为值得一提:

  

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的接口。