{ lib, ... }: with lib; let joinString = concatStringsSep; pow = x: e: if (e == 0) then 1 else x * (pow x (e - 1)); generateNBits = n: let helper = n: c: if (c == n) then pow 2 c else (pow 2 c) + (helper n (c + 1)); in if (n <= 0) then throw "Can't generate 0 or fewer bits" else helper (n - 1) 0; rightPadBits = int: bits: bitOr int (generateNBits bits); reverseIpv4 = ip: joinString "." (reverseList (splitString "." ip)); intToBinaryList = int: let helper = int: cur: let curExp = pow 2 cur; in if (curExp > int) then [ ] else [ (if ((bitAnd curExp int) > 0) then 1 else 0) ] ++ (helper int (cur + 1)); in reverseList (helper int 0); leftShift = int: n: int * (pow 2 n); rightShift = int: n: int / (pow 2 n); in rec { ipv4ToInt = ip: let els = map toInt (reverseList (splitString "." ip)); in foldr (a: b: a + b) 0 (imap0 (i: el: (leftShift el (i * 8))) els); intToIpv4 = int: joinString "." (map (i: toString (bitAnd (rightShift int (i * 8)) 255)) [ 3 2 1 0 ]); maskFromV32Network = network: let fullMask = ipv4ToInt "255.255.255.255"; insignificantBits = 32 - (getNetworkMask network); in intToIpv4 (leftShift (rightShift fullMask insignificantBits) insignificantBits); networkMinIp = network: intToIpv4 (1 + (ipv4ToInt (getNetworkBase network))); networkMaxIp = network: intToIpv4 (rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network))); # To avoid broadcast IP... networkMaxButOneIp = network: intToIpv4 ((rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network))) - 1); ipv4OnNetwork = ip: network: let ip-int = ipv4ToInt ip; net-min = networkMinIp network; net-max = networkMaxIp network; in (ip-int >= networkMinIp) && (ip-int <= networkMaxIp); getNetworkMask = network: toInt (elemAt (splitString "/" network) 1); getNetworkBase = network: let ip = elemAt (splitString "/" network) 0; insignificantBits = 32 - (getNetworkMask network); in intToIpv4 (leftShift (rightShift (ipv4ToInt ip) insignificantBits) insignificantBits); }