51 lines
1.5 KiB
Swift
Executable File
51 lines
1.5 KiB
Swift
Executable File
import Foundation
|
|
|
|
public enum IPMask {
|
|
case IPv4(UInt32), IPv6(UInt128)
|
|
|
|
func mask(baseIP: IPAddress) -> (IPAddress, IPAddress)? {
|
|
switch (self, baseIP.address) {
|
|
case (.IPv4(var m), .IPv4(let addr)):
|
|
guard m <= 32 else {
|
|
return nil
|
|
}
|
|
|
|
if m == 32 {
|
|
return (baseIP, baseIP)
|
|
}
|
|
|
|
if m == 0 {
|
|
return (IPAddress(ipv4InNetworkOrder: 0), IPAddress(ipv4InNetworkOrder: UInt32.max))
|
|
}
|
|
|
|
m = 32 - m
|
|
let base = (addr.s_addr.byteSwapped >> m) << m
|
|
let end = base | ~((UInt32.max >> m) << m)
|
|
let b = IPAddress(ipv4InNetworkOrder: base.byteSwapped)
|
|
let e = IPAddress(ipv4InNetworkOrder: end.byteSwapped)
|
|
return (b, e)
|
|
case (.IPv6(var m), .IPv6):
|
|
guard m <= 128 else {
|
|
return nil
|
|
}
|
|
|
|
if m == 128 {
|
|
return (baseIP, baseIP)
|
|
}
|
|
|
|
if m == 0 {
|
|
return (IPAddress(ipv6InNetworkOrder: 0), IPAddress(ipv6InNetworkOrder: UInt128.max))
|
|
}
|
|
|
|
m = 128 - m
|
|
let base = (baseIP.address.asUInt128.byteSwapped >> m) << m
|
|
let end = base | ~((UInt128.max >> m) << m)
|
|
let b = IPAddress(ipv6InNetworkOrder: base.byteSwapped)
|
|
let e = IPAddress(ipv6InNetworkOrder: end.byteSwapped)
|
|
return (b, e)
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
}
|