Сетевые драйверы
Сетевые драйверы можно разделить на 2 категории: TDI-драйверы (Transport Driver Interface) и NDIS-драйверы (Network Driver Interface Specification). TDI-драйверы — это высокоуровневые драйверы, например, SMB-клиент, SMB-сервер, обертки SMB (NFFS, MSFS) и т.п. Мы с Вами рассмотрим NDIS-драйвера. NDIS — это специальный драйвер (ему соответствует файл ndis.sys), который содержит функции, используемые низкоуровневыми сетевыми драйверами. NDIS как бы обволакивает низкоуровневые сетевые драйверы и является посредником в их общении между собой и с железом. По сути NDIS можно считать третьим ядром Windows. Чтобы более четко уяснить себе что из себя представляет NDIS можно посмтореть на следующую картинку:
Как видно из этой иллюстрации NDIS-драйверы бывают трёх типов:
- Минипорт-драйверы (драйверы адаптера)
- Промежуточные драйверы (например, psched.sys)
- Драйверы протокола (например, tcpip.sys)
Рассмотрим каждый из них по отдельности.
Минипорт-драйверы
У каждой сетевой железки есть свой минипорт-драйвер. Через NDIS минипорт-драйвер получает некотрые команды. Функции минипорт-драйвера можно описать следующим образом:
- производит инициализацию своего устройства (адаптера)
- создание /включение/выключение/удаление сетевых подключений
- выдача клиенту или изменение параметров адаптера
- отправка пакетов
- получение пакетов
- оповещение ОС о состоянии адаптера
- перезагрузка и остановка адаптера
Минипорт-драйвер содержит 22 стандартные callback-функции, с помощью которых он оповещает о различных событиях (некоторые из этих функций могут быть NULL, тогда драйвер о соответствующих событиях не оповещается). NDIS экспортирует около 150 функций для использования минипорт-драйверами.
Минипорт-драйверы бывают «Connectionless» (например, драйвер Ethernet-адаптера) и «Сonnection-oriented» (например, драйвер модема). У Сonnection-oriented драйверов система коллбэков чуть сложнее, в нее входят обработчики событий, связанных с подключением к каналу связи, отключением от канала, выбором канала (для беспроводных адаптеров) и т.п. Для некоторых операций Сonnection-oriented драйверы вызывают специальные функции NDIS, отличающиеся префиксом «Со» в имени (например, вместо NdisMIndicateReceivePacket Сonnection-oriented драйвер должен вызывать NdisMColndicateReceivePacket).
Каждый коллбэк выполняет свою задачу: выдача информации, отправка данных, прием данных и т.п. Подробнее можно посмотреть в хелпе к WDK (DDK). Там можно получить полную информацию о коллбэках.
Драйверы протоколов могут передоверять минипорт-драйверу (при условии, что минипорт-драйвер это умеет — либо сам, либо адаптер умеет это делать на аппаратном уровне) некоторые свои функции (например, разграничить контрольную сумму или цифровую подпись IP-пакета или принять решение, как фрагментировать большой ТСP-пакет). Это значительно повышает производитель сети.
Есть еще разные дополнительные продвинутые интерфейсы, которые минипорт-драйвер может поддерживать, например:
- LBFO (Load Balancing and Fail Over) — позволяет понимающим его адаптерам распределять между собой исходящий трафик и исправлять ошибки друг друга. Впрочем, что имеет смысл только на backbone routers (центральных маршрутизаторах больших сетей), на которые редко ставят Windows
- FFP (Fast Forwarding Path) — позволяет понимающим его адаптерам маршрутизировать/фильтровать пакеты чисто аппаратно, вообще без участия ОС и не нагружая основные процессоры компьютера
Промежуточные драйверы
Промежуточный драйвер сверху виден как минипорт-драйвер (смотрим на картинку), т.е. как бы виртуальный адаптер, а снизу — как драйвер протокола (снова смотрим на картинку), как бы виртуальный протокол. Как частный случай, возможна ситуация, когда промежуточный драйвер виден только сверху.
Промежуточные драйверы обычно делают одно из:
- организуют «справедливый» доступ разных клиентских программ к адаптерам дабы программы не мешали друг другу
- фильтруют и перехватывают трафик
- маршрутизируют пакеты из одной сети в другую, если эти сети различаются (например, Ethernet и WI-FI)
Именно промежутчные драйверы используются сниферами для сканирования сетевого трафика. Промежуточные драйверы могут садиться один на другой, если виртуальный протокол одного промежуточного драйвера привяжется к виртуальному адаптеру другого промежуточного драйвера. Но так делают редко ибо снижает производительность.
Драйверы протоколов
Драйверы протокола — это самый верхний уровень спецификации NDIS. Эти драйверы занимаются тем, что выделяют ресурсы для соответствующих пакетов, копируют данные приложений в пакеты и передают их драйверам нижнего уровня. Также драйверы протоколов обеспечивают интерфейс для получения пакетов от нижележащих драйверов.
К драйверам протоколов относятся и драйверы транспорта, реализующие стек сетевых протоколов, такой как например TCP/IP (tspip.sys).
Если пост будет интересен читателям, то в следующих постах можно конкретно на примере написать свой сниферо-подобный промежуточный драйвер или также описать как написать каждый из типов драйверов (минипорта, промежуточный или протокола).
Спасибо за внимание.