Enumerating available interfaces for use with NWEthernetChannel

We need to enumerate the available network interfaces(NWInterface) which can be used to initialize a NWEthernetChannel.

Note that this is for creating a custom network protocol. So we don't expect these interfaces to have any Internet connectivity.

In fact, we want to be able to enumerate the interfaces even when the cable is disconnected.

So we cannot use use the method described in this thread - which only works for interfaces which have a cable connection:

Getting NWInterface for ...

Alternatively, is there a way to get an NWInterface from a SCNetworkInterfaceRef (obtained via SCNetworkServiceCopyAll() -> SCNetworkServiceGetInterface())?

There is the undocumented nw_interface_create_with_name() - but I'm not sure if that's a good idea.

Thanks.
Devendra.


Answered by DTS Engineer in 668289022

Typical user workflow often involves the user wanting to select the
interface in our software even when no device is physically connected
to the interface - because they know where they will be connecting the
devices later on.

OK. In that case use SCNetworkInterfaceCopyAll. That API was specifically designed to return a list of known network ports and their user-visible names (using SCNetworkInterfaceGetLocalizedDisplayName), something that’s very hard to do with any other API.

You only need NWEthernetChannel when the user actually tries to use the interface. At that point, if you detect that there’s no IPv6 link local address, you can inform the user of the problem.

If you specifically want to determine whether the problem is that nothing is plugged in, use the dynamic store to check for the kSCPropNetLinkActive property in the interface’s kSCEntNetLink entity. For example:

Code Block
% scutil
> show State:/Network/Interface/en7/Link
<dictionary> {
Active : FALSE
}


[Although in a real app you’d do this in code rather relying on scutil.]

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I took a quick look at FB7551376 (from that other thread) and there’s no info to share on that front.

Alternatively, is there a way to get an NWInterface from a
SCNetworkInterfaceRef …?

No. I searched the macOS SDK for all instances of nw_interface_t and there’s nothing like that.

There is the undocumented … but I'm not sure if that's a good idea.

I’m quite sure it’s not )-:

In fact, we want to be able to enumerate the interfaces even when the
cable is disconnected.

Can you explain that? What good is having an NWInterface if there’s nothing connected to that interface?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Thanks Quinn for looking into this.

Here's the situation...

We have an Audio over Ethernet solution which communicates using our own Layer 2 protocol to devices connected on the (private) network.

As part of this - we allow the user to select which Ethernet interface to use for this audio driver.

Typical user workflow often involves the user wanting to select the interface in our software even when no device is physically connected to the interface - because they know where they will be connecting the devices later on.

Or simply, they want to setup the rest of the system while the device (or switch) is powered down - etc.

All of this is working well in our current releases - but we are using Kernel Extensions and the APIs available there.

As you know, we need to move out of the kernel - and thus the need for NWEthernetChannel and friends.

Thanks.
Devendra.



Accepted Answer

Typical user workflow often involves the user wanting to select the
interface in our software even when no device is physically connected
to the interface - because they know where they will be connecting the
devices later on.

OK. In that case use SCNetworkInterfaceCopyAll. That API was specifically designed to return a list of known network ports and their user-visible names (using SCNetworkInterfaceGetLocalizedDisplayName), something that’s very hard to do with any other API.

You only need NWEthernetChannel when the user actually tries to use the interface. At that point, if you detect that there’s no IPv6 link local address, you can inform the user of the problem.

If you specifically want to determine whether the problem is that nothing is plugged in, use the dynamic store to check for the kSCPropNetLinkActive property in the interface’s kSCEntNetLink entity. For example:

Code Block
% scutil
> show State:/Network/Interface/en7/Link
<dictionary> {
Active : FALSE
}


[Although in a real app you’d do this in code rather relying on scutil.]

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Thanks Quinn - that's exactly what we ended up doing.

It just sounds improper to have to use five different APIs (SCNetwork, NWEthernet, ifaddrs, DynamicStore, and sysctl) to work with the same network interface!!

The sysctl is also needed to determine the link speed - we also need to show that to the user - as DynamicStore only provides link status.

I hope this gets some attention from Apple in the future!

Thanks.
Devendra.


It just sounds improper to have to use five different APIs

Having said that, you do have some pretty unusual requirements. It’s not like your app is using HTTPS to fetch JSON, which is 99% of the networking done on our platforms (-:

The sysctl is also needed to determine the link speed - we also need
to show that to the user - as DynamicStore only provides link status.

The actual link speed? Or do you want the set of supported link speeds?

I hope this gets some attention from Apple in the future!

Rather than just “hope”, I encourage you to file enhancement requests for any particularly punishing speed bumps you hit. And please post any bug numbers you get, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Hi Quinn,

Agreed - we have some very unique requirements!

We need the actual link speed - to be able to identify cable issues, for example.

Regarding the enhancement request - I saw that other people had already file some.

But I think you are quite right - more is better!

So I filed one: FB9074593 - Need coherent APIs for using NWEthernetChannel.

As always, Thank You for your support!

Devendra.

FB9074593 - Need coherent APIs for using NWEthernetChannel.

Thanks for that.

We need the actual link speed

You can get this from the BSD interface name (en7 in my example) using the old school BSD API (SIOCGIFXMEDIA).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Hi Quinn,


You can get this from the BSD interface name (en7 in my example) using the old school BSD API (SIOCGIFXMEDIA).

If I understand this correctly, this ioctl provides the settings - and may not be the actual speed that the interface is working on. (BTW all of that is also available via NWInterface APIs).

What we would need seems to what the ifconfig utility seems to use - SIOCGIFLINKPARAMS, but that one seems to be PRIVATE - so we are not able to use that.

Thanks.
Devendra.
Hmmm. When I run ifconfig on my Mac I see this:

Code Block
% ifconfig en7
en7: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
media: autoselect (1000baseT <full-duplex,flow-control,energy-efficient-ethernet>)


That media value is definitely associated with SIOCGIFXMEDIA.

Unfortunately I don’t have time to comprehensively test this right now. If the above doesn’t help, open a DTS tech support incident and I’ll dig into this properly.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Enumerating available interfaces for use with NWEthernetChannel
 
 
Q