Sascha Simon Sascha Simon - 14 days ago 8
Objective-C Question

Thunderbolt to Ethernet adapter not found in Swift using getifaddrs()

I have the following code to get a list of all adapters on my MacBook:

if getifaddrs(&addresses) == 0
{
let buffer = UnsafeBufferPointer(start: addresses, count: 16)
for address in buffer
{
let rawData = address.ifa_data
let name = address.ifa_name
let socket: sockaddr = address.ifa_addr.pointee

if rawData != nil && name != nil && socket.sa_family == UInt8(AF_LINK)
{
let adapterName = String(utf8String: UnsafePointer<CChar>(name!))
let adapter = Adapter(name: adapterName!)
adapters.append(adapter)
}
}
}


The code works great and (almost) all adapters are returned. If a Thunderbolt to Ethernet adapter is used, this network is not returned.

How can I get this adapter?

Regards,
Sascha

Answer

Your code assumes that getifaddrs() returns an array of struct ifaddrs, and that is not true. The function stores a reference to a linked list at the given address, with the ifa_next member pointing to the next element (or nil for the last element).

Here is an example how to traverse the list and store the interface names into an array (a modification of the code in How to get Ip address in swift):

func getInterfaceNames() -> [String] {

    var names = [String]()

    // Get list of all interfaces on the local machine:
    var ifaddr : UnsafeMutablePointer<ifaddrs>?
    guard getifaddrs(&ifaddr) == 0 else { return [] }
    guard let firstAddr = ifaddr else { return [] }

    // For each interface ...
    for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
        let addr = ptr.pointee.ifa_addr.pointee
        if addr.sa_family == UInt8(AF_LINK) {
            let name = String(cString: ptr.pointee.ifa_name)
            names.append(name)
        }
    }

    return names
}

On my iMac, this gives

["lo0", "gif0", "stf0", "en1", "en2", "en3", "p2p0", "awdl0", "en0", "bridge0", "utun0"]

including "bridge0" for the Thunderbolt bridge, whereas your code only returns

"lo0", "gif0", "stf0", "en1"
Comments