【问题标题】:How do I send a raw ethernet frame in python?如何在 python 中发送原始以太网帧?
【发布时间】:2012-08-27 02:04:58
【问题描述】:

我需要在几天内完成一个项目,它是一个基本的客户端和服务器接口。问题是它必须是所有原始套接字。我创建它没有问题,我只是坚持发送数据包。

首先我尝试将它绑定到接口'en1',但它一直给我一个错误nodename not known。当我将它绑定到我的本地 IP 地址时,它工作正常。完成此操作后,我创建了一个原始数据包类,全部为十六进制。然后我做了一个 sendto 调用以通过网络发送它。

问题是,当我使用wireshark 捕获数据包时,它显示为ipv4 数据包的有效负载。我不希望它自动生成标题,这就是我的原始数据包类的用途。你知道我有什么办法可以取出这些标题吗?

这是我的代码 - 只有原始函数:

def raw():
    HOST = gethostbyname('192.168.1.10')

    s = socket(AF_INET, SOCK_RAW, IPPROTO_IP)
    s.bind((HOST, 0))

    s.setsockopt(IPPROTO_IP, IP_HDRINCL, 0) #no headers - it wont work!!

    pckt = packet("\x68\x65\x6c\x6c\x6f")
    netpacket = pckt.getpacket()

    print "Sending.. "
    print ""

    s.sendto(netpacket, ('192.168.1.1', 80))
    data = s.recv(4096)
    print data

这是捕获的数据包,末尾带有 hello

007f 2809 6da2 28cf daee 2156 0800 4500 004d 1bfc 0000 4000 db59 c0a8 010a c0a8 0101* 007f     

2809 6da2 28cf daee 2156 0800 4500 0036 2352 4000 4006 0000 c0a8 010a c0a8 0101 15c0 0050 

0000 0000 0000 0000 8010 813b 0000 68656c6c6f -hello

*这(0101)是有效载荷的开始,即使它应该是数据包的开始。另外我不会使用任何其他模块,我必须使用套接字。

【问题讨论】:

  • 有趣的问题,我帮不上忙,但也许这个问题是相关的:stackoverflow.com/questions/6329583/…
  • 耐心是一种美德。另外请记住,您的问题越容易阅读,就越有可能有人能够快速了解​​您的问题的性质并提出有用的解决方案(提示:正确的大小写和分段符很有帮助)
  • 其他示例使用 AF_PACKET 而不是 AF_INET,如果您正在运行 Linux,您可能想尝试一下,因为它似乎是特定于 Linux 的。
  • 谢谢大家,我还没有在 linux 上尝试过,但我想我可以。如果它适用于 linux,我会回复你。我有一个带有 Windows 7、xp 和 debian 的 mac osx 顺便说一句。我现在添加 linux... o 我很抱歉没有耐心。
  • @NoahKoster:如果您真的想发送原始以太网帧,正如您在标题中所说,为什么要使用绑定到 IP 地址的 AF_INET 套接字?您不应该使用绑定到接口的 AF_PACKET 吗?

标签: python sockets ethernet


【解决方案1】:

为了回答你的问题 Andrew,这里有一个例子:

这个答案帮助我让 WoL 正常工作。在这种情况下,数据是:

preamble = bytearray((0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF))
MAC = bytearray((0x00, 0x14, 0x85, 0xa4, 0x73, 0xce))
data = PREAMBLE + 16*MAC

【讨论】:

    【解决方案2】:

    感谢 cmets 提出这个问题,我设法与服务器建立了连接。只需将地址族更改为 linux 中的 af_packet 即可。然后我将它绑定到我的网卡并发送。有效。感谢人们的帮助! 这是一些示例代码:

    s = socket(AF_PACKET, SOCK_RAW)
    s.bind(("en1", 0))
    pckt = packet() #my class that initializes the raw hex
    data = pckt.getpacket()
    s.send(data)
    message = s.recv(4096)
    print s
    print s.decode('hex')
    

    它需要在 linux 或 debian 中。据我所知,它在 mac osx 中不起作用。对窗户不以为然。如果你有使用 pycap 或 scapy 的 mac,它们可以正常工作。

    【讨论】:

    • 感谢分享!您可以发布一个发送字符串或其他内容的示例吗?目前尚不清楚您的“数据包”类抽象了多少“魔法”。
    • 我无法在此处发布代码,因此请参阅下面对我有用的数据片段。
    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 2011-12-02
    • 2017-12-26
    相关资源
    最近更新 更多