Python 原始套接字到以太网接口 (Windows)

Sam*_*Sam 4 python sockets windows dhcp python-2.7

我正在尝试创建 DHCP 服务器,第一步是通过以太网端口发送数据包。我正在尝试将数据包发送到以太网接口,但出现错误。

代码如下。

import socket

def sendeth(src, dst, eth_type, payload, interface = "eth0"):
  """Send raw Ethernet packet on interface."""

  assert(len(src) == len(dst) == 6) # 48-bit ethernet addresses
  assert(len(eth_type) == 2) # 16-bit ethernet type

  #s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
  s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)

  # From the docs: "For raw packet
  # sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])"
  s.bind((interface, 0))
  return s.send(src + dst + eth_type + payload)

if __name__ == "__main__":
  print("Sent %d-byte Ethernet packet on eth0" %
    sendeth("\xFE\xED\xFA\xCE\xBE\xEF",
            "\xFE\xED\xFA\xCE\xBE\xEF",
            "\x7A\x05",
            "hello"))
Run Code Online (Sandbox Code Playgroud)

我对创建套接字的方式有疑问。AF_PACKET 无法识别,所以我假设它仅适用于 Linux。我将其注释掉并在其下方添加了新行。我再次运行它,并开始出现如下所示的错误。

Traceback (most recent call last):
  File "eth.py", line 27, in <module>
    "hello"))
  File "eth.py", line 19, in sendeth
    s.bind((interface, 0))
  File "C:\Python27\lib\socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.gaierror: [Errno 11001] getaddrinfo failed
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会发生这种情况?

Cuk*_*c0d 5

正如已经多次说过的,由于 Win32 的限制,在 Windows 上没有实现ETH_P_ALL。 \n替代方案称为Winpcap(最近是Npcap)),它设置 Windows 来访问此类低级事物(它添加了额外的驱动程序)

\n\n

然后你可以做的是使用基于 Winpcap/Npcap 的库,例如Scapy)来访问原始低级套接字。这需要在计算机上安装Npcap(或Winpcap)。

\n\n

然后您可以按原样使用该库(它具有许多处理数据包的功能),或者如果您想访问原始数据

\n\n
from scapy.all import *\nIFACES.show() # let\xe2\x80\x99s see what interfaces are available. Windows only\niface = <<"full iface name">> or <<IFACES.dev_from_index(12)>> or <<IFACES.dev_from_pcapname(r"\\\\Device_stuff")>>\nsocket = conf.L2socket(iface=iface)\n# socket is now an Ethernet socket\n### RECV\npacket_raw = socket.recv_raw()[0]  # Raw data\npacket_decoded = socket.recv() # Using the library (also contains things like sent time...)\n### SEND\nsocket.send(b"\\x00......"). # send raw data\nsocket.send(Ether()/IP(dst="www.google.com")/TCP()/Raw(load=b"data")) # use library\n
Run Code Online (Sandbox Code Playgroud)\n