0

I tried several codes that are answered on other questions. But I could not find one answer in swift that can provide me IPv4 Address and IPv6 Address when running over cellular data.

ipv4  : [192.168.40.2]
ipv6  : [FE80::AA9F:BAFF:FEB1:7201]

Above are the kind of values I'm trying to fetch.

Code that I tried:

func getIFAddresses() -> [String] {
        var addresses = [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 flags = Int32(ptr.pointee.ifa_flags)
            let addr = ptr.pointee.ifa_addr.pointee

            // Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
            if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
                if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {

                    // Convert interface address to a human readable string:
                    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                    if (getnameinfo(ptr.pointee.ifa_addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count),
                                    nil, socklen_t(0), NI_NUMERICHOST) == 0) {
                        let address = String(cString: hostname)
                        addresses.append(address)
                        if addr.sa_family == UInt8(AF_INET) {
                            print("ipv4 ### \(address)")
                        }

                        if addr.sa_family == UInt8(AF_INET6) {
                            print("ipv6 ### \(address)")
                        }
                    }
                }
            }
        }

        freeifaddrs(ifaddr)
        return addresses
    }

Output I get is:

ipv6 ### fe80::14**:b142:c143:daa4%en0
ipv4 ### 1**.25*.5.105
ipv6 ### fe80::d**:304f:f**:bcc3%utun0
ipv6 ### fe80::cc6:3***:4d31:1b35%en5
ipv4 ### 10.85.47.***
ipv4 ### 192.1**.2.1
ipv6 ### fe**::18**:90ff:fefc:9364%bridge100

I already referred this, this and many other related answers

PS: * is used to changed the original value

piet.t
  • 11,718
  • 21
  • 43
  • 52
Dhruv
  • 2,153
  • 3
  • 21
  • 45
  • The `fe80::/10` address is a link-local address, not a global address. It can only reach devices on the same link. Global addresses are in the `2000::/3` range. – Ron Maupin Apr 01 '19 at 06:44
  • 1
    What is wrong with the output you are getting? – Paulw11 Apr 01 '19 at 06:46
  • @RonMaupin Thank for the info. – Dhruv Apr 01 '19 at 06:48
  • @Paulw11 Well I'm getting multiple values and I'm not sure if its proper. Shouldn't we get single values ? Also, the one I posted above as my requirement are different from my ipv6 address – Dhruv Apr 01 '19 at 06:49
  • You get multiple values because the device has multiple interfaces. pdp_ip0 is your cellular interface. The values returned by these calls and the values seen by sites on the internet can often differ because cellular carriers will use CG-NAT to gain address space. From the looks of your output your device doesn't have an IPv6 address. You can check at http://ipv6-test.com – Paulw11 Apr 01 '19 at 06:58
  • @Paulw11 Thanks, I will check the IPv6. So pdp_ip0 is what I need. – Dhruv Apr 01 '19 at 07:57
  • Make sure you are on 4G LTE. If you still don't get a global IPv6 address, your carrier is to blame. – Michael Hampton Apr 01 '19 at 17:03
  • @MichaelHampton Yup, I get IPv6 while on LTE. – Dhruv Apr 02 '19 at 05:06

0 Answers0