diff --git a/packages/network_info_plus/network_info_plus/CHANGELOG.md b/packages/network_info_plus/network_info_plus/CHANGELOG.md index dab95e052c..3150ada97b 100644 --- a/packages/network_info_plus/network_info_plus/CHANGELOG.md +++ b/packages/network_info_plus/network_info_plus/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.0 + +- macOS: Add submask, broadcast, gateway info + ## 2.0.2 - Upgrade Android compile SDK version diff --git a/packages/network_info_plus/network_info_plus/pubspec.yaml b/packages/network_info_plus/network_info_plus/pubspec.yaml index a08d81d20d..4708a0aff6 100644 --- a/packages/network_info_plus/network_info_plus/pubspec.yaml +++ b/packages/network_info_plus/network_info_plus/pubspec.yaml @@ -1,6 +1,6 @@ name: network_info_plus description: Flutter plugin for discovering information (e.g. WiFi details) of the network. -version: 2.0.2 +version: 2.1.0 homepage: https://plus.fluttercommunity.dev/ repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ @@ -27,7 +27,7 @@ dependencies: meta: ^1.3.0 network_info_plus_platform_interface: ^1.1.0 network_info_plus_linux: ^1.0.0 - network_info_plus_macos: ^1.1.0 + network_info_plus_macos: ^1.3.0 network_info_plus_windows: ^1.0.0 network_info_plus_web: ^1.0.0 diff --git a/packages/network_info_plus/network_info_plus_macos/CHANGELOG.md b/packages/network_info_plus/network_info_plus_macos/CHANGELOG.md index 43a6ca580d..ef0ae95d67 100644 --- a/packages/network_info_plus/network_info_plus_macos/CHANGELOG.md +++ b/packages/network_info_plus/network_info_plus_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.0 + +- Add submask, broadcast, gateway info + ## 1.2.0 - Remove `Reachability` dependency diff --git a/packages/network_info_plus/network_info_plus_macos/macos/Classes/NetworkInfoPlusPlugin.swift b/packages/network_info_plus/network_info_plus_macos/macos/Classes/NetworkInfoPlusPlugin.swift index ba55958f58..0a05a35924 100644 --- a/packages/network_info_plus/network_info_plus_macos/macos/Classes/NetworkInfoPlusPlugin.swift +++ b/packages/network_info_plus/network_info_plus_macos/macos/Classes/NetworkInfoPlusPlugin.swift @@ -39,52 +39,125 @@ public class NetworkInfoPlusPlugin: NSObject, FlutterPlugin { case "wifiBSSID": result(cwinterface?.bssid()) case "wifiIPAddress": - result(getWiFiAddress(family: AF_INET)) + result(getWifiAddress(family: AF_INET)) case "wifiIPv6Address": - result(getWiFiAddress(family: AF_INET6)) + result(getWifiAddress(family: AF_INET6)) case "wifiSubmask": - result("") + result(getWifiSubmask()) case "wifiBroadcast": - result("") + result(getWifiBroadcast()) case "wifiGatewayAddress": - result("") + result(getDefaultGateway()) default: result(FlutterMethodNotImplemented) } } -} -// Return IP address of WiFi interface (en0) as a String, or `nil` -func getWiFiAddress(family: Int32) -> String? { - var address : String? - - // Get list of all interfaces on the local machine: - var ifaddr : UnsafeMutablePointer? - guard getifaddrs(&ifaddr) == 0 else { return nil } - guard let firstAddr = ifaddr else { return nil } - - // For each interface ... - for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { - let interface = ifptr.pointee - - // Check for IPv4 or IPv6 interface: - let addrFamily = interface.ifa_addr.pointee.sa_family - if addrFamily == UInt8(family) { - - // Check interface name: - let name = String(cString: interface.ifa_name) - if name == "en0" { - - // Convert interface address to a human readable string: - 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) - address = String(cString: hostname) - } + public func getWifiAddress(family: Int32) -> String? { + return withWifiInterface(family: family) { descriptionForAddress($0.pointee.ifa_addr) } + } + + public func getWifiSubmask() -> String? { + return withWifiInterface(family: AF_INET) { descriptionForAddress($0.pointee.ifa_netmask) } + } + + public func getWifiBroadcast() -> String? { + return withWifiInterface(family: AF_INET) { descriptionForAddress($0.pointee.ifa_dstaddr) } + } + + public func getDefaultGateway() -> String? { + var mib : [Int32] = [CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY]; + var l : Int = 0 + guard sysctl(&mib, UInt32(mib.count), nil, &l, nil, 0) == 0 else { return nil } + + var buf = [UInt8](repeating: 0, count: l) + guard sysctl(&mib, UInt32(mib.count), &buf, &l, nil, 0) == 0 else { return nil } + + return buf.withUnsafeBytes { buf in + var result : String? + + var sa_tab = [UnsafePointer?](repeating: nil, count: Int(RTAX_MAX)) + + var p = buf.baseAddress! + while p < buf.baseAddress! + l { + let rt = p.bindMemory(to: rt_msghdr.self, capacity: 1) + var sa = (UnsafeRawPointer(rt) + Int(MemoryLayout.stride)).bindMemory(to: sockaddr.self, capacity: 1) + + for i in 0..` parameter that +/// points to the found Wi-Fi interface. The argument is valid only for the +/// duration of the closure's execution. +/// - returns: The result of last call to `body` or `nil` if there was no `en0` +/// interface found. +func withWifiInterface(family: Int32, body: (UnsafePointer) throws -> R) rethrows -> R? { + var result : R? + + // Get list of all interfaces on the local machine: + var ifaddr : UnsafeMutablePointer? + guard getifaddrs(&ifaddr) == 0 else { return nil } + guard let firstAddr = ifaddr else { return nil } + + defer { freeifaddrs(ifaddr) } + + // For each interface ... + for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { + let interface = ifptr.pointee + + // Check for IPv4 or IPv6 interface: + let addrFamily = interface.ifa_addr.pointee.sa_family + if addrFamily == UInt8(family) { + + // Check interface name: + let name = String(cString: interface.ifa_name) + if name == "en0" { + + result = try body(ifptr) + } } - freeifaddrs(ifaddr) + } + + return result +} + +private func descriptionForAddress(_ addr : UnsafePointer) -> String{ + var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) + getnameinfo(addr, socklen_t(addr.pointee.sa_len), + &hostname, socklen_t(hostname.count), + nil, socklen_t(0), NI_NUMERICHOST) + return String(cString: hostname) +} - return address +private func roundup(_ a: Int) -> Int { + return a > 0 ? (1 + ((a - 1) | (MemoryLayout.stride - 1))) : MemoryLayout.stride } diff --git a/packages/network_info_plus/network_info_plus_macos/pubspec.yaml b/packages/network_info_plus/network_info_plus_macos/pubspec.yaml index 8feb320ac5..d697a49fd4 100644 --- a/packages/network_info_plus/network_info_plus_macos/pubspec.yaml +++ b/packages/network_info_plus/network_info_plus_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: network_info_plus_macos description: macOS implementation of the network_info_plus plugin. -version: 1.2.0 +version: 1.3.0 homepage: https://plus.fluttercommunity.dev/ repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/