在数据 link 层(在获取 IP 地址之前)与 Python 通信

Communicate on the data link layer (prior to obtaining IP address) with Python

是否可以使用 Python 在 IP 地址之前或之外直接在数据 link 层上进行通信?类似于与 USB 通信?

我有一个客户有兴趣尝试这个。据我所知,没有办法。但我永远不想低估 Python 的力量。

Python 并没有什么内在因素阻止您编写自己的用户级网络堆栈。但是,如果你想说,访问原始以太网驱动程序来发送原始以太网数据包,那必须得到操作系统的支持。

我将尝试对正在发生的事情进行模糊描述。其中一些你可能已经知道(或不知道)。传统的操作系统提供了一个称为系统调用层的抽象来允许程序与硬件交互。这种抽象通常有点 "high level" 因为它抽象掉了硬件的一些细节。在实现 Unix 抽象的操作系统中,网络抽象系统调用之一是 socket(int domain, int type, int proto),它创建一个新的套接字端点。什么东西在这里被抽象掉了?好吧,对于大多数协议来说,处理 data-link 层的细节变得不必要了。显然你在这里失去了一些灵活性,这样你就可以获得安全性(如果你有原始硬件访问权限,你不必担心破坏其他 OS 数据结构)和便利性(大多数人不需要实现用户级网络堆栈)。

因此,是否 "can" 在不修改内核的情况下完成取决于 OS 提供的抽象。 Linux 提供了 the packet(7) 接口,允许您使用 AF_PACKET 作为您的套接字域。根据手册页,"Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level."

那么可以在 Python 中访问它吗? You bet!

 import socket
 s = socket(socket.AF_PACKET, socket.SOCK_RAW)
 s.bind(("eth1", 0))

s 现在应该是一个可以用来发送原始数据包的套接字。有关如何执行此操作的更多信息,请参阅其他 Stack Overflow post——他们比我做得更好。看起来这种技术也应该适用于 Windows,因为我怀疑它们提供了类似的抽象。