SYNOPSIS

  #!/usr/local/bin/perl -w
  # uni-ifconfig.pl
  # The unified ifconfig command.
  # Works the same way on FreeBSD, OpenBSD, Solaris, Linux, OS X, WinNT (from Win2K).
  # Note: due of Net::Ifconfig::Wrapper limitations 'inet' and 'down' commands
  # are not working on WinNT. +/-alias are working, of course.

  use strict;

  use Net::Ifconfig::Wrapper;

  my $Usage = << 'EndOfText';
  uni-ifconfig.pl         # Print this notice
  uni-ifconfig.pl -a      # Print info about all interfaces
  uni-ifconfig.pl <iface> # Print info obout specified interface
  uni-ifconfig.pl <iface> down
                          # Bring specified interface down
  uni-ifconfig.pl <iface> inet <AAA.AAA.AAA.AAA> mask <MMM.MMM.MMM.MMM>
                          # Set the specified address on the specified interface
                          # and bring this interface up
  uni-ifconfig.pl <iface> inet <AAA.AAA.AAA.AAA> mask <MMM.MMM.MMM.MMM> [+]alias
                          # Set the specified alias address
                          # on the specified interface
  uni-ifconfig.pl <iface> inet <AAA.AAA.AAA.AAA> [mask <MMM.MMM.MMM.MMM>] -alias
                          # Remove specified alias address
                          # from the specified interface
  EndOfText

  my $Info = Net::Ifconfig::Wrapper::Ifconfig('list', '', '', '')
        or die $@;

  scalar(keys(%{$Info}))
        or die "No one interface found. Something wrong?\n";

  if (!scalar(@ARGV))
        {
        print $Usage;
        exit 0;
        }

  if ($ARGV[0] eq '-a')
        {
        defined($ARGV[1])
                and die $Usage;
        foreach (sort(keys(%{$Info})))
                { print IfaceInfo($Info, $_); };
        exit 0;
        };

  $Info->{$ARGV[0]}
        or die "Interface '$ARGV[0]' is unknown\n";

  if    (!defined($ARGV[1]))
        {
        print IfaceInfo($Info, $ARGV[0]);
        exit 0;
        }

  my $CmdLine = join(' ', @ARGV);
  my $Result = undef;

  if    ($CmdLine =~ m/\A\s*([\w\{\}\-]+)\s+down\s*\Z/i)
        {
        $Result = Net::Ifconfig::Wrapper::Ifconfig('down', $1, '', '');
        }
  elsif ($CmdLine =~ m/\A\s*([\w\{\}\-]+)\s+inet\s+(\d{1,3}(?:\.\d{1,3}){3})\s+mask\s+(\d{1,3}(?:\.\d{1,3}){3})\s*\Z/i)
        {
        $Result = Net::Ifconfig::Wrapper::Ifconfig('inet', $1, $2, $3);
        }
  elsif ($CmdLine =~ m/\A\s*([\w\{\}\-]+)\s+inet\s+(\d{1,3}(?:\.\d{1,3}){3})\s+mask\s+(\d{1,3}(?:\.\d{1,3}){3})\s+\+?alias\s*\Z/i)
        {
        $Result = Net::Ifconfig::Wrapper::Ifconfig('+alias', $1, $2, $3);
        }
  elsif ($CmdLine =~ m/\A\s*([\w\{\}\-]+)\s+inet\s+(\d{1,3}(?:\.\d{1,3}){3})\s+(:?mask\s+(\d{1,3}(?:\.\d{1,3}){3})\s+)?\-alias\s*\Z/i)
        {
        $Result = Net::Ifconfig::Wrapper::Ifconfig('-alias', $1, $2, '');
        }
  else
        { die $Usage; };

  $Result
        or die $@;

  exit 0;

  sub IfaceInfo
        {
        my ($Info, $Iface) = @_;

        my $Res = "$Iface:\t".($Info->{$Iface}{'status'} ? 'UP' : 'DOWN')."\n";

        while (my ($Addr, $Mask) = each(%{$Info->{$Iface}{'inet'}}))
                { $Res .= sprintf("\tinet %-15s mask $Mask\n", $Addr); };

        $Info->{$Iface}{'ether'}
                and $Res .= "\tether ".$Info->{$Iface}{'ether'}."\n";

        $Info->{$Iface}{'descr'}
                and $Res .= "\tdescr '".$Info->{$Iface}{'descr'}."'\n";

        return $Res;
        };

DESCRIPTION

This module provides a unified way to configure the network interfaces on FreeBSD, OpenBSD, Solaris, Linux, \s-1OS\s0 X, and WinNT (from Win2K) systems.

Only \*(C`inet\*(C' (IPv4) and \*(C`ether\*(C' (\s-1MAC\s0) addresses are supported at the moment

On Unixes this module calls the system \*(C`ifconfig\*(C' command to perform the actions. On Windows the functions from IpHlpAPI.DLL are called.

For all supported Unixes \*(C`Net::Ifconfig::Wrapper\*(C' expect \*(C`ifconfig\*(C' command to be \*(C`/sbin/ifconfig\*(C'.

Module was tested on FreeBSD 4.7,4.8,5.3 (Intel), RedHat 6.2,7.3,8.0 (Intel), Win2000 Pro (Intel), OpenBSD 3.1 (\s-1SPARC\s0), Solaris 7 (\s-1SPARC\s0), \s-1OS\s0 X 10.3 (aka Panther), \s-1OS\s0 X 10.4 (aka Tiger).

In MSWin32 family only WinNT is supported. In WinNT family only Win2K or later is supported.

The Net::Ifconfig::Wrapper methods

The first and the last method of the \*(C`Net::Ifconfig::Wrapper\*(C' module. Do all the job. The particular action is described by the $Command parameter. $Command could be:

'list'

\*(C`Ifconfig('list', '', '', '')\*(C' will return the reference to the hash contains the information about interfaces. The structure of this hash is the following: {IfaceName => {'status' => 0|1 # The status of the interface. 0 means down, 1 means up 'ether' => MACaddr, # The ethernet address of the interface if available 'descr' => Description, # The description of the interface if available 'inet' => {IPaddr1 => NetMask, # The IP address and his netmask, both are in AAA.BBB.CCC.DDD notation IPaddr2 => NetMask, ... }, ... }; Interface, Address, Netmask parameters are ignored. The following programs are called:

FreeBSD

\*(C`/sbin/ifconfig -a\*(C'

Solaris

\*(C`/sbin/ifconfig -a\*(C'

OpenBSD

\*(C`/sbin/ifconfig -A\*(C'

Linux

\*(C`/sbin/ifconfig -a\*(C'

\s-1OS\s0 X

\*(C`/sbin/ifconfig -a\*(C'

MSWin32

\*(C`GetAdaptersInfo\*(C' function from \*(C`IpHlpAPI.DLL\*(C'

Limitations: OpenBSD: \*(C`/sbin/ifconfig -A\*(C' command is not returning information about \s-1MAC\s0 addresses so we are trying to get it from '/usr/sbin/arp -a' command (first 'static' entry). If no one present the 'ff:ff:ff:ff:ff' address is returned. MSWin32: \*(C`GetAdaptersInfo\*(C' function is not returning information about interface which have address 127.0.0.1 binded so \*(C`Net::Ifconfig::Wrapper\*(C' have no ability to display it. Not limitation but little problem: MSWin32 interface names are not human-readable, they looks like \*(C`{843C2077-30EC-4C56-A401-658BB1E42BC7}\*(C' (on Win2K at least).

'inet'

This function is used to set IPv4 address on interface. It have to be called as Ifconfig('inet', $IfaceName, $Addr, $Mask); $IfaceName is an interface name as displayed by 'list' command $Addr is an IPv4 address in the \*(C`AAA.AAA.AAA.AAA\*(C' notation $Mask is an IPv4 subnet mask in the \*(C`MMM.MMM.MMM.MMM\*(C' notation The following actual \*(C`ifconfig\*(C' programs are called

FreeBSD

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% up\*(C'

Solaris

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% up\*(C'

OpenBSD

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% up\*(C'

Linux

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% up\*(C'

\s-1OS\s0 X

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% up\*(C'

MSWin32:

nothing :(

Limitations: MSWin32: I did not find the relaible way to recognize the \*(L"main\*(R" address on the Win32 network interface, so I have disabled this functionality. If you know the way please let me know.

'up'

Just a synonym for 'inet'

'down'

This function is used to bring specified interface down. It have to be called as Ifconfig('inet', $IfaceName, '', ''); $IfaceName is an interface name as displayed by 'list' command Address and Netmask are ignored. The following actual \*(C`ifconfig\*(C' programs are called

FreeBSD

\*(C`/sbin/ifconfig %Iface% down\*(C'

Solaris

\*(C`/sbin/ifconfig %Iface% down\*(C'

OpenBSD

\*(C`/sbin/ifconfig %Iface% down\*(C'

Linux

\*(C`/sbin/ifconfig %Iface% down\*(C'

\s-1OS\s0 X

\*(C`/sbin/ifconfig %Iface% down\*(C'

MSWin32

nothing :(

Limitations: MSWin32: I did not find the way to implement the 'up' command so I did not implement 'down'.

'+alias'

This function is used to set IPv4 alias address on interface. It have to be called as Ifconfig('+alias', $IfaceName, $Addr, $Mask); $IfaceName is an interface name as displayed by 'list' command $Addr is an IPv4 address in the \*(C`AAA.AAA.AAA.AAA\*(C' notation $Mask is an IPv4 subnet mask in the \*(C`MMM.MMM.MMM.MMM\*(C' notation The following actual \*(C`ifconfig\*(C' programs are called

FreeBSD

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% alias\*(C'

Solaris

\*(C`/sbin/ifconfig %Iface%:%Logic% inet %Addr% netmask %Mask% up\*(C'

OpenBSD

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% alias\*(C'

Linux

\*(C`/sbin/ifconfig %Iface%:%Logic% inet %Addr% netmask %Mask% up\*(C'

\s-1OS\s0 X

\*(C`/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% alias\*(C'

MSWin32

\*(C`AddIPAddress\*(C' function from \*(C`IpHlpAPI.DLL\*(C'

First available logic interface is taken automatically for Solaris and Linux

'alias'

Just a synonim for '+alias'

'-alias'

This function is used to remove IPv4 alias address from interface. It have to be called as Ifconfig('-alias', $IfaceName, $Addr, ''); $IfaceName is an interface name as displayed by 'list' command $Addr is an IPv4 address in the \*(C`AAA.AAA.AAA.AAA\*(C' notation Netmask> parameter is ignored The following actual \*(C`ifconfig\*(C' programs are called

FreeBSD

\*(C`/sbin/ifconfig %Iface% inet %Addr% -alias\*(C'

Solaris

\*(C`/sbin/ifconfig %Iface%:%Logic% down\*(C'

OpenBSD

\*(C`/sbin/ifconfig %Iface% inet %Addr% -alias\*(C'

Linux

\*(C`/sbin/ifconfig %Iface%:%Logic% down\*(C'

\s-1OS\s0 X

\*(C`/sbin/ifconfig %Iface% inet %Addr% -alias\*(C'

MSWin32

\*(C`DeleteIPAddress\*(C' function from \*(C`IpHlpAPI.DLL\*(C'

Appropriate logic interface is obtained automatically for Solaris and Linux

On success \*(C`Ifconfig(...)\*(C' returns the defined value. Actually, it is a reference to the array contains the output of the actual \*(C`ifconfig\*(C' program called. In case of troubles \*(C`Ifconfig(...)\*(C' returns 'undef' value, $@ variable contains the error message.

\s-1EXPORT\s0

None by default.

AUTHOR

Daniel Podolsky, <[email protected]>

RELATED TO Net::Ifconfig::Wrapper…

ifconfig(8), Internet Protocol Helper in Platform \s-1SDK\s0.