创建Python原始套接字的正确方法

2 投票
1 回答
1814 浏览
提问于 2025-04-18 11:13

我最近在看一些信息安全和编程的内容,碰到了“原始套接字”(raw socket)。我对如何创建原始套接字并正确捕获数据包有点困惑。

方法一

使用 AF_INET 创建套接字

sock=socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.IPPROTO_*)

##IPPROTO_* can be IPPROTO_IP/IPPROTO_TCP/IPPROTO_UDP

raw_data=sock.recvfrom(65535)

不过用这种方法我能捕获到数据包,但当我尝试解码时,却完全搞不懂。

方法二

sock=socket.socket(socket.AF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))

raw_data=socket.recvfrom(65535)

通过第二种方法,我不仅能捕获数据包,还能解码它。

顺便说一下,我是想从以太网层解码数据包。

所以我的问题是,为什么方法一会失败?还有没有其他方法可以在Python中创建原始套接字?

1 个回答

0

如果你想创建一个没有协议的原始套接字,可以使用:socket(AF_PACKET, SOCK_RAW);

示例:

#!/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)

所有感谢归于 brice

撰写回答