I'm setting up a new segment in my network that will be managed by DHCP. I estimate that a /22 net, with just over one thousand addresses (1022 to be precise), gives me sufficient space for a dynamic pool and room to spare to allow mapping of known MACs to IP addresses in the future.
To start the ball rolling, I figured I'd just start with just about all of it assigned dynamically, with a bit left over. So, why not 1000 contiguous addresses in a dynamic pool, and 22 left over: one for the router and 21 to play with.
Ok, so the start address is easy, but how to find the end address quickly and make sure I don't make a mistake? NetAddr::IP to the rescue.
I actually did this as a one-liner, but this is a bit more readable.
Now to edit my dhcpd.conf file...
#! /usr/local/bin/perl -wl
my $first = shift || '172.17.220.1';
my $nr = shift || 1000;
my $end = NetAddr::IP->new($first)->numeric + $nr;
# prints 172.17.223.233
Good stuff, but as an experienced professional network engineer, I'd keep more than 22 addresses reserved. Lots of things need/work better with static addresses. Like shared printers, "special people" who need special holes in the firewall, manageable network equipment (how are you going to deploy 1000 ports without having several chassis?) etc.
We like to use /22's here, and typically reserve one entire class C from each range for static addresses. That is a bit of overkill, but I'd guess we have a minimum of 50 static/reserved addresses used in each of our /22 networks.
Cool. I haven't had a look at NetAddr::IP but I had to some similar calculation in one of the NMS programs where we don't want to use non-core modules (in this case to determine if an IP was in a specified network.) In case one is in a similar position of needing to do this calculation and not able to install the module, the code can boil down to:
my ($ip,$number ) = @_;
my $ip_i = ip_to_int($ip);
$ip_i += $number;
return inet_ntoa(pack('N', $ip_i));
my ( $ip ) = @_;
my $ip_n = inet_aton($ip);
my $ip_i = unpack('N', $ip_n);