From def91f6c962ee545cb9f26b3d4456a4f02891087 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Fri, 4 Apr 2025 18:45:01 +0200 Subject: [PATCH] feat: added support of local v6 IP address --- Modules/Net/main.swift | 8 +++++--- Modules/Net/notifications.swift | 13 +++++++++---- Modules/Net/portal.swift | 10 ++++++++-- Modules/Net/readers.swift | 24 ++++++++++++------------ Modules/Net/settings.swift | 2 ++ 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/Modules/Net/main.swift b/Modules/Net/main.swift index 5449a9b3..cacb6ef6 100644 --- a/Modules/Net/main.swift +++ b/Modules/Net/main.swift @@ -72,7 +72,7 @@ public struct Network_Usage: Codable { var bandwidth: Bandwidth = Bandwidth() var total: Bandwidth = Bandwidth() - var laddr: String? = nil // local ip + var laddr: Network_addr = Network_addr() // local ip var raddr: Network_addr = Network_addr() // remote ip var interface: Network_interface? = nil @@ -84,7 +84,7 @@ public struct Network_Usage: Codable { mutating func reset() { self.bandwidth = Bandwidth() - self.laddr = nil + self.laddr = Network_addr() self.raddr = Network_addr() self.interface = nil @@ -254,7 +254,9 @@ public class Network: Module { case "public": replacement = value.raddr.v4 ?? value.raddr.v6 ?? "-" case "publicV4": replacement = value.raddr.v4 ?? "-" case "publicV6": replacement = value.raddr.v6 ?? "-" - case "private": replacement = value.laddr ?? "-" + case "private": replacement = value.laddr.v4 ?? value.laddr.v6 ?? "-" + case "privateV4": replacement = value.laddr.v4 ?? "-" + case "privateV6": replacement = value.laddr.v6 ?? "-" default: return } case "$interface": diff --git a/Modules/Net/notifications.swift b/Modules/Net/notifications.swift index d61ce83f..2612f6fd 100644 --- a/Modules/Net/notifications.swift +++ b/Modules/Net/notifications.swift @@ -87,8 +87,13 @@ class Notifications: NotificationsWrapper { self.interfaceInit = true } if !self.localIPInit { - self.localIP = value.laddr - self.localIPInit = true + if let v4 = value.raddr.v4 { + self.localIP = v4 + self.localIPInit = true + } else if let v6 = value.raddr.v6 { + self.localIP = v6 + self.localIPInit = true + } } if !self.publicIPInit { if let v4 = value.raddr.v4 { @@ -112,10 +117,10 @@ class Notifications: NotificationsWrapper { } if self.localIPState { - if value.laddr != self.localIP { + if value.laddr.v4 ?? value.laddr.v6 != self.localIP { self.newNotification(id: self.localID, title: localizedString("Local IP changed"), subtitle: nil) } - self.localIP = value.laddr + self.localIP = value.laddr.v4 ?? value.laddr.v6 } if self.publicIPState { diff --git a/Modules/Net/portal.swift b/Modules/Net/portal.swift index 520b6399..0069f321 100644 --- a/Modules/Net/portal.swift +++ b/Modules/Net/portal.swift @@ -135,8 +135,14 @@ public class Portal: PortalWrapper { } } - if self.localIPField?.stringValue != value.laddr { - self.localIPField?.stringValue = value.laddr ?? localizedString("Unknown") + var privateIP = localizedString("Unknown") + if let v4 = value.laddr.v4, !v4.isEmpty { + privateIP = v4 + } else if let v6 = value.laddr.v6, !v6.isEmpty { + privateIP = v6 + } + if self.localIPField?.stringValue != privateIP { + self.localIPField?.stringValue = privateIP } }) } diff --git a/Modules/Net/readers.swift b/Modules/Net/readers.swift index 802690f7..913e4a51 100644 --- a/Modules/Net/readers.swift +++ b/Modules/Net/readers.swift @@ -229,16 +229,14 @@ internal class UsageReader: Reader, CWEventDelegate { var pointer = interfaceAddresses while pointer != nil { defer { pointer = pointer?.pointee.ifa_next } + guard let pointer = pointer else { break } - if String(cString: pointer!.pointee.ifa_name) != self.interfaceID { + if String(cString: pointer.pointee.ifa_name) != self.interfaceID { continue } + self.getLocalIP(pointer) - if let ip = getLocalIP(pointer!), self.usage.laddr != ip { - self.usage.laddr = ip - } - - if let info = getBytesInfo(pointer!) { + if let info = self.getBytesInfo(pointer) { totalUpload += info.upload totalDownload += info.download } @@ -402,17 +400,19 @@ internal class UsageReader: Reader, CWEventDelegate { } } - private func getLocalIP(_ pointer: UnsafeMutablePointer) -> String? { + private func getLocalIP(_ pointer: UnsafeMutablePointer) { var addr = pointer.pointee.ifa_addr.pointee - - guard addr.sa_family == UInt8(AF_INET) else { - return nil - } + guard addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) else { return} var ip = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(&addr, socklen_t(addr.sa_len), &ip, socklen_t(ip.count), nil, socklen_t(0), NI_NUMERICHOST) - return String(cString: ip) + let ipStr = String(cString: ip) + if addr.sa_family == UInt8(AF_INET) && !ipStr.isEmpty { + self.usage.laddr.v4 = ipStr + } else if addr.sa_family == UInt8(AF_INET6) && !ipStr.isEmpty { + self.usage.laddr.v6 = ipStr + } } private func getPublicIP() { diff --git a/Modules/Net/settings.swift b/Modules/Net/settings.swift index 24829e1e..34d055db 100644 --- a/Modules/Net/settings.swift +++ b/Modules/Net/settings.swift @@ -27,6 +27,8 @@ You can use a combination of any of the variables. There is only one limitation:
  • $addr.publicV4: Public IPv4 address.
  • $addr.publicV6: Public IPv6 address.
  • $addr.private: Private/local IP address.
  • +
  • $addr.privateV4: Private/local IPv4 address.
  • +
  • $addr.privateV6: Private/local IPv6 address.
  • $interface.displayName: Network interface name.
  • $interface.BSDName: BSD name of the network interface.
  • $interface.address: MAC address of the network interface.