我如何在python中发送原始以太网帧?

问题描述 投票:4回答:2

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

首先,我试图将其绑定到接口'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)是有效负载的开始,即使它被认为是数据包的开始。另外,我将不使用任何其他模块,而必须使用套接字。

python sockets ethernet
2个回答
6
投票

由于对此问题的评论,我设法与服务器建立了连接。要做的就是在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 OS X中不起作用。关于Windows的idk。如果您的Mac使用pycap或scapy,它们可以正常工作。


0
投票

为回答您的问题,安德鲁,这是一个例子:

此答案帮助我使WoL正常工作。在这种情况下,数据为:

preamble = bytearray((0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF))
MAC = bytearray((0x00, 0x14, 0x85, 0xa4, 0x73, 0xce))
data = PREAMBLE + 16*MAC
© www.soinside.com 2019 - 2024. All rights reserved.