Ндис. Net_Buffer Архитектура

Давай продолжим начал серия статей о NDIS. В этой теме мы рассмотрим версии NDIS и принципы передачи пакетов между драйверами «стека» и архитектурой NET_BUFFER.

НДИС.
</p><p>
 NET_BUFFER архитектура



Введение

Для начала давайте рассмотрим версии NDIS и их особенности в связи с тем, что их чуть больше одной.

  • НСИС 5.1. Windows XP, Server 2003. Большинство драйверов написано под эту версию и портировать их никто не берется, т.к.

    портировать там особо нечего - почти все придется переписывать;

  • НСИС 5.2. Windows Сервер 2003 с пакетом обновления 2. Скорее всего, для этой версии не написаны драйвера, потому что.

    Драйвера от 5.1 здесь работают нормально;

  • НДИС 6.0. Виндоус виста.

    подсистема NDIS в Windows Vista претерпела огромные изменения, были добавлены новые типы драйверов, улучшена производительность;

  • НСИС 6.1. Windows Vista SP2, Server 2008. Та же история, что и с NDIS 5.2;
  • НСИС 6.20. Windows 7. Незначительные изменения относительно NDIS 6.0, поддержка последней в режиме эмуляции.

Старый хлам в виде W2K с его NDIS 4.0 трогать не буду, потому что.

Поддерживать это нет смысла.

Microsoft также прекращает поддержку NDIS 5.1 в Windows 8. Как видно из списка, между NDIS 5.x и NDIS 6.x существует огромный разрыв.

Фактически, все, что у них было общего, — это архитектурная особенность и библиотека функций.

Все остальные компоненты были переработаны для повышения производительности.

Кстати, этот прирост унаследован на 20%, так что хоть в чем-то Vista лучше своей предшественницы.

В архитектуру добавлены драйверы фильтров, которых так не хватало в предыдущих версиях.

Кардинально изменились принципы передачи пакетов, а именно: если раньше промежуточный драйвер должен был реализовать как минимум три функции приема и отправки пакетов, то теперь количество этих функций в любом случае равно одной.

Это стало возможным благодаря новой архитектуре передачи пакетов под названием NET_BUFFER. Мы поговорим об этом ниже.



NET_BUFFER архитектура

Так что же это такое? По сути, NET_BUFFER — это замена предыдущего NDIS_BUFFER, но обо всем по порядку.

Что случилось? Драйвер реализует три функции отправки и получения пакетов.

По-русски назовем эти функции так:

  • ПринятьПакет;
  • Принять пакеты;
  • ПодтвердитьПринятиеПакетов;
  • ОтправитьПакет;
  • ОтправитьПакеты;
  • Подтвердите отправку посылки.

Понятно, что для получения одного пакета нужно было совершить кучу действий.

А для промежуточных драйверов вообще разбирать пакет до ядра, собирать свой (потому что чужое все равно трогать нельзя) и отправлять.

Поэтому в NDIS 6.x появилась архитектура NET_BUFFER. Согласно этой архитектуре достаточно реализовать по 2 функции для приема и отправки пакета (теперь это не пакет, а буфер, поэтому ниже воспринимайте эти слова как синонимы, говоря о NDIS 6+).

Да, насчет 2х я соврал, но эти двое ничего особенного не делают и переходят от драйвера к драйверу без изменений.

Итак, функции приема и отправки, их подписи я напишу здесь для общего понимания:

   

VOID FilterSendNetBufferLists( IN NDIS_HANDLE FilterModuleContext, IN PNET_BUFFER_LIST NetBufferLists, IN NDIS_PORT_NUMBER PortNumber, IN ULONG SendFlags ); VOID FilterReceiveNetBufferLists( IN NDIS_HANDLE FilterModuleContext, IN PNET_BUFFER_LIST NetBufferLists, IN NDIS_PORT_NUMBER PortNumber, IN ULONG NumberOfNetBufferLists, IN ULONG ReceiveFlags );

Первые параметры по сути представляют собой указатель, который передаст вам NDIS. При регистрации драйвера, а точнее при присоединении его к очереди, можно указать этот самый указатель.

Что.

В нашем распоряжении всегда есть ссылка на пользовательскую переменную, которая, как мы знаем, имеет неограниченную сферу применения.

Очень удобно.

Вторые параметры — это указатели на списки NET_BUFFER. Мы разберемся с этим позже.

Все остальные параметры используются редко, поэтому рассматривать их не будем.

Перейдем к самой архитектуре.

На рисунке ниже примерно представлена архитектура:

НДИС.
</p><p>
 NET_BUFFER архитектура

Каждый NET_BUFFER может описывать пакет, как показано на рисунке ниже:

НДИС.
</p><p>
 NET_BUFFER архитектура

Наша посылка хранится в затененном месте.

Как видите, это не обязательно непрерывный блок памяти; один пакет может быть разбросан по всему адресному пространству системы.

Также рекомендуется хранить пакеты в невыгружаемой памяти (для справки: при попытке доступа к страничной памяти по IRQL > = DISPATCH_LEVEL мы получим синий экран с кодом D1. DRIVER_IRQL_NOT_LESS_OR_EQUAL, самая распространенная ошибка авторов драйверов).

Сразу возникает вопрос: зачем оставлять пустое место перед упаковкой? Затем, когда IP-пакет приходит, он упаковывается в кадр Ethernet для отправки.

И чтобы не перестраивать это дело, заголовок Ethernet просто записывается перед пакетом.

Довольно задумчиво.

Тот же принцип реализован в драйверах верхнего уровня.

Вся информация о так называемом пространстве обратной засыпки (он же DataOffset), смещениях и длине буфера хранится в структуре NET_BUFFER. Еще хочу отметить, что размер буфера можно менять, т.е.

начало буфера можно переместить влево, а конец — вправо.

Это делается с помощью специальных функций, экспортируемых ядром NDIS.

Вместо заключения

В этой статье намеренно опущено огромное количество деталей, с которыми я столкнулся при исследовании подсистемы NDIS. Я их не публикую, потому что.

количество материала, однако, не укладывается ни в какие разумные рамки.

При этом я пытаюсь пролить свет на некоторые ключевые особенности, которые считаю базовыми для понимания сути происходящего.

Дополнительную литературу читайте здесь: www.codemachine.com/article_ndis6nbls.html msdn.microsoft.com/en-us/library/ff564881 (v=vs.85).

aspx До скорого.

Теги: #NDIS #filter #реализация драйвера фильтра #C++ #KM #режим ядра #Разработка для Windows

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.