src/Utils/IPMask.swift
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
}
}
}