That’s not my experience. How are you testing this?
ps Pasted in below is the code I wrote to digest
getifaddrs into something more pleasant. This assumes the
SockAddr type I posted
here.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Code Block | static var allAddresses: [AddressInfo] { |
| var addrList: UnsafeMutablePointer<ifaddrs>? = nil |
| let err = getifaddrs(&addrList) |
| guard err == 0, let start = addrList else { return [] } |
| defer { freeifaddrs(start) } |
| return sequence(first: start, next: { $0.pointee.ifa_next }) |
| .map { i -> AddressInfo in |
| AddressInfo( |
| name: String(cString: i.pointee.ifa_name), |
| flags: .init(rawValue: i.pointee.ifa_flags), |
| address: i.pointee.ifa_addr.flatMap { SockAddr(saPtr: $0) }, |
| netmask: i.pointee.ifa_netmask.flatMap { SockAddr(saPtr: $0) }, |
| destinationAddress: i.pointee.ifa_dstaddr.flatMap { SockAddr(saPtr: $0) }, |
| data: i.pointee.ifa_data.flatMap { Data(bytes: $0, count: MemoryLayout<if_data>.size) } |
| ) |
| } |
| } |
|
| struct AddressInfo { |
| // Reading the (frankly terrifying) code for `getifaddrs` I believe that |
| // the name field (`ifa_addr`) is always non-`NULL`. That seems to be |
| // confirmed by the man page. All the other fields, however, may be |
| // NULL. |
| var name: String |
| var flags: InterfaceFlags |
| var address: SockAddr? |
| var netmask: SockAddr? |
| var destinationAddress: SockAddr? |
| var data: Data? |
| } |
|
| struct InterfaceFlags: OptionSet { |
| var rawValue: CUnsignedInt |
|
| static let isUp = InterfaceFlags(rawValue: CUnsignedInt(bitPattern: IFF_UP)) |
| … and so on … |
| } |