主要使用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 项目不在本地计算机上。