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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 ... 3 4 5 [6] 7 8   Вниз
  Печать  
Автор Тема: NDIS InterMediate Driver - Обсуждение  (Прочитано 238130 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
aks68
Модератор

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

« Ответ #150 : 15-05-2006 09:01 » 

з.ы.а, да, еще такой интересный момент. В заголовке TCP есть 2 поля - порт отправителья и порт получателя. Что-то я не до конца врублюсь, а разве можно послыть с одного порта,чтоб получили на другом(ну,если тока вручную пакеты не собирать)?

Не понял
Да, можно... А в чем собственно проблема?
Записан
aks68
Модератор

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

« Ответ #151 : 16-05-2006 01:44 » new

Я как-то проглядел...
В библиотеке клуба club.shelek.com имеется та самая книга Стивенса TcpIp Illustrated vol 1.
Так что вот выдержка из 3-й главы:

Цитата
Длина заголовка (header length) это количество 32-битных слов в заголовке, включая любые опции. Так как это 4-битное поле, оно ограничивает размер заголовка в 60 байт. В главе 8 мы увидим, что это ограничение сильно влияет на некоторые опции, такие как опция записи маршрута. Обычная величина в этом поле (когда отсутствуют опции) - 5.

С уважением,
Акс.
Записан
Uhri
Гость
« Ответ #152 : 16-05-2006 12:32 » 

Да, Акс, все верно, Ури. Улыбаюсь
В принципе у меня и была похожая структура заголовка. Тем не менее получается размер структуры 20 байт. Не пойму, если резмер будет непостоянный, т.е. некоторые поля будут переменной длины, как тогда определять смещение того или иного поля?
Как бы там ни было, у меня получается 20 байт. Но вот порты наотрез отказывается определять. Значение дает постоянное (для одного приложения), а вот порт не тот. Нопример, передаю данные по приложению на 1080 порту. Значение порта в структуре ТСР заголовка - 3804. Я полагаю это шестнадцатиричное значение. Тем не менее никак не 1080. В чем же может быть дело???
p.s. где можно прочитать про преобразование ИП адресов?Т.е. как,например,в программе мне присвоить переменной ИП?
Код:
UCHAR chr_ip = '192.168.0.1';
ULONG ip = (ULONG)chr_ip
?
« Последнее редактирование: 14-12-2007 22:49 от Алексей1153++ » Записан
Uhri
Гость
« Ответ #153 : 16-05-2006 14:44 » 

а, еще такой момент. Уже был приведен маршрут прохождения пакета (драйвер -> protocol -> miniport -> стек NDIS). Из всего я понял, что группа protocol взаимодействует непосредственно с драйвером сет. карты. Но сечас вдруг сомнения возникли. Получается по приходу на компьютер пакета он принимается драйвером сет. карты, оттуда protocol'ом (ф-я Resieve()), и т.д.. А когда пакеты уходят из машины - как тогда? От стека NDIS в miniport, потом в protocol и оттуда в драйвер карточки? Т.е. та самая Recieve() получает данные как приходящие на машину, так и исходящие? Или я не правильно понял?
Т.е. могу ли я поставить оработчик пакетов (ну, самое простое просто фильтр) в функции Recieve и у меня будут фильтроваться как входящие, атк и исходящие пакеты или для исходящих все же в miniport лезть придется?
« Последнее редактирование: 14-12-2007 22:50 от Алексей1153++ » Записан
aks68
Модератор

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

« Ответ #154 : 16-05-2006 18:34 » 

Да, Акс, все верно, Ури. Улыбаюсь
В принципе у меня и была похожая структура заголовка. Тем не менее получается размер структуры 20 байт. Не пойму, если резмер будет непостоянный, т.е. некоторые поля будут переменной длины, как тогда определять смещение того или иного поля?
Как бы там ни было, у меня получается 20 байт. Но вот порты наотрез отказывается определять. Значение дает постоянное (для одного приложения), а вот порт не тот. Нопример, передаю данные по приложению на 1080 порту. Значение порта в структуре ТСР заголовка - 3804. Я полагаю это шестнадцатиричное значение. Тем не менее никак не 1080. В чем же может быть дело???
p.s. где можно прочитать про преобразование ИП адресов?Т.е. как,например,в программе мне присвоить переменной ИП?
Код:
UCHAR chr_ip = '192.168.0.1';
ULONG ip = (ULONG)chr_ip
?
Привет!

Настаятельно рекомендую Стивенса. Там всё описанно и разрисованно. Заявленные поля имеют постоянный рамер, но там еще между Destination IP и Data имеется опциональное поле Options. Вот оно-то и будет увеличивать заголовок.

По поводу порта...  Я не спроста упоминал остроконечников (big endian). Пример: 0x3804 => 0x0438 => 1080. Далее додумай сам Ага

UCHAR chr_ip = '192.168.0.1';  С ума сойти... Я шокирован! Эт чё такое??? Поясни, я недогоняю...

С уважением,
Акс.
« Последнее редактирование: 14-12-2007 22:51 от Алексей1153++ » Записан
aks68
Модератор

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

« Ответ #155 : 16-05-2006 18:50 » 

а, еще такой момент. Уже был приведен маршрут прохождения пакета (драйвер -> protocol -> miniport -> стек NDIS). Из всего я понял, что группа protocol взаимодействует непосредственно с драйвером сет. карты. Но сечас вдруг сомнения возникли. Получается по приходу на компьютер пакета он принимается драйвером сет. карты, оттуда protocol'ом (ф-я Resieve()), и т.д.. А когда пакеты уходят из машины - как тогда? От стека NDIS в miniport, потом в protocol и оттуда в драйвер карточки? Т.е. та самая Recieve() получает данные как приходящие на машину, так и исходящие? Или я не правильно понял?
Т.е. могу ли я поставить оработчик пакетов (ну, самое простое просто фильтр) в функции Recieve и у меня будут фильтроваться как входящие, атк и исходящие пакеты или для исходящих все же в miniport лезть придется?

Неверно.

Что такое "драйвер", что такое "стек NDIS"?
И минипорт, и интермедиэйт, и протокол - это всё стек NDIS! Вы путаете стек NDIS и интерфейс NDIS.

Inbound flow: NIC -> Miniport -> Intermediate-Protocol -> Protocol -> TDI -> итд...
Outbound flow: TDI -> Protocol ->Intermediate-Miniport -> Minioirt -> NIC

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

Акс.

PS: Вот это сообщение...

Цитата
Путь входящего пакета (с IM).
1. Сетевая карта получила фрейм Ethernet пакета и MP преобразовал его в NDIS_PACKET
2. MP сигнализирует NDIS-у (так-же, как и в случае без IM)
3. Т.к. адаптер MP связан с "протокольным" концом IM, NDIS вызывает PotocolReceive/ProtocolReceivePacket зарегистрированные IM-ом, и пакет поступает в IM
4. Вначале IM-овский ProtocolReceive(Packet) ведет себя аналогично PD-шному, т.е. анализирует полученые данные чтобы определить что делать с пакетом. Особо подчеркну, что именно здесь должен вступать в игру обработчик правил фильтрации входящих пакетов брэндмауэра (о, блин,  словечко ...) если таковой имеется.
5. Если после всех проверок система решает пропустить пакет, то IM использует ф-ю NdisMIndicateReceivePacket (здорово выглядит вызов минипортной ф-и из протокольного контекста  ) указывая 1м аргументом хэндлер (незнаю как перевести) на контекст привязки вышерасположенного PD к виртуальному адаптеру IM, и таким образом, пакет уходит в PD.

Путь исходящего пакета (с IM).
1. Сформировав пакет PD вызывает NdisSend/NdisSendPacket указывая контекст привязки к виртуальному адаптеру IM, как 1й аргумент.
2. Определив из контекста "куда дуть", NDIS вызывает зарегистрированный IM-ом колбэк MiniportSendPackets.
3. MiniportSendPackets проверяет и копирует пакет, проверяеи состояние MP (> D0), и запускает обработчик правил фильтрации исходящих пакетов брэндмауэра.
4. Если все вышеперечисленное прошло на ОК, то для данного пакета вызывается ф-я NdisSend с указанием на контекст привязки к реальному адаптеру низлежащего MP, и пакет уплывает дальше...
« Последнее редактирование: 14-12-2007 22:53 от Алексей1153++ » Записан
Uhri
Гость
« Ответ #156 : 17-05-2006 06:48 » 

конечно я помню это сообщение. Правда, хорошо написано.
Блин, да запутался я немного. ЩАс тока вроде разобрался. Получается при входящих данных работает ТОЛЬКО Recieve, а при исходящих - ТОЛЬКО MPSend()? Не прикол. Придется для фильтрации входящего трафика одну обработку писать, а для исходящего другую. Интересно, а прохляет такое присвоение:
Код:
...
 NDIS_PACKET packet;
...
 pIP_Hdr pIPHdr = (pIP_Hdr)packet;
...
?
Записан
aks68
Модератор

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

« Ответ #157 : 17-05-2006 16:17 » 

конечно я помню это сообщение. Правда, хорошо написано.
Блин, да запутался я немного. ЩАс тока вроде разобрался. Получается при входящих данных работает ТОЛЬКО Recieve, а при исходящих - ТОЛЬКО MPSend()? Не прикол. Придется для фильтрации входящего трафика одну обработку писать, а для исходящего другую. Интересно, а прохляет такое присвоение:
Код:
...
 NDIS_PACKET packet;
...
 pIP_Hdr pIPHdr = (pIP_Hdr)packet;
...
?
Тоесть Вы хотите вот это

Код:
typedef struct _NDIS_PACKET
{
NDIS_PACKET_PRIVATE Private;

union
{
struct // For Connection-less miniports
{
UCHAR MiniportReserved[2*sizeof(PVOID)];
UCHAR WrapperReserved[2*sizeof(PVOID)];
};

struct
{
//
// For de-serialized miniports. And by implication conn-oriented miniports.
// This is for the send-path only. Packets indicated will use WrapperReserved
// instead of WrapperReservedEx
//
UCHAR MiniportReservedEx[3*sizeof(PVOID)];
UCHAR WrapperReservedEx[sizeof(PVOID)];
};

struct
{
UCHAR MacReserved[4*sizeof(PVOID)];
};
};

ULONG_PTR Reserved[2]; // For compatibility with Win95
UCHAR ProtocolReserved[1];

} NDIS_PACKET, *PNDIS_PACKET, **PPNDIS_PACKET;

привести вот к этому:

Код:
typedef struct _IP_HDR {
UCHAR iph_verlen;
UCHAR iph_tos;
USHORT iph_length;
USHORT iph_id;
USHORT iph_offset;
CHAR iph_ttl;
UCHAR iph_protocol;
SHORT iph_xsum;
LONG iph_src;
ULONG iph_dest;
} IP_HDR, *PIP_HDR;
а зачем?

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

С уважением,
Акс.
Записан
Uhri
Гость
« Ответ #158 : 17-05-2006 20:55 » 

в общем да, хотел (или хочу... - сам уже не знаю). Просто NDIS_PACKET какой-то кривой, нельзя там просто взять, скажем, IP или номер порта узнать (хотя может это руки у меня кривые, а там все довольно легко?). Еще там эти указатели на буферы (продолжение пакета), а в буферах еще указатели на буферы... Ужас! Как начнешь копаться по этим буферам!!!
Записан
brovy@n
Гость
« Ответ #159 : 19-05-2006 16:45 » 

Народ, может кто знает(ваще хоть че нибудь), как на основе passthru или может еще чего-нить замутить фильтр пакетов?
Здесь имеется в виду, что у меня есть прога(на Буилдере), которая выявляет какие пакеты мне ненужны.
Записан
heptohedron2004
Гость
« Ответ #160 : 27-05-2006 16:19 » 

Народ мот у кого есть пример работающего кода по передачи из приложения массива чисел в драйвер.
Записан
BlackStar
Постоялец

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

WWW
« Ответ #161 : 14-06-2006 16:51 » 

Это всё, конечно, чудесно и познавательно, после прочтения всей ветки, лично я, открыл для себя массу нового, но вот одна проблема (которая, по моему мнению, является краеугольной в нелегком деле фильтрации пакетов) осталась не раскрыта. Очень точно сказал Uhri: "там эти указатели на буферы (продолжение пакета), а в буферах еще указатели на буферы... Ужас!".
И действительно, прежде, чем разбивать Ethernet пакет на заголовки и данные нужно, ведь, получить сам этот пакет, который, в свою очередь, является данными в NDIS ПАКЕТЕ! А как эти данные оттуда выковырять??? Ведь, гораздо проще было бы сначала выделить ровный как стол буфер и скопировать туда данные из NDIS_PACKET, а уже потом городить огород с заголовками сетевых пакетов. Тогда отпала бы сразу масса вопросов (о том как парсить сетевой пакет и прочее) и дальнейшие действия были бы интуитивно понятны каждому. Но КАК это сделать? Как вытащить данные из NDIS_PACKET???
Насколько я понял, весь НДИС пакет представляет собой однонаправленный список структур MDL, да? В принципе, всё очень просто, но есть одно НО!!!  Мы ж на уровне ядра работаем! А тут как раз и начинаются всякие "страницы памяти", "выравнивание" и прочая ерунда, которую я, честно говоря, совершенно не понимаю (пока), ибо всегда имел дело только с Neither I/O. Может кто-нибудь сможет объяснить в двух словах коллегиальному сообществу как работать со всей этой кашей?  Похоже, что данная ветка заглохла, но мало ли...

ЗЫ:  Хотя, я точно знаю, что глубокоуважаемый aks68 последнее время посещает форум Ага      И активно помогает пионэрам NDISа вроде меня Улыбаюсь   За что ему отедельная благодарность.
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
sss
Специалист

ru
Offline Offline

« Ответ #162 : 15-06-2006 01:05 » 

Чтение из пакета NDIS в буфер!

Код:
VOID HlpReadOnPacket( 
                      PNDIS_PACKET Packet,                  // Исходный пакет
                      PUCHAR       lpBuffer,                // Буфер приемник
                      ULONG        nNumberOfBytesToRead,    // Максимальный размер п
                      ULONG        nOffset,                 // Смещение в пакете, начиная с MAC заголовка
                      PULONG       lpNumberOfBytesRead      // Количество реально прочитанных байт
                     )
{
   PNDIS_BUFFER    CurrentBuffer;
   UINT            nBufferCount, TotalPacketLength;
   PUCHAR          VirtualAddress;
   UINT            CurrentLength, CurrentOffset;
   UINT            AmountToMove;

   *lpNumberOfBytesRead = 0;
   if ( !nNumberOfBytesToRead)  return;

   // Чтение информации пакета
   NdisQueryPacket( (PNDIS_PACKET ) Packet,
                    (PUINT )        NULL,           // Physical Buffer Count
                    (PUINT )        &nBufferCount,  // Buffer Count
                    &CurrentBuffer,                 // First Buffer
                    &TotalPacketLength              // TotalPacketLength
                  );

   // Информация первого буффера
   NdisQueryBuffer( CurrentBuffer, &VirtualAddress, &CurrentLength);

   CurrentOffset = 0;

   while( nOffset || nNumberOfBytesToRead )
   {
      while( !CurrentLength )
      {
        NdisGetNextBuffer( CurrentBuffer, &CurrentBuffer);

        if (!CurrentBuffer) return;

        NdisQueryBuffer( CurrentBuffer, &VirtualAddress, &CurrentLength);
        CurrentOffset = 0;
      }
      if( nOffset)
      {
         // Вычисляем количество данных, переносимых из этого фрагмента
         if( CurrentLength > nOffset) CurrentOffset = nOffset;
         else                         CurrentOffset = CurrentLength;
         nOffset -= CurrentOffset;
         CurrentLength -= CurrentOffset;
      }

      if( nOffset)
      {
         CurrentLength = 0;
         continue;
      }

      if( !CurrentLength )
      {
         continue;
      }
      // Вычисляем количество данных, переносимых из этого фрагмента
      if ( CurrentLength > nNumberOfBytesToRead)
         AmountToMove = nNumberOfBytesToRead;
      else
         AmountToMove = CurrentLength;

      // Копируем данные.
      NdisMoveMemory( lpBuffer, &VirtualAddress[ CurrentOffset], AmountToMove);

      // Обновляем указатель приемника
      lpBuffer += AmountToMove;
     
      // Обновляем счетчики
      *lpNumberOfBytesRead += AmountToMove;
      nNumberOfBytesToRead -= AmountToMove;
      CurrentLength = 0;
   }
}
Записан

while (8==8)
BlackStar
Постоялец

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

WWW
« Ответ #163 : 15-06-2006 08:36 » 

Благодарю за код!  Сейчас я его попробую внедрить и проверить.
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
BlackStar
Постоялец

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

WWW
« Ответ #164 : 15-06-2006 10:23 » 

Что-то не понятен смысл переменной nOffset...  Я так понимаю, что это входной параметр?  Тогда чему он должен быть равен?
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
sss
Специалист

ru
Offline Offline

« Ответ #165 : 16-06-2006 00:44 » 

Это вдруг, если захочется пропустить ненужные (уже проанализированные) заголовки ( нaпример Ethernet) или другие данные пакета (цепи буферов пакетов).
« Последнее редактирование: 16-06-2006 00:58 от sss » Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #166 : 16-06-2006 00:51 » 

Технология такая.
1. Читаешь Ethernet (FDDI, Token Ring) header
2. затем ip header
3. затем tcp, udp, icmp и любой другой header
4. затем сами данные

Записан

while (8==8)
BlackStar
Постоялец

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

WWW
« Ответ #167 : 16-06-2006 08:55 » 

Понятно. Спасибо.
Значит, если мне нужен весь пакет, то надо выставить nOffset равным нулю.
Очхорошо Улыбаюсь
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
BlackStar
Постоялец

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

WWW
« Ответ #168 : 16-06-2006 10:43 » 

Да, и еще один маленький вопрос. Можно ли в двух словах объяснить КАК отправить обратно в сеть пакет, только что полученный от сетевой карты? Ну, скажем, пришло управление в PtReceive, да? Я вытащил пакет, что-то изменил и теперь хочу запхать его обратно в сетевую карту, а как это сделать? И вообще, есть ли возможность отправлять пакеты в сеть (NDIS IM->Adapter) и к приложению (NDIS IM->TDI) из любого произвольного места в драйвере?
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
sss
Специалист

ru
Offline Offline

« Ответ #169 : 19-06-2006 01:13 » 

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

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

Код:

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

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


 
Записан

while (8==8)
BlackStar
Постоялец

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

WWW
« Ответ #170 : 19-06-2006 10:10 » 

Хм... Всё бы ничего, но я наблюдаю какую-то странную вещь в Passthru ! А именно:
Мы имеем приблизительно следующую структуру функции PtReceive():

NDIS_STATUS PtReceive(...)
{
        if (!pAdapt->MiniportHandle)
   {
      Status = NDIS_STATUS_FAILURE;
   }
   else do
   {
                 Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);

      if (Packet != NULL)
      {
                      ....................................
                      отправка пакета
                      break;
                 }
                 else
                 { тут пусто }

                pAdapt->IndicateRcvComplete = TRUE;
      switch (pAdapt->Medium)
      {
                       отправка пакета
                       break;
                       ......................................
                 }
                 ...........................................
        } while(FALSE);

     return Status;

}

Так вот, NdisGetReceivedPacket() почти всегда возвращает NULL !    Ненулевое значение похоже возвращается только в случае исходящего (Не понял) пакета! Как же так?!! Почему это происходит?Может я чего-то не понимаю, но я был уверен, что в эту функцию попадают все ВХОДЯЩИЕ пакеты из сети и вызвав NdisGetReceivedPacket() можно получить доступ к их содержимому, но на практике всё оказалось совсем не так - я ставлю бряку в начале этой функции И после вызова NdisGetReceivedPacket(), после чего запускаю браузер. Во время загрузки сайта (входящие пакеты, да?) все вызовы NdisGetReceivedPacket() вернули нулевое значение!!!  Почему???  Что не так??? Я уже вообще ничего не понимаю! Как тогда получить доступ к входящему траффику???
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
sss
Специалист

ru
Offline Offline

« Ответ #171 : 20-06-2006 00:52 » 

Код:
NDIS_STATUS PtReceive( IN  NDIS_HANDLE  ProtocolBindingContext,
                                   IN  NDIS_HANDLE   MacReceiveContext,
                                   IN  PVOID             HeaderBuffer,
                                   IN  UINT               HeaderBufferSize,
                                   IN  PVOID             LookAheadBuffer,
                                   IN  UINT               LookAheadBufferSize,
                                   IN  UINT               PacketSize)

Если драйвер посредник принимает пакет, ProtocolReceive должна вызвать NdisTransferData с дескриптором пакета и распределенными драйвером буферами. NdisTransferData нужно вызвать в контексте ProtocolReceive, и можно вызвать только однажды. Очень внимательно читай об NdisTransferData!
Записан

while (8==8)
BlackStar
Постоялец

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

WWW
« Ответ #172 : 20-06-2006 08:25 » 

Ага! Спасибо за объяснение! Буду пробовать!
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
BlackStar
Постоялец

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

WWW
« Ответ #173 : 20-06-2006 17:20 » 

Всё-равно ничего не получается Жаль   Совершенно не пойму смысла многих функций.
Сделал так:

pBuf = ExAllocatePool(NonPagedPool, 2048); выделяем память для пакета

   if (pBuf == NULL)
   {
      return NULL;
   }
   
   NdisAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); // создам структуру пакета
   
   NdisAllocateBufferPool(&Status, Pool, 1); // выделяем пул. В последнем параметре я не уверен

   NdisAllocateBuffer(&Status, &Buffer, Pool, pBuf, 2048); // просовываем в этот пул наш буффер

   NdisChainBufferAtBack(MyPacket, Buffer); // цепляем буффер к пакету

   if (Status == NDIS_STATUS_SUCCESS)
   {   
      // получаем весь пакет от нижележащего драйвера
      NdisTransferData(&Status,
             ProtocolBindingContext,
             MacReceiveContext,
             0,
             0,
             MyPacket,
             &BytesTransferred);
   }

Не работает.

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

Программирование на заказ   C/C++, Delphi, PHP, javascript
sss
Специалист

ru
Offline Offline

« Ответ #174 : 21-06-2006 01:36 » 

У меня готовых решений нет. Есть логгеры, брандмауэры - а вот редакторов пакетов и антивирусов пока не писал... Собираюсь. Сейчас занят другим проектом... Вот только есть одна мысля.  Не работает, в смысле NdisTransferData возвращает Status != NDIS_STATUS_SUCCESS ?
Или сюда не заходит ?

Код:
if ( Status == NDIS_STATUS_SUCCESS)
   {   
      // получаем весь пакет от нижележащего драйвера
      NdisTransferData(&Status,
             ProtocolBindingContext,
             MacReceiveContext,
             0,
             0,
             MyPacket,
             &BytesTransferred);
   }

в общем, мне кажется, надо самому копировать LookAheadBuffer в распределенный тобой буфер дескриптора и передавать ByteOffset не 0, а LookaheadBufferRange + 1 (см. MSDN) и  BytesToTransfer тоже какой то выбирать...
Записан

while (8==8)
BlackStar
Постоялец

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

WWW
« Ответ #175 : 21-06-2006 07:59 » 

Сюда не приходит - валится раньше. Я ж говорю, что никак в толк не возьму как именно нужно выделять память и прочее... Пулы, буфферы... А как одно соотносится с другим???
Про NdisTransferData() пока ничего не скажу, ибо, по изложенным выше причинам, не знаю как она отрабатывает.
Что ж, буду морочиться дальше. Как что-то получится - выложу код.

Да, и еще один злободневный вопрос! Никак не разберусь с установкой passthru. Ну, то есть, конечно, он устанавливается и начинает работать, но только до первой перезагрузки - после нее сразу появляется сообщение о том, что найдено новое устройство "Passthru Miniport" и предлагается его установить! Что за аномалия??? Ведь, изначально, вроде как, всё ставится нормально! Как лечить этот трабл? На РСДНе молчит народ... Уж не знаю чтО и делать... Решил уж обнаглеть и поинтересоваться еще и здесь Улыбаюсь
Записан

Программирование на заказ   C/C++, Delphi, PHP, javascript
aks68
Модератор

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

« Ответ #176 : 21-06-2006 10:22 » 

Сюда не приходит - валится раньше. Я ж говорю, что никак в толк не возьму как именно нужно выделять память и прочее... Пулы, буфферы... А как одно соотносится с другим???
Про NdisTransferData() пока ничего не скажу, ибо, по изложенным выше причинам, не знаю как она отрабатывает.
Что ж, буду морочиться дальше. Как что-то получится - выложу код.

Да, и еще один злободневный вопрос! Никак не разберусь с установкой passthru. Ну, то есть, конечно, он устанавливается и начинает работать, но только до первой перезагрузки - после нее сразу появляется сообщение о том, что найдено новое устройство "Passthru Miniport" и предлагается его установить! Что за аномалия??? Ведь, изначально, вроде как, всё ставится нормально! Как лечить этот трабл? На РСДНе молчит народ... Уж не знаю чтО и делать... Решил уж обнаглеть и поинтересоваться еще и здесь Улыбаюсь

Добрый день!
Предлагаю решать проблемы по очереди.
1. Как мне кажется у Вас не очень хорошая среда для отладки. А именно, как мне показалось Вы: во-первых используете браузеер для генерирования трафика (тут непонятно какие пакеты и куда он шлет) вместо чего-то узко-заточенного (наподобие hping), во-вторых Вы не используете эталонный перехватчик пакетов (наподобие ethereal) ну и в-третих я-бы порекомендовал либо 2 компьютера, либо эмулятор (тут безо всяких наподобие рулит VmWare). Понимаю, что это все затраты времени и средтв, но работа в удобной среде позволяет сэкономить больше.

2. Теперь разберемся с PtRecieve. Эта функция обьявленная обязательной. Еще имеется дополнительная PtReceivePacket. Кто что и как получает я в свое время уже писал. Однако есть интересная закономерность - если обьявленна PtReceivePacket, то PtReceive не получает практически ничего (весь траффик идет через PtReceivePacket). Может в этом дело? Для отладки я пользуюсь единичными пакетами (например попытка открыть telnet генерирует 4 TCP пакета с извстным destination IP), так вот, чтобы добраться до PtReceive мне пришлось отменить регистрацию PtReceivePacket. Попробуйте так сделать и не пользуйтесь (пока) браузером. Могу лишь добавить, что прочтя вашу переписку я наколенке модифицировал PtReceive и убедился, что все работает.

3. NdisTransferData – Выделять пулы для пакетов и буферов нужно где-то в начале. Пока больше ничего не посоветую,- сперва разберитесь с PtRecieve и NdisGetReceivedPacket.

4. По поводу установки. Я ниже приведу 2 INF файла. Возьмите их. Что и как – давайте спишемся в Вашей ветке Регистрация NDIS драйвера. Если установка непойдет – там-же.

С уважением,
Акс.
Записан
aks68
Модератор

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

« Ответ #177 : 21-06-2006 10:51 » 

Вот функция полностью. Фирменные коментарии MS удалил...

Код:
PtReceive(
    IN  NDIS_HANDLE         ProtocolBindingContext,
    IN  NDIS_HANDLE         MacReceiveContext,
    IN  PVOID               HeaderBuffer,
    IN  UINT                HeaderBufferSize,
    IN  PVOID               LookAheadBuffer,
    IN  UINT                LookAheadBufferSize,
    IN  UINT                PacketSize
    )
{
    PADAPT            pAdapt = (PADAPT)ProtocolBindingContext;
    PNDIS_PACKET      MyPacket, Packet;
    NDIS_STATUS       Status = NDIS_STATUS_SUCCESS;

USHORT PktType;
PCHAR Buf = HeaderBuffer;
PIP_HDR pIpHdr;
PUCHAR pOctSrc, pOctDst;

PTCP_HDR pTcpHdr;

DBGPRINT(("==> PtReceive.\n"));

// Check the packet //

PktType = ((USHORT) Buf[12]) * 0x100U + (USHORT) Buf[13];

switch(PktType)
{
case 0x0800:
DBGPRINT(("Packet type IP 0x%x\n", PktType));

// Trying to check IP adderss...
pIpHdr = (PIP_HDR)LookAheadBuffer;
pOctSrc = (PUCHAR) &(pIpHdr->iph_src);
pOctDst = (PUCHAR) &(pIpHdr->iph_dest);

DBGPRINT(("Packet from %d.%d.%d.%d to %d.%d.%d.%d\n",\
*pOctSrc, *(pOctSrc+1), *(pOctSrc+2), *(pOctSrc+3),\
*pOctDst, *(pOctDst+1), *(pOctDst+2), *(pOctDst+3) ));

switch(pIpHdr->iph_protocol)
{
case 0x01:
DBGPRINT(("ICMP: ...\n"));
break;

case 0x06:
// Trying to check TCP related parameters
// pTcpHdr = (PTCP_HDR)((PUCHAR)LookAheadBuffer + sizeof(IP_HDR));
pTcpHdr = (PTCP_HDR)((PUCHAR)LookAheadBuffer + 4 * pIpHdr->iph_verlen.ip.len);
DBGPRINT(("TCP: from port %d to port %d\n", pTcpHdr->tcp_src, pTcpHdr->tcp_dest));
break;

case 0x11:
DBGPRINT(("UDP: ...\n"));
break;

}

break;

case 0x0806:
DBGPRINT(("Packet type ARP 0x%x\n", PktType));
break;
}

    if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))
    {
        Status = NDIS_STATUS_FAILURE;
    }
    else do
    {
        //
        // Get at the packet, if any, indicated up by the miniport below.
        //
        Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
        if (Packet != NULL)
        {
        DBGPRINT(("Retrived received packet (%08X)\n"));

            //
            // The miniport below did indicate up a packet. Use information
            // from that packet to construct a new packet to indicate up.
            //


            //
            // Get a packet off the pool and indicate that up
            //
            NdisDprAllocatePacket(&Status,
                                &MyPacket,
                                pAdapt->RecvPacketPoolHandle);

            if (Status == NDIS_STATUS_SUCCESS)
            {
                MyPacket->Private.Head = Packet->Private.Head;
                MyPacket->Private.Tail = Packet->Private.Tail;

                NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
                NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

                NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

                NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);


DBGPRINT(("Has been copied to packet (%08X)\n", MyPacket));
                NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

                NdisDprFreePacket(MyPacket);

                break;
            }
        }
        else
        {
            //
            // The miniport below us uses the old-style (not packet)
            // receive indication. Fall through.
            //
        }

        pAdapt->IndicateRcvComplete = TRUE;
        switch (pAdapt->Medium)
        {
            case NdisMedium802_3:
            case NdisMediumWan:
                NdisMEthIndicateReceive(pAdapt->MiniportHandle,
                                             MacReceiveContext,
                                             HeaderBuffer,
                                             HeaderBufferSize,
                                             LookAheadBuffer,
                                             LookAheadBufferSize,
                                             PacketSize);
                break;

            case NdisMedium802_5:
                NdisMTrIndicateReceive(pAdapt->MiniportHandle,
                                            MacReceiveContext,
                                            HeaderBuffer,
                                            HeaderBufferSize,
                                            LookAheadBuffer,
                                            LookAheadBufferSize,
                                            PacketSize);
                break;

            case NdisMediumFddi:
                NdisMFddiIndicateReceive(pAdapt->MiniportHandle,
                                              MacReceiveContext,
                                              HeaderBuffer,
                                              HeaderBufferSize,
                                              LookAheadBuffer,
                                              LookAheadBufferSize,
                                              PacketSize);
                break;

            default:
                ASSERT(FALSE);
                break;
        }

    } while(FALSE);


    DBGPRINT(("<== PtReceive.\n"));
    return Status;
}
Записан
aks68
Модератор

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

« Ответ #178 : 21-06-2006 10:54 » 

А вот кусок ее вывода:

Цитата
Passthru: ==> PtReceive.
Passthru: Packet type IP 0x800
Passthru: Packet from 2.2.2.6 to 2.2.2.255
Passthru: UDP: ...
Passthru: Retrived received packet (81F55560)
Passthru: Has been copied to packet (81697F30)
Passthru: <== PtReceive.
Passthru: <== MPSendPackets
Passthru: ==> MPSendPackets
Passthru: ==> PtReceive.
Passthru: Packet type IP 0x800
Passthru: Packet from 2.2.2.6 to 2.2.2.255
Passthru: UDP: ...
Passthru: Retrived received packet (81A2CC78)
Passthru: Has been copied to packet (81697F30)
Passthru: <== PtReceive.
Passthru: <== MPSendPackets
Passthru: ==> MPSendPackets
Passthru: ==> PtReceive.
Passthru: Packet type IP 0x800
Passthru: Packet from 2.2.2.6 to 2.2.2.255
Passthru: UDP: ...
Passthru: Retrived received packet (819B3E70)
Passthru: Has been copied to packet (81697F30)
Passthru: <== PtReceive.
Passthru: <== MPSendPackets
Passthru: ==> MPSendPackets
Passthru: ==> PtReceive.
Passthru: Packet type IP 0x800
Passthru: Packet from 2.2.2.6 to 2.2.2.255
Passthru: UDP: ...
Passthru: Retrived received packet (816D85D0)
Passthru: Has been copied to packet (81697F30)
Passthru: <== PtReceive.
Passthru: <== MPSendPackets
Записан
aks68
Модератор

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

« Ответ #179 : 21-06-2006 11:30 » 

Вот установочные файлы от passthru:

netsf.inf
Код:
[Version]
Signature  = "$Windows NT$"
Class      = NetService
ClassGUID  = {4D36E974-E325-11CE-BFC1-08002BE10318}
Provider   = %Msft%
DriverVer  = 06/24/1999,5.00.2071.1


[Manufacturer]
%Msft% = MSFT

[ControlFlags]

;=========================================================================
;
;=========================================================================

[MSFT]
%Passthru_Desc% = Passthru.ndi, ms_passthru



[Passthru.ndi]
AddReg          = Passthru.ndi.AddReg, Passthru.AddReg
Characteristics = 0x4410 ;  NCF_FILTER | NCF_NDIS_PROTOCOL !--Filter Specific--!!
CopyFiles       = Passthru.Files.Sys
CopyInf         = netsf_m.inf

[Passthru.ndi.Remove]
DelFiles = Passthru.Files.Sys

[Passthru.ndi.Services]
AddService = Passthru,, Passthru.AddService

[Passthru.AddService]
DisplayName    = %PassthruService_Desc%
ServiceType    = 1 ;SERVICE_KERNEL_DRIVER
StartType      = 3 ;SERVICE_DEMAND_START
ErrorControl   = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\passthru.sys
LoadOrderGroup = PNP_TDI
AddReg         = Passthru.AddService.AddReg


[Passthru.AddService.AddReg]
; ----------------------------------------------------------------------
; Add any miniport-specific parameters here.  These are params that your
; filter device is going to use.
;
;HKR, Parameters, ParameterName,  0x10000, "MultiSz", "Parameter", "Value"
;HKR, Parameters, ParameterName2, 0x10001, 4


; ----------------------------------------------------------------------
; File copy
;
[SourceDisksNames]
1=%DiskDescription%,"",,

[SourceDisksFiles]
passthru.sys=1

[DestinationDirs]
DefaultDestDir = 12
Passthru.Files.Sys   = 12   ; %windir%\System32\drivers

[Passthru.Files.Sys]
passthru.sys,,,2



[Passthru.ndi.AddReg]
HKR, Ndi, HelpText, , %Passthru_HELP%


HKR, Ndi,            FilterClass,         , failover
HKR, Ndi,            FilterDeviceInfId,   , ms_passthrump
HKR, Ndi,            Service,             , Passthru
HKR, Ndi\Interfaces, UpperRange,          , noupper
HKR, Ndi\Interfaces, LowerRange,          , nolower
HKR, Ndi\Interfaces, FilterMediaTypes,    , "ethernet, tokenring, fddi, wan"

[Passthru.AddReg]

HKR, Parameters, Param1, 0, 4

; ----------------------------------------------------------------------
[Strings]
Msft = "Microsoft"
DiskDescription = "Microsoft Passthru Driver Disk"

Passthru_Desc = "Passthru Driver"
Passthru_HELP = "Passthru Driver"
PassthruService_Desc = "Passthru Service"


netsf_m.inf

Код:
[Version]
signature  = "$Windows NT$"
Class      = Net
ClassGUID  = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider   = %Msft%
DriverVer  = 06/24/1999,5.00.2071.1

[ControlFlags]
ExcludeFromSelect = ms_passthrump

[DestinationDirs]
DefaultDestDir=12
; No files to copy

[Manufacturer]
%Msft% = MSFT

[MSFT]
%PassthruMP_Desc% = PassthruMP.ndi, ms_passthrump

[PassthruMP.ndi]
Characteristics = 0x29 ;NCF_NOT_USER_REMOVABLE | NCF_VIRTUAL | NCF_HIDDEN
CopyFiles =

[PassthruMP.ndi.Services]
AddService = Passthru,0x2, PassthruMP.AddService


[PassthruMP.AddService]
ServiceType    = 1 ;SERVICE_KERNEL_DRIVER
StartType      = 3 ;SERVICE_DEMAND_START
ErrorControl   = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\passthru.sys


[PassthruMP.AddService.AddReg]
; ----------------------------------------------------------------------
; Add any miniport-specific parameters here.  These are params that your
; filter device is going to use.
;
;HKR, Parameters, ParameterName,  0x10000, "MultiSz", "Parameter", "Value"
;HKR, Parameters, ParameterName2, 0x10001, 4

[Strings]
Msft = "Microsoft"
PassthruMP_Desc = "Passthru Miniport"

[SourceDisksNames]
;None

[SourceDisksFiles]
;None

Записан
Страниц: 1 ... 3 4 5 [6] 7 8   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines