PATH が通っている /usr/local/bin に入れて使用しています。
IPアドレスとサブネットマスクを入力すると、ネットワークアドレスとブロードキャストアドレスを表示します。この2つのアドレスの間が、そのネットワークで端末に割り振れるIPアドレスです。
実行例
$ ipaddr --help
ipaddr: `--help': unknown argument
usage: ipaddr # interactive mode
ipaddr [ipaddress/mask]
ipaddr [ipaddress] [mask]
$
$ ipaddr 192.168.174.128/25
[ 192.168.174.128/25 ]
LABEL DECIMAL BINARY HEX
-------------- --------------- ----------------------------------- ----------
IP_ADDRESS 192.168.174.128 11000000-10101000-10101110-10000000 0xC0A8AE80
SUBNET_MASK 255.255.255.128 11111111-11111111-11111111-10000000 0xFFFFFF80
NETWORK_ADDR 192.168.174.128 11000000-10101000-10101110-10000000 0xC0A8AE80
BROADCAST_ADDR 192.168.174.255 11000000-10101000-10101110-11111111 0xC0A8AEFF
$
$ ipaddr
IP address ?: 192.168.174.128
Subnet mask ?: 26
[ 192.168.174.128/26 ]
LABEL DECIMAL BINARY HEX
-------------- --------------- ----------------------------------- ----------
IP_ADDRESS 192.168.174.128 11000000-10101000-10101110-10000000 0xC0A8AE80
SUBNET_MASK 255.255.255.192 11111111-11111111-11111111-11000000 0xFFFFFFC0
NETWORK_ADDR 192.168.174.128 11000000-10101000-10101110-10000000 0xC0A8AE80
BROADCAST_ADDR 192.168.174.191 11000000-10101000-10101110-10111111 0xC0A8AEBF
$
$ ipaddr 192.168.174.128/255.255.255.0
[ 192.168.174.0/24 ]
LABEL DECIMAL BINARY HEX
-------------- --------------- ----------------------------------- ----------
IP_ADDRESS 192.168.174.128 11000000-10101000-10101110-10000000 0xC0A8AE80
SUBNET_MASK 255.255.255.0 11111111-11111111-11111111-00000000 0xFFFFFF00
NETWORK_ADDR 192.168.174.0 11000000-10101000-10101110-00000000 0xC0A8AE00
BROADCAST_ADDR 192.168.174.255 11000000-10101000-10101110-11111111 0xC0A8AEFF
$
スクリプト
[ipaddr]
#!/usr/bin/perl -w
################################################################################
## IPADDR -- 引数として与えられたIPアドレスから、使用可能なアドレス空間を計算する
## - Only for personal use !
## - 2006/02/12(Sun) Create tomyama
################################################################################use strict ;
use File::Basename ;exit (&pl_main (@ARGV)) ;
##########
## スクリプトのエントリポイント
sub pl_main (@) {
## 初期化処理
&initialize (@_) ;## IPアドレスが指定されていなければ、入力を求める
if (! defined ($main::ipaddr)) {
print ("IP address ?: ") ;
my $myparam = readline (*STDIN) ; chomp ($myparam) ;
&chk_ipaddr ($myparam) ;
}## MASK値が指定されていなければ、入力を求める
if (! defined ($main::subnetmask)) {
print ("Subnet mask ?: ") ;
my $myparam = readline (*STDIN) ; chomp ($myparam) ;
&chk_subnetmask ($myparam) ;
}## 出力する
&print_cidr ($main::ipaddr, $main::subnetmask) ;
printf("%14s %-15s %-35s %-10s\n", 'LABEL',
'DECIMAL',
'BINARY',
'HEX') ;
printf("%14s %-15s %-35s %-10s\n", '-' x 14,
'-' x 15,
'-' x 35,
'-' x 10) ;
&print_addr ('IP_ADDRESS', $main::ipaddr) ;
&print_addr ('SUBNET_MASK', $main::subnetmask) ;
&print_addr ('NETWORK_ADDR', $main::ipaddr & $main::subnetmask) ;
&print_addr ('BROADCAST_ADDR', $main::ipaddr | ~$main::subnetmask) ;return 0 ;
}##########
## 初期化処理
sub initialize (@) {
my @val = @_ ;## グローバルな変数
$main::appname = basename ($0) ;## 引数解析
while (my $myparam = shift (@val)) {
if ($myparam =~ m!^(\d+(?:\.\d+){3})(/.*)?$!o) {
if (defined ($2)) {
unshift (@val, substr ($2, 1)) ;
}if (! defined ($main::ipaddr)) {
&chk_ipaddr ($1) ;
} else {
&chk_subnetmask ($1) ;
}
} elsif (defined ($main::ipaddr) &&
! defined ($main::subnetmask) &&
$myparam =~ m/^(?:0x)?([\da-fA-F]{8})$/o) {
&chk_subnetmask ($myparam) ;
} elsif (defined ($main::ipaddr) &&
! defined ($main::subnetmask) &&
$myparam =~ m/^(\d+)$/o) {
&chk_subnetmask ($myparam) ;
} else {
warn ("$main::appname: `$myparam': unknown argument\n") ;
&p_usage () ; exit (1) ;
}
}return 0 ;
}##########
## 引数チェック
sub chk_ipaddr ($) {
my $myarg = shift (@_) ;$myarg =~ s/^\s+//o ;
$myarg =~ s/\s+$//o ;if ($myarg =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/o) {
if ($1<0 || 255<$1) {
warn ("$main::appname: `$1': out of range\n") ;
&p_usage () ; exit (1) ; }
if ($2<0 || 255<$2) {
warn ("$main::appname: `$2': out of range\n") ;
&p_usage () ; exit (1) ; }
if ($3<0 || 255<$3) {
warn ("$main::appname: `$3': out of range\n") ;
&p_usage () ; exit (1) ; }
if ($4<0 || 255<$4) {
warn ("$main::appname: `$4': out of range\n") ;
&p_usage () ; exit (1) ; }
$main::ipaddr = pack ("CCCC", $1, $2, $3, $4) ;
} else {
warn ("$main::appname: `$myarg': mistake ip-address format\n") ;
&p_usage () ; exit (1) ;
}return 0 ;
}##########
## 引数チェック
sub chk_subnetmask ($) {
my $myarg = shift (@_) ;$myarg =~ s/^\s+//o ;
$myarg =~ s/\s+$//o ;if ($myarg =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/o) {
if (! ($1==0 || $1==128 || $1==192 || $1==224 || $1==240 ||
$1==248 || $1==252 || $1==254 || $1==255)) {
warn ("$main::appname: `$1': out of range\n") ;
&p_usage () ; exit (1) ; }
if (! ($1==255 &&
( $2==128 || $2==192 || $2==224 || $2==240 ||
$2==248 || $2==252 || $2==254 || $2==255
) || (
$2==0
))) {
warn ("$main::appname: `$2': out of range\n") ;
&p_usage () ; exit (1) ; }
if (! ($2==255 &&
( $3==128 || $3==192 || $3==224 || $3==240 ||
$3==248 || $3==252 || $3==254 || $3==255
) || (
$3==0
))) {
warn ("$main::appname: `$3': out of range\n") ;
&p_usage () ; exit (1) ; }
if (! ($3==255 &&
( $4==128 || $4==192 || $4==224 || $4==240 ||
$4==248 || $4==252 || $4==254 || $4==255
) || (
$4==0
))) {
warn ("$main::appname: `$4': out of range\n") ;
&p_usage () ; exit (1) ; }
$main::subnetmask = pack ("CCCC", $1, $2, $3, $4) ;
} elsif ($myarg =~ m/^(?:0x)?([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/o) {
my @myhex ;
$myhex[0] = uc ($1) ;
$myhex[1] = uc ($2) ;
$myhex[2] = uc ($3) ;
$myhex[3] = uc ($4) ;
if (! ("$myhex[0]"eq'00'||
"$myhex[0]"eq'80'||"$myhex[0]"eq'C0'||
"$myhex[0]"eq'E0'||"$myhex[0]"eq'F0'||
"$myhex[0]"eq'F8'||"$myhex[0]"eq'FC'||
"$myhex[0]"eq'FE'||"$myhex[0]"eq'FF'
)) {
warn ("$main::appname: `$1': out of range\n") ;
&p_usage () ; exit (1) ; }
if (! ("$myhex[0]"eq'FF' &&
( "$myhex[1]"eq'80'||"$myhex[1]"eq'C0'||
"$myhex[1]"eq'E0'||"$myhex[1]"eq'F0'||
"$myhex[1]"eq'F8'||"$myhex[1]"eq'FC'||
"$myhex[1]"eq'FE'||"$myhex[1]"eq'FF'
) || (
"$myhex[1]"eq'00'
))) {
warn ("$main::appname: `$2': out of range\n") ;
&p_usage () ; exit (1) ; }
if (! ("$myhex[1]"eq'FF' &&
( "$myhex[2]"eq'80'||"$myhex[2]"eq'C0'||
"$myhex[2]"eq'E0'||"$myhex[2]"eq'F0'||
"$myhex[2]"eq'F8'||"$myhex[2]"eq'FC'||
"$myhex[2]"eq'FE'||"$myhex[2]"eq'FF'
) || (
"$myhex[2]"eq'00'
))) {
warn ("$main::appname: `$3': out of range\n") ;
&p_usage () ; exit (1) ; }
if (! ("$myhex[2]"eq'FF' &&
( "$myhex[3]"eq'80'||"$myhex[3]"eq'C0'||
"$myhex[3]"eq'E0'||"$myhex[3]"eq'F0'||
"$myhex[3]"eq'F8'||"$myhex[3]"eq'FC'||
"$myhex[3]"eq'FE'||"$myhex[3]"eq'FF'
) || (
"$myhex[3]"eq'00'
))) {
warn ("$main::appname: `$4': out of range\n") ;
&p_usage () ; exit (1) ; }
$main::subnetmask = pack ("CCCC",
hex ($myhex[0]), hex ($myhex[1]),
hex ($myhex[2]), hex ($myhex[3])) ;
} elsif ($myarg =~ m/^(\d+)$/o) {
if ($1<0 || 32<$1) {
warn ("$main::appname: `$1': out of range\n") ;
&p_usage () ; exit (1) ; }my $mystrbin = sprintf ("%32s", '1' x $1 . '0' x (32-$1)) ;
my @myarray ;
for (my $i=0; $i<4; $i++) {
$myarray[$i] = &bin2dec (substr ($mystrbin, ($i*8), 8)) ;
}
$main::subnetmask = pack ("CCCC", @myarray) ;
} else {
warn ("$main::appname: `$myarg': mistake subnet-mask format\n") ;
&p_usage () ; exit (1) ;
}return 0 ;
}##########
## 書式表示
sub p_usage {
warn ( "usage: ${main::appname} # interactive mode\n",
" ${main::appname} [ipaddress/mask]\n",
" ${main::appname} [ipaddress] [mask]\n") ;return 0 ;
}##########
##
sub print_cidr ($$) {
my $myipaddr = shift (@_) ;
my $mysubnet = shift (@_) ;my @bin ;
foreach my $i (unpack ("CCCC", $mysubnet)) {
push (@bin, &dec2bin ($i)) ;
}
my $mybinary = join ('', @bin) ;
$mybinary =~ s/[^1]//go ;
my $mymask = length ($mybinary) ;my @myarray = unpack ("CCCC", $myipaddr & $mysubnet) ;
my $mynet = join ('.', @myarray) ;print ("[ $mynet/$mymask ]\n") ;
}##########
##
sub print_addr ($$) {
my $mytitle = shift (@_) ;
my $myaddr = shift (@_) ;my @octb ;
my @octd ;
my @octh ;
foreach my $i (unpack ("CCCC", $myaddr)) {
push (@octb, sprintf ("%08d", &dec2bin ($i))) ;
push (@octd, $i) ;
push (@octh, sprintf ("%02X", $i)) ;
}printf("%14s %-15s %-35s %-10s\n", "$mytitle",
&bin2dec32 ($myaddr),
join ('-', @octb),
'0x' . join ('', @octh)
) ;
}
##### 低レベル関数群 ###############
##
sub dec2bin {
my $mystr = unpack ("B32", pack ("N", shift (@_))) ;
$mystr =~ s/^0+(?=\d)//o ; ## これをやらないと整数の頭の0が残る
return $mystr ;
}##########
##
sub bin2dec {
return unpack ("N", pack ("B32", substr ("0" x 32 . shift (@_), -32))) ;
}##########
##
sub bin2dec32 ($) {
my $myaddr = shift (@_) ;my @myarray = unpack ("CCCC", $myaddr) ;
return join ('.', @myarray) ;
}