0

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?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
inexcitus
  • 2,471
  • 2
  • 26
  • 41

1 Answers1

1

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"
Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382