Description
On FreeBSD, Socket.ReceiveMessageFromAsync() returns IPPacketInformation.Interface == 0 when receiving an IPv4 limited broadcast packet, although the FreeBSD kernel provides the correct receiving interface through native recvmsg() / IP_RECVIF.
The issue was initially observed while debugging DHCPv4 traffic, but it was reproduced independently of the DHCP application.
For a packet received as:
0.0.0.0:68 -> 255.255.255.255:67
.NET 10 reports:
Remote endpoint : 0.0.0.0:68
Bytes : 300
Destination : 255.255.255.255
Interface index : 0
The packet was actually received on interface igc1, whose interface index is 2.
A native FreeBSD recvmsg() test using IP_RECVDSTADDR and IP_RECVIF reports:
destination : 255.255.255.255
ifindex : 2
ifname : igc1
Thus, the receiving-interface information is available from the FreeBSD kernel but is not reflected in SocketReceiveMessageFromResult.PacketInformation.Interface.
Reproduction Steps
Run the following .NET 10 console application on FreeBSD:
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using Socket socket = new(
AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);
socket.SetSocketOption(
SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress,
true);
socket.EnableBroadcast = true;
socket.SetSocketOption(
SocketOptionLevel.IP,
SocketOptionName.PacketInformation,
true);
socket.Bind(new IPEndPoint(IPAddress.Any, 67));
byte[] buffer = new byte[2048];
EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
SocketReceiveMessageFromResult result =
await socket.ReceiveMessageFromAsync(
buffer,
SocketFlags.None,
remote);
Console.WriteLine($"Remote endpoint : {result.RemoteEndPoint}");
Console.WriteLine($"Bytes : {result.ReceivedBytes}");
Console.WriteLine($"Destination : {result.PacketInformation.Address}");
Console.WriteLine($"Interface index : {result.PacketInformation.Interface}");
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
IPv4InterfaceProperties? ipv4 =
ni.GetIPProperties().GetIPv4Properties();
if (ipv4 != null)
Console.WriteLine($"{ni.Name}: interface index {ipv4.Index}");
}
Send an IPv4 limited broadcast packet to UDP port 67 on the same L2 network.
The issue was reproduced with a DHCPDISCOVER packet:
0.0.0.0:68 -> 255.255.255.255:67
The .NET application reports:
Destination : 255.255.255.255
Interface index : 0
while the receiving interface is:
As a control test, a native FreeBSD UDP socket using recvmsg() with IP_RECVDSTADDR and IP_RECVIF receives the same type of limited-broadcast packet and reports:
destination : 255.255.255.255
ifindex : 2
ifname : igc1
Expected behavior
SocketReceiveMessageFromResult.PacketInformation.Interface should contain the index of the interface on which the IPv4 broadcast packet was received.
For this test, the expected value is:
corresponding to interface igc1, consistent with the interface information returned by native FreeBSD recvmsg() / IP_RECVIF.
Actual behavior
SocketReceiveMessageFromResult.PacketInformation.Interface is returned as:
while PacketInformation.Address correctly contains:
Native FreeBSD recvmsg() / IP_RECVIF reports interface index 2 (igc1) for the same type of packet.
Regression?
Unknown.
The behavior has been reproduced with .NET 10.0.10 on FreeBSD 15.1-RELEASE-p2. Earlier .NET runtime versions on FreeBSD have not been tested.
Known Workarounds
There is no reliable general application-level workaround when multiple interfaces may exist.
For an IPv4 limited broadcast, the destination address is 255.255.255.255, so the destination address itself cannot be used to determine the receiving interface.
In the original DHCP use case, a fallback can be implemented when only one unambiguous DHCP scope exists, but this does not solve the underlying loss of receiving-interface information and is not suitable for multi-interface systems.
Configuration
.NET SDK:
Version: 10.0.110
Commit: f7d90799ce
Workload version: 10.0.100-manifests.1641d827
MSBuild version: 18.0.11+f7d90799c
Host:
Version: 10.0.10
Architecture: x64
Commit: f7d90799ce
.NET runtimes installed:
Microsoft.AspNetCore.App 10.0.10
Microsoft.NETCore.App 10.0.10
Runtime Environment:
OS Name: FreeBSD
OS Version: 15
OS Platform: FreeBSD
RID: freebsd.15-x64
freebsd-version -ku:
15.1-RELEASE-p2
15.1-RELEASE-p2
uname -a:
FreeBSD opnsense.home.arpa 15.1-RELEASE-p2 FreeBSD 15.1-RELEASE-p2 stable/26.7-n283714-dd064f22c895 SMP amd64
Other information
The discrepancy was isolated independently of the DHCP application that originally exposed it.
For the same type of IPv4 limited-broadcast traffic:
.NET Socket.ReceiveMessageFromAsync() reports interface index 0.
- Native FreeBSD
recvmsg() using IP_RECVIF reports interface index 2 (igc1).
The native test also confirms the destination address as 255.255.255.255.
This indicates that the FreeBSD kernel provides the receiving-interface information, but that information is not propagated into IPPacketInformation.Interface by the .NET socket implementation in this environment.
Description
On FreeBSD,
Socket.ReceiveMessageFromAsync()returnsIPPacketInformation.Interface == 0when receiving an IPv4 limited broadcast packet, although the FreeBSD kernel provides the correct receiving interface through nativerecvmsg()/IP_RECVIF.The issue was initially observed while debugging DHCPv4 traffic, but it was reproduced independently of the DHCP application.
For a packet received as:
.NET 10 reports:
The packet was actually received on interface
igc1, whose interface index is2.A native FreeBSD
recvmsg()test usingIP_RECVDSTADDRandIP_RECVIFreports:Thus, the receiving-interface information is available from the FreeBSD kernel but is not reflected in
SocketReceiveMessageFromResult.PacketInformation.Interface.Reproduction Steps
Run the following .NET 10 console application on FreeBSD:
Send an IPv4 limited broadcast packet to UDP port 67 on the same L2 network.
The issue was reproduced with a DHCPDISCOVER packet:
The .NET application reports:
while the receiving interface is:
As a control test, a native FreeBSD UDP socket using
recvmsg()withIP_RECVDSTADDRandIP_RECVIFreceives the same type of limited-broadcast packet and reports:Expected behavior
SocketReceiveMessageFromResult.PacketInformation.Interfaceshould contain the index of the interface on which the IPv4 broadcast packet was received.For this test, the expected value is:
corresponding to interface
igc1, consistent with the interface information returned by native FreeBSDrecvmsg()/IP_RECVIF.Actual behavior
SocketReceiveMessageFromResult.PacketInformation.Interfaceis returned as:while
PacketInformation.Addresscorrectly contains:Native FreeBSD
recvmsg()/IP_RECVIFreports interface index2(igc1) for the same type of packet.Regression?
Unknown.
The behavior has been reproduced with .NET 10.0.10 on FreeBSD 15.1-RELEASE-p2. Earlier .NET runtime versions on FreeBSD have not been tested.
Known Workarounds
There is no reliable general application-level workaround when multiple interfaces may exist.
For an IPv4 limited broadcast, the destination address is
255.255.255.255, so the destination address itself cannot be used to determine the receiving interface.In the original DHCP use case, a fallback can be implemented when only one unambiguous DHCP scope exists, but this does not solve the underlying loss of receiving-interface information and is not suitable for multi-interface systems.
Configuration
Other information
The discrepancy was isolated independently of the DHCP application that originally exposed it.
For the same type of IPv4 limited-broadcast traffic:
.NET Socket.ReceiveMessageFromAsync()reports interface index0.recvmsg()usingIP_RECVIFreports interface index2(igc1).The native test also confirms the destination address as
255.255.255.255.This indicates that the FreeBSD kernel provides the receiving-interface information, but that information is not propagated into
IPPacketInformation.Interfaceby the .NET socket implementation in this environment.