changequote(,)dnl
#!/usr/bin/perl -w
# $Id: haveip.pl.host,v 1.13 2010/04/09 14:21:23 ksb Exp $
# $Source: /usr/msrc/usr/local/bin/haveip/RCS/haveip.pl.host,v $
#
# Figure out if a given ip is configured on this host --jad
# We need at least 1 IP in each of the RRs (or IPs) given on the command line.

use lib  '/usr/local/lib/sac/perl'.join('.', unpack('c*', $^V)),
	'/usr/local/lib/sac';
use strict;
use vars qw($progname $opt_a $opt_h $opt_V);
use Getopt::Std qw(getopts);
use Socket;

ifelse(HOSTTYPE,HPUX11,
# HPUX version

package EmuInterface;
sub interface { my $self = shift; return $self->{interface}; }
sub address { my $self = shift; return $self->{address}; }
sub mtu { my $self = shift; return $self->{mtu}; }
sub index { my $self = shift; return $self->{index}; }
sub hwaddr { my $self = shift; return $self->{hwaddr}; }
sub netmask { my $self = shift; return $self->{netmask}; }
sub broadcast { my $self = shift; return $self->{broadcast}; }
sub is_running { my $self = shift; return $self->{is_running}; }
sub is_broadcast { my $self = shift; return $self->{is_broadcast}; }
sub is_multicast { my $self = shift; return $self->{is_multicast}; }
sub is_notrailers { my $self = shift; return $self->{is_notrailers}; }
sub is_noarp { my $self = shift; return $self->{is_noarp}; }
sub is_promiscuous { my $self = shift; return $self->{is_promiscuous}; }
sub is_pt2pt { my $self = shift; return $self->{is_pt2pt}; }
sub is_loopback { my $self = shift; return $self->{is_loopback}; }

sub new {
	my $self = {};
	bless $self;
	return $self;
}

package main;
sub GetInterfaceList() {
	my @ret = ();
	local(*RDR, *DET);

	my(@s, @d, $ref, $line);
	my $idx = 0;
	open RDR, "netstat -inw|" or die "netstat failed: $!";
	while (<RDR>) {
		next if (m/^Name/oi);
		@s = split(/\s+/o);
		$ref = EmuInterface::new();
		$ref->{'interface'} = $s[0];
		$ref->{'address'} = $s[3];
		$ref->{'mtu'} = $s[1];
		$ref->{'index'} = $idx;
		if (open DET, "ifconfig $s[0]|") {
			$line = <DET>;
			if (defined($line)) {
				@d = split(/\s+/o, $line);
				$ref->{'is_running'} = 1 if ($d[1] =~ m/[<,]running[,>]/oi);
				$ref->{'is_broadcast'} = 1 if ($d[1] =~ m/[<,]broadcast[,>]/oi);
				$ref->{'is_multicast'} = 1 if ($d[1] =~ m/[<,]multicast[,>]/oi);
				$ref->{'is_notrailers'} = 1 if ($d[1] =~ m/[<,]notrailers[,>]/oi);
				$ref->{'is_noarp'} = 1 if ($d[1] =~ m/[<,]noarp[,>]/oi);
				$ref->{'is_promiscuous'} = 1 if ($d[1] =~ m/[<,]promisc[uous]*[,>]/oi);
				$ref->{'is_pt2pt'} = 1 if ($d[1] =~ m/[<,]pointopoint[,>]/oi);
				$ref->{'is_loopback'} = 1 if ($d[1] =~ m/[<,]loopback[,>]/oi);
			}
			$line = <DET>;
			if (defined($line)) {
				$line =~ s/^\s+//o;
				@d = split(/\s+/o, $line);
				$ref->{'netmask'} = $d[3];
				$ref->{'broadcast'} = $d[5] if (defined($d[4]) && 'broadcast' eq $d[4]);
			}
			close DET;
		} else {
			$ref->{'is_loopback'} = $s[0] eq 'lo0';
		}
		push @ret, $ref;
		++$idx;
	}
	close RDR;
	open RDR, "/usr/sbin/lanscan|" or return @ret;
	while (<RDR>) {
		next if (m/^hardware/io || m/^path/io);
		@s = split(/\s+/o);
		map { $_->{'hwaddr'} = lc substr($s[1],2) if $_->interface eq $s[4]; } @ret;
	}
	close RDR;
	return @ret;
}
,
# Use the standard CPAN module
use IO::Interface::Simple;

package main;
sub GetInterfaceList() {
	return IO::Interface::Simple->interfaces;
}
)dnl

($progname = $0) =~ s,.*/,,;
getopts('ahV');

sub usage($) {
	my ($ret) = $_[0];
	my($fh) = *STDERR;
	$ret ==	0 and
		$fh = *STDOUT;
	print $fh
		"$progname: usage ip_addrs\n",
		"$progname: usage [-h | -V]\n",
		"h        print only this help message\n",
		"V        show only version info\n",
		"ip_addr  check ip address, hostname, or round-robin is locally configured\n";
	return $ret;
}

$opt_h and
	usage(0);
if ($opt_V || $opt_a) {
	print "$progname: ", '$Id: haveip.pl.host,v 1.13 2010/04/09 14:21:23 ksb Exp $',"\n";
	print "$progname: local addresses: ", join(', ', map { $_->address; } grep {defined $_->address;} GetInterfaceList()), "\n";
	exit 0;
}

my(%found);
map {
	$found{$_->address} = 1 if defined($_->address);
} GetInterfaceList();

my(@hosts, $ip, $rr);
top: foreach $rr (@ARGV) {
	if ($rr =~ m/^\d+\.\d+.\d+\.\d+$/o) {
		@hosts = ($rr);
	} elsif ($rr !~ m/^[a-zA-Z][a-zA-Z0-9\-\_\.]+$/o) {
		print STDERR "$progname: $_: invalid IPv4 address or host name\n";
		usage(65);
	} else {
		(undef, undef, undef, undef, @hosts) = gethostbyname($rr);
		if (!@hosts) {
			print STDERR "$progname: gethostbyname: $rr: failed\n";
			exit 68;
		}
		@hosts = map { inet_ntoa($_) } @hosts;
	}
	foreach $ip (@hosts) {
		next top if ($found{$ip});
	}
	exit 67;
}

exit 0;
dnl
changequote(`,')dnl
