使用 Python 发送原始 IP 流量:检测 MTU

Sending raw IP Traffic with Python: Detect MTU

如何使用 Python 实现手动 MTU 发现?

发件人:https://networkengineering.stackexchange.com/a/28988/23983

Send a ping to a target, in my example, I'll use Google's DNS server (8.8.8.8). Set your DF bit in your ping to on, to prevent your ping from being fragmented. Set your packet size to some large number, or the standard MTU of 1500. Note that some ping implementations set the size of just the payload, which means you have to account for the 8 byte ICMP header, and 20 byte IP header.

在 python 中发送任何原始内容,您正在考虑使用 scapy。

有关如何发送 ping 消息的信息:

http://www.secdev.org/projects/scapy/doc/usage.html#icmp-ping

设置 DF 标志:

IP(flags='DF')

关于如何调整特定大小以便模拟碎片:

Adding payload in packet (scapy)

综合起来:

data = "x" * 1473
ans,unans = sr(IP(dst="<target_ip>", flags='DF' )/ICMP() / Raw(load=data))

如果您实际上对原始创建这些东西不那么感兴趣,那么这个问题是以下问题的重复:How to find mtu value of network through code(in python)?

我想补充一点,您也可以使用原始套接字。
scapy 是一个很好的抽象层,可以为您带来很多神奇的效果,但平心而论,如果您要走低层,您可以一路走来获得学习经验。 (请注意,原始套接字在大多数现代 OS 中需要更高的权限,并且随着您深入实施,可能会与 Windows 和 Linux 不同。)

import socket
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))

这将为您提供一个基于原始数据包的套接字,它可以真正为您提供所有帧。它在 Windows 和 Linux 之间略有不同,但我会在这个答案中坚持使用 Linux。另请注意,所有传出数据包可能不会被此套接字接收,如果您需要该功能(嗅探东西),请考虑搜索 promiscuous mode 相关命中。

您现在需要做的就是将每个数据包视为它们进入或进入的段,例如 - 解包以太网和 IP 帧看起来像这样:

frame, meta = s.recvfrom(65565)
print(frame, meta)

ethernet = frame[0:14]
ethernet_segments = struct.unpack("!6s6s2s", ethernet)

mac_source, mac_dest = (binascii.hexlify(mac) for mac in ethernet_segments[:2])

ip = frame[14:34]
ip_segments = struct.unpack("!12s4s4s", ip)

ip_source, ip_dest = (socket.inet_ntoa(section) for section in ip_segments[1:3])

print('MAC Source:', b':'.join(mac_source[i:i+2] for i in range(0, len(mac_source), 2)))
print('MAC Dest:', b':'.join(mac_dest[i:i+2] for i in range(0, len(mac_dest), 2)))
print('IP Source:', ip_source)
print('IP Dest:', ip_dest)

考虑到您是自己构建数据包,有效载荷将为 "easy"。
所有这一切都不是最传统的方式或最初最快的方式,但你可以实现你想要的任何东西。

发送同样简单,使用 struct 并查看那里的许多 ICMP 示例,包括那些计算校验和的示例:

关于 MTU,这是您必须自己实现的逻辑,因为据我所知,没有可以执行此操作的预构建库。

但这是我用 Python 发送 原始 IP 流量的贡献。