1
0
mirror of https://github.com/wfjm/w11.git synced 2026-01-18 09:32:31 +00:00
wfjm.w11/tools/bin/ip_inspect
2018-12-24 09:02:41 +01:00

154 lines
4.2 KiB
Perl
Executable File

#!/usr/bin/perl -w
# $Id: ip_inspect 1089 2018-12-19 10:45:41Z mueller $
#
# Copyright 2017-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# This program is free software; you may redistribute and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3, 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 complete details.
#
# Revision History:
# Date Rev Version Comment
# 2018-12-18 1089 0.1.1 add and use bailout
# 2017-04-08 872 0.1 First draft
#
use 5.14.0; # require Perl 5.14 or higher
use strict; # require strict checking
use Getopt::Long;
my %opts = ();
GetOptions(\%opts,
)
or bailout("bad command options");
autoflush STDOUT 1 if (-p STDOUT); # autoflush if output into pipe
my $cmd = shift @ARGV;
bailout("missing command; use 'ip_inspect help'") unless (defined $cmd);
if ($cmd eq "help") {
print_usage();
} elsif ($cmd eq "defeif") {
do_defeif();
} elsif ($cmd eq "addr4") {
do_addr4();
} elsif ($cmd eq "defroute") {
do_defroute();
} else {
bailout("invalid command '$cmd'");
}
exit 0;
#-------------------------------------------------------------------------------
sub do_defeif {
my @devs;
open (IPRES, "ip link show|") or bailout("failed to call ip");
while (<IPRES>) {
chomp;
next unless m|^\d+:\s*(\w+):|;
my $dev = $1;
next unless $dev =~ m/^(en|eth)/;
push @devs,$dev;
}
close (IPRES);
bailout("failed to detect default device") if (scalar(@devs) == 0);
if (scalar(@devs) > 1) {
my $devstr = join ',',@devs;
bailout("multiple ethernet interfaces '$devstr'");
}
print "$devs[0]\n";
return;
}
#-------------------------------------------------------------------------------
sub do_addr4 {
my $dev = shift @ARGV;
my $fld = shift @ARGV;
bailout("missing device or field") unless (defined $dev && defined $fld);
my $addr;
my $size;
my $bcast;
open (IPRES, "ip addr show dev $dev|") or bailout("failed to call ip");
while (<IPRES>) {
chomp;
next unless m|^\s+inet\s+([0-9.]+)/(\d+)\s+brd\s+([0-9.]+)|;
$addr = $1;
$size = $2;
$bcast = $3;
}
close (IPRES);
if ($fld eq "addr") {
print "$addr\n";
} elsif ($fld eq "addrm") {
print "$addr/$size\n";
} elsif ($fld eq "mask") {
my $mask = size2mask($size);
print "$mask\n";
} elsif ($fld eq "bcast") {
print "$bcast\n";
} else {
bailout("invalid field '$fld'");
}
return;
}
#-------------------------------------------------------------------------------
sub do_defroute {
open (IPRES, "ip route show|") or bailout("failed to call ip");
while (<IPRES>) {
chomp;
if (m|^default via\s+([0-9.]+)|) {
close (IPRES);
print "$1\n";
return;
}
}
bailout("failed to find default route");
}
#-------------------------------------------------------------------------------
sub size2mask {
my ($size) = @_;
my $bmask = ('1' x $size) . ('0' x (32-$size));
my $dmask = oct("0b".substr($bmask, 0,8)) . '.' .
oct("0b".substr($bmask, 8,8)) . '.' .
oct("0b".substr($bmask,16,8)) . '.' .
oct("0b".substr($bmask,24,8));
return $dmask;
}
#-------------------------------------------------------------------------------
sub bailout {
my ($msg) = @_;
print STDERR "ip_inspect-F: $msg\n";
exit 1;
}
#-------------------------------------------------------------------------------
sub print_usage {
print "usage: ip_inspect <command> <args>\n";
print " ip_inspect defeif # get default eth interface\n";
print " ip_inspect addr4 <if> addrm # get ip4 addr/mask\n";
print " ip_inspect addr4 <if> addr # get ip4 bare addr\n";
print " ip_inspect addr4 <if> mask # get ip4 subnet mask\n";
print " ip_inspect addr4 <if> bcast # get ip4 bcast addr\n";
print " ip_inspect defroute # get default route\n";
return;
}