See comments inline to your questions.
Good Luck,
-dave
David R. Cattley
Consulting Engineer
Systems Software Development
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@uab.edu
Sent: Wednesday, November 28, 2007 7:43 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Modifying Incoming/Outgoing Packets using a NDIS IM Driver
Hey all,
Let me first say that I’m rather new to driver development, and most of the
knowledge I have about NDIS IM driver is drawn from the PassThru and
PassThruEx (part 2 specifically). So I apologize if my questions appear to
be rather silly.
I’m trying to code an IM driver that will modify both incoming and outgoing
packets (specifically, TCP packets; and it only modifies SOME packets). So
far, by observing what’s written in PassThruEx part 2 (by Thomas), I am able
to log each packet. As far as I know, from reading a few threads on this
topic, that I’m not allowed to modify the content of the packet directly
because I don’t have “owernship” of that packet. So a few questions I have
are…
- Assembling a packet.
Can I assemble a packet by copying the raw data out (as in, use
NdisMoveMemory on each buffer), modify it (and update the checksum), and
allocate buffers with the same sizes as the original buffers? Or does it
depend on whether the packet modification changes the data? Note: the
modification will NOT change the headers (other than checksum), only the
data portion.
[drc] Yes. There is not requirement that your new packet have the same
buffer sizes, etc. It is more common to allocate a single buffer of the
appropriate size and copy all of original packet data to it. The NIC does
not care if you coallesce the buffers sent by (in this case TCPIP.SYS) into
a single buffer. The only requirement is that the entire MAC header be in
the first buffer. Getting clever here is not necessary nor likely to buy
you anything other than headache.
- ProtocolSendComplete.
As a few mentioned on this forum/list, a modified outgoing packet should
duplicate the original packet, modify it, report success on the original
packet, and send the new one. Then on ProtocolSendComplete the copy packet
must be freed and the original must be completed. If this is correct, how
would I go about doing this? Should I use NDIS_SET_ORIGINAL_PACKET on the
modified packet, so that when ProtocolSendComplete detects that the original
packet is different, it would complete the original packet and free the
modified packet? In other words, how would I know if a packet I get in
ProtocolSendComplete is a modified packet, and how do I get a handle to the
original packet to be completed?
[drc] Yes, almost. Two things about what you said which I have issue with.
a) Don’t report the original packet as completed (via
NdisMSendComplete()) until the copy has completed. Your proposal above
seems to indicate you would complete the packet twice which would not be
very good. Only complete it when the copy has been completed (or canceled).
b) Don’t store the original packet in the
NDIS_SET_ORIGINAL_PACKET() structure. Instead, save it in the
ProtocolReserved area of the copy packet so that you can get it back during
ProtocolSendComplete() processing.
- What about inbound packets?
In the PtReceiveComplete function, individual packets are not even passed to
the function. Does it mean that if I modified the packet in the same way as
sending (copying, modifying, and indicating the modified packet up instead
of the original one), I still have to free the modified packet and complete
the original? If so, how do I get the handle to the packets?
[drc] ProtocolReceiveComplete() is a kind of ‘status’ indication that says
that the (legacy) NIC has finished indicating packets. A protocol is
encouraged to defer processing any packets indicated by ProtocolReceive()
until a ProtocolReceiveComplete() occurs. Yes, you need to copy the
received packet into a new packet, modify the copy, and indicate the copy.
When the copy is returned, you can return the original packet - if there was
one! In the case of ProtocolRecieve() there is *not* an original packet
which is to be return via NdisReturnPackets(). Of course, you will keep
track of all of this in the MiniportReserved area of the copies for the RX
packets so again, when MiniportReturnPacket() is called, you can get the
original packet from the MiniportReserved area (if there was an original
packet, which, there might not be) and ‘return’ it with NdisReturnPackets().
Thanks in advance for any help!
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer