Hi.
I want to write a simple packet modification NDIS LWF driver working with user-mode app like as pcausa redirector driver(http://www.pcausa.com/filters/ipredir/default.html).
My driver is based on WDK LWF sample.
My driver works well for receiving packets, but if it began to redirect sending packets, it couldn’t connect to any http sites. (my target is tcp 80 port.)
The following is the procedures for sending packets:
In FilterSendNetBufferLists, check packet data if it sends to target port.(ipv4 tcp 80 port)
If it is target packet, copy packet data into local buffer and drop original nbl (NdisFSendNetBufferListsComplete). Otherwise the packet will be passed (NdisFSendNetBufferLists)
And if user’s read irp queue is not empty, pop up the first irp and copy packet data into it and complete user irp(IRP_MJ_READ).
In application, if read request is completed, call WriteFile with the packet data from ReadFile. (for test, the packet data does not be modified)
In the driver’s IRP_MJ_WRITE handler, allocates new nbl, nbl context, mdl from user’s buffer and call NdisFSendNetBufferLists with new nbl. (i.e the packet is redirected with user’s packet data)
In FilterSendNetBufferListsComplete, if it is originated from my driver(by checking nbl’s pool), free it and complete user’s write irp.
The wireshark shows sending packets but there is no replying packet.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, August 6, 2013 8:20 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NDIS packet redirection driver problem
Hi.
I want to write a simple packet modification NDIS LWF driver working with
user-mode app like as pcausa redirector
driver(http://www.pcausa.com/filters/ipredir/default.html).
My driver is based on WDK LWF sample.
My driver works well for receiving packets, but if it began to redirect
sending packets, it couldn’t connect to any http sites. (my target is tcp 80
port.)
The following is the procedures for sending packets:
In FilterSendNetBufferLists, check packet data if it sends to target
port.(ipv4 tcp 80 port)
If it is target packet, copy packet data into local buffer and drop
original nbl (NdisFSendNetBufferListsComplete). Otherwise the packet will be
passed (NdisFSendNetBufferLists)
And if user’s read irp queue is not empty, pop up the first irp and
copy packet data into it and complete user irp(IRP_MJ_READ).
In application, if read request is completed, call WriteFile with the
packet data from ReadFile. (for test, the packet data does not be modified)
In the driver’s IRP_MJ_WRITE handler, allocates new nbl, nbl context, mdl
from user’s buffer and call NdisFSendNetBufferLists with new nbl. (i.e the
packet is redirected with user’s packet data) 4. In
FilterSendNetBufferListsComplete, if it is originated from my driver(by
checking nbl’s pool), free it and complete user’s write irp.
The wireshark shows sending packets but there is no replying packet.
I examine packets in wireshark, but my redirected packets does not be malformed.
The normal packets and my redirected packets are almost equal.
I changed procedure 1, I didn’t dropping original nbl in step 1 and stored original nbl pointer into user’s read irp buffer.
In step 3, i take the original nbl pointer from user’s write irp buffer and insert it into nbl context.
In step 4, if my redirected nbl arrived, i complete the original nbl (FilterSendNetBufferListsComplete)
I think that it may be dangerous, but the result was the same.
What’s the problem ? Is my procedure correct?
And is my second approach OK ? If it is dangerous, please i want to know the reason.
Thanks in advance.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, August 6, 2013 9:30 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] NDIS packet redirection driver problem
I examine packets in wireshark, but my redirected packets does not be
malformed.
The normal packets and my redirected packets are almost equal.
I changed procedure 1, I didn’t dropping original nbl in step 1 and stored
original nbl pointer into user’s read irp buffer.
In step 3, i take the original nbl pointer from user’s write irp buffer and
insert it into nbl context.
In step 4, if my redirected nbl arrived, i complete the original nbl
(FilterSendNetBufferListsComplete)
I think that it may be dangerous, but the result was the same.
What’s the problem ? Is my procedure correct?
And is my second approach OK ? If it is dangerous, please i want to know the
reason.
Thanks in advance.
The question mark; aka an interrogation point, interrogation mark, question point, query, or eroteme. A punctuation mark that replaces the full stop or period at the end of an interrogative sentence in English and many other languages. The question mark is not used for indirect questions. The question mark is also used in place of missing or unknown data.
I think in this case the latter applies. There is a whole lot of of missing or unknown data.
Gary Little xxxxx@comcast.net
C 952-454-4629
H 952-223-1349
Tain’t what you want that makes you fat, it’s what you get.
The modified procedure is dangerous, because you are creating a hidden dependency between two applications. The web browser, IE, sends a packet to TCP port 80. This results in an NBL from TCPIP. Now your filter intercepts the NBL and attaches it to some IRP queue. The original NBL cannot be completed until your application issues a WriteFile command. If your application hangs, then the original NBL will get stuck, and the poor web browser will also hang (likely in its call to ws2_32!close).
This also permits priority inversions: if your application is starved for CPU because a high-priority application is consuming all the CPU, then the network will stop working.
The original procedure is safer, but you do have to spend some time worrying about how to provide proper backpressure to the application. Especially if you get into the business of intercepting UDP, the application can start to overwhelm you with more packets than you can process. The typical method to apply backpressure is to delay the completion of the original NBL. However, as noted above, you can’t use some usermode application to implement the delay; it needs to be a rock-solid service in your own driver.
As to the original problem - I’m not sure what has gone wrong. The procedure you outlined *should* work correctly, if there are no bugs. It’s likely that there is a small bug somewhere. I have two suggestions:
(a) Make sure you’re calling NdisCopySendNetBufferListInfo. This will copy over TCP checksum offload information, without which, the NIC won’t apply a correct checksum to the outgoing packet.
(b) When working with LWFs, you’ll also want to use Microsoft Network Monitor (netmon). Netmon is itself a LWF, so it will see what happens *below your filter*. Wireshark is a protocol, so it really only sees what happens *above your filter*. Except with TX packets; for TX packets the loopback happens once the packets reach the NIC.
Are you doing this for recieved packets coming up the stack, or outbound
going down the stack?
If the former as I supect, I think the problem is more simple.
You say you aren’t changing the data.
So you’re not changing the source IP. If the destination you are
forwarding the packet to has a direct route to the source, it will
bypass you on the way back. It will just do an ARP lookup on the source
IP and send the response directly to that HW address.
Adrien
------ Original Message ------
From: “Jeffrey Tippet” To: “Windows System Software Devs Interest List” Sent: 7/08/2013 7:03:48 a.m. Subject: RE: RE:[ntdev] NDIS packet redirection driver problem >The modified procedure is dangerous, because you are creating a hidden >dependency between two applications. The web browser, IE, sends a >packet to TCP port 80. This results in an NBL from TCPIP. Now your >filter intercepts the NBL and attaches it to some IRP queue. The >original NBL cannot be completed until your application issues a >WriteFile command. If your application hangs, then the original NBL >will get stuck, and the poor web browser will also hang (likely in its >call to ws2_32!close). > >This also permits priority inversions: if your application is starved >for CPU because a high-priority application is consuming all the CPU, >then the network will stop working. > >The original procedure is safer, but you do have to spend some time >worrying about how to provide proper backpressure to the application. >Especially if you get into the business of intercepting UDP, the >application can start to overwhelm you with more packets than you can >process. The typical method to apply backpressure is to delay the >completion of the original NBL. However, as noted above, you can’t use >some usermode application to implement the delay; it needs to be a >rock-solid service in your own driver. > > >As to the original problem - I’m not sure what has gone wrong. The >procedure you outlined should work correctly, if there are no bugs. >It’s likely that there is a small bug somewhere. I have two >suggestions: > >(a) Make sure you’re calling NdisCopySendNetBufferListInfo. This will >copy over TCP checksum offload information, without which, the NIC >won’t apply a correct checksum to the outgoing packet. > >(b) When working with LWFs, you’ll also want to use Microsoft Network >Monitor (netmon). Netmon is itself a LWF, so it will see what happens >below your filter. Wireshark is a protocol, so it really only sees >what happens above your filter. Except with TX packets; for TX >packets the loopback happens once the packets reach the NIC. > > > > > >— >NTDEV is sponsored by OSR > >Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev > >OSR is HIRING!! See http://www.osr.com/careers > >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
it’s also possible Wireshark is not showing you the correct data.
Depending on where WireShark and your driver sit, Wireshark may be
showing the packets before your driver sees them. You need to do
wireshark on another computer connected by a hub - not a switch -
(broadcast) to be sure what packets are going on the wire.
Or just try using wireshark on the target computer or some other
intermediary.
Regards
Adrien
------ Original Message ------
From: “xxxxx@gmail.com” To: “Windows System Software Devs Interest List” Sent: 7/08/2013 1:30:18 a.m. Subject: RE:[ntdev] NDIS packet redirection driver problem >Thanks Thomas for your quick answer. >I read your articles at http://www.ndis.com/ , http://www.pcausa.com >and http://www.osronline.com/showthread.cfm?link=242847 >They help me very much. > >I examine packets in wireshark, but my redirected packets does not be >malformed. >The normal packets and my redirected packets are almost equal. > >I changed procedure 1, I didn’t dropping original nbl in step 1 and >stored original nbl pointer into user’s read irp buffer. >In step 3, i take the original nbl pointer from user’s write irp buffer >and insert it into nbl context. >In step 4, if my redirected nbl arrived, i complete the original nbl >(FilterSendNetBufferListsComplete) > >I think that it may be dangerous, but the result was the same. > >What’s the problem ? Is my procedure correct? >And is my second approach OK ? If it is dangerous, please i want to >know the reason. >Thanks in advance. > >— >NTDEV is sponsored by OSR > >Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev > >OSR is HIRING!! See http://www.osr.com/careers > >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
To examine more clearly, I had tested on ICMP packets.
My driver is running on machine A and I had send ping message to machine B.
MS netmon is installed in A, and wireshark is in B.
After some tests, I confirmed that sending packet captured in A is equal with the received packet in B.
And I compared received packets in B when my driver is runing or not.
When my driver is running, the IP checksum of packet captured in B is 0.
But in normal environment, it has the valid checksum value.
In both case, the IP checksum of sending packet in A is 0.(I think that it results from IP checksum offload)
I want to know why received packet’s checksum in B is 0 when my driver is running.