Dialup/Ndiswanip and LWF drivers ...

Hello all,

Id like to express my appreciation to everyone who has helped me with
problems in the past. This mailing list is the only decent source of
NDIS driver development related information ( besides MS ) that I have
been able to locate. Thanks to ORS online and its contributing members!

On to my problem. I have developed a few NDIS drivers in recent years.
The two of interest are an NDIS 5 IM driver and an NDIS 6 LWF driver.
The purpose of these are to allow a user-land application to capture
packets that match a specified rule and inject packets up or down the
NDIS stack.

For packets to be injected, the user-land application does what I would
expect any IP send path would do … Check the source address of the
packet to determine the outbound adapter, check the destination address
to see if its in the local network or if it needs to be forwarded to a
router, and then adds an Ethernet header using the appropriate source
and destination MAC addresses. Afterwards, the packet is forwarded to
the IM/LWF driver which is in turn forwarded to the appropriate adapter
based on the source MAC address. This works flawlessly in all normal
cases. Unfortunately, MS Dialup adapters are a bit of a pain.

There doesn’t seem to be a lot of information available on how the MS
Dialup adapter operates under the hood. The MAC address reported to
user-land applications appears to only be relevant to MS TCP/IP. This
makes it difficult to determine which WAN_LINE to use when sending a
packet. I say this because I can’t find any correlation between info
reported to user-land and information included in the NDIS_WAN_LINE_UP
status notifications. As a hideous work around, I grubbed around in the
protocol space of the status message on 2K/XP and found the assigned IP
address. Using this information, I was able to send packets down to the
correct WAN_LINE instance by matching the packet source IP address (
instead of the MAC address ) to the appropriate WAN_LINE.

So now I need to support NDIS 6 and Vista. It would seem to me that MS
has been successful at pushing 3rd party vendors down an evolutionary
path towards NDIS 6 driver technology. Unfortunately, NDISWANIP appears
to be the same old crappy driver technology that is no longer supported
( or documented ) in NDIS 6. It sends NDIS_WAN_LINE_UP and DOWN
notifications just like 2K/XP. But with NDIS 6, the protocol space data
has been juggled around, presumably to support new features like IPv6.
Long story short, the IP address doesn’t appear to be included any more.

Please help! There must be a good way to match an NDIS kernel WAN_LINE
to a given adapter as reported to user-land applications. It don’t see
any documented method and would greatly, greatly appreciate some help
from someone with experience in this area.

Thanks in advance,

-Matthew

Matthew,

Assuming that your needs are only to match/capture & inject IP packets, on
NT6, you should really be looking at the Windows Filtering Platform (WFP)
and considering a WFP hook driver. This would get you out of having to
care about how the TCPIP protocol interacts with the various Layer 2 Media
interfaces. It also eliminates the need for your code to perform the
functions of the IP Forwarder and ARP in selecting an interface and
calculating the next-hop MAC address.

The situation can get even worse when you consider that the IP stack has
always had a ‘pluggable’ media interface layer (though not documented for us
mortals to use). The ARP module and WANARP (RASARP) are just two such
modules. I recall that there is a third for IP over 1394 and even perhaps
others for ATM, etc. The point is that with WFP we now have a way of doing
what you are asking for (with IP packets) without having to resort to media
specific machinations.

Since you are already thinking in terms of an NT6 only driver (LWF), you
might do either of:

  1. Change horses and create a WFP driver.
  2. Keep your LWF if you need Ethernet L2 capability and add a WFP hook
    driver to it to deal with IP packets.

The direction MSFT is pushing us on NT6 is from IM drivers to WFP for L3
operations. Sure, for L2 operations LWF drivers (or even IM drivers still)
might be necessary but not likely over NDISWAN.

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Matthew Grooms
Sent: Sunday, October 19, 2008 8:33 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Dialup/Ndiswanip and LWF drivers …

Hello all,

Id like to express my appreciation to everyone who has helped me with
problems in the past. This mailing list is the only decent source of
NDIS driver development related information ( besides MS ) that I have
been able to locate. Thanks to ORS online and its contributing members!

On to my problem. I have developed a few NDIS drivers in recent years.
The two of interest are an NDIS 5 IM driver and an NDIS 6 LWF driver.
The purpose of these are to allow a user-land application to capture
packets that match a specified rule and inject packets up or down the
NDIS stack.

For packets to be injected, the user-land application does what I would
expect any IP send path would do … Check the source address of the
packet to determine the outbound adapter, check the destination address
to see if its in the local network or if it needs to be forwarded to a
router, and then adds an Ethernet header using the appropriate source
and destination MAC addresses. Afterwards, the packet is forwarded to
the IM/LWF driver which is in turn forwarded to the appropriate adapter
based on the source MAC address. This works flawlessly in all normal
cases. Unfortunately, MS Dialup adapters are a bit of a pain.

There doesn’t seem to be a lot of information available on how the MS
Dialup adapter operates under the hood. The MAC address reported to
user-land applications appears to only be relevant to MS TCP/IP. This
makes it difficult to determine which WAN_LINE to use when sending a
packet. I say this because I can’t find any correlation between info
reported to user-land and information included in the NDIS_WAN_LINE_UP
status notifications. As a hideous work around, I grubbed around in the
protocol space of the status message on 2K/XP and found the assigned IP
address. Using this information, I was able to send packets down to the
correct WAN_LINE instance by matching the packet source IP address (
instead of the MAC address ) to the appropriate WAN_LINE.

So now I need to support NDIS 6 and Vista. It would seem to me that MS
has been successful at pushing 3rd party vendors down an evolutionary
path towards NDIS 6 driver technology. Unfortunately, NDISWANIP appears
to be the same old crappy driver technology that is no longer supported
( or documented ) in NDIS 6. It sends NDIS_WAN_LINE_UP and DOWN
notifications just like 2K/XP. But with NDIS 6, the protocol space data
has been juggled around, presumably to support new features like IPv6.
Long story short, the IP address doesn’t appear to be included any more.

Please help! There must be a good way to match an NDIS kernel WAN_LINE
to a given adapter as reported to user-land applications. It don’t see
any documented method and would greatly, greatly appreciate some help
from someone with experience in this area.

Thanks in advance,

-Matthew


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

David R. Cattley wrote:

Matthew,

Assuming that your needs are only to match/capture & inject IP packets, on
NT6, you should really be looking at the Windows Filtering Platform (WFP)
and considering a WFP hook driver. This would get you out of having to
care about how the TCPIP protocol interacts with the various Layer 2 Media
interfaces. It also eliminates the need for your code to perform the
functions of the IP Forwarder and ARP in selecting an interface and
calculating the next-hop MAC address.

The situation can get even worse when you consider that the IP stack has
always had a ‘pluggable’ media interface layer (though not documented for us
mortals to use). The ARP module and WANARP (RASARP) are just two such
modules. I recall that there is a third for IP over 1394 and even perhaps
others for ATM, etc. The point is that with WFP we now have a way of doing
what you are asking for (with IP packets) without having to resort to media
specific machinations.

Since you are already thinking in terms of an NT6 only driver (LWF), you
might do either of:

  1. Change horses and create a WFP driver.
  2. Keep your LWF if you need Ethernet L2 capability and add a WFP hook
    driver to it to deal with IP packets.

The direction MSFT is pushing us on NT6 is from IM drivers to WFP for L3
operations. Sure, for L2 operations LWF drivers (or even IM drivers still)
might be necessary but not likely over NDISWAN.

Dave,

Thanks for your concise answer. I suspected that someone would suggest
that I move to a different driver technology. I do have a few concerns
with this but maybe they are unwarranted.

My software provides IPsec services and is designed to work along side
the existing system service without interfering. My first attempt at
this used an NDIS 5 protocol driver to send and receive packets. I
quickly learned that if I hooked too high, identical packets would also
reach the MS TCP/IP protocol layer which caused quite a few undesired
effects such as parallel processing of IKE/ESP/AH packets. To avoid
these problems, I moved to an IM driver model.

I see that a WFP driver specifies where it would like to hook into the
stack. I assume that these would be the most appropriate …

FWPS_LAYER_INBOUND_IPPACKET_V4
FWPS_LAYER_OUTBOUND_IPPACKET_V4

Do you know if there are any restrictions on which layer I can register
with and still inject or redirect packets passed to my callout? The only
other problem I can see is that I also need to inspect ARP packets. From
an initial search, it would appear that WFP is strictly IP only.

Man, I really wish I could just stick with LWF. I have a lot of time
invested in it and I’m not to concerned about supporting other MAC
layers at the moment. It seems silly that LWF can inject packets if you
can’t do it effectively from lack of information about a fundamental
system service. Do you know of any other method that would help me to
get this to work, maybe just for Dialup adapters? Maybe a way to query
the ARP modules indirectly through an API?

Thanks,

-Matthew


I see that a WFP driver specifies where it would like to hook into the
stack. I assume that these would be the most appropriate …

FWPS_LAYER_INBOUND_IPPACKET_V4
FWPS_LAYER_OUTBOUND_IPPACKET_V4

Based on what you said your driver is attempting to do, that seems like a
reasonable start. It is the point closest to where you were filtering with
the IM driver in NT5.


Do you know if there are any restrictions on which layer I can register
with and still inject or redirect packets passed to my callout?

No. I am not aware of any restrictions regarding the
FWPS_LAYER_{INBOUND|OUTBOUND}IPPACKET{V4|V6} hooks. Depending on what you
do, however, you may need to re-inject at the IPFORWARD layer (for instance,
if you are encapsulating a packet in tunnel mode and the destination IP
address changes).


The only other problem I can see is that I also need to inspect ARP packets.
From
an initial search, it would appear that WFP is strictly IP only.

I am not sure why you want to inspect ARP packets but let’s assume you need
to: Keep the LWF for that purpose.
However, if the only reason you are snooping on ARP is to get some
information that the system ARP module is maintaining for you, then, perhaps
you will find you do not actually *need* to snoop ARP.


Do you know of any other method that would help me to
get this to work, maybe just for Dialup adapters? Maybe a way to query
the ARP modules indirectly through an API?

Nope. The facilities in WFP (which are documented!), Winsock Kernel (WSK),
and IP Helper (usable in Kernel Mode now - what ARP info did you want?), all
make this pretty tractable now.

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development


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

Matthew,

Regarding your IM driver dilemma:

I did a little checking with a quickly modified PASSTHRU driver sitting atop
of NDISWANIP…

The documented structure NDIS_WAN_LINE_UP contains a field DeviceName.

When the NdisMIndicateStatus() call returns, TCPIP.SYS should have filled in
that field with an NDIS_STRING looking something like
“\DEVICE{some-adapter-guid}”.

That ‘name’ string is the very same name (minus the "\DEVICE" prefix) that
will show up in the IP Helper IP_ADAPTER_INFO returned by GetAdaptersInfo().

Now that might not be as nice as getting the IPv4 Address by groking into
the NDISWAN/WANARP private ProtocolBuffer 'blob but it does seem to provide
a correlation key from which you can (in usermode) collect the other data.

Steer clear of trying to use the MAC Address or reported
RemoteAddress/LocalAddress to ‘associated’ the WAN link with anything. Yes,
as always you need that RemoteAddress/LocalAddress setup to inject packets
but the MAC Address of NDISWANIP adapter, the MAC Address reported in the
IP_ADAPTER_INFO, and the RemoteAddress/LocalAddress seem to have nothing in
common with one another.

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development

David R. Cattley wrote:

Matthew,

Regarding your IM driver dilemma:

I did a little checking with a quickly modified PASSTHRU driver sitting atop
of NDISWANIP…

Wow, thanks :slight_smile:

The documented structure NDIS_WAN_LINE_UP contains a field DeviceName.

When the NdisMIndicateStatus() call returns, TCPIP.SYS should have filled in
that field with an NDIS_STRING looking something like
“\DEVICE{some-adapter-guid}”.

That ‘name’ string is the very same name (minus the "\DEVICE" prefix) that
will show up in the IP Helper IP_ADAPTER_INFO returned by GetAdaptersInfo().

Now that might not be as nice as getting the IPv4 Address by groking into
the NDISWAN/WANARP private ProtocolBuffer 'blob but it does seem to provide
a correlation key from which you can (in usermode) collect the other data.

Steer clear of trying to use the MAC Address or reported
RemoteAddress/LocalAddress to ‘associated’ the WAN link with anything. Yes,
as always you need that RemoteAddress/LocalAddress setup to inject packets
but the MAC Address of NDISWANIP adapter, the MAC Address reported in the
IP_ADAPTER_INFO, and the RemoteAddress/LocalAddress seem to have nothing in
common with one another.

Nice! I hadn’t thought about that. Sounds like a decent way to get this
working as a stop gap in LWF until I have a chance to build a real WFP
solution.

Thanks again for all your help,

-Matthew

Matthew,

FYI, this association between the DeviceName field in the NDIS_WAN_LINE_UP
and the Name field in IP_ADAPTER_INFO continues to be true on 64-bit through
Longhorn (that was the last OS platform I tested my hacked PASSTHRU on).

Now please don’t put me out of business :slight_smile:

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Matthew Grooms
Sent: Tuesday, October 21, 2008 11:31 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Dialup/Ndiswanip and LWF drivers …

David R. Cattley wrote:

Matthew,

Regarding your IM driver dilemma:

I did a little checking with a quickly modified PASSTHRU driver sitting
atop
of NDISWANIP…

Wow, thanks :slight_smile:

The documented structure NDIS_WAN_LINE_UP contains a field DeviceName.

When the NdisMIndicateStatus() call returns, TCPIP.SYS should have filled
in
that field with an NDIS_STRING looking something like
“\DEVICE{some-adapter-guid}”.

That ‘name’ string is the very same name (minus the "\DEVICE" prefix)
that
will show up in the IP Helper IP_ADAPTER_INFO returned by
GetAdaptersInfo().

Now that might not be as nice as getting the IPv4 Address by groking into
the NDISWAN/WANARP private ProtocolBuffer 'blob but it does seem to
provide
a correlation key from which you can (in usermode) collect the other data.

Steer clear of trying to use the MAC Address or reported
RemoteAddress/LocalAddress to ‘associated’ the WAN link with anything.
Yes,
as always you need that RemoteAddress/LocalAddress setup to inject packets
but the MAC Address of NDISWANIP adapter, the MAC Address reported in the
IP_ADAPTER_INFO, and the RemoteAddress/LocalAddress seem to have nothing
in
common with one another.

Nice! I hadn’t thought about that. Sounds like a decent way to get this
working as a stop gap in LWF until I have a chance to build a real WFP
solution.

Thanks again for all your help,

-Matthew


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