81 lines
2.2 KiB
Nix
81 lines
2.2 KiB
Nix
|
{ 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);
|
||
|
}
|