【问题标题】:Sending raw IP Traffic with Python: Detect MTU使用 Python 发送原始 IP 流量:检测 MTU
【发布时间】:2016-07-23 22:52:58
【问题描述】:

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

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

向目标发送 ping,在我的示例中,我将使用 Google 的 DNS 服务器 (8.8.8.8)。将 ping 中的 DF 位设置为打开,以防止 ping 被碎片化。将数据包大小设置为某个较大的数字,或标准 M​​TU 1500。请注意,某些 ping 实现仅设置有效负载的大小,这意味着您必须考虑 8 字​​节 ICMP 标头和 20 字节 IP 标头。

【问题讨论】:

    标签: python ip mtu


    【解决方案1】:

    我想补充一点,你也可以使用原始套接字。
    scapy 是一个很好的抽象层,它为你做了很多魔法,但公平地说,如果你打算走低你可以一路走来获得学习经验。 (请注意,在大多数现代操作系统中,原始套接字需要提升权限,并且随着您的深入,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)
    

    考虑到您自己构建数据包,有效负载将“容易”。
    不管它不是最传统的方式或最初最快的方式,但你可以实现任何你想要的。

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

    关于 MTU,这是您必须自己实现的逻辑,因为据我所知,没有预先构建的库可以做到这一点。

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

    【讨论】:

      【解决方案2】:

      在 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)?

      【讨论】:

        猜你喜欢
        • 2021-06-05
        • 2016-09-20
        • 1970-01-01
        • 2019-05-31
        • 2012-04-08
        • 1970-01-01
        • 1970-01-01
        • 2020-07-13
        • 1970-01-01
        相关资源
        最近更新 更多