Здравствуйте, k732, Вы писали:
K>Можно ли как отправить/получить IP-пакеты системе?
K>Приложение имеет доступ к IP-трафику и нужно имитировать сетевой адаптер (как будто на него приходят данные и что он отправляет данные).
K>Можно ли это как-нибудь сделать ?
K>Можно ли как отправить/получить IP-пакеты системе? K>Приложение имеет доступ к IP-трафику и нужно имитировать сетевой адаптер (как будто на него приходят данные и что он отправляет данные). K>Можно ли это как-нибудь сделать ?
, — долго.
Взломать сервер БД, на котором храниться твоё сообщение, и кое-что подправить, — быстро если умеючи, но сидеть долго, а если не сидеть, то руки переломают точно.
, — долго.
потянет U>Взломать сервер БД, на котором храниться твоё сообщение, и кое-что подправить, — быстро если умеючи, но сидеть долго, а если не сидеть, то руки переломают точно.
Я так и думал.
U>>Взломать сервер БД, на котором храниться твоё сообщение, и кое-что подправить, — быстро если умеючи, но сидеть долго, а если не сидеть, то руки переломают точно. K>могешь ?
Скажу да — посадют ведь.
Скажу нет — ламер.
Скажем так, — "в мире нет ничего невозможного" (c).
Здравствуйте, k732, Вы писали:
K>Приложение имеет доступ к IP-трафику и нужно имитировать сетевой адаптер (как будто на него приходят данные и что он отправляет данные).
Потребуется сетевой драйвер, который изображает из себя виртуальный сетевой адаптер. В юниксе такой драйвер является стандартным и называется TUN/TAP (говорю в основном ради стандартной терминологии). А в винде его почему-то нет.
Возьмите Tap-Win32 из OpenVPN: http://openvpn.net/. Он довольно средненько написан, и по-моему не работает на 64-битных машинках, но чтобы поиграться/сделать прототип, его хватит. А потом перепишете, если дело пойдет.
Здравствуйте, Unmanaged, Вы писали:
K>>да не удобно как-то...
U>"Неудобно — это когда соседские дети на тебя похожи!" (c).
а еще неудобно — когда ты сверху и она сверху
U>>>Взломать сервер БД, на котором храниться твоё сообщение, и кое-что подправить, — быстро если умеючи, но сидеть долго, а если не сидеть, то руки переломают точно. K>>могешь ?
U>Скажу да — посадют ведь. U>Скажу нет — ламер.
Pzz>Возьмите Tap-Win32 из OpenVPN: http://openvpn.net/. Он довольно средненько написан, и по-моему не работает на 64-битных машинках, но чтобы поиграться/сделать прототип, его хватит. А потом перепишете, если дело пойдет.
а как на счет виртуалтного минипорт драйвера из DDK ?
Здравствуйте, k732, Вы писали:
Pzz>>Возьмите Tap-Win32 из OpenVPN: http://openvpn.net/. Он довольно средненько написан, и по-моему не работает на 64-битных машинках, но чтобы поиграться/сделать прототип, его хватит. А потом перепишете, если дело пойдет.
K> а как на счет виртуалтного минипорт драйвера из DDK ?
А он, по-моему, ничего делать не умеет, кроме как сидеть в систрее и прикидываться сетевым интерфейсом. Т.е., траффик через него не пропустишь.
Если бы все было так просто, вряд ли бы ребята из OpenVPN стали бы возиться со своим драйвером. Тем более, что он у них не очень получился
Pzz>А он, по-моему, ничего делать не умеет, кроме как сидеть в систрее и прикидываться сетевым интерфейсом. Т.е., траффик через него не пропустишь.
Но ведь на ping он могет отвечать...
Я просто не знаком с ndis, поэтому наверное многого не понимаю
Pzz>Если бы все было так просто, вряд ли бы ребята из OpenVPN стали бы возиться со своим драйвером. Тем более, что он у них не очень получился
Так если он не очень получился — стоит ли его смотреть ?
Неужели так сложно системе отдать пакет и забрать ответ на него
Здравствуйте, k732, Вы писали:
K>Можно ли как отправить/получить IP-пакеты системе?
K>Приложение имеет доступ к IP-трафику и нужно имитировать сетевой адаптер (как будто на него приходят данные и что он отправляет данные).
K>Можно ли это как-нибудь сделать ?
Тоесть вам нужно прокидывать сетевые пакеты, так чтобы какя то програмка их ловила?
Я думаю WinPCap вам поможет как нельзя лучше. Выбираете на какой адаптер валить пакеты и валите, API простое до безобразия.
Здравствуйте, k732, Вы писали:
Pzz>>А он, по-моему, ничего делать не умеет, кроме как сидеть в систрее и прикидываться сетевым интерфейсом. Т.е., траффик через него не пропустишь. K>Но ведь на ping он могет отвечать...
ping на собственный адрес не проходит через сетевой адаптер.
Pzz>>Если бы все было так просто, вряд ли бы ребята из OpenVPN стали бы возиться со своим драйвером. Тем более, что он у них не очень получился K>Так если он не очень получился — стоит ли его смотреть ?
Он good enough для прототипа. Но в нем есть некоторое количество ошибок, заметное невооруженным вглядом. Не знаю, поправили ли они их. Если нет, то иногда он будет глючить. Достаточно редко для прототипирования, но в релиз бы я не стал это отдавать. Кроме того, в нормальной релизнутой программе драйвера хорошо бы иметь подписанными, чтобы система не задавала лишних вопросов при инсталляции драйвера. Для того, чтобы получить подпись от микрософта, надо програть ихние довольно скурпулезные тесты. Я не уверен, что Tap-Win32 их пройдет.
K>Неужели так сложно системе отдать пакет и забрать ответ на него
Драйвера для винды писать довольно трудно, из-за довольно нетривиальной (и местами неясно документированной) модели жизни, в которой они живут.
Потом, трудно — понятие относительное. Я такой драйвер напишу недели за 2-3, вопрос захочу ли?
D>Тоесть вам нужно прокидывать сетевые пакеты, так чтобы какя то програмка их ловила?
Именно. Тоесть приложение на TCP уровне
D>Я думаю WinPCap вам поможет как нельзя лучше. Выбираете на какой адаптер валить пакеты и валите, API простое до безобразия.
вся проблемма в том, что нет адаптера Его нужно сэмитировать.
З.Ы. Но даже если есть — как понять что ответы пришли (где посмотреть описание работы с WinPcap ?)
Pzz>Потом, трудно — понятие относительное. Я такой драйвер напишу недели за 2-3, вопрос захочу ли?
везет тебе... я в написании драйвера имел опым максимум к достуту к экспортам.
Если мне сейчас заниматься NDIS — то на это уйдет несколько месяцев. Да и еще документации почти нет...
Здравствуйте, Danchik, Вы писали:
D>Тоесть вам нужно прокидывать сетевые пакеты, так чтобы какя то програмка их ловила? D>Я думаю WinPCap вам поможет как нельзя лучше. Выбираете на какой адаптер валить пакеты и валите, API простое до безобразия.
Насколько я понимаю, WinPCap валит пакеты "наружу". Чтобы их можно было поймать на той же машине, драйвер должен их уметь заворачивать назад, что не каждый драйвер умеет (впрочем, есть стандартный мелкософтовский драйвер по фамилии MS Loopback, который именно это и делает).
Кроме того, если принимать пакеты WinPCap'ом, то их будет принимать и система. И реагировать на них она может достаточно неадекватно. Например, послать TCP RST.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, Danchik, Вы писали:
D>>Тоесть вам нужно прокидывать сетевые пакеты, так чтобы какя то програмка их ловила? D>>Я думаю WinPCap вам поможет как нельзя лучше. Выбираете на какой адаптер валить пакеты и валите, API простое до безобразия.
Pzz>Насколько я понимаю, WinPCap валит пакеты "наружу".
не совсем понял
Pzz>Кроме того, если принимать пакеты WinPCap'ом, то их будет принимать и система. И реагировать на них она может достаточно неадекватно. Например, послать TCP RST.
да пусть реагирует как хочет. Если она на себя берет TCP соединение — это ее право. Мне нужно лишь ретранслировать пакеты в систему и получать ответы. Тоесть я работаю на MAC уровне и за TCP не отвечаю
Здравствуйте, k732, Вы писали:
Pzz>>Потом, трудно — понятие относительное. Я такой драйвер напишу недели за 2-3, вопрос захочу ли? K>везет тебе... я в написании драйвера имел опым максимум к достуту к экспортам.
Везло бы мне, если бы я всю жизнь мечтал писать виндовые драйвера. А я это занятие терпеть ненавижу
K>Если мне сейчас заниматься NDIS — то на это уйдет несколько месяцев. Да и еще документации почти нет...
Вся нужная тугаментация есть в DDK. Ее же можно читать в онлайне на мелкософтовском сайте. DDK можно заказать в Россию на CD за $25, и время от времени можно скачать с ихнего сайта забесплатно.
K>Печально, но что-то нужно делать
Ну вот и возьми Tap-Win32. На первые полгода-год этого хватит.
Pzz>Ну вот и возьми Tap-Win32. На первые полгода-год этого хватит.
вопрос стоит 2-3 недели. Все готово кроме этого. Если получиться общаться с ситемой, то остальное дело техники — приложения на более высоком уровне. (DHCP, DNS, WEB...)
Здравствуйте, k732, Вы писали:
Pzz>>Насколько я понимаю, WinPCap валит пакеты "наружу". K>не совсем понял
WinPCap позволяет 1) послать пакет через такой-то сетевой интерфейс 2) принять пакеты, пришедшие на такой-то сетевой интерфейс (все или с фильтром, фильтр достаточно быстрый). Это не то же самое, что добавить в систему сетевой интерфейс.
WinPCap тоже приносит с собой NDIS'овский драйвер, только не минипорт, а протокол. Если сравнивать с Tap-Win32, трудно сказать, кто из них хуже
Здравствуйте, k732, Вы писали:
Pzz>>Ну вот и возьми Tap-Win32. На первые полгода-год этого хватит.
K>вопрос стоит 2-3 недели. Все готово кроме этого. Если получиться общаться с ситемой, то остальное дело техники — приложения на более высоком уровне. (DHCP, DNS, WEB...)
Ну отлично — прикрутите пока Tap-Win32, это можно сделать за пару дней. Потом разберетесь. Все равно, после того, как проект будет полностью свинчен, какое-то время уйдет на доводку.
Pzz>WinPCap позволяет 1) послать пакет через такой-то сетевой интерфейс 2) принять пакеты, пришедшие на такой-то сетевой интерфейс (все или с фильтром, фильтр достаточно быстрый). Это не то же самое, что добавить в систему сетевой интерфейс.
Pzz>WinPCap тоже приносит с собой NDIS'овский драйвер, только не минипорт, а протокол. Если сравнивать с Tap-Win32, трудно сказать, кто из них хуже
Здравствуйте, k732, Вы писали:
Pzz>>А можно чуть подробнее? Любопытно мне очень...
K>ответ на ответ
K>P.S. Неужели кроме как полностью поднять драйвер нельзя дотянуться до ndis ?
Никак. NDIS живет в ядре, чтобы общаться с ним, нужен драйвер. Если бы было решение попроще, я бы сразу присоветовал бы именно его...
Pzz>Никак. NDIS живет в ядре, чтобы общаться с ним, нужен драйвер. Если бы было решение попроще, я бы сразу присоветовал бы именно его...
Блин... Я надеялся что можно...
Ответ. Нужно создать что-то вроде WmWare. Приходят пакеты и нужно перенаправлять их системе.
Re[15]: имитация сетевого интерфейса
От:
Аноним
Дата:
08.11.07 23:07
Оценка:
Здравствуйте, k732, Вы писали:
K>Ответ. Нужно создать что-то вроде WmWare. Приходят пакеты и нужно перенаправлять их системе.
Тогда начните с виртуального минипорта из DDK.
Пакеты на виртуальный адаптер из вашей программы "приходить" будут? Это не так трудно сделать.
Здравствуйте, Аноним, Вы писали:
K>>Ответ. Нужно создать что-то вроде WmWare. Приходят пакеты и нужно перенаправлять их системе.
А>Тогда начните с виртуального минипорта из DDK. А>Пакеты на виртуальный адаптер из вашей программы "приходить" будут? Это не так трудно сделать.
Вот уж чего бы я точно врагу не пожелал, так это начинать с DDK'ных самплов, и потом править их по месту напильником.
DDK'ные самплы надо рассматривать только в качестве иллюстрации к DDK'ной документации. С целью уточнения, правильно ли мы поняли описание той или иной функции. Код у большинства из них очень плохо структурирован, и каждое действие, которое по-хорошему надо бы делать в каком-то одном месте, размазано тонким слоем по всему исходнику. Хороший пример того, как не надо писать код на Си (чтобы плюсятники не смеялись).
Поддерживать потом такой код, выпилиный напильником из DDK'ного сампла — проще пойти и удавиться.
Я это однажды пробовал на драйвере размером в 45 тышш строк (поддерживать, написали его не мы, хотя половина этого драйвера была спортирована с моего линуксячего драйвера для той же железки) — воспоминания остались на всю жизнь
Re[17]: имитация сетевого интерфейса
От:
Аноним
Дата:
09.11.07 12:21
Оценка:
Предлагаете к примеру фильтр файловой системы или редиректор с нуля писать?
Встречаются конечно в DDK samples те еще поделки, но основная часть примеров написана так, как надо. Да, бывает что не хватает структурированности, но не нужна в примере на 30 кб какая-то особенная структурированность — за лесом всяких шаблонов проектирования можно легко упустить детали, которые этот пример должен был продемонстрировать.
Кстати насчет деталей — вы конечно можете самостоятельно написать NDIS miniport или Ndis interm. driver, но с первого раза обязательно упустите пару тонких моментов; позже вы узнаете о них, когда клиенты пришлют дампы
Более того, основные примеры из DDK просто расчитаны на то, что их будут использовать в качестве заготовок и пишут эти примеры далеко не рядовые программисты, а люди проектировавшие части ядра.
Драйвер для железяки в 45 т строк — видеокарточка или сетевая карта? Наверное, дело там не в MS, а в кривых руках тех, кто это писал
Посмотрел драйвер из OpenVPN, наверное в данном случае будет проще его использовать, там уже приделано взаимодействие с приложением, не знаю правда, что с производительносьтью.
Здравствуйте, Аноним, Вы писали:
А>Предлагаете к примеру фильтр файловой системы или редиректор с нуля писать?
Вот именно фильтр файловой системы я предлагаю писать руками профессионала — того, кто не боится писать код.
Кстати, я слышал, там давно уже появились минифильтры, и это дело перестало быть такой уж ракетной наукой.
А>Встречаются конечно в DDK samples те еще поделки, но основная часть примеров написана так, как надо. Да, бывает что не хватает структурированности, но не нужна в примере на 30 кб какая-то особенная структурированность — за лесом всяких шаблонов проектирования можно легко упустить детали, которые этот пример должен был продемонстрировать.
Когда за паттернами приектирования теряется смысл, это называется overdesing. Большинство DDK'ных самплов грешат отсутствием дизайна, как такового. Кроме того, в них встречаются откровенные ошибки, причем как раз в тех местах, использование которых эти самплы как раз и должны демонстрировать.
Да Вы посмотрите, как в этих самплах та же синхронизация сделана. В одном файле захватываем spin lock, в другом отпускаем, в 3-м делаем что-то волшебное с атомарным счетчиком, имеющее отношение к той же синхронизации. И там оно все такое. И чего это демонстрирует? Как не надо писать программы на Си? Ну так я про это и говорю, не надо брать оттуда код. Берите оттуда только знания.
А>Кстати насчет деталей — вы конечно можете самостоятельно написать NDIS miniport или Ndis interm. driver, но с первого раза обязательно упустите пару тонких моментов; позже вы узнаете о них, когда клиенты пришлют дампы
Пиля сампл напильником, вы упустите ровно те же тонкие моменты. Только получив дампы, будет гораздо труднее разобраться, к чему они относятся.
А>Более того, основные примеры из DDK просто расчитаны на то, что их будут использовать в качестве заготовок и пишут эти примеры далеко не рядовые программисты, а люди проектировавшие части ядра.
По-моему, это легенда. Мне очень трудно себе представить, чтобы у ключевого разработчика нашлось время на написание сампла. Ну разве что где-нибудь на отпуске, наспор, что он сможет написать живой драйвер после 3-х кружек пива
А>Драйвер для железяки в 45 т строк — видеокарточка или сетевая карта? Наверное, дело там не в MS, а в кривых руках тех, кто это писал
WiFi. Драйвер обычной сетевой карты редко разрастается до таких масштабов.
Между прочим, один из DDK'ный самплов написан теми же сами кривыми руками, которые переносили мой линуксячий драйвер в венду. Поубивал бы!
К сожалению, профессиональная этика не позволяет назвать мне фамилию гада.
Блин, мы угробили 1.5 человекогода на поддержку этого драйвера в более-менее живом состоянии (а для начала просто починили грубые ошибки — такие, как блокировка на NDIS_EVENT'е на DISPATCH_LEVEL'е). А потом, когда настал удобный в политическом плане момент, за 3 месяца переписали его нахрен.
А>Посмотрел драйвер из OpenVPN, наверное в данном случае будет проще его использовать, там уже приделано взаимодействие с приложением, не знаю правда, что с производительносьтью.
Там IRP canceling не худо бы починить. И я не уверен, что этот драйвер будет легко подписать: ребята довольно вольно обращаются с WDM'овским API. Большая его часть для минипортов запрещена.
Pzz, ну в общем я пришел к выводу, что все-равно придется писать дровину.
Только вопрос — Tap-Win32 — это единственное достойное решения на сегодняшний день под винду ?
Здравствуйте, k732, Вы писали:
K>Pzz, ну в общем я пришел к выводу, что все-равно придется писать дровину. K>Только вопрос — Tap-Win32 — это единственное достойное решения на сегодняшний день под винду ?
Я другого не знаю. И сам его юзаю. Но у меня запланированно переписать его нах, когда руки дойдут.
Насчет DDK — я не знаю другого выхода, кроме как учить английский. На самом деле, надо просто не бояться незнакомых слов. В техническом тексте знакомых слов достаточно много, чтобы понимать смысл. Я сам так выучил: начал читать программистские книжки на английском, и язык постепенно усвоился.
Pzz>Я другого не знаю. И сам его юзаю. Но у меня запланированно переписать его нах, когда руки дойдут.
Pzz, ты не мог бы привести простейший пример работы с ним ? Тоесть просто отправить пакет и принять ответ.
Здравствуйте, 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 в качестве примера работы с ихним же драйвером. Но ладно, раз уж набил, проще отправить
Pzz>Ну во-первых, драйвер надо слегка попатчить, чтобы он мог сосуществовать с другими такими же:
Pzz>1) Придумываем, во что мы переименуем: Pzz>1.1) Драйвер. Было tap0801.sys, стало — ? Pzz>1.2) Суффикс имени устройства. Было ".tap", стало — ?
Pzz>Примечание, у меня драйвер назывался tap0801, у Вас циферка может быть чуть другая.
Pzz>2) Находим ВСЕ упоминания tap0801 во ВСЕХ файлах, (независимо от наличия у них суффикса) и заменяем на выбранное имя. Проверяем еще раз с помощью grep'а, что ничего не забыли и нигде не опечатались — а то потом будет муторно это отлаживать.
Pzz>3) Правим информацию о продукте — нехорошо использовать измененный драйвер под чужим именем Pzz>3.1) DeviceDescription и Provider в .INF-файлах Pzz>3.2) PRODUCT_STRING в tap-win32/constants.h Pzz>3.2) VER_COMPANYNAME_STR, VER_FILEDESCRIPTION_STR в tap-win32/resource.rc
Pzz>4) В tap-win32/common.h заменяем TAPSUFFIX с ".tap" на выбранный нами. Если выбранный нами суффикс длинный, заменяем также NAME_BUFFER_SIZE в tap-win32/tapdrvr.c с 80 на, скажем, 260 (длиннее все равно не бывает)
Ну на самом деле зачем это делать ? Если есть готовые имена — пусть они и будут — проект не для продажи
Pzz>Теперь как с ним работать. Для начала его надо найти. Я лично, чтобы упростить себе жизнь, пошел следующим путем:
Pzz>1) Имя драйвера (с точки зрения CreateFile()) выглядит так:
Pzz> \\.\INTERFACE.SUFFIX
Pzz>INTERFACE — это имя сетевого интерфейса, оно назначается при инсталляции. SUFFIX — это тот суффукс, который был .tap, и который мы чем-то заменили
Pzz>2) Получить список всех сетевых интерфейсов с именами можно с помощью функции GetAdaptersInfo(). Она возвращает список структур IP_ADAPTER_INFO, нас интересует поле AdapterName. Под XP оно выглядит как GUID.
Pzz>3) Пробегаемся по всему списку, и пытаемся сделать CreateFile() на см. выше. Чтобы случайно не открыть что-то не то, я выбрал в качестве суффукса с Pzz>сгенеренный мной GUID. В результате имя довольно длинное, затем-то и понадобилось поменять NAME_BUFFER_SIZE (см. выше).
А если я знаю его символическую ссылку — зачем пытаться открыть все ?
Pzz>4) Открыв устройство, надо бы сказать системе, что "в него воткнули сетевой кабель". Для этого делаем DeviceIoControl: Pzz> * код — TAP_IOCTL_SET_MEDIA_STATUS (описан в tap-win32/common) Pzz> * данные — ULONG. 1 — кабель воткнули, 0 — отключили
Вот за это огромное спасибо — блише к телу
Pzz>5) Посылать/принимать очень просто: WriteFile() записывает пакет, который с точки зрения системы как-бы придет из виртуальной сетевой карточки. ReadFile() наоборот, выгребает очередной пакет, который система послала в интерфейс.
Тоесть отдельный поток на чтение ?
Pzz>6) Для эффективности следует использовать overlapped I/O, и сразу заскедулить несколько overlapped ReadFile(). По мере того, как пакеты проходят, надо подсовывать новые ReadFile(), чтобы все время несколько из них были активны.
Не совсем понял Pzz>7) Для записи делать этого, насколько я помню, нет особого смысла: драйвер завершает запрос на запись (IRP_MJ_WRITE) сразу, по мере получения. Pzz>8) Получаемые/отправляемые пакеты по дефолту имеют Ethernet'овский заголовок. Существует и другой режим, но про него я рассказывать не буду
Pzz>P.S. Драйвер GPL'ный, а это значит, что его измененные исходники надо распостранять вместе с продуктом. Однако это не означает, что надо распостранять исходники самого продукта, если только продукт не является "производной работой" (derived work) от драйвера.
Ну это для меня не важно
Pzz>P.P.S. Я тут распинаюсь, а следовало бы отправить Вас почитать исходники OpenVPN в качестве примера работы с ихним же драйвером. Но ладно, раз уж набил, проще отправить
Здравствуйте, k732, Вы писали:
Pzz>>4) В tap-win32/common.h заменяем TAPSUFFIX с ".tap" на выбранный нами. Если выбранный нами суффикс длинный, заменяем также NAME_BUFFER_SIZE в tap-win32/tapdrvr.c с 80 на, скажем, 260 (длиннее все равно не бывает)
K>Ну на самом деле зачем это делать ? Если есть готовые имена — пусть они и будут — проект не для продажи
Чтобы если Вы вдруг поставите какую-нибудь софтину, которая притаскивает с собой этот драйвер, они не столкнулись. Просто разумная мера предосторожности, как мыть руки перед едой.
Pzz>>3) Пробегаемся по всему списку, и пытаемся сделать CreateFile() на см. выше. Чтобы случайно не открыть что-то не то, я выбрал в качестве суффукса с Pzz>>сгенеренный мной GUID. В результате имя довольно длинное, затем-то и понадобилось поменять NAME_BUFFER_SIZE (см. выше). K>А если я знаю его символическую ссылку — зачем пытаться открыть все ?
Та часть его имени, которая берется из имени адаптера, назначается системой при инсталляции драйвера. Т.е., заранее ее знать нельзя.
Можно, конечно, перефигачить драйвер таким образом, чтобы его символическая ссылка не зависила от имени интерфейса, и была константой. Я выбрал динамический поиск, т.к. это позволяет мне при необходимости легко добавить в систему больше одной виртуальной сетевой карты.
Pzz>>5) Посылать/принимать очень просто: WriteFile() записывает пакет, который с точки зрения системы как-бы придет из виртуальной сетевой карточки. ReadFile() наоборот, выгребает очередной пакет, который система послала в интерфейс.
K>Тоесть отдельный поток на чтение ?
Совсем не обязательно.
Pzz>>6) Для эффективности следует использовать overlapped I/O, и сразу заскедулить несколько overlapped ReadFile(). По мере того, как пакеты проходят, надо подсовывать новые ReadFile(), чтобы все время несколько из них были активны.
K>Не совсем понял
Вы знаете, как работает overlapped I/O. Вы заказываете операцию, она там варится внутри операционной системы. Когда операция чем-нибудь кончается, Вам об этом сообщают через структуру OVERLAPPED.
Так вот, можно заказать следуюшую операцию, не дожидаясь окончания предыдущей. Каждой заказанной, но не оконченной операции соответствует IRP в драйверной очереди. Если поддерживать эту очередь непустой, то при появлении пакета драйвер кидает его прямо в IRP и завершает запрос. Иначе драйвер кладет пакет себе за щеку, и выгребает оттуда по приходу следующего запроса.
Если Ваша программа читает пакеты по одному, она будет просыпаться на каждый пакет, выгребать его и т.д. Если же она запустила сразу несколько запросов, то она проснется по первому, но выгрести сможет одним махом все. Это будет работать быстрее при большом потоке данных (при маленькой загрузке особой разницы не будет).
Надо накидать этих запросов сразу с запасом (я пока накидываю 16, но я никогда всерьез не тьюнил это место), и по мере окончания предыдущих докидываю соответствующее количество новых.
Pzz>Чтобы если Вы вдруг поставите какую-нибудь софтину, которая притаскивает с собой этот драйвер, они не столкнулись. Просто разумная мера предосторожности, как мыть руки перед едой.
разумно
Pzz>Можно, конечно, перефигачить драйвер таким образом, чтобы его символическая ссылка не зависила от имени интерфейса, и была константой. Я выбрал динамический поиск, т.к. это позволяет мне при необходимости легко добавить в систему больше одной виртуальной сетевой карты.
понятно
K>>Тоесть отдельный поток на чтение ? Pzz>Совсем не обязательно. Pzz>>>6) Для эффективности следует использовать overlapped I/O, и сразу заскедулить несколько overlapped ReadFile(). По мере того, как пакеты проходят, надо подсовывать новые ReadFile(), чтобы все время несколько из них были активны. Pzz>Вы знаете, как работает overlapped I/O. Вы заказываете операцию, она там варится внутри операционной системы. Когда операция чем-нибудь кончается, Вам об этом сообщают через структуру OVERLAPPED.
Но при этом нужно ждать на событии и если оно произошло — опрашивать GetOverlappedResult — тоесть полюбому вычитывающий поток
Pzz>Так вот, можно заказать следуюшую операцию, не дожидаясь окончания предыдущей. Каждой заказанной, но не оконченной операции соответствует IRP в драйверной очереди. Если поддерживать эту очередь непустой, то при появлении пакета драйвер кидает его прямо в IRP и завершает запрос. Иначе драйвер кладет пакет себе за щеку, и выгребает оттуда по приходу следующего запроса.
если 16 запросов — то 16 потоков. Может я чего-то не совсем понимаю ?
Здравствуйте, k732, Вы писали:
Pzz>>Вы знаете, как работает overlapped I/O. Вы заказываете операцию, она там варится внутри операционной системы. Когда операция чем-нибудь кончается, Вам об этом сообщают через структуру OVERLAPPED.
K>Но при этом нужно ждать на событии и если оно произошло — опрашивать GetOverlappedResult — тоесть полюбому вычитывающий поток
Мне трудно себе представить программу, которой всегда есть чем себя занять. Обычно все-таки в программе предусмотрено ожидание новой работы, когда старая закончилась. Окончание overlaped i/o — такая же новая работа, как и всякая другая.
Pzz>>Так вот, можно заказать следуюшую операцию, не дожидаясь окончания предыдущей. Каждой заказанной, но не оконченной операции соответствует IRP в драйверной очереди. Если поддерживать эту очередь непустой, то при появлении пакета драйвер кидает его прямо в IRP и завершает запрос. Иначе драйвер кладет пакет себе за щеку, и выгребает оттуда по приходу следующего запроса.
K>если 16 запросов — то 16 потоков. Может я чего-то не совсем понимаю ?
Что мешает поделить один Event между всеми OVERLAPPED'ами? Когда Event становится просигналенным, просто просматриваете по кругу относящиеся к делу OVERLAPPED'ы в поисках таких, для которых HasOverlappedIoCompleted() возвращает TRUE (или чего он там возвращает в таких случаях, я не помню).
Чтобы не просматривать ВСЕ OVERLAPPED'ы, я пользуюсь тем фактом, что Tap-Win32 завершает запросы на запись в порядке поступления. Т.е., если 5-й запрос еще не завершен, на 6-й и далее можно не смотреть.
Т.е., хватает одного потока. У меня вообще вся программа крутится в одном потоке, с централизованным диспетчером событий. А у меня кроме этого тун-тапа много чего еще есть в программе — несколько UDP-портов, несколько named pipe, таймеры и прочая муть Это значительно удобнее, чем городить многопоточность и разбираться с синхронизацией.
При желании можно использовать Completion Port — он автоматизирует часть перечисленной выше работы, и заодно умеет разбрасывать обработку по нескольким потокам. Однако им достаточно сложно пользоваться.
Pzz>Что мешает поделить один Event между всеми OVERLAPPED'ами? Когда Event становится просигналенным, просто просматриваете по кругу относящиеся к делу OVERLAPPED'ы в поисках таких, для которых HasOverlappedIoCompleted() возвращает TRUE (или чего он там возвращает в таких случаях, я не помню).
Если чесно — я в стопоре. Может я не совсем понял идею. Что даст деление одного события между OVERLAPPED'ами?
Здравствуйте, k732, Вы писали:
Pzz>>Что мешает поделить один Event между всеми OVERLAPPED'ами? Когда Event становится просигналенным, просто просматриваете по кругу относящиеся к делу OVERLAPPED'ы в поисках таких, для которых HasOverlappedIoCompleted() возвращает TRUE (или чего он там возвращает в таких случаях, я не помню).
K>Если чесно — я в стопоре. Может я не совсем понял идею. Что даст деление одного события между OVERLAPPED'ами?
Возможность проснуться, когда кто-то из OVERLAPPED'ов сработает, и сразу со всеми сработавшими разобраться.
Вам не нужна нотификация о каждом сработавшем OVERLAPPED'е. Вам надо знать, что ХОТЬ ОДИН сработал.
Здравствуйте, k732, Вы писали:
K>Pzz, если не сложно — можно псевдокод потока, который на одном событии задает несколько асинхронных операций I/O. Мне так будет понятнее
Здравствуйте, k732, Вы писали:
K>Скачал Tap-Win32. Установил. А где виртуальный адаптер ?
В компутере, где же еще?
Я вообще ничего не понял. В Device Manager'е устройство видно? Должно быть видно, как сетевая карта. А в систрее оно, наверное, появится только когда вы в него "кабель воткнете".
Re[19]: имитация сетевого интерфейса
От:
Аноним
Дата:
10.11.07 11:16
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Там IRP canceling не худо бы починить. И я не уверен, что этот драйвер будет легко подписать: ребята довольно вольно обращаются с WDM'овским API. Большая его часть для минипортов запрещена.
Есть такой тип драйверов — NDIS with lower WDM edge, им можно использовать не только NdisXXX функции. Нужно включить 'wdm.h' (а не 'ntddk.h' как в OpenVPN) и еще NDIS_WDM=1 в source задефайнить. Думаю, должны подписать.
А>Есть такой тип драйверов — NDIS with lower WDM edge, им можно использовать не только NdisXXX функции. Нужно включить 'wdm.h' (а не 'ntddk.h' как в OpenVPN) и еще NDIS_WDM=1 в source задефайнить. Думаю, должны подписать.
Ну это тоже ring-0 ? Если да, то какая тогда разница ?
P.S. И есть ли что готовое ?
Re[21]: имитация сетевого интерфейса
От:
Аноним
Дата:
10.11.07 12:52
Оценка:
Здравствуйте, k732, Вы писали:
K>Ну это тоже ring-0 ? Если да, то какая тогда разница ?
Это я pzz говорил, насчет подписывания драйвера.
K>P.S. И есть ли что готовое ?
Драйвер из OpenVpn готовый, можно использовать. Если готовый — в смысле ни с чем разбираться не надо, такого наверное нет.
K>>P.S. И есть ли что готовое ? А>Драйвер из OpenVpn готовый, можно использовать. Если готовый — в смысле ни с чем разбираться не надо, такого наверное нет.
Pzz>Я вообще ничего не понял. В Device Manager'е устройство видно? Должно быть видно, как сетевая карта. А в систрее оно, наверное, появится только когда вы в него "кабель воткнете".
Вроде нашел. Pzz, а можно все-таки кусок кода на отправку и прием пакетов (если не сложно)
Здравствуйте, k732, Вы писали:
Pzz>>Я вообще ничего не понял. В Device Manager'е устройство видно? Должно быть видно, как сетевая карта. А в систрее оно, наверное, появится только когда вы в него "кабель воткнете".
K>Вроде нашел. Pzz, а можно все-таки кусок кода на отправку и прием пакетов (если не сложно)
Не могу, это код из коммерческого проекта. Посмотрите в OpenVPN, как они с тун/тапом обращаются.
Pzz>Не могу, это код из коммерческого проекта. Посмотрите в OpenVPN, как они с тун/тапом обращаются.
Pzz, вроде разобрался как к нему подключиться и читать/писать с него.
Только вот некоторая странность происходит. Когда я к нему подключаюсь — он пытается получить IP через DHCP. Получает его, т.к. у меня запущен DHCP.
Но если потом я через него гоню Ethernet трафик, в котором записаны DHCP запросы другого устройства, то мой DHCP сервер говорит, что
INFO: Listening for DHCP messages on network...
INFO: oooh, got some!
INFO: Alarm off
INFO: received a DHCPDISCOVER
INFO: already in offered array
INFO: already offered you an address -- have it again (220a8c0)
INFO: Alarm On
INFO: Listening for DHCP messages on network...
сам DHCP где-то скачал, не помню где...
Складывается впечатление, что драйвер отсылает пакет от своего имени. Нафига ?
И как тогда мне этим трафиком достучаться до DHCP
З.Ы. Я думал, что он просто пропустит трафик без изменения...
Здравствуйте, k732, Вы писали:
E>>Устанавливаешь как новую сетевуху. Производитель Microsoft. Из списка выбираешь Microsoft Loopbak Adapter. И потом настраиваешь
K>И у меня в списке Microsoft нет Loopbak Adapter
Это потому, что Loopbak Adapter не привязан к железу. Соответственно, его и нет в списке найденного оборудования.
Идите в панель управления, жмите Добавить/Удалить железо, там выбрать вручную, сетевые адаптеры, поный список, Майкрософт, вот оно.
K>>И у меня в списке Microsoft нет Loopbak Adapter БП>Это потому, что Loopbak Adapter не привязан к железу. Соответственно, его и нет в списке найденного оборудования. БП>Идите в панель управления, жмите Добавить/Удалить железо, там выбрать вручную, сетевые адаптеры, поный список, Майкрософт, вот оно.
Извиняюсь, что поднимаю тему.
Перекачка данных по сети происходит в мегабайтах. При использовании Tap-адаптера — сотни кбайт.
Разница — порядок. Слишком медленно.
Добиться большего не удалось. Появилось ли что более быстрое ?
И подскажите где можно найти примеры работы с Loopback-адаптером...
Здравствуйте, k732, Вы писали:
K>>>И у меня в списке Microsoft нет Loopbak Adapter БП>>Это потому, что Loopbak Adapter не привязан к железу. Соответственно, его и нет в списке найденного оборудования. БП>>Идите в панель управления, жмите Добавить/Удалить железо, там выбрать вручную, сетевые адаптеры, поный список, Майкрософт, вот оно.
K>Извиняюсь, что поднимаю тему. K>Перекачка данных по сети происходит в мегабайтах. При использовании Tap-адаптера — сотни кбайт. K>Разница — порядок. Слишком медленно.
K>Добиться большего не удалось. Появилось ли что более быстрое ? K>И подскажите где можно найти примеры работы с Loopback-адаптером...
Я когда-то устанавливал coLinux.
Может, там и тот самый Tap-Win32, я не знаю, но сеть работала вполне прилично (десять мегабайт в секунду точно были).
Исходники открыты, можешь посмотреть.
Еще драйвер виртуального сетевого адаптера должен быть в составе VirtualBox, исходники тоже открыты.
Здравствуйте, k732, Вы писали:
K>Можно ли как отправить/получить IP-пакеты системе?
K>Приложение имеет доступ к IP-трафику и нужно имитировать сетевой адаптер (как будто на него приходят данные и что он отправляет данные).
K>Можно ли это как-нибудь сделать ?
набрал в гугле virtual network adapter, на первой же странице попал на ссылку
С>Может, там и тот самый Tap-Win32, я не знаю, но сеть работала вполне прилично (десять мегабайт в секунду точно были). С>Исходники открыты, можешь посмотреть.
Посмотрел — тот же Tap-Win32. Странно — как ты добился такой скорости ?
Я правда не замерял среднее премя операции чтения и записи устройства. Надо замерить.
Может я что с настройками замутил ? Не поделишся примерчиком ?
Здравствуйте, k732, Вы писали:
С>>Может, там и тот самый Tap-Win32, я не знаю, но сеть работала вполне прилично (десять мегабайт в секунду точно были). С>>Исходники открыты, можешь посмотреть.
K>Посмотрел — тот же Tap-Win32. Странно — как ты добился такой скорости ? K>Я правда не замерял среднее премя операции чтения и записи устройства. Надо замерить.
K>Может я что с настройками замутил ? Не поделишся примерчиком ?
K>P.S. Я имею ввиду программную работу с ним...
Нет, я имею ввиду работу сети между хост-системой и coLinux.
Я устанавливал coLinux, чтобы иметь доступ к reiserfs-разделу — я его монтировал в coLinux и расшаривал самбой. Скорость работы была порядка 10Мб/сек, правда, проц серьёзно загружался.
Наверное, тебе стоит посмотреть, как coLinux работает с Tap-интерфейсом.
С>Нет, я имею ввиду работу сети между хост-системой и coLinux. С>Я устанавливал coLinux, чтобы иметь доступ к reiserfs-разделу — я его монтировал в coLinux и расшаривал самбой. Скорость работы была порядка 10Мб/сек, правда, проц серьёзно загружался. С>Наверное, тебе стоит посмотреть, как coLinux работает с Tap-интерфейсом.
Проблемма в том, что я не смог там найти исходников Так есть SDK — но это не то...