我写一个应用程序来测试网络驱动程序处理损坏的数据。 而且我认为使用原始套接字发送这个数据的,所以它不会被发送机的TCP-IP协议栈进行修正。
我在Linux上只写这个程序。 我在系统调用中使用的原始套接字的代码示例,但我真的想保持我的测试动态地,谱写最如果不是所有的它在Python。
我用Google搜索网页有点解释和说明的python原始套接字的用法的例子,但没有发现任何真正启发。 只是,演示的想法,但在没有办法工作,AA很老的代码示例。
从我收集的,在Python原始套接字的用法是在语义UNIX的原始套接字几乎相同,但没有struct
定义了分组结构S。
我想知道如果它甚至会更好,不要用Python语言编写测试的原始套接字的一部分,但在C与系统调用,并从主Python代码调用它呢?
你不喜欢这样:
首先您禁用网卡的自动校验:
sudo ethtool -K eth1 tx off
然后发送蟒蛇2你躲闪帧(你必须转换到Python 3自己):
#!/usr/bin/env python
from socket import socket, AF_PACKET, SOCK_RAW
s = socket(AF_PACKET, SOCK_RAW)
s.bind(("eth1", 0))
# We're putting together an ethernet frame here,
# but you could have anything you want instead
# Have a look at the 'struct' module for more
# flexible packing/unpacking of binary data
# and 'binascii' for 32 bit CRC
src_addr = "\x01\x02\x03\x04\x05\x06"
dst_addr = "\x01\x02\x03\x04\x05\x06"
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x1a\x2b\x3c\x4d"
ethertype = "\x08\x01"
s.send(dst_addr+src_addr+ethertype+payload+checksum)
完成。
套接字系统调用(或Winsocks,在Windows上),已经包裹在标准模块socket
: 前奏 , 参考 。
我从来没有使用原始套接字,但它看起来像他们可与本模块一起使用:
最后一个例子展示了如何编写在Windows原始套接字一个非常简单的网络嗅探器。 这个例子需要管理员权限来修改界面:
import socket # the public network interface HOST = socket.gethostbyname(socket.gethostname()) # create a raw socket and bind it to the public interface s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) s.bind((HOST, 0)) # Include IP headers s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # receive all packages s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) # receive a package print s.recvfrom(65565) # disabled promiscuous mode s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
是这个你提到找到旧的代码? 它看上去很聪明给我,但我没有测试它自己(或大量使用原始套接字)。 这个例子从文档演示了如何使用原始套接字嗅探包,看起来很相似。
最终,这种情况下,最好的解决办法是用C来写了整个事情,因为它不是一个大的应用程序,所以它会一直发生较重的处罚写这样一个小东西在1种多语言。
经过多次与C和Python原始套接字都玩弄,我最终还是首选C生插座。 RAW套接需要少于8个组的位级的修改用于写入数据包报头。 有时只写4位或更少。 蟒蛇定义了这个没有帮助,而Linux下C有这个完整的API。
但我绝对相信,如果只有头初始化的这一点点在蟒蛇方便处理,我就从来没有用过这儿用。
s = socket(AF_PACKET, SOCK_RAW)
s = socket(PF_PACKET, SOCK_RAW)
结果:
[root@localhost python]# tcpdump -i eth0
capture size 96 bytes
11:01:46.850438
01:02:03:04:05:06 (oui Unknown) > 01:02:03:04:05:06 (oui Unknown), ethertype Unknown (0x0801), length 85:
0x0000: 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b [[[[[[[[[[[[[[[[
0x0010: 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5b5b 5041 [[[[[[[[[[[[[[PA
0x0020: 594c 4f41 445d 5d5d 5d5d 5d5d 5d5d 5d5d YLOAD]]]]]]]]]]]
0x0030: 5d5d 5d5d 5d5d 5d5d 5d5d 5d5d 5d5d 5d5d ]]]]]]]]]]]]]]]]
0x0040: 5d5d 5d00 0000 00 ]]]....
Socket类应该有所帮助。 如果没有,你要么需要用C编写一个Python模块或只使用C.见http://mail.python.org/pipermail/python-list/2001-April/077454.html 。
基本的谷歌搜索发现。
其实,我试过其中“开卷”指出了代码示例。 AF_PACKET在Python 2.7.4所做的工作对我来说
你可以使用这个Python库: rawsocketpy它允许使用上层原始套接字2 =>没有IP / TCP / UDP报头。
#!/usr/bin/env python
from rawsocketpy import RawSocket
sock = RawSocket("wlp2s0", 0xEEFA)
sock.send("some data")
sock.send("personal data", dest="\xAA\xBB\xCC\xDD\xEE\xFF")
或服务器的形式:
#!/usr/bin/env python
from rawsocketpy import RawRequestHandler, RawAsyncServerCallback
import time
def callback(handler, server):
print("Testing")
handler.setup()
handler.handle()
handler.finish()
class LongTaskTest(RawRequestHandler):
def handle(self):
time.sleep(1)
print(self.packet)
def finish(self):
print("End")
def setup(self):
print("Begin")
def main():
rs = RawAsyncServerCallback("wlp2s0", 0xEEFA, LongTaskTest, callback)
rs.spin()
if __name__ == '__main__':
main()