Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Дублирование исходящих пакетов в NDIS  (Прочитано 11319 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sagatov
Интересующийся

ru
Offline Offline

« : 13-03-2011 09:40 » 

Здравствуйте!

Имею необходимость продублировать все исходящие пакеты.
Взял пример Passthru из WDK 7600 (самый новый на сегодняшний день).
Чтобы разобраться, я упростил задачу, используя функцию MPSend вместо MPSendPackets.
Условно эту функцию можно разделить на две части:
1 Если у нас NDIS51 то пытаемся получить пришедший пакет и перенаправить его следующему обработчику.
2 Если ну нас не NDIS51 или не получилось извлечь пакет, то создаем копию пакета и уже копию направляем далее.

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

Во втором варианте создаем не один пакет, а сразу два. И два пытаемся отправить.

НО если попытаться отправить второй пакет, то система виснет. Просто всё замирает.

Проверял, драйвер работает нормально, если не отправлять второй пакет, а просто его создавать.
То есть создаются оба пакета, заполняются информацией. Всё проходит корректно.

Как только отправляем второй пакет - всё виснет.

Тоже самое пробовал в MPSendPackets проводить. Результат совершенно тот же - отправка дублированного пакета приводит к зависанию.

Функцию MPReturnPacket менял соответственно.

Уже месяц роюсь в интернете, но ничего дельного не нахожу. Пример с изменением пакета (VPN примеры и т.п.) не вносит ясности, потому что на один вызов MPSend отправляется один пакет, только измененный.

Черновик miniport.c прикладываю.

А теперь главный вопрос: Как продублировать исходящий пакет?

* miniport.c (48.79 Кб - загружено 1357 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 13-03-2011 14:57 » 

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

пока в голову приходит только
https://forum.shelek.ru/index.php/topic,21532.msg213492.html#msg213492
Цитата
Короче для "своих" пакетов не надо вызывать NdisMSendComplete в функции PtSendComplete.
Осталось только научиться их отличать.

и https://forum.shelek.ru/index.php/topic,7748.msg132637.html#msg132637
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sagatov
Интересующийся

ru
Offline Offline

« Ответ #2 : 13-03-2011 16:33 » 

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

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

пока в голову приходит только
https://forum.shelek.ru/index.php/topic,21532.msg213492.html#msg213492
Цитата
Короче для "своих" пакетов не надо вызывать NdisMSendComplete в функции PtSendComplete.
Осталось только научиться их отличать.
Да, над этим я уже думал. Но в MPSend вообще не используется данная функция, а в MPSendPackets она естественно вызывается только один раз. По тому неприменимо для данного случая.

1. Вниз - NdisSend, NdisSendPackets. Это твой драйвер должен уже делать...
2. Вверх - NdisMIndicateReceivePacket. Это твой драйвер должен уже делать...

Если ты хочешь создать новый пакет, ты должен сам его распределить.
Логическая цепочка:

Код:
ProtocolReceive()
{
  ...
  NdisAllocatePacket (...)
  NdisAllocateBuffer(...)
  NdisChainBufferAtBack(...)
  //После отправки, ждать возврата пакета в ProtocolSendComplete
  NdisSend(...)                           
}

ProtocolSendComplete()
{
  NdisUnchainBufferAtBack(...)
  NdisFreeBuffer(...)
  NdisReinitializePacket(...)
  NdisFreePacket(...)
}

А вот это интересно. В примере NdisAllocateBuffer и NdisChainBufferAtBack вообще не используются.
Я могу предположить, что в новый пакет помещается тот же буфер, что был в старом.
И получается какая-то нестыковка, когда я ещё раз этот буфер использую в третьем пакете.

Что думаете про это? Какие мысли?

* passthru.zip (37.89 Кб - загружено 927 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 13-03-2011 21:27 » 

Цитата
Each packet descriptor will eventually have one or more buffer descriptors chained to it. NdisAllocatePacket zero-initializes the packet descriptor and sets its buffer chain pointer to NULL. The caller must chain the buffer descriptor(s) mapping the packet data to the packet descriptor before it is sent or indicated. Most NDIS drivers allocate buffer descriptors with NdisAllocateBuffer.

а в примере по видимому это замещается так:
NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);

PS может размера не хватило А черт его знает...
« Последнее редактирование: 13-03-2011 21:31 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sagatov
Интересующийся

ru
Offline Offline

« Ответ #4 : 14-03-2011 10:09 » 

Всё снова переделал (исходники во вложении).
Сделал часть для создания и отправки полного дубликата пакета. Создаю свой буфер.
При отправке своего пакета - виснет. Всё перепробовал уже, что мог придумать.

Ochkarik: Посмотрите пожалуйста. Я отделил то, что я писал. Помечено "//--------.....".

Нужно очень срочно, горю! )

* driver.zip (43.1 Кб - загружено 938 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 14-03-2011 10:16 » 

попробуйте посмотреть DBGPRINT-ами, где что происходит и куда отправляется)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sagatov
Интересующийся

ru
Offline Offline

« Ответ #6 : 14-03-2011 11:11 » 

попробуйте посмотреть DBGPRINT-ами, где что происходит и куда отправляется)
Ну так что ж я не пробовал что ли.
Всё замечательно проходит.
GetPktPayload возвращает реальные данные нужного размера.
NdisAllocateBuffer успешно создает буфер.
Но если я пытаюсь отправить созданный пакет - система виснет. На каком именно месте она виснет сложно сказать, так как при зависании не успевает отладочная информация пройти из режима ядра. Скорей всего первый вызов NdisSend или второй NdisAllocatePacket.
Если не пытаюсь, то всё прекрасно продолжает работать.

...

Добавлено через 2 минуты и 1 секунду:
Скорей всего первый вызов NdisSend или второй NdisAllocatePacket.
Хотя нет. Он виснет именно на первом NdisSend, так как всё остальное можно комментировать и всё равно виснет.

Добавлено через 1 день, 4 часа, 8 минут и 24 секунды:
Предложение более не актуально!
« Последнее редактирование: 15-03-2011 15:20 от sagatov » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 15-03-2011 15:24 » 

sagatov, надеюсь по причине найденного решения задачи?)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sagatov
Интересующийся

ru
Offline Offline

« Ответ #8 : 15-03-2011 20:38 » 

Вроде да )
Я вынес процедуру дублирования в PtSendComplete и зависать перестало )
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 15-03-2011 23:20 » 

хорошо, но.... жаль, потому что эффект по-прежнему необъясним...)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines