Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if the internet connection is over WiFi or Ethernet?

Tags:

swift

tvos

Is there a way to open network settings programmatically? Closest thing I know is opening the main settings page:

let settingsURL = NSURL(string: UIApplicationOpenSettingsURLString)!
UIApplication.sharedApplication().openURL(settingsURL)

I want to be able to detect if the internet connection is over WiFi or Ethernet.

like image 529
hanjustin Avatar asked Oct 24 '15 07:10

hanjustin


People also ask

How do you identify if your device is connected to WiFi or LAN connection?

Select the Start button, then type settings. Select Settings > Network & internet. The status of your network connection will appear at the top. Windows 10 lets you quickly check your network connection status.

How do I know what type of internet connection I have?

Find out your internet connection type by equipmentLocate your modem and router and see what wires are connected to it. Most current modem and router combos, also known as gateways, will have the type of internet connection clearly marked on the device.

How do I know if I have Ethernet?

Look for an Ethernet port on the back of your computer (it will look like a phone jack but a little bigger). The presence of an Ethernet port indicates that a NIC is already installed in your computer.


1 Answers

The way to detect this is to look at the name of the network interfaces. For Mac and Apple TV, en0 and en1 refer to the wired and wireless interfaces respectively.

Add this to your bridging header (or create one if needed):

#include <ifaddrs.h>
#include <net/if_dl.h>

Then use this Swift code to get the information you need:

struct Networking {

    enum NetworkInterfaceType: String, CustomStringConvertible {
        case Ethernet = "en0"
        case Wifi = "en1"
        case Unknown = ""

        var description: String {
            switch self {
            case .Ethernet:
                return "Ethernet"
            case .Wifi:
                return "Wifi"
            case .Unknown:
                return "Unknown"
            }
        }
    }

    static var networkInterfaceType: NetworkInterfaceType {
        if let name = Networking().getInterfaces().first?.name, let type = NetworkInterfaceType(rawValue: name) {
            return type
        }

        return .Unknown
    }

    static var isConnectedByEthernet: Bool {
        let networking = Networking()
        for addr in networking.getInterfaces() {
            if addr.name == NetworkInterfaceType.Ethernet.rawValue {
                return true
            }
        }
        return false
    }

    static var isConnectedByWiFi: Bool {
        let networking = Networking()
        for addr in networking.getInterfaces() {
            if addr.name == NetworkInterfaceType.Wifi.rawValue {
                return true
            }
        }
        return false
    }

    // Credit to Martin R http://stackoverflow.com/a/34016247/600753 for this lovely code
    // New Swift 3 implementation needed upated to replace unsafepointer calls with .withMemoryRebound
    func getInterfaces() -> [(name : String, addr: String, mac : String)] {

        var addresses = [(name : String, addr: String, mac : String)]()
        var nameToMac = [ String: 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)
            if var addr = ptr.pointee.ifa_addr {
                let name = String(cString: ptr.pointee.ifa_name)

                // Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
                if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
                    switch Int32(addr.pointee.sa_family) {
                    case AF_LINK:
                        nameToMac[name] = withUnsafePointer(to: &addr) { unsafeAddr in
                            unsafeAddr.withMemoryRebound(to: sockaddr_dl.self, capacity: 1) { dl in
                                dl.withMemoryRebound(to: Int8.self, capacity: 1) { dll in
                                    let lladdr = UnsafeRawBufferPointer(start: dll + 8 + Int(dl.pointee.sdl_nlen), count: Int(dl.pointee.sdl_alen))

                                    if lladdr.count == 6 {
                                        return lladdr.map { String(format:"%02hhx", $0)}.joined(separator: ":")
                                    } else {
                                        return nil
                                    }
                                }
                            }
                        }

                    case AF_INET, AF_INET6:
                        // Convert interface address to a human readable string:
                        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                        if (getnameinfo(addr, socklen_t(addr.pointee.sa_len),
                                        &hostname, socklen_t(hostname.count),
                                        nil, socklen_t(0), NI_NUMERICHOST) == 0) {
                            let address = String(cString: hostname)
                            addresses.append( (name: name, addr: address, mac : "") )
                        }
                    default:
                        break
                    }
                }
            }
        }

        freeifaddrs(ifaddr)

        // Now add the mac address to the tuples:
        for (i, addr) in addresses.enumerated() {
            if let mac = nameToMac[addr.name] {
                addresses[i] = (name: addr.name, addr: addr.addr, mac : mac)
            }
        }

        return addresses
    }
}

Usage is:

debugPrint(Networking.networkInterfaceType)

Or:

switch Networking.networkInterfaceType {
case .Ethernet:
    // do something
    break

case .Wifi:
    // do something else
    break

default:
    break
}
like image 65
picciano Avatar answered Sep 28 '22 03:09

picciano