aboutsummaryrefslogtreecommitdiffstats
path: root/Sources/WireGuardKit/IPAddressRange.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Sources/WireGuardKit/IPAddressRange.swift')
-rw-r--r--Sources/WireGuardKit/IPAddressRange.swift48
1 files changed, 48 insertions, 0 deletions
diff --git a/Sources/WireGuardKit/IPAddressRange.swift b/Sources/WireGuardKit/IPAddressRange.swift
index 67c3955..ecb888e 100644
--- a/Sources/WireGuardKit/IPAddressRange.swift
+++ b/Sources/WireGuardKit/IPAddressRange.swift
@@ -64,4 +64,52 @@ extension IPAddressRange {
return (address, networkPrefixLength)
}
+
+ public func subnetMask() -> IPAddress {
+ if address is IPv4Address {
+ let mask = networkPrefixLength > 0 ? ~UInt32(0) << (32 - networkPrefixLength) : UInt32(0)
+ let bytes = Data([
+ UInt8(truncatingIfNeeded: mask >> 24),
+ UInt8(truncatingIfNeeded: mask >> 16),
+ UInt8(truncatingIfNeeded: mask >> 8),
+ UInt8(truncatingIfNeeded: mask >> 0)
+ ])
+ return IPv4Address(bytes)!
+ }
+ if address is IPv6Address {
+ var bytes = Data(repeating: 0, count: 16)
+ for i in 0..<Int(networkPrefixLength/8) {
+ bytes[i] = 0xff
+ }
+ let nibble = networkPrefixLength % 32
+ if nibble != 0 {
+ let mask = ~UInt32(0) << (32 - nibble)
+ let i = Int(networkPrefixLength / 32 * 4)
+ bytes[i + 0] = UInt8(truncatingIfNeeded: mask >> 24)
+ bytes[i + 1] = UInt8(truncatingIfNeeded: mask >> 16)
+ bytes[i + 2] = UInt8(truncatingIfNeeded: mask >> 8)
+ bytes[i + 3] = UInt8(truncatingIfNeeded: mask >> 0)
+ }
+ return IPv6Address(bytes)!
+ }
+ fatalError()
+ }
+
+ public func maskedAddress() -> IPAddress {
+ let subnet = subnetMask().rawValue
+ var masked = Data(address.rawValue)
+ if subnet.count != masked.count {
+ fatalError()
+ }
+ for i in 0..<subnet.count {
+ masked[i] &= subnet[i]
+ }
+ if subnet.count == 4 {
+ return IPv4Address(masked)!
+ }
+ if subnet.count == 16 {
+ return IPv6Address(masked)!
+ }
+ fatalError()
+ }
}