feat: added support of local v6 IP address

This commit is contained in:
Serhiy Mytrovtsiy
2025-04-04 18:45:01 +02:00
parent 5ad92bf2fd
commit def91f6c96
5 changed files with 36 additions and 21 deletions

View File

@@ -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":

View File

@@ -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 {

View File

@@ -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
}
})
}

View File

@@ -229,16 +229,14 @@ internal class UsageReader: Reader<Network_Usage>, 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<Network_Usage>, CWEventDelegate {
}
}
private func getLocalIP(_ pointer: UnsafeMutablePointer<ifaddrs>) -> String? {
private func getLocalIP(_ pointer: UnsafeMutablePointer<ifaddrs>) {
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() {

View File

@@ -27,6 +27,8 @@ You can use a combination of any of the variables. There is only one limitation:
<li><b>$addr.publicV4</b>: <small>Public IPv4 address.</small></li>
<li><b>$addr.publicV6</b>: <small>Public IPv6 address.</small></li>
<li><b>$addr.private</b>: <small>Private/local IP address.</small></li>
<li><b>$addr.privateV4</b>: <small>Private/local IPv4 address.</small></li>
<li><b>$addr.privateV6</b>: <small>Private/local IPv6 address.</small></li>
<li><b>$interface.displayName</b>: <small>Network interface name.</small></li>
<li><b>$interface.BSDName</b>: <small>BSD name of the network interface.</small></li>
<li><b>$interface.address</b>: <small>MAC address of the network interface.</small></li>