Вставка NDIS пакетов в очередь

Тема в разделе "WASM.NT.KERNEL", создана пользователем amn, 4 фев 2009.

  1. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    Доброго времени суток. Появилась необходимость в passthru(DDK) отправлять дополнительный пакет при обработке в MPSendPackets. Возможно ли это сделать?
    Возникает еще один вопрос: при изменении длины исходного пакета путем Unchain(chain) и adjustbufferlength ДДК предостерегает о том, что эту длину перед отправкой пакета надо вернуть в исходную; есть ли способ изменить исходный пакет и отправить его без создания дополнительных пакетов?
     
  2. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Конечно можно. Сделай allocation и setup новому NDIS_PACKET и скорми NDIS-у. Сложность будет в том как определить свой/passthrough пакет в callback-e.

    Трогать чужие пакеты ни в коем случае нельзя. Скопируй данные в новый пакет а этот можешь просто вернуть (drop).
     
  3. SashaTalakin

    SashaTalakin New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2008
    Сообщения:
    261
    Там есть резервные поля в которых можно вставить маркер, который будет проверяться в коллбеке. Это например.
     
  4. ECk

    ECk Member

    Публикаций:
    0
    Регистрация:
    9 апр 2004
    Сообщения:
    454
    Адрес:
    Russia
    поле ProtocolReserved, если не ошибаюсь
     
  5. gandr

    gandr New Member

    Публикаций:
    0
    Регистрация:
    5 фев 2009
    Сообщения:
    1
    allocation понятно, а что за setup?
     
  6. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    Создаю пакет, копирую в него информацию из оригинального, создаю на него копию и пытаюсь отправить с помощью NdisSend, получается BSOD DRIVER_IRQL_NOT_LESS_OR_EQUAL, который вываливается после вызова NdisMSendComplete в функции PtSendComplete. Сначала пытался просто отправлять пакет, но прочитал, что отправлять надо копию: результат получался такой же.
    Вот код:
    Код (Text):
    1. PUCHAR            FirstBuf;
    2. PUCHAR            SecondBuf;
    3. ULONG               nOffset = 0;
    4. ULONG              lpNumberOfBytesRead;
    5. PNDIS_BUFFER  CurrentBuffer;
    6. UINT        TotalPacketLength;
    7. UCHAR       IpLen;
    8. UINT        nBufferCount;
    9. UINT        CurrentLength;
    10. UINT        Length;
    11. PUCHAR            VirtualAddress;
    12. NDIS_STATUS   Status;
    13. PNDIS_BUFFER  FirstPacketBuffer;
    14. PVOID        MediaSpecificInfo = NULL;
    15. UINT         MediaSpecificInfoSize = 0;
    16.  
    17. // Считывание информации об оригинальном пакете            
    18. NdisQueryPacket( Packet, NULL, &nBufferCount, &CurrentBuffer, &TotalPacketLength  );
    19.  
    20. FirstBuf = (PUCHAR)ExAllocateFromNPagedLookasideList( &ListHeader );
    21. SecondBuf = (PUCHAR)ExAllocateFromNPagedLookasideList( &ListHeader );
    22.  
    23. // Считывание данных из оригинального пакета  
    24. ReadPacket( Packet, FirstBuf, TotalPacketLength, nOffset, &lpNumberOfBytesRead );
    25.  
    26. // Для создания пакета я сам создаю хэндл пула
    27. NdisAllocatePacket( &Status, &FirstPacket, PktPoolHandle );
    28.                            
    29. if (Status == NDIS_STATUS_SUCCESS)
    30. {
    31. NdisAllocateBuffer( &Status, &FirstPacketBuffer, PoolHandle, SecondBuf, TotalPacketLength );
    32. NdisChainBufferAtBack( FirstPacket, FirstPacketBuffer );
    33.  
    34. NdisQueryPacket( FirstPacket, NULL, &nBufferCount, &CurrentBuffer, &TotalPacketLength  );                      
    35.                            
    36. NdisQueryBufferSafe( CurrentBuffer, &VirtualAddress, &CurrentLength, NormalPagePriority );
    37. NdisMoveMemory( VirtualAddress, FirstBuf, CurrentLength );
    38.  
    39. }
    40.                             ExFreeToNPagedLookasideList( &ListHeader, FirstBuf );
    41.                             ExFreeToNPagedLookasideList( &ListHeader, SecondBuf ); 
    42.  
    43. // Создание копии пакета, аналог присваивания Packet = PacketArray[i]
    44. MyPacket = *(PPNDIS_PACKET)(&FirstPacket);
    45.  
    46. // Пакет для отправки
    47. NdisAllocatePacket( &Status,&SecPacket,  pAdapt->SendPacketPoolHandle );
    48.    
    49. if (Status == NDIS_STATUS_SUCCESS)
    50. {
    51.     PNDIS_PACKET_EXTENSION  Old, New;
    52.    
    53.     Rsvd = (PRSVD)(SecPacket->ProtocolReserved);
    54.     Rsvd->OriginalPkt = FirstPacket;
    55.    
    56.     SecPacket->Private.Flags = NdisGetPacketFlags(MyPacket);
    57.              
    58.     SecPacket->Private.Head = MyPacket->Private.Head;
    59.     SecPacket->Private.Tail = MyPacket->Private.Tail;
    60.                
    61.     NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(SecPacket),                    NDIS_OOB_DATA_FROM_PACKET(MyPacket),
    62.         sizeof(NDIS_PACKET_OOB_DATA));
    63.                
    64.     NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,                                       &MediaSpecificInfo,
    65.                                 &MediaSpecificInfoSize);
    66.  
    67.     if (MediaSpecificInfo || MediaSpecificInfoSize)
    68.     {
    69.         NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(SecPacket,                                      MediaSpecificInfo,
    70.                                     MediaSpecificInfoSize);
    71.                
    72.     }
    73.            
    74.             NdisSend( &Status,
    75.         pAdapt->BindingHandle,
    76.         SecPacket );
    77. }
     
  7. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    amn, ты в своём SendComplete() смотришь какие пакеты твои а какие нет?
     
  8. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    То есть мне надо самому освобождать пакет, а в PtSendComplete() просто проверить мой или нет и, если мой, ничего с ним не делать?
     
  9. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    В SendComplete() ты должен освобождать (free) свои пакеты и переправлять (forward the callback) чужих, которые ты не трогал.
     
  10. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    С посылкой разобрался, спасибо:) Теперь неплохо бы понять как работает прием, по аналогии если, то мы тоже создаем свой пакет в PtReceivePackets(...), делаем с ним что надо и обрабатываем в MpReturnPacket(...).
     
  11. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    amn, при приёме на же схема, только вызовы другие :)
     
  12. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    Разобрался с приемом и отправкой, на виртуальной машине все без проблем работает, но на физических компьютерах, соединенных просто кроссом пакеты не доходят, может у кого есть идеи?:) Возможно косяк кроется в превышении длины ethernet пакета, то есть превышении 1514 байт. По идее это же не задача ndis драйвера разбивать пакет на 2 в таком случае?
     
  13. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    ты добавляешь что-то своё к пакету? надо уменьшить размер на это что-то. например так:
    Код (Text):
    1. RequestComplete(... )
    2. {
    3. ...
    4.     switch (NdisRequest->RequestType)
    5.     {
    6.         case NdisRequestQueryInformation:
    7.                 if ( (Oid == OID_GEN_MAXIMUM_FRAME_SIZE) || (Oid == OID_GEN_MAXIMUM_TOTAL_SIZE) )
    8.                     *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer -= MyAddedSize;
    9. ....
     
  14. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    второй вариант почему пакеты не доходят после пересборки - TCP_TASK_OFFLOAD
    надо отключать
     
  15. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    Добавляю некое число байт при отправке и убираю после обработки их на приеме.
     
  16. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    Доходят только пакеты с нетронутой длинной. Может быть еще дело во флагах создаваемого пакета? Контрольную сумму пересчитываю.
     
  17. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    amn, проинсталь wireshark и смотри что происходит с пакетами.
     
  18. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    Пакеты с добавленной длинной один раз приходят с Retransmission, а потом приходит множество запросов (Out-of-order) и ответов на них в виде пакета (Dup ACK) с длиной данных, равных добавленной.
     
  19. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    amn, ты редактируешь TCP packets? Если так, то ты вообще представляешь как работает протокол? Sequence numbers, checksum...
     
  20. amn

    amn New Member

    Публикаций:
    0
    Регистрация:
    3 фев 2009
    Сообщения:
    12
    Видимо недостаточно, буду еще разбираться.