aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Sources/WireGuardKit/IPAddressRange.swift48
-rw-r--r--Sources/WireGuardKit/PacketTunnelSettingsGenerator.swift37
2 files changed, 67 insertions, 18 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()
+ }
}
diff --git a/Sources/WireGuardKit/PacketTunnelSettingsGenerator.swift b/Sources/WireGuardKit/PacketTunnelSettingsGenerator.swift
index 2d8cda1..7baa7cc 100644
--- a/Sources/WireGuardKit/PacketTunnelSettingsGenerator.swift
+++ b/Sources/WireGuardKit/PacketTunnelSettingsGenerator.swift
@@ -113,38 +113,26 @@ class PacketTunnelSettingsGenerator {
networkSettings.mtu = NSNumber(value: mtu)
}
- let (ipv4Routes, ipv6Routes) = routes()
+ let (ipv4Addresses, ipv6Addresses) = addresses()
let (ipv4IncludedRoutes, ipv6IncludedRoutes) = includedRoutes()
- let ipv4Settings = NEIPv4Settings(addresses: ipv4Routes.map { $0.destinationAddress }, subnetMasks: ipv4Routes.map { $0.destinationSubnetMask })
+ let ipv4Settings = NEIPv4Settings(addresses: ipv4Addresses.map { $0.destinationAddress }, subnetMasks: ipv4Addresses.map { $0.destinationSubnetMask })
ipv4Settings.includedRoutes = ipv4IncludedRoutes
networkSettings.ipv4Settings = ipv4Settings
- let ipv6Settings = NEIPv6Settings(addresses: ipv6Routes.map { $0.destinationAddress }, networkPrefixLengths: ipv6Routes.map { $0.destinationNetworkPrefixLength })
+ let ipv6Settings = NEIPv6Settings(addresses: ipv6Addresses.map { $0.destinationAddress }, networkPrefixLengths: ipv6Addresses.map { $0.destinationNetworkPrefixLength })
ipv6Settings.includedRoutes = ipv6IncludedRoutes
networkSettings.ipv6Settings = ipv6Settings
return networkSettings
}
- private func ipv4SubnetMaskString(of addressRange: IPAddressRange) -> String {
- let length: UInt8 = addressRange.networkPrefixLength
- assert(length <= 32)
- var octets: [UInt8] = [0, 0, 0, 0]
- let subnetMask: UInt32 = length > 0 ? ~UInt32(0) << (32 - length) : UInt32(0)
- octets[0] = UInt8(truncatingIfNeeded: subnetMask >> 24)
- octets[1] = UInt8(truncatingIfNeeded: subnetMask >> 16)
- octets[2] = UInt8(truncatingIfNeeded: subnetMask >> 8)
- octets[3] = UInt8(truncatingIfNeeded: subnetMask)
- return octets.map { String($0) }.joined(separator: ".")
- }
-
- private func routes() -> ([NEIPv4Route], [NEIPv6Route]) {
+ private func addresses() -> ([NEIPv4Route], [NEIPv6Route]) {
var ipv4Routes = [NEIPv4Route]()
var ipv6Routes = [NEIPv6Route]()
for addressRange in tunnelConfiguration.interface.addresses {
if addressRange.address is IPv4Address {
- ipv4Routes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: ipv4SubnetMaskString(of: addressRange)))
+ ipv4Routes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: "\(addressRange.subnetMask())"))
} else if addressRange.address is IPv6Address {
/* Big fat ugly hack for broken iOS networking stack: the smallest prefix that will have
* any effect on iOS is a /120, so we clamp everything above to /120. This is potentially
@@ -160,10 +148,23 @@ class PacketTunnelSettingsGenerator {
private func includedRoutes() -> ([NEIPv4Route], [NEIPv6Route]) {
var ipv4IncludedRoutes = [NEIPv4Route]()
var ipv6IncludedRoutes = [NEIPv6Route]()
+
+ for addressRange in tunnelConfiguration.interface.addresses {
+ if addressRange.address is IPv4Address {
+ let route = NEIPv4Route(destinationAddress: "\(addressRange.maskedAddress())", subnetMask: "\(addressRange.subnetMask())")
+ route.gatewayAddress = "\(addressRange.address)"
+ ipv4IncludedRoutes.append(route)
+ } else if addressRange.address is IPv6Address {
+ let route = NEIPv6Route(destinationAddress: "\(addressRange.maskedAddress())", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength))
+ route.gatewayAddress = "\(addressRange.address)"
+ ipv6IncludedRoutes.append(route)
+ }
+ }
+
for peer in tunnelConfiguration.peers {
for addressRange in peer.allowedIPs {
if addressRange.address is IPv4Address {
- ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: ipv4SubnetMaskString(of: addressRange)))
+ ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: "\(addressRange.subnetMask())"))
} else if addressRange.address is IPv6Address {
ipv6IncludedRoutes.append(NEIPv6Route(destinationAddress: "\(addressRange.address)", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength)))
}