Tag Archives: subnet

Check if an IP is in a subnet

At some point I counted my DROP rules in my firewall and the result was kinda frightening. A lot of subnets and even more IPs...
What was really annoying was that there were a lot of IP addresses which belonged to an already blocked subnet, so I needed a script to check this for me.

It has to be a script to do this already out there in the wild. Also a machine is faster than a human. Having this in mind, why should I reinvent the wheel? So after searching a little bit on web, I found this nice perl script.

[codesyntax lang="perl"]

#!/usr/bin/perl

use strict;

use Socket qw( inet_aton );

sub ip2long($);
sub in_subnet($$);

my $ip = $ARGV[0];
my $subnet = $ARGV[1];

if( in_subnet( $ip, $subnet ) )
{
	print "It's in the subnet\n";
}
else
{
	print "It's NOT in the subnet\n";
}

sub ip2long($)
{
	return( unpack( 'N', inet_aton(shift) ) );
}

sub in_subnet($$)
{
	my $ip = shift;
	my $subnet = shift;

	my $ip_long = ip2long( $ip );

	if( $subnet=~m|(^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$| )
	{
		my $subnet = ip2long( $1 );
		my $mask = ip2long( $2 );

		if( ($ip_long & $mask)==$subnet )
		{
			return( 1 );
		}
	}
	elsif( $subnet=~m|(^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/(\d{1,2})$| )
	{
		my $subnet = ip2long( $1 );
		my $bits = $2;
		my $mask = -1<<(32-$bits);

		$subnet&= $mask;

		if( ($ip_long & $mask)==$subnet )
		{
			return( 1 );
		}
	}
	elsif( $subnet=~m|(^\d{1,3}\.\d{1,3}\.\d{1,3}\.)(\d{1,3})-(\d{1,3})$| )
	{
		my $start_ip = ip2long( $1.$2 );
		my $end_ip = ip2long( $1.$3 );

		if( $start_ip<=$ip_long and $end_ip>=$ip_long )
		{
			return( 1 );
		}
	}
	elsif( $subnet=~m|^[\d\*]{1,3}\.[\d\*]{1,3}\.[\d\*]{1,3}\.[\d\*]{1,3}$| )
	{
		my $search_string = $subnet;

		$search_string=~s/\./\\\./g;
		$search_string=~s/\*/\.\*/g;

		if( $ip=~/^$search_string$/ )
		{
			return( 1 );
		}
	}

	return( 0 );
}

[/codesyntax]

Source: http://www.mikealeonetti.com/wiki/index.php?title=Check_if_an_IP_is_in_a_subnet_in_Perl