TC>Нет. NDIS_PACKET описывает один сетевой пакет. Он может быть устроен примерно так: первый буфер — заголовок эзернет, второй буфер — загловок IP, третий — заголовок UDP, четвертый — пользовательские данные. Так сделано, чтобы избежать лишних операций копирования при обработке пакета сетевым стеком.
Но ведь тогда возникает проблема — как найти начало ETHERNET_FRAME ??? Другими словами, как понять, что вот этот пакет — есть ETHERNET_FRAME, а этот вот — TCP_HEADER ?
TC>Еще совет — все описания должны быть сделаны с однобайтовым выравниванием, иначе поля разъедутся.
Здравствуйте, Аноним, Вы писали:
А>Но ведь тогда возникает проблема — как найти начало ETHERNET_FRAME ??? Другими словами, как понять, что вот этот пакет — есть ETHERNET_FRAME, а этот вот — TCP_HEADER ?
Нет никаких проблем — это гарантировано логической вложенностью протоколов. Всегда последовательность такая: ethernet заголовок — ip заголовок — tcp заголовок — данные. Если вы начинаете раскручивать пакет с головы ( вы по-моему в посте попутали пакет с буфером ), то всегда первым идет ethernet заголовок с фиксированным размером 14 байт, ну и так далее.
Чтобы не сложилось неверного представления, замечу, что все может быть и в одном буфере. Так обычно бывает при приеме. Или вообще частично объединено. Например так:
TC>
TC>Чтобы не сложилось неверного представления, замечу, что все может быть и в одном буфере. Так обычно бывает при приеме. Или вообще частично объединено. Например так:
Так... ага... т.е. получается, что ETHERNET_FRAME есть в каждом пакете NDIS'а, и при чём всегда в начале, так?
А>Так... ага... т.е. получается, что ETHERNET_FRAME есть в каждом пакете NDIS'а, и при чём всегда в начале, так?
Так, с небольшим уточнением — если Medium ( среда ) — NdisMedium802_3 или NdisMediumWan ( см DDK OID_GEN_MEDIA_SUPPORTED ), т.е для ethernet сетей. Если сеть — token ring или еще какая нибудь — будет соответствующий заголовок.
А>>Так... ага... т.е. получается, что ETHERNET_FRAME есть в каждом пакете NDIS'а, и при чём всегда в начале, так? TC>Так, с небольшим уточнением — если Medium ( среда ) — NdisMedium802_3 или NdisMediumWan ( см DDK OID_GEN_MEDIA_SUPPORTED ), т.е для ethernet сетей. Если сеть — token ring или еще какая нибудь — будет соответствующий заголовок.
Ага, т.е. вот как всё хитро оказывается Значит, если среда другая — то структура первого заголовка будет не ETHERNET_FRAME, а что-то вроде ANOTHER_FRAME_TYPE_STRUCT ?
Отсюда напрашивается вопрос — как же понять, что за кадр нам пришёл? Ethernet — не Ethernet... Может функция какая-то предусмотрена в NDIS для запроса информации о пакете?..
А>Может функция какая-то предусмотрена в NDIS для запроса информации о пакете?..
Фильтр или протокол, обрабатывающий пакет, точно знает тип физической среды. Во-первых он это указывает при установке драйвера ( в инф файле ), во вторых ему это сообщают при инициализации ( см NdisOpenAdapter — 4-ый параметр ). Так что политика такая — что умеем, то и фильтруем, тем более ethernet — это 99% ( учитывая, что ndiswan.sys весь траффик от модемных подключений, туннелей и.т.п превращает в ethrnet формат ).
А>>Может функция какая-то предусмотрена в NDIS для запроса информации о пакете?..
TC>Фильтр или протокол, обрабатывающий пакет, точно знает тип физической среды. Во-первых он это указывает при установке драйвера ( в инф файле ), во вторых ему это сообщают при инициализации ( см NdisOpenAdapter — 4-ый параметр ). Так что политика такая — что умеем, то и фильтруем, тем более ethernet — это 99% ( учитывая, что ndiswan.sys весь траффик от модемных подключений, туннелей и.т.п превращает в ethrnet формат ).
Что вы имеете в виду? Что нужно хучить ещё и NdisOpenAdapter(), чтобы узнать binding handle, который потом придёться отслеживать далее? Или вы рекомендуете просто забить и анализировать все пакеты как ethernet'овские?
TC>Они все используют двухуровневую фильтрацию. Верхний уровень ( TDI фильтр ) отслеживает выделении сетевых ресурсов ( локальные порты, запросы на соединения и.т.п ). Все эти действия происходят в контексте процесса. Затем на основе этих данных создаются фильтрующие правила для нижнего уровня ( NDIS фильтра ). Таким образом, NDIS фильтр не знает, что SYN запрос послан конкретным приложением, он лишь предполагает это на основе работы своего верхнего фильтра. В принципе, TDI фильтр можно заменить на опрос драйвера tcpip.sys ( аналог netstat в режиме ядра ), но смысл от этого не меняется.
можно поподробней, что значит опрос драйвера tcpip.sys ? как это сделать? какие функции существуют?
Здравствуйте, Аноним, Вы писали:
_>>можно поподробней, что значит опрос драйвера tcpip.sys ? как это сделать? какие функции существуют?
А>Запрос IOCTL_TCP_QUERY_INFORMATION_EX. Возвращает список сетевых соединений (включая неактивные).
а из этого списка что-ли можно узнать какой процесс установил соединение ?
Здравствуйте, TarasCo, Вы писали:
TC>Для ТСР уникален квартет: пара адресов ( локальный и удаленный ) и пара портов ( локальный и удаленный ). Именно по этим значением NDIS фильтр и считает пакеты принадлежащим определенному процессу. Он конечно может анализировать еще другие поля сетевых пакетов, чтобы предотвратить прохождение "похожих" пакетов. Например, отслеживать номера последовательностей для ТСР потока, соответствие MAC и ip и.т.д, но это не имеет отношения к разграничению доступа процессов к сети.
1)а для других протоколов (не TCP) как быть? что для них уникально?
2)я пока экспериментировал на уровне NDIS, MPSendPackets, там такие Ethernet-фрэймы:
(IP) — 0x0800
(ARP) — 0x0806;
могут быть еще какие-нибудь типы фрэймов в стандартной винде (XP)?
3)еще заметил, что пакеты могут посылаться без установления соединения... что это значит?
4) что значит адрес с таким типом TDI_ADDRESS_TYPE_UNSPEC??? там обычно нули лежат...
A>>Каким же образом верхний фильтр понимает, что это запрос от одного из процессов, которого он отфильтровал ранее? Может быть возможно сопоставить по номеру локального порта, он всегда уникален?
TC>Для ТСР уникален квартет: пара адресов ( локальный и удаленный ) и пара портов ( локальный и удаленный ). Именно по этим значением NDIS фильтр и считает пакеты принадлежащим определенному процессу. Он конечно может анализировать еще другие поля сетевых пакетов, чтобы предотвратить прохождение "похожих" пакетов. Например, отслеживать номера последовательностей для ТСР потока, соответствие MAC и ip и.т.д, но это не имеет отношения к разграничению доступа процессов к сети.
есть NDIS фильтр и TDI фильтр, я беру из NDIS-фильтра пакет, беру из пакета адреса и пытаюсь их найти в TDI фильтре...
иногда получается находить, но иногда встречаются такие "квартеты", которых нету в TDI (там есть похожие, но часть — нули)
вот примеры:
1)на уровне NDIS
b100a8c0 8900 -> ff00a8c0 8900 (LocalAddr LocalPort -> RemoteAddr RemotePort)
на уровне TDI в фильтре:
b100a8c0 8900 -> 0 0
2)NDIS
b100a8c0 4d04 -> 1a3943c2 5000
TDI
0 4d04 -> 1a3943c2 5000
3)NDIS
b100a8c0 104 -> 100a8c0 3500
TDI
???? ничего не нашел
я только догадываюсь в случае 2), что биндится адрес 0 — а потом припысывается на уровне NDIS адрес адаптера
1) и 3) не знаю...
разъясните плиз
А>>Запрос IOCTL_TCP_QUERY_INFORMATION_EX. Возвращает список сетевых соединений (включая неактивные).
_>а из этого списка что-ли можно узнать какой процесс установил соединение ?
Можно, но не всегда.
Если нужно узнать процесс — imho, лучше приаттачить девайс на \Device\Tcp и в обработчиках смотреть текущий процесс.
Здравствуйте, TarasCo, Вы писали:
TC>Для ТСР уникален квартет: пара адресов ( локальный и удаленный ) и пара портов ( локальный и удаленный ). Именно по этим значением NDIS фильтр и считает пакеты принадлежащим определенному процессу. Он конечно может анализировать еще другие поля сетевых пакетов, чтобы предотвратить прохождение "похожих" пакетов. Например, отслеживать номера последовательностей для ТСР потока, соответствие MAC и ip и.т.д, но это не имеет отношения к разграничению доступа процессов к сети.
и еще вопрос :
как определить MAC адрес на уровне tdi для данного соединения???
Здравствуйте, Аноним, Вы писали:
_>>на уровне TDI (LocalAddr==0)&&(LocalPort!=0)
А>Чо паникуешь? Local Address == 0 на уровне TDI — это нормально. Точнее не 0, а 0.0.0.0 или ещё может быть 127.0.0.1.
да не паникую, я не знаю че делать...
ну и как с этим бороться?
допустим у меня 2 сетевые карты: 10.0.0.1 и 10.0.0.2
и процессы биндят 2 одинаковых порта port=123 на обеих картах
тогда получается на уровне TDI не различить их 0.0.0.0:123 ???