diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-01-01 18:26:49 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-01-01 18:28:14 +0100 |
commit | 7b5b564a6ee3d3be90cdb56472cd404e8a0eaa18 (patch) | |
tree | 40bcbb9a1877a2bcf33d44187530f4c5ac393293 /Sources/WireGuardKit/IPAddressRange.swift | |
parent | Kit: Go: mod bump (diff) | |
download | wireguard-apple-7b5b564a6ee3d3be90cdb56472cd404e8a0eaa18.tar.xz wireguard-apple-7b5b564a6ee3d3be90cdb56472cd404e8a0eaa18.zip |
Kit: netcfg: add explicit IP mask routes
macOS will use the wrong source address unless we add explicit routes
that mention the self-pointing gateway. Actually, it won't add any
implicit routes on its own, so in order to route the masks of the
addresses, we have to add our own routes explicitly.
However, this still doesn't fix the problem while inside of the network
extension, even though it works outside it.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'Sources/WireGuardKit/IPAddressRange.swift')
-rw-r--r-- | Sources/WireGuardKit/IPAddressRange.swift | 48 |
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() + } } |