On Sat, Jan 20, 2001 at 09:38:43AM +0200, Mircea Damian wrote:
> Bai dar de "bc -l" si ibase/obase a auzit cineva. Ce poate fi mai simplu
> decat ala?
ipcalc ;-)
--
___
<o-o> Viorel ANGHEL <vang AT altavista DOT net>
[`-']
-"-"- In Linux We Trust.
-- Attached file included as plaintext by Listar --
#!/usr/bin/perl -w
#
# ipcalc.pl.
# Given an IPv4 address and the number of bits in the netmask or
# the netmask itself, calculate assorted network information.
# Sat Aug 29 16:43:01 EST 1998
#
# Tue Sep 8 16:11:00 EST 1998, correct first host, thanks to
# David Wilson.
#
# Takes one positional parameter, the IPv4 address as dotted
# quad, optionally followed by /mask, mask can be the number of
# bits in the netmask or a netmask as a dotted quad. If the
# mask is omitted, it defaults to the normal class A, B or C
# mask, depending on the first byte of the address.
#
# In the bit representation of the address, the network bits are
# displayed in reverse video, using tput strings. Environment
# variable TPUT defines the name of your tput binary, if not set
# it defaults to "tput". If TPUT is the empty string then no
# highlighting is done. For example, under bash,
# "TPUT= ipcalc.pl ..." will suppress the use of tput. If you
# are paranoid about finding the correct version of tput, do
# TPUT=/full/path/name/tput ipcalc.pl ...
#
# All dotted quad addresses are printed twice. Once for a fixed
# table layout, again without spaces ready for cut and paste.
#
# Examples.
# ipcalc.pl 230.143.254.1 Defaults to class C, 24 bits
# ipcalc.pl 230.143.254.1/25 25 bit netmask
# ipcalc.pl 230.143.254.1/255.255.255.128 25 bit netmask as dotted quad
#
# For demonstration purposes or if you really must have a GUI,
# see ipcalc.tcl.
#
# Copyright Keith Owens <[EMAIL PROTECTED]>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
require 5;
use integer;
use strict;
my $tput = $ENV{'TPUT'};
$tput = 'tput' if (!defined($tput));
my $ipaddr = shift(@ARGV); # user supplied, required
my $mask; ## user supplied, optional
my @ia; # individual bytes of ipaddr
my @nm; # individual bytes of netmask
my $netmask; # netmask as 32 bit value
my $maskbits; # number of bits in netmask
my $i; # work
my @j; # work
if (!defined($ipaddr)) {
usage();
}
# gotta love those Perl regular expressions :)
if ($ipaddr =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)(?:\/([\d.]+))?$/) {
(@ia) = ($1, $2, $3, $4);
$mask = $5;
}
else {
usage("Parameter $ipaddr not recognised");
}
for ($i = 0; $i < 4; ++$i) {
if ($ia[$i] > 255) {
usage("Invalid byte $ia[$i] in IPv4 address, must be 0-255");
}
}
if ($ia[0] < 1 || $ia[0] > 223) {
usage("First byte must be 1-223, I do not handle multicast or experimental");
}
if (!defined($mask)) {
# default to class A, B or C
if ($ia[0] < 128) {
$mask = 8;
}
elsif ($ia[0] < 192) {
$mask = 16;
}
else {
$mask = 24;
}
}
if ($mask =~ /^\d+$/) {
# user supplied number of bits or we defaulted to number of bits in netmask
$maskbits = $mask;
$mask = undef(); # don't use user supplied value any more
if ($maskbits <= 32) {
# use integer implies signed shift, I want unsigned
no integer;
# only assumption is at least 32 bit arithmetic, should handle > 32
bits
$i = 0xffffffff << (32 - $maskbits) & 0xffffffff;
$i = 0 if ($maskbits == 0); # shift left 32 may do nothing
(@nm) = ($i >> 24, $i >> 16 & 0xff, $i >> 8 & 0xff, $i & 0xff);
use integer;
}
else {
usage("Netmask bits must be 0-32, $maskbits is invalid");
}
}
elsif ($mask =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
# user supplied dotted quad netmask
(@nm) = ($1, $2, $3, $4);
$mask = undef(); # don't use user supplied value any more
for ($i = 0; $i < 4; ++$i) {
if ($nm[$i] > 255) {
usage("Invalid byte $nm[$i] in netmask, must be 0-255");
}
}
}
else {
usage("Netmask must be 0-32 or dotted quad, $mask is invalid");
}
no integer; # do unsigned shift
$ipaddr = ($ia[0] << 24) + ($ia[1] << 16) + ($ia[2] << 8) + $ia[3];
$netmask = ($nm[0] << 24) + ($nm[1] << 16) + ($nm[2] << 8) + $nm[3];
for ($maskbits = 0, $i = $netmask; $i != 0; ++$maskbits) {
if (($i & 0xc0000000) == 0x40000000) {
usage("Netmask must have contiguous leftmost '1' bits, " .
sprintf("%08X", $netmask) . " is invalid");
}
$i <<= 1;
}
use integer;
# We now have $maskbits, $netmask and @nm bytes in sync, no matter
# which format the user supplied. It's downhill from here.
printf("IP address %3d . %3d . %3d . %3d / %2d %d.%d.%d.%d/%d\n",
@ia, $maskbits, @ia, $maskbits);
printf("Netmask bits %s %s %s %s\n",
unpack("B8", chr($nm[0])),
unpack("B8", chr($nm[1])),
unpack("B8", chr($nm[2])),
unpack("B8", chr($nm[3])));
printf("Netmask bytes %3d . %3d . %3d . %3d %d.%d.%d.%d\n",
@nm, @nm);
my $addressbits = unpack("B8", chr($ia[0])) . " " .
unpack("B8", chr($ia[1])) . " " .
unpack("B8", chr($ia[2])) . " " .
unpack("B8", chr($ia[3]));
if ($tput ne "") {
# try to use reverse video for the network bits
my $rev = `$tput rev`;
my $sgr0 = `$tput sgr0`;
if (defined($rev) && $rev ne "" && defined($sgr0) && $sgr0 ne "") {
$i = $maskbits + int(($maskbits-1)/8); # space every 8 bits
my $hostbits = substr($addressbits, $i); # save host bits
$addressbits = substr($addressbits, 0, $i); # extract network bits
$addressbits =~ s/([01]+)/$rev$1$sgr0/g; # reverse video for
network bits
$addressbits .= $hostbits; # put it back together
}
}
printf("Address bits %s\n",
$addressbits);
if ($maskbits < 32) {
no integer; # do unsigned arithmetic
$i = $ipaddr & $netmask;
@j = ($i >> 24, $i >> 16 & 0xff, $i >> 8 & 0xff, $i & 0xff);
use integer;
printf("Network %3d . %3d . %3d . %3d
%d.%d.%d.%d\n",
@j, @j);
}
else {
printf("Network None, mask == 32\n");
}
if ($maskbits < 32) {
no integer; # do unsigned arithmetic
$i |= 0xffffffff >> $maskbits;
@j = ($i >> 24, $i >> 16 & 0xff, $i >> 8 & 0xff, $i & 0xff);
use integer;
printf("Broadcast %3d . %3d . %3d . %3d
%d.%d.%d.%d\n",
@j, @j);
}
else {
printf("Broadcast None, mask == 32\n");
}
if ($maskbits < 31) {
no integer; # do unsigned arithmetic
$i = ($ipaddr & $netmask) + 1;
@j = ($i >> 24, $i >> 16 & 0xff, $i >> 8 & 0xff, $i & 0xff);
use integer;
printf("First Host %3d . %3d . %3d . %3d
%d.%d.%d.%d\n",
@j, @j);
}
else {
printf("First Host None, mask >= 31\n");
}
if ($maskbits < 31) {
no integer; # do unsigned arithmetic
$i |= 0xffffffff >> $maskbits;
--$i;
@j = ($i >> 24, $i >> 16 & 0xff, $i >> 8 & 0xff, $i & 0xff);
use integer;
printf("Last Host %3d . %3d . %3d . %3d
%d.%d.%d.%d\n",
@j, @j);
}
else {
printf("Last Host None, mask >= 31\n");
}
if ($maskbits != 0 && $maskbits <= 30) {
no integer; # do unsigned arithmetic
$i = (1 << (32-$maskbits)) - 2;
use integer;
printf("Total Hosts %d\n", $i);
}
elsif ($maskbits == 32) {
printf("Total Hosts 1\n");
}
elsif ($maskbits == 0) {
printf("Total Hosts None, default route\n");
}
else {
printf("Total Hosts None, mask >= 31\n");
}
printf("PTR %d.%d.%d.%d.in-addr.arpa\n", $ia[3], $ia[2], $ia[1], $ia[0]);
printf("IP Address (hex) %08X\n", $ipaddr);
sub usage() {
if (defined($_[0])) {
print(STDERR "$0: error: $_[0]\n");
}
printf(STDERR "usage: $0 IPv4_address[/mask]\n");
printf(STDERR "\tmask can be number of bits (0-32) or dotted quad\n");
exit(1);
}
---
Send e-mail to '[EMAIL PROTECTED]' with 'unsubscribe rlug' to
unsubscribe from this list.