Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal static partial class Sys
public struct LinkLayerAddressInfo
{
public int InterfaceIndex;
public InlineArray8<byte> AddressBytes;
public InlineArray12<byte> AddressBytes;
public byte NumAddressBytes;
private byte __padding; // For native struct-size padding. Does not contain useful data.
public ushort HardwareType;
Expand All @@ -38,7 +38,7 @@ public struct NetworkInterfaceInfo
public ushort HardwareType;
public byte OperationalState;
public byte NumAddressBytes;
public InlineArray8<byte> AddressBytes;
public InlineArray12<byte> AddressBytes;
public byte SupportsMulticast;
private InlineArray3<byte> __padding;
}
Expand Down
42 changes: 38 additions & 4 deletions src/native/libs/System.Native/pal_interfaceaddresses.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,31 @@ static inline uint8_t mask2prefix(uint8_t* mask, int length)
}
#endif /* TARGET_WASI */

#if defined(AF_LINK)
static uint8_t GetLinkLayerAddressLength(const struct sockaddr_dl* address, size_t destinationLength)
{
#if defined(TARGET_SUNOS)
size_t availableLength = sizeof(address->sdl_data) > address->sdl_nlen ? sizeof(address->sdl_data) - address->sdl_nlen : 0;
#else
size_t addressOffset = offsetof(struct sockaddr_dl, sdl_data) + address->sdl_nlen;
size_t availableLength = address->sdl_len > addressOffset ? address->sdl_len - addressOffset : 0;
#endif
size_t addressLength = address->sdl_alen;

if (addressLength > availableLength)
{
addressLength = availableLength;
}

if (addressLength > destinationLength)
{
addressLength = destinationLength;
}

return (uint8_t)addressLength;
}
#endif

int32_t SystemNative_EnumerateInterfaceAddresses(void* context,
IPv4AddressFound onIpv4Found,
IPv6AddressFound onIpv6Found,
Expand Down Expand Up @@ -242,7 +267,7 @@ int32_t SystemNative_EnumerateInterfaceAddresses(void* context,
LinkLayerAddressInfo lla;
memset(&lla, 0, sizeof(LinkLayerAddressInfo));
lla.InterfaceIndex = interfaceIndex;
lla.NumAddressBytes = sadl->sdl_alen;
lla.NumAddressBytes = GetLinkLayerAddressLength(sadl, sizeof(lla.AddressBytes));
lla.HardwareType = MapHardwareType(sadl->sdl_type);

#if HAVE_NET_IFMEDIA_H || HAVE_IOS_NET_IFMEDIA_H
Expand All @@ -265,7 +290,10 @@ int32_t SystemNative_EnumerateInterfaceAddresses(void* context,
}
}
#endif
memcpy_s(&lla.AddressBytes, sizeof_member(LinkLayerAddressInfo, AddressBytes), (uint8_t*)LLADDR(sadl), sadl->sdl_alen);
if (lla.NumAddressBytes != 0)
{
memcpy_s(&lla.AddressBytes, sizeof_member(LinkLayerAddressInfo, AddressBytes), (uint8_t*)LLADDR(sadl), lla.NumAddressBytes);
}
onLinkLayerFound(context, current->ifa_name, &lla);
}
}
Expand All @@ -286,6 +314,9 @@ int32_t SystemNative_EnumerateInterfaceAddresses(void* context,
}

// See entriesCount, calloc() below.
c_static_assert(sizeof(LinkLayerAddressInfo) == 20);
c_static_assert(sizeof_member(LinkLayerAddressInfo, AddressBytes) == 12);
c_static_assert(sizeof_member(NetworkInterfaceInfo, AddressBytes) == 12);
c_static_assert(sizeof(NetworkInterfaceInfo) >= sizeof(IpAddressInfo));

int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInterfaceInfo **interfaceList, int32_t * addressCount, IpAddressInfo **addressList )
Expand Down Expand Up @@ -439,8 +470,11 @@ int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInter
struct sockaddr_dl* sadl = (struct sockaddr_dl*)ifaddrsEntry->ifa_addr;

nii->HardwareType = MapHardwareType(sadl->sdl_type);
nii->NumAddressBytes = sadl->sdl_alen;
memcpy_s(&nii->AddressBytes, sizeof_member(NetworkInterfaceInfo, AddressBytes), (uint8_t*)LLADDR(sadl), sadl->sdl_alen);
nii->NumAddressBytes = GetLinkLayerAddressLength(sadl, sizeof(nii->AddressBytes));
if (nii->NumAddressBytes != 0)
{
memcpy_s(&nii->AddressBytes, sizeof_member(NetworkInterfaceInfo, AddressBytes), (uint8_t*)LLADDR(sadl), nii->NumAddressBytes);
}

#if defined(SIOCGIFMTU)
struct ifreq ifr;
Expand Down
4 changes: 2 additions & 2 deletions src/native/libs/System.Native/pal_interfaceaddresses.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ typedef enum
typedef struct
{
uint32_t InterfaceIndex; // The index of the interface to which this address belongs.
uint8_t AddressBytes[8]; // A pointer to the bytes containing the address.
uint8_t AddressBytes[12]; // The bytes containing the address.
uint8_t NumAddressBytes; // The number of bytes actually stored in the address.
uint8_t _padding;
uint16_t HardwareType;
Expand All @@ -42,7 +42,7 @@ typedef struct
uint16_t HardwareType; // Interface mapped from L2 to NetworkInterfaceType.
uint8_t OperationalState; // Operational status.
uint8_t NumAddressBytes; // The number of bytes actually stored in the address.
uint8_t AddressBytes[8]; // Link address.
uint8_t AddressBytes[12]; // Link address.
uint8_t SupportsMulticast; // Interface supports multicast.
uint8_t _padding[3];
} NetworkInterfaceInfo;
Expand Down
Loading