#!/bin/sh

debug=false
args=""

print_help()
{
    cat <<EOF

ifstat [-a] [-d] [-h] [-t hostname]
    -a: output similar to ifconfig -a.
    -d: turn debugging on.
    -h: show this help.
    -t: test hostname or IP is configured and UP on this host.
        Exits true if configured, false if not or unresolved hostname.

EOF

}

address()
{
    args="$args -t `hac_getmask -a $1`"
}

while true; do
    case "$1" in
	-a)	args="-a $args";		;;
	-d)	debug=true;			;;
	-h)	print_help;	exit 0;		;;
	-t)	shift;	address "$1" || exit 1;	;;
	"")     break				;;

	*)	echo "Unknown option $1";
		exit 1;
		;;
    esac
    shift
done

$debug && args="-d $args" && echo "ARGS=$args"

awk="/usr/bin/nawk"
test -x $awk || awk="awk"
$debug && echo "awk = $awk"

#for f in `netstat -i|grep -v Name|awk '{print $1}'` ; do ifconfig $f; done

ifconfig -a | $awk -v "ARGS=$args" '
# This parses the output of ifconfig -a

# Data structructures:
#  interface[interface name]		= count of address on the interface.
#  flags[interface name]		= comma delimited list of flags
#  mtu[interface name]			= MTU
#  address[interface, address number]	= IP address
#  netmask[interface, address number]	= IP netmask
#  broadcast[interface, address number]	= IP broadcast address


# Join the elements of an array together into a string,
# with the delimiter betreen them.
function join(elements, delimiter,  local, i, delim, string)
{
    delim = "";
    string = "";

    for (i = 1;  i in elements;  ++i)
    {
	string = string delim elements[i];
	delim = delimiter;
    }
    return string;
}


function strip_leading_zeros(value)
{
    sub(/^0+/, "", value);
    if (value == "")
	value = "0";

    return value;
}


# Takes an ip address in the form of a dotted quad, &
# removes leading zeros from each number in the quad.
function trim_ip_address(addr,  local, i, bytes)
{
    split(addr, bytes, ".");
    for (i = 1;  i in bytes;  ++i)
	bytes[i] = strip_leading_zeros(bytes[i]);

    return join(bytes, ".");
}


# See if an IP address is attached to any of the interfaces, & return the
# interface name if so.
function find_ip_address(addr,  local, name, address_count, count)
{
    addr = trim_ip_address(addr);
    for (name in interface)
    {
	address_count = interface[name];
	for (count = 1;  count <= address_count;  ++count)
	    if (address[name, count] == addr)
		return name;
    }
    return "";
}


function show_interface(name,  local, address_count, count)
{
    address_count = interface[name];
    printf("%s:\tFlags <%s> mtu %s\n", name, flags[name], mtu[name]);
    for (count = 1; count <= address_count; count += 1)
	printf("\t inet %s netmask %s broadcast %s\n",
	       address[name, count], netmask[name, count],
	       broadcast[name, count]);
}

###############################################################################

BEGIN	{
    debug = 0;
    test = "";
    interfaces = "";
    argc = split(ARGS, argv);
    for (argn = 1;  argn < argc;  ++argn)
    {
	if (argv[argn] == "-d")
	    debug = 1;
	else if (argv[argn] == "-t")
	{
	    ++argn;
	    test = argv[argn];
	}
    }
    if (debug)
	print "Args =", ARGS;
}


#
# System dependant patterns for linux-x86_64 - is a copy of the x86 file.
#

# Collect interface names
/^[^ \t]+[ \t]/ {
    name = $1;
    sub(/:$/, "", name);		# Remove trailing colon
    interface[name] = 0;		# Record name & zero the address count
}


# Get the interface flags & MTU
/MTU:/ {
    for (flag = 1;  $flag !~ /MTU:/;  ++flag)
	theseflags[flag] = $flag;

    flags[name] = join(theseflags, ",");
    sub(/MTU:/, "", $flag);
    mtu[name] = $flag;
    delete theseflags;
}


# Collect internet address / netmack / broadcast address lines
/[ \t]*inet /	{
    address_count = interface[name] + 1;
    for (i = 2;  i <= 4;  ++i)
    {
	if ($i ~ /addr:/)
	{
	    sub(/addr:/, "", $i);
	    address[name, address_count] = trim_ip_address($i);
	}
	else if ($i ~ /Bcast:/)
	{
	    sub(/Bcast:/, "", $i);
	    broadcast[name, address_count] = trim_ip_address($i);
	}
	else if ($i ~ /Mask:/)
	{
	    sub(/Mask:/, "", $i);
	    netmask[name, address_count] = $i;
	}
    }
    interface[name] = address_count;
}


#
# End of system dependant patterns
#

END	{
    result = 0;

    if (test == "")
    {
	for (name in interface)
	    show_interface(name);
    }
    else
    {
	ifname = find_ip_address(test);
	if (ifname == "")
	    result = 1;
	else if (flags[ifname] !~ /UP/)
	    result = 1;
    }

#    print find_ip_address("127.0.0.1");
#    print find_ip_address("1.2.3.4");
    exit result;
}
'
