Отправка вызова IOCTL в сетевой драйвер с помощью Python
Я хотел бы отправить вызов IOCTL из приложения Python на поддельный сетевой интерфейс, который я использую в Ubuntu 12.04. Я знаю, что могу открыть сокет и связать его с сетью, которой управляет поддельный сетевой интерфейс, а затем использовать fcntl.ioctl(socket, IOC_COMMAND_NUM, some_struct)
отправить вызов IOCTL. Но, похоже, для этого используется другой сетевой интерфейс, чем мне нужно. Итак, мой вопрос: как я могу убедиться, что используется определенный сетевой интерфейс? И, кажется, очень трудно открыть сокет только для того, чтобы отправить вызов IOCTL, так что, есть ли способ обойти этот шаг? Ниже приведен пример кода Python, который ведет себя так, как указано выше.
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.bind(("192.168.0.1",0))
>>> fcntl.ioctl(sock,IOC_COMMAND_NUM,some_struct)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 25] Inappropriate ioctl for device
# This proves that it is sending the IOCTL to a different interface because my
# interface automatically returns success for any IOCTL call.
Ниже вывод ifconfig myDummyNetInter
,
myDummyNetInter0 Link encap:Ethernet HWaddr e2:44:46:d5:79:3e
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::e044:46ff:fed5:793e/64 Scope:Link
UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:24 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:2682 (2.6 KB)
Если это поможет, у меня есть другое приложение, написанное на C++, использующее этот сетевой интерфейс без каких-либо проблем. (Включая вызовы IOCTL.)
Спасибо, я ценю любую помощь.
1 ответ
Хотя это не обязательно отвечает на все мои вопросы, я смог найти решение. Вызов IOCTL немного отличается от того, что я ожидал. Первое, что мне нужно было исправить, это использовать правильный номер IOCTL. В отличие от символьных драйверов, сетевые драйверы могут использовать только определенный диапазон (начиная с 0x89F0) для пользовательских IOCTL. Другая вещь, которую я должен был сделать, это положить ifreq
struct как третий аргумент вызова IOCTL. ifreq
структура имеет ifr_name
член, который используется для выбора конкретного сетевого интерфейса для взаимодействия. Эти два исправления позволили мне безупречно общаться с водителем.