Здравствуйте, k732, Вы писали:
Pzz>>Я другого не знаю. И сам его юзаю. Но у меня запланированно переписать его нах, когда руки дойдут.
K>Pzz, ты не мог бы привести простейший пример работы с ним ? Тоесть просто отправить пакет и принять ответ.
K>А там если заработает — буду разбираться...
Ну во-первых, драйвер надо слегка попатчить, чтобы он мог сосуществовать с другими такими же:
1) Придумываем, во что мы переименуем:
1.1) Драйвер. Было tap0801.sys, стало — ?
1.2) Суффикс имени устройства. Было ".tap", стало — ?
Примечание, у меня драйвер назывался tap0801, у Вас циферка может быть чуть другая.
2) Находим ВСЕ упоминания tap0801 во ВСЕХ файлах, (независимо от наличия у них суффикса) и заменяем на выбранное имя. Проверяем еще раз с помощью grep'а, что ничего не забыли и нигде не опечатались — а то потом будет муторно это отлаживать.
3) Правим информацию о продукте — нехорошо использовать измененный драйвер под чужим именем
3.1) DeviceDescription и Provider в .INF-файлах
3.2) PRODUCT_STRING в tap-win32/constants.h
3.2) VER_COMPANYNAME_STR, VER_FILEDESCRIPTION_STR в tap-win32/resource.rc
4) В tap-win32/common.h заменяем TAPSUFFIX с ".tap" на выбранный нами. Если выбранный нами суффикс длинный, заменяем также NAME_BUFFER_SIZE в tap-win32/tapdrvr.c с 80 на, скажем, 260 (длиннее все равно не бывает)
Теперь как с ним работать. Для начала его надо найти. Я лично, чтобы упростить себе жизнь, пошел следующим путем:
1) Имя драйвера (с точки зрения CreateFile()) выглядит так:
\\.\INTERFACE.SUFFIX
INTERFACE — это имя сетевого интерфейса, оно назначается при инсталляции. SUFFIX — это тот суффукс, который был .tap, и который мы чем-то заменили
2) Получить список всех сетевых интерфейсов с именами можно с помощью функции GetAdaptersInfo(). Она возвращает список структур IP_ADAPTER_INFO, нас интересует поле AdapterName. Под XP оно выглядит как GUID.
3) Пробегаемся по всему списку, и пытаемся сделать CreateFile() на см. выше. Чтобы случайно не открыть что-то не то, я выбрал в качестве суффукса с
сгенеренный мной GUID. В результате имя довольно длинное, затем-то и понадобилось поменять NAME_BUFFER_SIZE (см. выше).
4) Открыв устройство, надо бы сказать системе, что "в него воткнули сетевой кабель". Для этого делаем DeviceIoControl:
* код — TAP_IOCTL_SET_MEDIA_STATUS (описан в tap-win32/common)
* данные — ULONG. 1 — кабель воткнули, 0 — отключили
5) Посылать/принимать очень просто: WriteFile() записывает пакет, который с точки зрения системы как-бы придет из виртуальной сетевой карточки. ReadFile() наоборот, выгребает очередной пакет, который система послала в интерфейс.
6) Для эффективности следует использовать overlapped I/O, и сразу заскедулить несколько overlapped ReadFile(). По мере того, как пакеты проходят, надо подсовывать новые ReadFile(), чтобы все время несколько из них были активны.
7) Для записи делать этого, насколько я помню, нет особого смысла: драйвер завершает запрос на запись (IRP_MJ_WRITE) сразу, по мере получения.
8) Получаемые/отправляемые пакеты по дефолту имеют Ethernet'овский заголовок. Существует и другой режим, но про него я рассказывать не буду
P.S. Драйвер GPL'ный, а это значит, что его измененные исходники надо распостранять вместе с продуктом. Однако это не означает, что надо распостранять исходники самого продукта, если только продукт не является "производной работой" (derived work) от драйвера.
P.P.S. Я тут распинаюсь, а следовало бы отправить Вас почитать исходники OpenVPN в качестве примера работы с ихним же драйвером. Но ладно, раз уж набил, проще отправить