Manipulate IP addresses in Nix-lang

I’m trying to write a NixOS module that is able to generate IP addresses and subnets within a defined IPv4 address space. I might give it a.b.c.d/N, and have it generate IP addresses corresponding to M bits’ worth of subnets and the remaining 32-N-M bits’ worth of host addresses.

For example, to clarify, given an address space of 192.168.0.0/23, and a 3-bit subnet allocation, I want a function that I could ask for host number 5 on subnet 3, and it would be able to tell me the IP address is 192.168.0.197 (or host 2 on subnet 4 would be 192.168.1.2 and so on).

Doing this in a language with bitwise operators would be pretty straightforward, but I’m unsure if there’s an obvious way to approach this in nix. Any hints?

I’m not sure if there’s a reusable library for this, but I wrote something like this which you can freely use

Example use:

nix-repl> :a import ./ip.nix (import <nixpkgs/lib>)
Added 4 variables.

nix-repl> :p parseSubnet "192.168.0.0/23"
{
  baseIp = [ 192 168 0 0 ];
  check = «lambda»;
  cidr = 23;
  mask = [ 255 255 254 0 ];
  range = { from = [ 192 168 0 0 ]; to = [ 192 168 1 255 ]; };
  subnet = "192.168.0.0/23";
}

nix-repl> (parseSubnet "192.168.0.0/23").check (parseIp "192.168.1.16")    
true

nix-repl> prettyIp (parseSubnet "192.168.0.0/23").range.to              
"192.168.1.255"
2 Likes

fwiw builtins.bitAnd (and bitOr/bitXor) do exist at least.

2 Likes

Thank you so much! This is incredibly helpful! I’ve been able to do exactly what I wanted.

Oh btw @djacu opened a PR to add such functionality to Nixpkgs’ lib directly! Might want to subscribe there :slight_smile: Add network library with IPv4 conversion functions. by djacu · Pull Request #258250 · NixOS/nixpkgs · GitHub