1

我创建了类型 3 和代码 4 的伪造目标不可达 ICMP(需要分段并设置了 DF 位)。我的设置有服务器、客户端和它们之间的开关。理想情况下,这个 ICMP 由路由器/网关生成,但我在客户端生成它。我正在使用 Scapy 工具创建这个 ICMP。这是我创建的方式:

ip = IP()
icmp = ICMP()
# IP Packet sent to client
ip.dst = ip_server
ip.src = ip_client
ip.protocol = 1 #shows that ip header contains icmp as data 
# icmp type 3 + code 4 
icmp.type = 3
icmp.code = 4
mtu =1300
icmp.unused = mtu
#
# build original packet for ICMP ping request
#
ip_orig = IP()
ip_orig.src = ip_server
ip_orig.dst = ip_client
icmp_orig = TCP()
tcp_orig.sport = 50000 
tcp_orig.dport = 50000
tcp_orig.seq= original sequence number
#
# send the packet
#
send (ip/icmp/ip_orig/tcp_orig)

我正在遵循的步骤来演示此 ICMP 的效果: 1> 服务器和客户端使用套接字相互通信 2> 一旦服务器接受连接,我将在机器中暂停 60 秒,在此期间我禁用所有从客户端机器发出的 TCP ACK(因为如果服务器接收到它发送的消息的 ACK,那么它就不会响应 ICMP)。3> 服务器将第一条消息发送给客户端,但不会收到任何 ACK 并且服务器不断重新发送消息,同时我注入了上面 scapy 代码中提到的 ICMP 消息:send (ip/icmp/ip_orig/tcp/orig )。我正在发送的 icmp 中报告 MTU 1300。4> 理想情况下,服务器应该减少它的 MTU,并将 MTU 大小为 1300 的消息发送回客户端。

但服务器不断重新传输 MTU 大小为 1500 的消息。请帮助我。为什么服务器不降低其 MTU?我在演示中做错了吗?任何帮助将不胜感激。

4

1 回答 1

1

我在此答案及其评论中概述了一些要点:

  1. 该规范要求封装在 ICMP 错误消息(即ip_orig)中的原始 IP 报头与收到的报头完全相同。因此,仅设置其源 IP 地址和目标 IP 地址(即分别为ip_orig.srcip_orig.dst)可能是不够的。
  2. 封装在 ICMP 错误消息(即tcp_orig.seq)中的原始 TCP 报头的序列号也应该设置,因为规范要求问题数据包的 IP 层有效负载的至少 8 个字节包含在 ICMP 错误消息中。
  3. 验证路径 MTU 发现已启用并且该DF位已设置。您可以使用启用路径 MTU 发现sysctl -w net.ipv4.ip_no_pmtu_disc=0
  4. 确认没有任何防火墙和/或 iptables 规则阻止 ICMP 消息。
于 2014-11-23T09:12:25.497 回答