aboutsummaryrefslogtreecommitdiffstats
path: root/Sources/WireGuardKitSwift/IPAddressRange.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Sources/WireGuardKitSwift/IPAddressRange.swift')
-rw-r--r--Sources/WireGuardKitSwift/IPAddressRange.swift67
1 files changed, 67 insertions, 0 deletions
diff --git a/Sources/WireGuardKitSwift/IPAddressRange.swift b/Sources/WireGuardKitSwift/IPAddressRange.swift
new file mode 100644
index 0000000..c65ff1d
--- /dev/null
+++ b/Sources/WireGuardKitSwift/IPAddressRange.swift
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
+
+import Foundation
+import Network
+
+public struct IPAddressRange {
+ public let address: IPAddress
+ public let networkPrefixLength: UInt8
+
+ init(address: IPAddress, networkPrefixLength: UInt8) {
+ self.address = address
+ self.networkPrefixLength = networkPrefixLength
+ }
+}
+
+extension IPAddressRange: Equatable {
+ public static func == (lhs: IPAddressRange, rhs: IPAddressRange) -> Bool {
+ return lhs.address.rawValue == rhs.address.rawValue && lhs.networkPrefixLength == rhs.networkPrefixLength
+ }
+}
+
+extension IPAddressRange: Hashable {
+ public func hash(into hasher: inout Hasher) {
+ hasher.combine(address.rawValue)
+ hasher.combine(networkPrefixLength)
+ }
+}
+
+extension IPAddressRange {
+ public var stringRepresentation: String {
+ return "\(address)/\(networkPrefixLength)"
+ }
+
+ public init?(from string: String) {
+ guard let parsed = IPAddressRange.parseAddressString(string) else { return nil }
+ address = parsed.0
+ networkPrefixLength = parsed.1
+ }
+
+ private static func parseAddressString(_ string: String) -> (IPAddress, UInt8)? {
+ let endOfIPAddress = string.lastIndex(of: "/") ?? string.endIndex
+ let addressString = String(string[string.startIndex ..< endOfIPAddress])
+ let address: IPAddress
+ if let addr = IPv4Address(addressString) {
+ address = addr
+ } else if let addr = IPv6Address(addressString) {
+ address = addr
+ } else {
+ return nil
+ }
+
+ let maxNetworkPrefixLength: UInt8 = address is IPv4Address ? 32 : 128
+ var networkPrefixLength: UInt8
+ if endOfIPAddress < string.endIndex { // "/" was located
+ let indexOfNetworkPrefixLength = string.index(after: endOfIPAddress)
+ guard indexOfNetworkPrefixLength < string.endIndex else { return nil }
+ let networkPrefixLengthSubstring = string[indexOfNetworkPrefixLength ..< string.endIndex]
+ guard let npl = UInt8(networkPrefixLengthSubstring) else { return nil }
+ networkPrefixLength = min(npl, maxNetworkPrefixLength)
+ } else {
+ networkPrefixLength = maxNetworkPrefixLength
+ }
+
+ return (address, networkPrefixLength)
+ }
+}