aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix30
-rw-r--r--lib/ipv4.nix38
2 files changed, 68 insertions, 0 deletions
diff --git a/lib/default.nix b/lib/default.nix
new file mode 100644
index 0000000..036af97
--- /dev/null
+++ b/lib/default.nix
@@ -0,0 +1,30 @@
+nixpkgslib: let
+ lib = nixpkgslib // nlib;
+
+ nlib = with builtins;
+ with lib; {
+ # Generic power of number
+ pow = base: e:
+ if e == 0
+ then 1
+ else foldl (a: b: a * base) 1 (genList id (e - 1));
+ # Power of 2
+ pow2 = pow 2;
+
+ # Convert integer to list of bits
+ int2bits = len: e: reverseList (genList (x: bitAnd e (pow2 (x + 1)) > 0) len);
+ # Reverse operation for int2bits
+ bits2int = l: let
+ len = length l;
+ zf = a: b:
+ if a
+ then pow2 b
+ else 0;
+ in
+ foldl add 0 (zipListsWith zf l (genList (i: len - i) len));
+
+ # IPv4 utilities
+ ipv4 = import ./ipv4.nix lib;
+ };
+in
+ nlib
diff --git a/lib/ipv4.nix b/lib/ipv4.nix
new file mode 100644
index 0000000..c843cb6
--- /dev/null
+++ b/lib/ipv4.nix
@@ -0,0 +1,38 @@
+lib:
+with builtins;
+with lib; rec {
+ # Converts string representation of IPv4 address to 32 bits
+ ip2bits = ip: let
+ perBits = map (x: int2bits 8 (toInt x)) (splitString "." ip);
+ in
+ flatten perBits;
+ # Converts 32 bits to IPv4
+ bits2ip = bits: let
+ bts = i: toString (bits2int (sublist (i * 8) 8 bits));
+ in "${bts 0}.${bts 1}.${bts 2}.${bts 3}";
+
+ # Convert IPv4 to number
+ ip2int = ip: bits2int (ip2bits ip);
+ # Convert number to IPv4
+ int2ip = ip: bits2ip (int2bits 32 ip);
+
+ # Generate bits for netmas of gitven prefix length
+ netmaskBits = prefixLength: genList (x: x < prefixLength) 32;
+ # Convert IP network prefix length to network mask
+ prefix2netmask = prefixLength: bits2ip (netmaskBits prefixLength);
+ # Mask IP by network mask specified by given network prefix length
+ prefix2ip = ip: prefixLength: let
+ a = netmaskBits prefixLength;
+ b = ip2bits ip;
+ in
+ bits2ip (zipListsWith (a: b: a && b) a b);
+ # Last address in the range
+ prefix2broadcast = ip: prefixLength: let
+ a = netmaskBits prefixLength;
+ b = ip2bits ip;
+ in
+ bits2ip (zipListsWith (a: b: !a || b) a b);
+
+ # Offset address in network
+ ipAdd = ip: prefixLength: off: int2ip ((ip2int (prefix2ip ip prefixLength)) + off);
+}