Hi, I need to send modified packets in NDIS IM driver. First of all I
try to simply send my not modified packet in MiniportSendPackets to
check if this works. Before NdisSend I do the following :

NdisQueryPacketLength(Packet,&TotalPacketLength);
NdisAllocateMemoryWithTag(&pStartVa, TotalPacketLength,
TAG);
NdisAllocateBuffer(&Status,
&pNdisBuffer,pAdapt->SendBufferPoolHandle,
pStartVa, TotalPacketLength );

NdisChainBufferAtFront( MyPacket, pNdisBuffer );
NdisCopyFromPacketToPacketSafe(MyPacket, 0,
TotalPacketLength,
Packet, 0,
&BytesCopied, NormalPagePriority);

and not all packets are being sent (the bigger ones I suppose). What I
do wrong? Should I add some code to ProtocolSendComplete function? I'll
appreciate any help.

Re: MiniportSendPackets by soviet_bloke

soviet_bloke
Sun Oct 15 22:05:21 CDT 2006

Hi mate

First of all, I don't see that you check whether BytesCopied equals
TotalPacketLength, i.e. whether NdisCopyFromPacketToPacketSafe()call
was successfull......

Even if it was, don't forget that NdisCopyFromPacketToPacketSafe()
does not copy out-of-band data - you have to
get a pointer to it with NDIS_OOB_DATA_FROM_PACKET and then copy it
with NdisCopyMemory(). Furthermore,
the packet may have media-specific info, so that you have to check it
with NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO, and, if necessary, copy it
with NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO


Furthermore, you make a single-buffer packet - you allocate a buffer
the size of the packet, attach it at the front, and then copy all
packet data to it with NdisCopyFromPacketToPacketSafe(). To give you an
idea, any IP packet that comes from TCPIP.SYS has at least 4 buffers -
ARP header, IP header, protocol header and packet data are in separate
buffers

First of all, try to copy each buffer buffer, and chain them to your
packet. It does not make sense to do it in non-modifying driver (all
you have to do in non-modifying driver is to set your packet's head and
tail to those of the original packet), but, as far as I understand, you
final goal is modifying one. In such case, probably, at some later
stage it will make sense to re-construct the whole IP packet from NDIS
buffers, then break it into separate buffers again, and chain them to
your packet

All the above applies only to packets that are being sent - when it
comes to the ones that you indicate to TCPIP,
make sure that the very first buffer describes both MAC header and
LookaheadData . Otherwise, TCPIP will ignore the packet


Anton Bassov

szymonas_82@go2.pl wrote:
> Hi, I need to send modified packets in NDIS IM driver. First of all I
> try to simply send my not modified packet in MiniportSendPackets to
> check if this works. Before NdisSend I do the following :
>
> NdisQueryPacketLength(Packet,&TotalPacketLength);
> NdisAllocateMemoryWithTag(&pStartVa, TotalPacketLength,
> TAG);
> NdisAllocateBuffer(&Status,
> &pNdisBuffer,pAdapt->SendBufferPoolHandle,
> pStartVa, TotalPacketLength );
>
> NdisChainBufferAtFront( MyPacket, pNdisBuffer );
> NdisCopyFromPacketToPacketSafe(MyPacket, 0,
> TotalPacketLength,
> Packet, 0,
> &BytesCopied, NormalPagePriority);
>
> and not all packets are being sent (the bigger ones I suppose). What I
> do wrong? Should I add some code to ProtocolSendComplete function? I'll
> appreciate any help.


Re: MiniportSendPackets by soviet_bloke

soviet_bloke
Mon Oct 16 00:57:58 CDT 2006

Hi mate

What I forgot to tell you in my previous post is that modifying drivers
may fail on adapters that support task offload. Therefore, when you
proceed to modifying data, make sure that your driver fails
OID_TCP_TASK_OFFLOAD, rather than passing it down to miniport.
Furthermore, as far as I am concerned, large packets may get lost with
NDIS IM. This is about sending data.When it comes to indicating it, you
should set a packet status to NDIS_STATUS_RESOURCES when indicating a
packet of more than one buffer to NDIS library


In general, you should clearly realize that NDIS IM is not the easiest
thing - the same driver may work well with adapter X and fail with
adapter Y

Anton Bassov



szymonas_82@go2.pl wrote:
> Hi, I need to send modified packets in NDIS IM driver. First of all I
> try to simply send my not modified packet in MiniportSendPackets to
> check if this works. Before NdisSend I do the following :
>
> NdisQueryPacketLength(Packet,&TotalPacketLength);
> NdisAllocateMemoryWithTag(&pStartVa, TotalPacketLength,
> TAG);
> NdisAllocateBuffer(&Status,
> &pNdisBuffer,pAdapt->SendBufferPoolHandle,
> pStartVa, TotalPacketLength );
>
> NdisChainBufferAtFront( MyPacket, pNdisBuffer );
> NdisCopyFromPacketToPacketSafe(MyPacket, 0,
> TotalPacketLength,
> Packet, 0,
> &BytesCopied, NormalPagePriority);
>
> and not all packets are being sent (the bigger ones I suppose). What I
> do wrong? Should I add some code to ProtocolSendComplete function? I'll
> appreciate any help.


Re: MiniportSendPackets by Maxim

Maxim
Mon Oct 16 03:46:56 CDT 2006

> packet data to it with NdisCopyFromPacketToPacketSafe(). To give you an
> idea, any IP packet that comes from TCPIP.SYS has at least 4 buffers -
> ARP header, IP header, protocol header and packet data are in separate
> buffers

In older OSes like w2k or NT4, it had 2 buffers - a) Ethernet+IP+protocol
header b) the data.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com


Re: MiniportSendPackets by szymonas_82

szymonas_82
Mon Oct 16 16:24:36 CDT 2006

Hi Anton,
thanks for your reply. I'm modifying the passthru sample so stuff with
OOB_DATA and MEDIA_SPECIFIC_INFO is already done in MPSendPackets
routine. As you recommended, I create the same buffers as in orginal
packet (usually 3 buffers for each layer header + one buffer fof
payload), then copy data into my packet. But the result is the same -
something is wrong with sending bigger packtes.
I'll describe what happens - maybe somebody had similar problem. I
try to connect to www server. After I send a bigger packet, server
doesn't send me an ACK, then my protocol retransmits packet again.
Then I receive FIN from server. The odds are that larger packets have
wrong FCS or something, but I don't modify the packet. Please help.


Re: MiniportSendPackets by szymonas_82

szymonas_82
Mon Oct 16 16:35:44 CDT 2006

Ah, here's the code :

NdisQueryPacket(Packet,
&PhysicalBufferCount,
&BufferCount,
&CurrentBuffer,
&TotalPacketLength);

NdisAllocateMemoryWithTag(&pStartVa, TotalPacketLength, TAG);

CurrentOffset = 0;

for (i = 0; i < BufferCount; i++)
{
NdisQueryBuffer(
CurrentBuffer,
&VirtualAddress,
&CurrentLength);

NdisAllocateBuffer(&Status,
&pBufferArray[i],
pAdapt->SendBufferPoolHandle,
pStartVa + CurrentOffset,
CurrentLength );

CurrentOffset += CurrentLength;

NdisGetNextBuffer(CurrentBuffer,
&CurrentBuffer);
}

for(i = BufferCount ; i > 0; i--)
NdisChainBufferAtFront( MyPacket, pBufferArray[i-1] );

NdisCopyFromPacketToPacketSafe(MyPacket, 0, TotalPacketLength,
Packet, 0, &BytesCopied,
NormalPagePriority);


Re: MiniportSendPackets by soviet_bloke

soviet_bloke
Tue Oct 17 04:46:53 CDT 2006

Hi mate

>As you recommended, I create the same buffers as in orginal
> packet (usually 3 buffers for each layer header + one buffer fof
> payload), then copy data into my packet.

Actually, I meant copying buffers one-by-one and chaining them to the
newly allocated packet, rather than using
NdisCopyFromPacketToPacketSafe(). I don't know if it makes any
difference in your situation, but, once your ultimate goal is modifying
driver, this step is inevitable....

> But the result is the same -
> something is wrong with sending bigger packtes.
> I'll describe what happens - maybe somebody had similar problem.

Indeed, you are not the first one who came across this problem with
NDIS IM - the fact that large packets may get lost with NDIS IM is well
known. I am afraid this is only the beginning - as I told you already,
NDIS IM is not the easiest thing to develop. This is why they do NDIS
hooking (A.K.A NDIS PIM, i.e. pseudo- IM). To be honest, I find it to
be much easier solution.......


Anton Bassov

szymonas_82@go2.pl wrote:
> Hi Anton,
> thanks for your reply. I'm modifying the passthru sample so stuff with
> OOB_DATA and MEDIA_SPECIFIC_INFO is already done in MPSendPackets
> routine. As you recommended, I create the same buffers as in orginal
> packet (usually 3 buffers for each layer header + one buffer fof
> payload), then copy data into my packet. But the result is the same -
> something is wrong with sending bigger packtes.
> I'll describe what happens - maybe somebody had similar problem. I
> try to connect to www server. After I send a bigger packet, server
> doesn't send me an ACK, then my protocol retransmits packet again.
> Then I receive FIN from server. The odds are that larger packets have
> wrong FCS or something, but I don't modify the packet. Please help.