主要使用python自带的ctypes和wintypes进行类型转换和交互
# python 3.11.7
import ctypes
from ctypes import wintypes
import inspect
import socketdef log(data):print("----------------log start---------------")try:for attr, value in inspect.getmembers(data):if not attr.startswith('__') and not attr.startswith('_'):print(f"{attr}: {value}")except Exception:print(Exception)print("----------------log end---------------")# 引入dll
winsock2 = ctypes.WinDLL('ws2_32', use_last_error=True)# 开启 WSAStartup
wintypes.MAX_LEN = 256
class WSADATA(ctypes.Structure):_fields_ = [('wVersion', wintypes.WORD),('wHighVersion', wintypes.WORD),('iMaxSockets', wintypes.WORD),('iMaxUdpDg', wintypes.WORD),('lpVendorInfo', wintypes.LPSTR),('szDescription', wintypes.CHAR * (wintypes.MAX_LEN + 1)),('szSystemStatus', wintypes.CHAR * (wintypes.MAX_LEN + 1)),]wsaData = WSADATA()
errno = winsock2.WSAStartup(0x0202, ctypes.pointer(wsaData))
if errno != 0:print('WSAStartup: ' + str(errno))print(winsock2.WSAGetLastError())exit()log(wsaData)# 创建 socket
AF_INET = 2
SOCK_RAW = 3
IPPROTO_IP = 0
raw_socket = winsock2.socket(AF_INET, SOCK_RAW, IPPROTO_IP)
if raw_socket == 0:print('socket: ' + str(errno))print(winsock2.WSAGetLastError())exit()print(raw_socket)# 设置允许接收ip头
IP_HDRINCL = 2
enable = ctypes.c_char_p(1)
winsock2.setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL, ctypes.pointer(enable), ctypes.sizeof(enable))# 绑定监听的ip
class InAddr(ctypes.Structure):_fields_ = [('s_addr', wintypes.UINT),]class SockAddrIn(ctypes.Structure):_fields_ = [('sin_family', wintypes.SHORT),('sin_port', wintypes.USHORT),('sin_addr', InAddr),('sin_zero', wintypes.CHAR * 8),]hostname = socket.gethostname()
ip = socket.gethostbyname(hostname)
ip_bytes = socket.inet_aton(ip)inAddr = InAddr()
inAddr.s_addr = ctypes.c_uint.from_buffer_copy(ip_bytes)sockAddrIn = SockAddrIn()
sockAddrIn.sin_family = AF_INET
sockAddrIn.sin_port = 0
sockAddrIn.sin_addr = inAddrerrno = winsock2.bind(raw_socket, ctypes.pointer(sockAddrIn), ctypes.sizeof(SockAddrIn))
if errno != 0:print('bind: ' + str(errno))print(winsock2.WSAGetLastError())exit()# 设置混杂模式
SIO_RCVALL = 0x98000001 # 2550136833
SIO_RCVALL_ON = ctypes.c_ulong(0x00000001)errno = winsock2.ioctlsocket(raw_socket, SIO_RCVALL, ctypes.pointer(SIO_RCVALL_ON),
)
if errno != 0:print('WSAIoctl: ' + str(errno))print(winsock2.WSAGetLastError())exit()print('成功开启')
# 开始接收数据
while True:try:buf = (wintypes.CHAR * 4096)()resCount = winsock2.recv(raw_socket, buf, 4096, 0)if resCount != -1:print(resCount)except Exception as e:print(e)# 0	    WSAE_SUCCESS	操作成功。
# 10004	WSAE_INTR	操作被中断。
# 10009	WSAEBADF	文件描述符无效。
# 10013	WSAEACCES	权限不足。
# 10014	WSAEFAULT	地址无效。
# 10022	WSAEINVAL	参数无效。
# 10024	WSAEMFILE	打开文件过多。
# 10035	WSAEWOULDBLOCK	资源暂时不可用(非阻塞操作)。
# 10036	WSAEINPROGRESS	操作正在进行中。
# 10037	WSAEALREADY	操作已经在进行中。
# 10038	WSAENOTSOCK	描述符不是套接字。
# 10039	WSAEDESTADDRREQ	需要目标地址。
# 10040	WSAEMSGSIZE	消息太大。
# 10041	WSAEPROTOTYPE	协议类型不正确。
# 10042	WSAENOPROTOOPT	选项对于协议不适用。
# 10043	WSAEPROTONOSUPPORT	协议未支持。
# 10044	WSAESOCKTNOSUPPORT	套接字类型不支持。
# 10045	WSAEOPNOTSUPP	操作不支持。
# 10046	WSAEPFNOSUPPORT	协议族不支持。
# 10047	WSAEAFNOSUPPORT	地址族不支持。
# 10048	WSAEADDRINUSE	地址已在使用。
# 10049	WSAEADDRNOTAVAIL	地址不可用。
# 10050	WSAENETDOWN	网络不可达。
# 10051	WSAENETUNREACH	网络不可达。
# 10052	WSAENETRESET	网络连接重置。
# 10053	WSAECONNABORTED	连接已中止。
# 10054	WSAECONNRESET	连接已重置。
# 10055	WSAENOBUFS	缓冲区空间不足。
# 10056	WSAEISCONN	套接字已连接。
# 10057	WSAENOTCONN	套接字未连接。
# 10058	WSAESHUTDOWN	无法发送或接收数据,因为套接字已被关闭。
# 10059	WSAETOOMANYREFS	太多引用。
# 10060	WSAETIMEDOUT	连接超时。
# 10061	WSAECONNREFUSED	连接被拒绝。
# 10062	WSAELOOP	无法解析主机名。
# 10063	WSAENAMETOOLONG	主机名太长。
# 10064	WSAEHOSTDOWN	主机不可达。
# 10065	WSAEHOSTUNREACH	主机不可达。
# 10066	WSAENOTEMPTY	目录不为空。
# 10067	WSAEPROCLIM	进程限制。
# 10068	WSAEUSERS	用户数量限制。
# 10069	WSAEDQUOT	磁盘配额超出。
# 10070	WSAESTALE	文件句柄过期。
# 10071	WSAEREMOTE	项目不在本地计算机上。
# 10091	WSAEDISCON	连接被优雅地断开。
# 10092	WSAENOMORE	没有更多记录。
# 10093	WSAECANCELLED	操作被取消。
# 10101	WSAEINVALIDPROCTABLE	无效的过程表。
# 10102	WSAEINVALIDPROVIDER	无效的服务提供者。
# 10103	WSAEPROVFAILEDINIT	服务提供者初始化失败。
# 10104	WSAEASYNCFAIL	异步过程调用失败。
# 10105	WSAEASYNCNOTSUPPORTED	不支持异步。
# 10106	WSAENOTINITIALISED	Winsock 库未初始化。
# 10107	WSAESTRUCT	结构体无效。
# 10108	WSAEBADSTRUCT	结构体无效。
# 10109	WSAEADDRINUSE	地址已在使用。
# 10110	WSAEADDRNOTAVAIL	地址不可用。
# 10111	WSAENETDOWN	网络不可达。
# 10112	WSAENETUNREACH	网络不可达。
# 10113	WSAENETRESET	网络连接重置。
# 10114	WSAECONNABORTED	连接已中止。
# 10115	WSAECONNRESET	连接已重置。
# 10116	WSAENOBUFS	缓冲区空间不足。
# 10117	WSAEISCONN	套接字已连接。
# 10118	WSAENOTCONN	套接字未连接。
# 10119	WSAESHUTDOWN	无法发送或接收数据,因为套接字已被关闭。
# 10120	WSAETOOMANYREFS	太多引用。
# 10121	WSAETIMEDOUT	连接超时。
# 10122	WSAECONNREFUSED	连接被拒绝。
# 10123	WSAELOOP	无法解析主机名。
# 10124	WSAENAMETOOLONG	主机名太长。
# 10125	WSAEHOSTDOWN	主机不可达。
# 10126	WSAEHOSTUNREACH	主机不可达。
# 10127	WSAENOTEMPTY	目录不为空。
# 10128	WSAEPROCLIM	进程限制。
# 10129	WSAEUSERS	用户数量限制。
# 10130	WSAEDQUOT	磁盘配额超出。
# 10131	WSAESTALE	文件句柄过期。
# 10132	WSAEREMOTE	项目不在本地计算机上。