ISINNET Function (or similar)

A

Antgoodlife

New to perl and this community...Hi all...

I've done some javascript / proxy pac work and I was curious if perl
has a built in (or if someone can point me to a module) that
determines if an IP is in a specific network? (Similar to proxy.pac
isinnet function)

For example :

#!/usr/bin/perl -w
# if ip 10.8.5.3 is in net 10.8.0.0 w/mask 255.255.0.0 return true
$ipaddr = "10.8.5.3"
print "$ipaddr is in the network!" if isinnet
($ipaddr,"10.8.0.0","255.255.0.0");

CIDR notation acceptance is a plus however not required for my
question.

Thank you in advance.
 
A

Antgoodlife

Thank you Klaus, I actually found that but was unable to get it
working.. thus headed to the forums... any idea what I can be doing
wrong?
On a Win32 box running Perl 5.10.0

Ran : ppm install HTTP-ProxyAutoConfig

Then :
C:\>type TestInNet.pl
#!/usr/bin/perl -w
# if ip 10.16.5.3 is in net 10.16.0.0 w/mask 255.255.0.0 return true
use HTTP::proxyAutoConfig;

$ipaddr = "10.16.5.3";

if isInNet($ipaddr,"10.16.0.0","255.255.0.0"); {
print "$ipaddr is in the network!";
}

C:\>TestInNet.pl
Useless use of a constant in void context at C:/Perl/site/lib/HTTP/
ProxyAutoConfig.pm line 367.
syntax error at C:\TestInNet.pl line 7, near "if isInNet"
Execution of C:\TestInNet.pl aborted due to compilation errors.
 
A

Antgoodlife

!! Sorry... modified for the post too quickly w/out proper syntax... I
mean I get "THIS error"
C:\>TestInNet.pl
Useless use of a constant in void context at C:/Perl/site/lib/HTTP/
ProxyAutoConfig.pm line 367.
Undefined subroutine &main::isInNet called at C:\TestInNet.pl line 7.

C:\>type TestInNet.pl
#!/usr/bin/perl -w
# if ip 10.16.5.3 is in net 10.16.0.0 w/mask 255.255.0.0 return true
use HTTP::proxyAutoConfig;
$ipaddr = "10.16.5.3";

if (isInNet($ipaddr,"10.16.0.0","255.255.0.0")) {
print "$ipaddr is in the network!";
}
 
M

Mirco Wahab

Antgoodlife said:
!! Sorry... modified for the post too quickly w/out proper syntax... I
mean I get "THIS error"
C:\>TestInNet.pl
Useless use of a constant in void context at C:/Perl/site/lib/HTTP/
ProxyAutoConfig.pm line 367.
Undefined subroutine &main::isInNet called at C:\TestInNet.pl line 7.

C:\>type TestInNet.pl
#!/usr/bin/perl -w
# if ip 10.16.5.3 is in net 10.16.0.0 w/mask 255.255.0.0 return true
use HTTP::proxyAutoConfig;
$ipaddr = "10.16.5.3";

if (isInNet($ipaddr,"10.16.0.0","255.255.0.0")) {
print "$ipaddr is in the network!";
}

I don't know what the module is supposed to do,
but wouldn't a simple comparison of fields against
the netmask:


...

my $net = '10.16.0.0';
my $mask = '255.255.0.0';

my $ip = "10.16.5.3";

if( isInNet($ip, $net, $mask) ) {
print 'true'
}
else {
print 'false'
}

sub isInNet {
my @ip = split /\./, $_[0]; # split ip into net fields
my @net = split /\./, $_[1]; # split network into fields
for( $_[2] =~ /255/g ) { # iterate over '255' mask fields
return 0 if shift(@ip) ne shift(@net) # bail if different
}
1
}

...



suffice? Of course, only for IPV4.

Regards

M.
 
J

John W. Krahn

Antgoodlife said:
New to perl and this community...Hi all...

I've done some javascript / proxy pac work and I was curious if perl
has a built in (or if someone can point me to a module) that
determines if an IP is in a specific network? (Similar to proxy.pac
isinnet function)

For example :

#!/usr/bin/perl -w
# if ip 10.8.5.3 is in net 10.8.0.0 w/mask 255.255.0.0 return true
$ipaddr = "10.8.5.3"
print "$ipaddr is in the network!" if isinnet
($ipaddr,"10.8.0.0","255.255.0.0");

CIDR notation acceptance is a plus however not required for my
question.

$ perl -le'
use Socket;
sub isinnet {
my ( $ip_addr, $net, $mask ) = map inet_aton( $_ ), @_;
return $net eq ( $ip_addr & $mask );
}

my $ipaddr = "10.8.5.3";
print "$ipaddr is in the network!" if isinnet( $ipaddr, "10.8.0.0",
"255.255.0.0" );
'
10.8.5.3 is in the network!




John
 
H

Hans Mulder

Mirco said:
Antgoodlife said:
!! Sorry... modified for the post too quickly w/out proper syntax... I
mean I get "THIS error"
C:\>TestInNet.pl
Useless use of a constant in void context at C:/Perl/site/lib/HTTP/
ProxyAutoConfig.pm line 367.
Undefined subroutine &main::isInNet called at C:\TestInNet.pl line 7.

C:\>type TestInNet.pl
#!/usr/bin/perl -w
# if ip 10.16.5.3 is in net 10.16.0.0 w/mask 255.255.0.0 return true
use HTTP::proxyAutoConfig;
$ipaddr = "10.16.5.3";

if (isInNet($ipaddr,"10.16.0.0","255.255.0.0")) {
print "$ipaddr is in the network!";
}

I don't know what the module is supposed to do,
but wouldn't a simple comparison of fields against
the netmask:


...

my $net = '10.16.0.0';
my $mask = '255.255.0.0';

my $ip = "10.16.5.3";

if( isInNet($ip, $net, $mask) ) {
print 'true'
}
else {
print 'false'
}

sub isInNet {
my @ip = split /\./, $_[0]; # split ip into net fields
my @net = split /\./, $_[1]; # split network into fields
for( $_[2] =~ /255/g ) { # iterate over '255' mask fields
return 0 if shift(@ip) ne shift(@net) # bail if different
}
1
}

...



suffice? Of course, only for IPV4.

That worked in the early days when the only numbers allowed in a netmask
were 0 and 255. In 1993 the rules changed. Today netmasks can also
contain 128, 192, 224, 240, 248, 252 and 254.

One way to check that a network contains an IP addres is to convert all
three numbers to binary. If the bitwise "and" of the IP addres and the
netmask is equal to the network number, then the network contains the
address:

sub binary { return pack("C4", split(/\./, shift)); }

$ipaddr = "10.16.5.3";
if ((binary($ipaddr) & binary("255.255.0.0")) eq binary("10.16.0.0")) {
print "$ipaddr is in the network!";
}

I can understand why the OP prefers to use a module.

Hope this helps,

-- HansM
 
M

Mart van de Wege

Hans Mulder said:
One way to check that a network contains an IP addres is to convert all
three numbers to binary. If the bitwise "and" of the IP addres and the
netmask is equal to the network number, then the network contains the
address:

sub binary { return pack("C4", split(/\./, shift)); }

$ipaddr = "10.16.5.3";
if ((binary($ipaddr) & binary("255.255.0.0")) eq binary("10.16.0.0")) {
print "$ipaddr is in the network!";
}

I can understand why the OP prefers to use a module.
Why?

Silly question maybe, but I feel using binary ANDs is the most logical
way to handle this. After all, that's *exactly* what the netmask is
for.

Mart
 
P

Peter J. Holzer

Mirco said:
Antgoodlife wrote:
sub isInNet {
my @ip = split /\./, $_[0]; # split ip into net fields
my @net = split /\./, $_[1]; # split network into fields
for( $_[2] =~ /255/g ) { # iterate over '255' mask fields
return 0 if shift(@ip) ne shift(@net) # bail if different
}
1
}

...



suffice? Of course, only for IPV4.

That worked in the early days when the only numbers allowed in a netmask
were 0 and 255. In 1993 the rules changed. Today netmasks can also
contain 128, 192, 224, 240, 248, 252 and 254.

The rules changed long before 1993. At the TU Vienna we've had a
(sub)netmask of 255.255.255.128 since at least 1988. You are probably
thinking about "classful routing". Until ca. 1993, the netmask was
implicit in the IP address - if the high byte was between 0 and 127, the
netmask was /8, if the high byte was between 128 and 191, it was /16 and
between 192 and 223 it was /24. Obviously this was only used for global
routing - a flat class A (with 16 million addresses) or class B (with
65536 addresses) network would have been impractical, so there was
always the possibility to split a "net" into "subnets", with arbitrary
subnet masks (our university split their class B network into 512
subnets). Later this was seen as wasteful, and classless routing was
introduced in the backbone, so that intermediate sized networks could be
assigned.

hp
 
A

Antgoodlife

Why?

Silly question maybe, but I feel using binary ANDs is the most logical
way to handle this. After all, that's *exactly* what the netmask is
for.

Mart

Well, it seems I've actually been able to get the posted module to
work as well as the example above ... Here's the script incase anyone
has more comments. Thank you all for your assistance. (And it works
with .128 and/or other various masks...)

$ipaddr = "10.16.127.3";
$network = "10.16.0.0";
$netmask = "255.255.128.0";

if (isinnet($ipaddr,$network,$netmask)) {
print "$ipaddr is in $network/$netmask";
}
else {
print "$ipaddr not in network";
}

sub isinnet {
return(1) if ((binary($_[0]) & binary($_[2])) eq binary($_[1]));
}
sub binary { return pack("C4", split(/\./, shift)); }
 
T

Ted Zlatanov

A> New to perl and this community...Hi all...
A> I've done some javascript / proxy pac work and I was curious if perl
A> has a built in (or if someone can point me to a module) that
A> determines if an IP is in a specific network? (Similar to proxy.pac
A> isinnet function)

A> For example :

A> #!/usr/bin/perl -w
A> # if ip 10.8.5.3 is in net 10.8.0.0 w/mask 255.255.0.0 return true
A> $ipaddr = "10.8.5.3"
A> print "$ipaddr is in the network!" if isinnet
A> ($ipaddr,"10.8.0.0","255.255.0.0");

A> CIDR notation acceptance is a plus however not required for my
A> question.

Net::Netmask should do what you need, and much more.

Ted
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top