[lug] Calculating network addresses
    Ralf Mattes 
    rm at ns.aura.de
       
    Wed Mar  8 10:43:45 MST 2000
    
    
  
On Wed, 8 Mar 2000, Ian Hall-Beyer wrote:
> 
> Does anyone hava  quick and dirty alogorithm for extrapolating a network
> address from an IP and subnet mask, preferably one that can be implemented
> in bash?
> 
Here a simple solution if you are willing to use/install the perl
Net::Netmask module
cat - > net_address.pl
#!/usr/bin/perl
use Net::Netmask;
my ($ip, $mask) = @ARGV;
my $net = new Net::Netmask($ip, $mask)
   or die "The values you gave me make no sense to me :-)\n";
printf (qq{
        IP: %s
   Netmask: %s
   Network: %s
 Broadcast: %s
  Hostmask: %s
      Bits: %s
}, $ip, $net->mask, $net->base, $net->broadcast, $net->hostmask, $net->bits);
exit 0;
^D
You then can type things like 'net_address.pl 192.168.2.44 255.255.255.248' or
'10.0.0.32/28'. If you want to code it yourself, you basically just have to
bitwise-and the IP-address and the netmask:
cat - > handcoded.pl
#!/usr/bin/perl
# get program arguments
# (we don't support xx.xxx.xxx.xxx/nnn
# notation here)
my ($ip, $mask) = @ARGV;
# convert ip to number
map { ($ip_num *=  256) += $_ }
split (/\.|:/, $ip);
# do the same thing for the netmask
map { ($mask_num *=  256) += $_ }
split (/\.|:/, $mask);
# get network address
$net_num = $ip_num & $mask_num;
# convert the network address back to
# ip notation
print join(".", unpack ("CCCC", pack("NNNN", $net_num))), "\n";
# of course, you coul use pack() also for
# the convertion to numbers, but that wouldn't
# be half as fun ;-)
exit 0;
^D
And here for a bash version (contibuted by courtesy of my collegue
Tomas) that still has a small 'bug':
cat - >net_bash.sh
#!/bin/bash
ptobin()
{
  a=0
  for i in ${1//./ } ; do
    a=$((256*$a + $i))
  done;
  echo $a
}
bintoip()
{
  bin=$1
  ip=$(($bin % 256))
  for x in 0 1 2 ; do
    bin=$(($bin / 256))
    ip=$(($(($bin % 256 + 256)) % 256)).$ip; # get rid of negatives
  done
  echo $ip
}
get_network()
{
   bintoip $((`iptobin $1` & `iptobin $2`))
}
^D
You can run '. net_bash.sh' and then use get_network in your
bash. The bug: if one of your IP address parts is greater than
127 the convertion will go wrong--the number will be one to big
(thanks to signed integers in bash ...). We'll leave this as an
exercise ... 
 Ralf
*-------------------------------------------------------------------*
|                                     |                             |==
| Ralf Mattes                         | rm at schauinsland.com         |==
| Programming, Administration         | rm at ns.aura.de               |==
|                                     |                             |==
*-------------------------------------------------------------------*==
   ====================================================================
    
    
More information about the LUG
mailing list