UDP broadcast from TDI client

I have a TDI client driver that generates a DHCP Inform in response to
a ClientPnPAddNetAddress callback notification.

It creates an address file object against \Device\Udp that specifies
the address we were just informed of, and then we construct a
TDI_CONNECTION_INFORMATION.RemoteAddress that describes the IP
broadcast address (FF.FF.FF.FF) for TdiBuildSendDatagram and then call
for the send.

The packet presented on the wire appears perfect; IP source address
and port are specified in the EA passed to ZwCreateFile, destination
is IP-level broadcast and port specified, and contents are the valid
DHCP Inform supplied.

But this exact packet gets sent out over all interfaces, not just the
interface that corresponds to the source address provided.

(e.g. If I have a machine multi-homed to a 10.xx.xx.xx and a
172.xx.xx.xx network and I was just notified of the 172.xx.xx.xx
address. Although the DHCP Inform does go out over the 172.xx.xx.xx
interface, the exact same packet goes out the 10.xx.xx.xx interface
too, still with the 172.xx.xx.xx IP source address.)

It almost looks like the packet is being “routed” by the workstation,
possibly as a result of the destination being the broadcast address.
But the intention was for this DHCP Inform request to only be
presented on the interface that had just come up.

When Microsoft’s own DHCPCSVC makes an Inform request it only appears
on the interface you would expect, but they’re going through Winsock
and AFD to TCPIP directly, not via TDI, so a comparison of “how” isn’t
straight forward.

Anyone know whether my expectation isn’t correct that having specified
the source address to TDI would limit which interface the UDP datagram
was sent from, or any other way in which my desired goal of sending
this request via TDI only on the one interface could be achieved?

Alan Adams

I’d have to dig out an IP book to be sure but it seems like the broadcast
address for a specific subnet will NOT be FF.FF.FF.FF. Each IP subnet, like
192.168.1.0 (mask 255.255.255.0) will have an IP subnet broadcast address of
192.168.1.255. The IP address FF.FF.FF.FF seems like it probably means
broadcast to ALL subnets. The Ethernet broadcast address is
FF.FF.FF.FF.FF.FF (48 bits).

  • Jan

It creates an address file object against \Device\Udp that specifies
the address we were just informed of, and then we construct a
TDI_CONNECTION_INFORMATION.RemoteAddress that describes the IP
broadcast address (FF.FF.FF.FF) for TdiBuildSendDatagram and then call
for the send.

Understood. A DHCP broadcast does in fact go to all networks
(FF.FF.FF.FF), not the local network (e.g. 10.FF.FF.FF). I’m not
looking at the DHCP RFC, but I would assume it’s because there’s no
assumption the DHCP server is going to be on the local subnet, and in
most large networks is not on the local subnet. (And if you observe
the DHCP Inform request generated by calling Microsoft’s DHCPCSVC, the
destination IP address is the same, FF.FF.FF.FF.)

So the question is still the more programmatic / TDI-specific
question, of whether there is something different to be done when
invoking the UDP sent through TDI to prevent the packet from going out
through all interfaces. (Again, on the assumption it is possible to
control this behavior, at least within TCPIP.SYS, since the AFD
interface into TCPIP.SYS is able to achieve it.)

“Jan Bottorff” wrote:

> I’d have to dig out an IP book to be sure but it seems like the broadcast
> address for a specific subnet will NOT be FF.FF.FF.FF. Each IP subnet, like
> 192.168.1.0 (mask 255.255.255.0) will have an IP subnet broadcast address of
> 192.168.1.255. The IP address FF.FF.FF.FF seems like it probably means
> broadcast to ALL subnets. The Ethernet broadcast address is
> FF.FF.FF.FF.FF.FF (48 bits).
>
> - Jan
>
> > It creates an address file object against \Device\Udp that specifies
> > the address we were just informed of, and then we construct a
> > TDI_CONNECTION_INFORMATION.RemoteAddress that describes the IP
> > broadcast address (FF.FF.FF.FF) for TdiBuildSendDatagram and then call
> > for the send.
>
>
>

Alan Adams

You might be confusing multicast and broadcast, and network interface scope.

If you submit a UDP frame to the IP stack with a destination address of
255.255.255.255, IP will transmit that frame on all network interfaces, and
it will use a link-layer broadcast address. If the destination address is
(say) 192.168.255.255, the frame will be transmitted on just the local
interface that has 192.168.255.255 as its broadcast IP address, and it will
use a link-layer broadcast address.

Under normal circumstances, routers (IP gateways) that receive those frames
will NOT retransmit them. They have subnet scope. That is, layer 2 devices
(Ethernet switches and hubs) will retransmit them, but layer 3 devices (IP
gateways) will NOT retransmit them. Therefore, the DHCP server MUST be
reachable via a path composed only of layer 2 devices, including a path of
“none”, meaning directly.

IP multicast is different from broadcast. IP multicast uses class “D”
address (beginning at 224.x.x.x). Layer 3 gateways (routers) may forward IP
multicast frames, depending on whether IP multicast routing is enabled (and
it often is not). IP multicast routing is a complicated topic, and is far
outside the scope of NTDEV. However, DHCP uses IP broadcast, not multicast
– the word “multicast” does not appear anywhere in RFC 2131.

DHCP in some enterprises is managed remotely by using DHCP relays (proxies).
This is often enabled in routers, because routers have excellent
connectivity, and “see” many subnets. (DHCP relays are stateless.) When a
DHCP relay receives a DHCP frame, it forwards it (using unicast IP) to the
real DHCP server, which handles allocating addresses, etc. and sends the
responses back through the DHCP relay. I bring this up not because this is
a DHCP development list, but to point out that DHCP broadcasts are NOT
forwarded by routers in the “IP forwarding” sense; they are processed at
application-layer and forwarded in a very different manner.

Anyway, this is far outside of NTDEV scope. Just be aware that
255.255.255.255 does NOT mean “all networks everywhere” – it means “all
directly connected subnets”, and that if you want to broadcast a frame on a
specific interface, use the broadcast address of that interface. I believe
TDI_QUERY_BROADCAST_ADDRESS will get you that address.

If you can produce the behavior you want in user-mode, consider sniffing the
TDI requests between AFD.SYS and TCPIP.SYS that you app generates. That
will show the exact addresses and options that are being used.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alan Adams
Sent: Sunday, February 19, 2006 11:42 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] UDP broadcast from TDI client

Understood. A DHCP broadcast does in fact go to all networks (FF.FF.FF.FF),
not the local network (e.g. 10.FF.FF.FF). I’m not looking at the DHCP RFC,
but I would assume it’s because there’s no assumption the DHCP server is
going to be on the local subnet, and in most large networks is not on the
local subnet. (And if you observe the DHCP Inform request generated by
calling Microsoft’s DHCPCSVC, the destination IP address is the same,
FF.FF.FF.FF.)

So the question is still the more programmatic / TDI-specific question, of
whether there is something different to be done when invoking the UDP sent
through TDI to prevent the packet from going out through all interfaces.
(Again, on the assumption it is possible to control this behavior, at least
within TCPIP.SYS, since the AFD interface into TCPIP.SYS is able to achieve
it.)

> When Microsoft’s own DHCPCSVC makes an Inform request it only appears

on the interface you would expect, but they’re going through Winsock
and AFD to TCPIP directly, not via TDI, so a comparison of “how” isn’t
straight forward.

TDI is the only interface to TCPIP. AFD uses TDI.

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

Try using raw IP instead of UDP.

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

----- Original Message -----
From: “Alan Adams”
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Sent: Sunday, February 19, 2006 7:41 PM
Subject: Re:[ntdev] UDP broadcast from TDI client

> Understood. A DHCP broadcast does in fact go to all networks
> (FF.FF.FF.FF), not the local network (e.g. 10.FF.FF.FF). I’m not
> looking at the DHCP RFC, but I would assume it’s because there’s no
> assumption the DHCP server is going to be on the local subnet, and in
> most large networks is not on the local subnet. (And if you observe
> the DHCP Inform request generated by calling Microsoft’s DHCPCSVC, the
> destination IP address is the same, FF.FF.FF.FF.)
>
> So the question is still the more programmatic / TDI-specific
> question, of whether there is something different to be done when
> invoking the UDP sent through TDI to prevent the packet from going out
> through all interfaces. (Again, on the assumption it is possible to
> control this behavior, at least within TCPIP.SYS, since the AFD
> interface into TCPIP.SYS is able to achieve it.)
>
> “Jan Bottorff” wrote:
>
> > I’d have to dig out an IP book to be sure but it seems like the broadcast
> > address for a specific subnet will NOT be FF.FF.FF.FF. Each IP subnet, like
> > 192.168.1.0 (mask 255.255.255.0) will have an IP subnet broadcast address
of
> > 192.168.1.255. The IP address FF.FF.FF.FF seems like it probably means
> > broadcast to ALL subnets. The Ethernet broadcast address is
> > FF.FF.FF.FF.FF.FF (48 bits).
> >
> > - Jan
> >
> > > It creates an address file object against \Device\Udp that specifies
> > > the address we were just informed of, and then we construct a
> > > TDI_CONNECTION_INFORMATION.RemoteAddress that describes the IP
> > > broadcast address (FF.FF.FF.FF) for TdiBuildSendDatagram and then call
> > > for the send.
> >
> >
> >
>
> Alan Adams
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks for the response. And I agree with your points, and also of
being far outside of NTDEV.

The facts that still stand are that the DHCPCSVC does in fact send to
the FF.FF.FF.FF address (and also FFFFFFFFFFFF at the MAC level, for
what it’s worth), and the frame does not get transmitted on all
interfaces. And my NTDEV inquiry is whether there was a known way to
achieve this through the TDI client interface.

And the fact that two days ago I would have sworn I was seeing AFD
interact with TCPIP via a direct IOCTL and not via a TDI interface is
the only reason I had said “is not straight forward”. But as I try
and confirm additional facts for response here, indeed I do see AFD
calling into TCPIP using a TDI IOCTL.

So no more from me until I understand where I went wrong in the
debugging and/or discover anything unique that has been done in
setting up for this TDI send.

“Arlie Davis” wrote:

> You might be confusing multicast and broadcast, and network interface scope.
>
> If you submit a UDP frame to the IP stack with a destination address of
> 255.255.255.255, IP will transmit that frame on all network interfaces, and
> it will use a link-layer broadcast address. If the destination address is
> (say) 192.168.255.255, the frame will be transmitted on just the local
> interface that has 192.168.255.255 as its broadcast IP address, and it will
> use a link-layer broadcast address.
>
> Under normal circumstances, routers (IP gateways) that receive those frames
> will NOT retransmit them. They have subnet scope. That is, layer 2 devices
> (Ethernet switches and hubs) will retransmit them, but layer 3 devices (IP
> gateways) will NOT retransmit them. Therefore, the DHCP server MUST be
> reachable via a path composed only of layer 2 devices, including a path of
> “none”, meaning directly.
>
> IP multicast is different from broadcast. IP multicast uses class “D”
> address (beginning at 224.x.x.x). Layer 3 gateways (routers) may forward IP
> multicast frames, depending on whether IP multicast routing is enabled (and
> it often is not). IP multicast routing is a complicated topic, and is far
> outside the scope of NTDEV. However, DHCP uses IP broadcast, not multicast
> – the word “multicast” does not appear anywhere in RFC 2131.
>
> DHCP in some enterprises is managed remotely by using DHCP relays (proxies).
> This is often enabled in routers, because routers have excellent
> connectivity, and “see” many subnets. (DHCP relays are stateless.) When a
> DHCP relay receives a DHCP frame, it forwards it (using unicast IP) to the
> real DHCP server, which handles allocating addresses, etc. and sends the
> responses back through the DHCP relay. I bring this up not because this is
> a DHCP development list, but to point out that DHCP broadcasts are NOT
> forwarded by routers in the “IP forwarding” sense; they are processed at
> application-layer and forwarded in a very different manner.
>
> Anyway, this is far outside of NTDEV scope. Just be aware that
> 255.255.255.255 does NOT mean “all networks everywhere” – it means “all
> directly connected subnets”, and that if you want to broadcast a frame on a
> specific interface, use the broadcast address of that interface. I believe
> TDI_QUERY_BROADCAST_ADDRESS will get you that address.
>
> If you can produce the behavior you want in user-mode, consider sniffing the
> TDI requests between AFD.SYS and TCPIP.SYS that you app generates. That
> will show the exact addresses and options that are being used.
>
> – arlie

Alan Adams

Thanks. Somehow I was focusing on some 12xxxx IRP_MJ_DEVICE_CONTROL
codes going into TCPIP from AFD, but after Arlie’s post I’m now
clearly seeing the TDI interaction, too.

For what it’s worth, DHCPCSVC’s invocation of TDI via AFD appears to
be normal that I can detect thus far. (Normal == not significantly
different than mine, aside from additional TDI_QUERY_INFORMATION work
they’re doing.)

What is different is that prior to the send, dhcpcsvc!IPSetInterface
opens \Device\Ip and sends a IRP_MJ_DEVICE_CONTROL 0x128008 via that
device, with the input buffer containing a single parameter that
appears to be the interface index value. (i.e. As returned through
user-mode interface like GetAdaptersInfo or GetInterfaceInfo.) Appears
to do this prior to each send and then afterwords “cleans up” by
calling one more time with an “index” of 0xFFFFFFFF. There must be
more to it than that, but this is all of the apparatus I’ve observed
thus far.

So unless anyone still has an idea of how the TDI interface itself
should be used to send to address FF.FF.FF.FF only over a specified
interface, its perhaps looking like I would need to take it up with
Microsoft regarding how they would support someone doing that. Since
potentially it looks like they’re not doing it with TDI either.

“Maxim S. Shatskih” wrote:

> > When Microsoft’s own DHCPCSVC makes an Inform request it only appears
> > on the interface you would expect, but they’re going through Winsock
> > and AFD to TCPIP directly, not via TDI, so a comparison of “how” isn’t
> > straight forward.
>
> TDI is the only interface to TCPIP. AFD uses TDI.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>

Alan Adams