Swift-获取ipv6链接本地地址?

时间:2018-08-24 07:50:49

标签: ios swift ipv6

我检查了以下代码以获得ipv6地址,此代码返回了全球单播地址,例如“ 2001:x:x ...”。 但是我想获取链接本地地址,例如“ fe80:...”。 如何使用以下代码获取链接本地地址?

static var ipAddress: String? {
    var ipv6 : String?
    var ifaddr : UnsafeMutablePointer<ifaddrs>?
    guard getifaddrs(&ifaddr) == 0 else { return (nil, nil) }
    guard let firstAddr = ifaddr else { return (nil, nil) }

    for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
        let interface = ifptr.pointee
        let addrFamily = interface.ifa_addr.pointee.sa_family
        if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
            let name = String(cString: interface.ifa_name)
            if  name == "en0" {
                var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len),&hostname, socklen_t(hostname.count),nil, socklen_t(0), NI_NUMERICHOST)
                ipv6 = String(cString: hostname)
            }
        }
    }
    freeifaddrs(ifaddr)
    return ipv6
}

1 个答案:

答案 0 :(得分:1)

系统包含文件netinet6/in6.h定义了一个宏

#define IN6_IS_ADDR_LINKLOCAL(a)        \
        (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))

该宏未导入到Swift中,但显示了我们必须如何进行。 对循环的以下修改(来自Swift - Get device's IP Address)可以找到所有IPv6本地链接地址:

    for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
        let interface = ifptr.pointee
        let addrFamily = interface.ifa_addr.pointee.sa_family
        if addrFamily == UInt8(AF_INET6) {
            // Get the sin6_addr part of the sockaddr as UInt8 "array":
            let s6_addr = interface.ifa_addr.withMemoryRebound(to: sockaddr_in6.self, capacity: 1) {
                $0.pointee.sin6_addr.__u6_addr.__u6_addr8
            }
            // Check for link-local address:
            if s6_addr.0 == 0xfe && (s6_addr.1 & 0xc0) == 0x80 {
                let name = String(cString: interface.ifa_name)

                // ...
            }
        }
    }