如何使用原始套接字在Python?如何使用原始套接字在Python?(How Do I Use Ra

2019-06-12 05:29发布

我写一个应用程序来测试网络驱动程序处理损坏的数据。 而且我认为使用原始套接字发送这个数据的,所以它不会被发送机的TCP-IP协议栈进行修正。

我在Linux上只写这个程序。 我在系统调用中使用的原始套接字的代码示例,但我真的想保持我的测试动态地,谱写最如果不是所有的它在Python。

我用Google搜索网页有点解释和说明的python原始套接字的用法的例子,但没有发现任何真正启发。 只是,演示的想法,但在没有办法工作,AA很老的代码示例。

从我收集的,在Python原始套接字的用法是在语义UNIX的原始套接字几乎相同,但没有struct定义了分组结构S。

我想知道如果它甚至会更好,不要用Python语言编写测试的原始套接字的一部分,但在C与系统调用,并从主Python代码调用它呢?

Answer 1:

你不喜欢这样:

首先您禁用网卡的自动校验:

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)

完成。



Answer 2:

套接字系统调用(或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) 


Answer 3:

是这个你提到找到旧的代码? 它看上去很聪明给我,但我没有测试它自己(或大量使用原始套接字)。 这个例子从文档演示了如何使用原始套接字嗅探包,看起来很相似。



Answer 4:

最终,这种情况下,最好的解决办法是用C来写了整个事情,因为它不是一个大的应用程序,所以它会一直发生较重的处罚写这样一个小东西在1种多语言。

经过多次与C和Python原始套接字都玩弄,我最终还是首选C生插座。 RAW套接需要少于8个组的位级的修改用于写入数据包报头。 有时只写4位或更少。 蟒蛇定义了这个没有帮助,而Linux下C有这个完整的API。

但我绝对相信,如果只有头初始化的这一点点在蟒蛇方便处理,我就从来没有用过这儿用。



Answer 5:

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                        ]]]....


Answer 6:

Socket类应该有所帮助。 如果没有,你要么需要用C编写一个Python模块或只使用C.见http://mail.python.org/pipermail/python-list/2001-April/077454.html 。

基本的谷歌搜索发现。

其实,我试过其中“开卷”指出了代码示例。 AF_PACKET在Python 2.7.4所做的工作对我来说



Answer 7:

你可以使用这个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()


文章来源: How Do I Use Raw Socket in Python?