Net-Ifconfig-Wrapper-0.14/0000755000175000017500000000000012655413415014700 5ustar martinmartinNet-Ifconfig-Wrapper-0.14/t/0000755000175000017500000000000012655413414015142 5ustar martinmartinNet-Ifconfig-Wrapper-0.14/t/uni-ifconfig.pl0000644000175000017500000000555712626326745020100 0ustar martinmartin#!/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 # Print info obout specified interface uni-ifconfig.pl down # Bring specified interface down uni-ifconfig.pl inet mask # Set the specified address on the specified interface # and bring this interface up uni-ifconfig.pl inet mask [+]alias # Set the specified alias address # on the specified interface uni-ifconfig.pl inet [mask ] -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 $@; 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; }; __END__ Net-Ifconfig-Wrapper-0.14/t/20_list.t0000644000175000017500000000052612626325516016611 0ustar martinmartin use warnings; use strict; use Data::Dumper; use Test::More; use blib; use Net::Ifconfig::Wrapper qw( Ifconfig ); my $rh = Ifconfig('list'); isa_ok($rh, 'HASH'); # warn Dumper($rh); my @a = keys %$rh; my $iCount = scalar @a; diag "found $iCount adapters"; cmp_ok(1, '<=', $iCount, 'at least one adapter found'); done_testing(); __END__ Net-Ifconfig-Wrapper-0.14/lib/0000755000175000017500000000000012655413414015445 5ustar martinmartinNet-Ifconfig-Wrapper-0.14/lib/Net/0000755000175000017500000000000012655413414016173 5ustar martinmartinNet-Ifconfig-Wrapper-0.14/lib/Net/Ifconfig/0000755000175000017500000000000012655413414017717 5ustar martinmartinNet-Ifconfig-Wrapper-0.14/lib/Net/Ifconfig/Wrapper.pm0000644000175000017500000010054412655412513021700 0ustar martinmartinpackage Net::Ifconfig::Wrapper; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS @EXPORT_FAIL); $VERSION = 0.14; #$^W++; require Exporter; @ISA = qw(Exporter); # Items to export into caller's namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @EXPORT = qw(); %EXPORT_TAGS = ('Ifconfig' => [qw(Ifconfig)]); foreach (keys(%EXPORT_TAGS)) { push(@{$EXPORT_TAGS{'all'}}, @{$EXPORT_TAGS{$_}}); }; $EXPORT_TAGS{'all'} and @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); my $DEBUG = 0; use POSIX; my ($OsName, $OsVers) = (POSIX::uname())[0,2]; my $Win32_FormatMessage = undef; my %Win32API = (); my %ToLoad = ('iphlpapi' => {'GetAdaptersInfo' => [['P','P'], 'N'], #'GetIpAddrTable' => [['P','P','I'], 'N'], 'AddIPAddress' => [['N','N','N','P','P'], 'N'], 'DeleteIPAddress' => [['N'], 'N'], }, ); my $Win32_ERROR_BUFFER_OVERFLOW = undef; my $Win32_ERROR_INSUFFICIENT_BUFFER = undef; my $Win32_NO_ERROR = undef; my $ETHERNET = 'ff:ff:ff:ff:ff:ff'; (($^O eq 'openbsd') && (`/usr/sbin/arp -a 2>&1` =~ m/(?:\A|\n).+\s+at\s+([a-f\d]{1,2}(?:\:[a-f\d]{1,2}){5})\s+static\s*(?:\n|\Z)/i)) and $ETHERNET = $1; if (($^O eq 'MSWin32') || ($^O eq 'cygwin')) { eval 'use Win32::API; use Win32::WinError; Win32::IsWinNT() or die "Only WinNT (from Win2K) is supported"; $Win32_FormatMessage = sub { return Win32::FormatMessage(@_); }; $Win32_ERROR_BUFFER_OVERFLOW = ERROR_BUFFER_OVERFLOW; $Win32_ERROR_INSUFFICIENT_BUFFER = ERROR_INSUFFICIENT_BUFFER; $Win32_NO_ERROR = NO_ERROR; foreach my $DLib (keys(%ToLoad)) { foreach my $Func (keys(%{$ToLoad{$DLib}})) { $Win32API{$DLib}{$Func} = Win32::API->new($DLib, $Func, $ToLoad{$DLib}{$Func}->[0], $ToLoad{$DLib}{$Func}->[1]) or die "Cannot import function \'$Func\' from \'$DLib\' DLL: $^E"; }; }; '; $@ and die $@; }; my $MAXLOGIC = 65535; my %Hex2Mask = ('00000000' => '0.0.0.0', '80000000' => '128.0.0.0', 'c0000000' => '192.0.0.0', 'e0000000' => '224.0.0.0', 'f0000000' => '240.0.0.0', 'f8000000' => '248.0.0.0', 'fc000000' => '252.0.0.0', 'fe000000' => '254.0.0.0', 'ff000000' => '255.0.0.0', 'ff800000' => '255.128.0.0', 'ffc00000' => '255.192.0.0', 'ffe00000' => '255.224.0.0', 'fff00000' => '255.240.0.0', 'fff80000' => '255.248.0.0', 'fffc0000' => '255.252.0.0', 'fffe0000' => '255.254.0.0', 'ffff0000' => '255.255.0.0', 'ffff8000' => '255.255.128.0', 'ffffc000' => '255.255.192.0', 'ffffe000' => '255.255.224.0', 'fffff000' => '255.255.240.0', 'fffff800' => '255.255.248.0', 'fffffc00' => '255.255.252.0', 'fffffe00' => '255.255.254.0', 'ffffff00' => '255.255.255.0', 'ffffff80' => '255.255.255.128', 'ffffffc0' => '255.255.255.192', 'ffffffe0' => '255.255.255.224', 'fffffff0' => '255.255.255.240', 'fffffff8' => '255.255.255.248', 'fffffffc' => '255.255.255.252', 'fffffffe' => '255.255.255.254', 'ffffffff' => '255.255.255.255', ); my $Inet2Logic = undef; my $Logic2Inet = undef; my $Name2Index = undef; my %Ifconfig = (); my $RunCmd = sub($$) { my ($CName, $Iface, $Logic, $Addr, $Mask) = @_; my $Cmd = (defined($Ifconfig{$CName}{$^O}{$OsName}{$OsVers}{'ifconfig'}) ? $Ifconfig{$CName}{$^O}{$OsName}{$OsVers}{'ifconfig'} : $Ifconfig{$CName}{$^O}{'ifconfig'}).' 2>&1'; #print "\n=== RunCmd ===\n\$CName: $CName, \$Iface: $Iface, \$Logic: $Logic, \$Addr: $Addr, \$Mask: $Mask\n"; $Cmd =~ s{%Iface%}{$Iface}gsex; $Cmd =~ s{%Logic%}{$Logic}gsex; $Cmd =~ s{%Addr%}{$Addr}gsex; $Cmd =~ s{%Mask%}{$Mask}gsex; my $saveLang = $ENV{'LANG'} || ''; $ENV{'LANG'} = 'C'; my @Output = `$Cmd`; $ENV{'LANG'} = $saveLang; $@ = "Command '$Cmd', exit code '".(defined($?) ? $? : '!UNDEFINED!')."'".join("\t", @Output); $? ? return : return \@Output; }; my $SolarisList = sub($$$$) { $Inet2Logic = undef; $Logic2Inet = undef; my $Output = &{$RunCmd}('list', '', '', '', '') or return; $Inet2Logic = {}; $Logic2Inet = {}; my $Iface = undef; my $Logic = undef; my $LogUp = undef; my $Info = {}; foreach (@{$Output}) { if ( ($_ =~ m/\A([a-z]+\d+)(?:\:(\d+))?\:\s+flags=[^\<]+\<(?:\w+\,)*(up)?(?:\,\w+)*\>.*\n?\Z/io) || ($_ =~ m/\A([a-z]+\d+)(?:\:(\d+))?\:\s+flags=[^\<]+\<(?:\w+(?:\,\w+)*)*\>.*\n?\Z/io) ) { $Iface = $1; $Logic = defined($2) ? $2 : ''; $LogUp = 1 && $3; #$Info->{$Iface}{'status'} = ($Info->{$Iface}{'status'} || $LogUp) ? 1 : 0; $Info->{$Iface}{'status'} = $Info->{$Iface}{'status'} || $LogUp; } elsif (!$Iface) { next; } elsif ( ($_ =~ m/\A\s+inet\s+(\d{1,3}(?:\.\d{1,3}){3})\s+netmask\s+(?:0x)?([a-f\d]{8})(?:\s.*)?\n?\Z/io) || 0 ) { $LogUp and $Info->{$Iface}{'inet'}{$1} = $Hex2Mask{$2}; $Inet2Logic->{$Iface}{$1} = $Logic; $Logic2Inet->{$Iface}{$Logic} = $1; } elsif (($_ =~ m/\A\s+media\:?\s+(ethernet.*)\s*\n?\Z/io) && !$Info->{$Iface}{'ether'}) { $Info->{$Iface}{'ether'} = $ETHERNET; if (!$Info->{$Iface}{'media'}) {$Info->{$Iface}{'media'} = $1; }; } elsif (($_ =~ m/\A\s+supported\s+media\:?\s+(.*)\s*\n?\Z/io) && !$Info->{$Iface}{'media'}) { $Info->{$Iface}{'media'} = $1; } elsif ($_ =~ m/\A\s+ether\s+([a-f\d]{1,2}(?:\:[a-f\d]{1,2}){5})(?:\s.*)?\n?\Z/io) { $Info->{$Iface}{'ether'} = $1; }; }; return $Info; }; my $LinuxList = sub($$$$) { # warn " DDD start sub LinuxList...\n"; $Inet2Logic = undef; $Logic2Inet = undef; my $Output = &{$RunCmd}('list', '', '', '', '') or return; $Inet2Logic = {}; $Logic2Inet = {}; my $Iface = undef; my $Logic = undef; my $Info = {}; foreach (@{$Output}) { $DEBUG && warn " DDD looking at line of Output=$_"; if ( ($_ =~ m/\A([a-z0-9]+)(?:\:(\d+))?\s+link\s+encap\:(?:ethernet\s+hwaddr\s+([a-f\d]{1,2}(?:\:[a-f\d]{1,2}){5}))?.*\n?\Z/io) || # German locale de_DE.UTF-8 ($_ =~ m/\A([a-z0-9]+)(?:\:(\d+))?\s+Link\s+encap\:(?:Ethernet\s+Hardware\s+Adresse\s+([a-f\d]{1,2}(?:\:[a-f\d]{1,2}){5}))?.*\n?\Z/io) ) { $Iface = $1; $Logic = defined($2) ? $2 : ''; defined($3) and $Info->{$Iface}{'ether'} = $3; $Info->{$Iface}{'status'} = 0; } elsif ( ($_ =~ m/\A([a-z0-9]+)\:\s+flags=\d+<(\w+(?:,\w+)*)*>.*\n?\Z/io) ) { $Iface = $1; my $sFlags = $2; $DEBUG && warn " DDD matched 'flags' line, Iface=$Iface, sFlags=$sFlags\n"; $Info->{$Iface}{'status'} = 1 if ($sFlags =~ m/\bUP\b/); } elsif (!$Iface) { next; } elsif ( ($_ =~ m/\A\s+inet\s+addr\:(\d{1,3}(?:\.\d{1,3}){3})\s+(?:.*\s)?mask\:(\d{1,3}(?:\.\d{1,3}){3}).*\n?\Z/io) || ($_ =~ m/\A\s+inet\s+(\d{1,3}(?:\.\d{1,3}){3})\s+netmask\s+(\d{1,3}(?:\.\d{1,3}){3})(?:\s.*)?\n?\Z/io) || # German locale de_DE.UTF-8 ($_ =~ m/\A\s+inet\s+Adresse\:(\d{1,3}(?:\.\d{1,3}){3})\s+(?:.*\s)?Maske\:(\d{1,3}(?:\.\d{1,3}){3}).*\n?\Z/io) ) { my $sIP = $1; my $sNetmask = $2; $DEBUG && warn " DDD matched 'netmask' line, sIP=$sIP, sNetmask=$sNetmask\n"; $Info->{$Iface}{'inet'}{$sIP} = $sNetmask; $Inet2Logic->{$Iface}{$sIP} = $Logic; $Logic2Inet->{$Iface}{$Logic} = $sIP; } elsif ($_ =~ m/\A\s+ether\s+([a-f0-9]{1,2}(?:\:[a-f0-9]{1,2}){5})(?:\s|\n|\Z)/io) { $Info->{$Iface}{'ether'} = $1; } elsif ($_ =~ m/\A\s+up(?:\s+[^\s]+)*\s*\n?\Z/io) { $DEBUG && warn " DDD matched 'up' line\n"; $Info->{$Iface}{'status'} = 1; }; }; return $Info; }; my $st_IP_ADDR_STRING = ['Next' => 'L', #struct _IP_ADDR_STRING* 'IpAddress' => 'a16', #IP_ADDRESS_STRING 'IpMask' => 'a16', #IP_MASK_STRING 'Context' => 'L' #DWORD ]; my $MAX_ADAPTER_NAME_LENGTH = 256; my $MAX_ADAPTER_DESCRIPTION_LENGTH = 128; my $MAX_ADAPTER_ADDRESS_LENGTH = 8; my $st_IP_ADAPTER_INFO = ['Next' => 'L', #struct _IP_ADAPTER_INFO* 'ComboIndex' => 'L', #DWORD 'AdapterName' => 'a'.($MAX_ADAPTER_NAME_LENGTH+4), #char[MAX_ADAPTER_NAME_LENGTH + 4] 'Description' => 'a'.($MAX_ADAPTER_DESCRIPTION_LENGTH+4), #char[MAX_ADAPTER_DESCRIPTION_LENGTH + 4] 'AddressLength' => 'L', #UINT 'Address' => 'a'.$MAX_ADAPTER_ADDRESS_LENGTH, #BYTE[MAX_ADAPTER_ADDRESS_LENGTH] 'Index' => 'L', #DWORD 'Type' => 'L', #UINT 'DhcpEnabled' => 'L', #UINT 'CurrentIpAddress' => 'L', #PIP_ADDR_STRING 'IpAddressList' => $st_IP_ADDR_STRING, #IP_ADDR_STRING 'GatewayList' => $st_IP_ADDR_STRING, #IP_ADDR_STRING 'DhcpServer' => $st_IP_ADDR_STRING, #IP_ADDR_STRING 'HaveWins' => 'L', #BOOL 'PrimaryWinsServer' => $st_IP_ADDR_STRING, #IP_ADDR_STRING 'SecondaryWinsServer' => $st_IP_ADDR_STRING, #IP_ADDR_STRING 'LeaseObtained' => 'L', #time_t 'LeaseExpires' => 'L', #time_t ]; #my $st_MIB_IPADDRROW = # ['dwAddr' => 'L', #DWORD # 'dwIndex' => 'L', #DWORD # 'dwMask' => 'L', #DWORD # 'dwBCastAddr' => 'L', #DWORD # 'dwReasmSize' => 'L', #DWORD # 'unused1' => 'S', #unsigned short # 'unused2' => 'S', #unsigned short # ]; my %UnpackStrCache = (); my $UnpackStr = undef; $UnpackStr = sub($$) { my ($Struct, $Repeat) = @_; $Repeat or $Repeat = 1; my $StructUpStr = ''; if (!defined($UnpackStrCache{$Struct})) { for (my $RI = 1; defined($Struct->[$RI]); $RI += 2) { $StructUpStr .= ref($Struct->[$RI]) ? &{$UnpackStr}($Struct->[$RI], 1) : $Struct->[$RI]; }; $UnpackStrCache{$Struct} = $StructUpStr; } else { $StructUpStr = $UnpackStrCache{$Struct}; }; my $UpStr = ''; for (; $Repeat > 0; $Repeat--) { $UpStr .= $StructUpStr; }; return $UpStr; }; my $ShiftStruct = undef; $ShiftStruct = sub($$) { my ($Array, $Struct) = @_; my $Result = {}; #tie(%{$Result}, 'Tie::IxHash'); for (my $RI = 0; defined($Struct->[$RI]); $RI += 2) { $Result->{$Struct->[$RI]} = ref($Struct->[$RI+1]) ? &{$ShiftStruct}($Array, $Struct->[$RI+1]) : shift(@{$Array}); }; return $Result; }; my $UnpackStruct = sub($$) { my ($pBuff, $Struct) = @_; my $UpStr = &{$UnpackStr}($Struct); my @Array = unpack($UpStr, ${$pBuff}); substr(${$pBuff}, 0, length(pack($UpStr)), ''); return &{$ShiftStruct}(\@Array, $Struct); }; my $if_hwaddr = sub($$) { my($len, $addr) = @_; return join(':', map {sprintf '%02x', $_ } unpack('C' x $len, $addr)); }; sub if_ipaddr { my ($addr) = @_; return join(".", unpack("C4", pack("L", $addr))); }; my $Win32List = sub($$$$) { $Inet2Logic = undef; $Logic2Inet = undef; $Name2Index = undef; my $Buff = ''; my $BuffLen = pack('L', 0); my $Res = $Win32API{'iphlpapi'}{'GetAdaptersInfo'}->Call(0, $BuffLen); while ($Res == $Win32_ERROR_BUFFER_OVERFLOW) { $Buff = "\0" x unpack("L", $BuffLen); $Res = $Win32API{'iphlpapi'}{'GetAdaptersInfo'}->Call($Buff, $BuffLen); }; if ($Res != $Win32_NO_ERROR) { $! = $Res; $@ = "Error running 'GetAdaptersInfo' function: ".&{$Win32_FormatMessage}($Res); return; }; my $Info = {}; $Inet2Logic = {}; $Logic2Inet = {}; $Name2Index = {}; while (1) { my $ADAPTER_INFO = &{$UnpackStruct}(\$Buff, $st_IP_ADAPTER_INFO); foreach my $Field ('AdapterName', 'Description') { $ADAPTER_INFO->{$Field} =~ s/\x00+\Z//o; }; foreach my $AddrField ('IpAddressList', 'GatewayList', 'DhcpServer', 'PrimaryWinsServer', 'SecondaryWinsServer') { foreach my $Field ('IpAddress', 'IpMask') { $ADAPTER_INFO->{$AddrField}{$Field} =~ s/\x00+\Z//o; }; }; $ADAPTER_INFO->{'Address'} = &{$if_hwaddr}($ADAPTER_INFO->{'AddressLength'}, $ADAPTER_INFO->{'Address'}); foreach my $IpList ('IpAddressList', 'GatewayList') { my $ADDR_STRING = $ADAPTER_INFO->{$IpList}; $ADAPTER_INFO->{$IpList} = [$ADDR_STRING,]; while ($ADDR_STRING->{'Next'}) { $ADDR_STRING = &{$UnpackStruct}(\$Buff, $st_IP_ADDR_STRING); foreach my $Field ('IpAddress', 'IpMask') { $ADDR_STRING->{$Field} =~ s/\x00+\Z//o; }; push(@{$ADAPTER_INFO->{$IpList}}, $ADDR_STRING); }; }; my $Iface = $ADAPTER_INFO->{'AdapterName'}; $Info->{$Iface}{'descr'} = $ADAPTER_INFO->{'Description'}; $Info->{$Iface}{'ether'} = $ADAPTER_INFO->{'Address'}; $Info->{$Iface}{'status'} = 1; foreach my $Addr (@{$ADAPTER_INFO->{'IpAddressList'}}) { ($Addr->{'IpAddress'} eq '0.0.0.0') and next; $Info->{$Iface}{'inet'}{$Addr->{'IpAddress'}} = $Addr->{'IpMask'}; $Inet2Logic->{$Iface}{$Addr->{'IpAddress'}} = $Addr->{'Context'}; $Logic2Inet->{$Iface}{$Addr->{'Context'}} = $Addr->{'IpAddress'}; }; $Name2Index->{$Iface} = $ADAPTER_INFO->{'Index'}; $ADAPTER_INFO->{'Next'} or last; }; #$Buff = ''; #$BuffLen = pack('L', 0); #$Res = $Win32API{'iphlpapi'}{'GetIpAddrTable'}->Call($Buff, $BuffLen, 0); # #while ($Res == ERROR_INSUFFICIENT_BUFFER) # { # $Buff = "\0" x unpack("L", $BuffLen); # $Res = $Win32API{'iphlpapi'}{'GetIpAddrTable'}->Call($Buff, $BuffLen, 0); # }; # #if ($Res != $Win32_NO_ERROR) # { # $! = $Res; # $@ = "Error running 'GetIpAddrTable' function: ".&{$Win32_FormatMessage}($Res); # return; # }; # #my $IpAddrTable = &{$UnpackStruct}(\$Buff, ['Len' => 'L']); #my %Info1 = (); #for (; $IpAddrTable->{'Len'} > 0; $IpAddrTable->{'Len'}--) # { # my $IPADDRROW = &{$UnpackStruct}(\$Buff, $st_MIB_IPADDRROW); # $Info->{$IPADDRROW->{'dwIndex'}} # and next; # $Info1{$IPADDRROW->{'dwIndex'}}{'inet'}{if_ipaddr($IPADDRROW->{'dwAddr'})} = if_ipaddr($IPADDRROW->{'dwMask'}); # }; # #foreach my $Iface (keys(%Info1)) # { $Info->{$Iface} = $Info1{$Iface}; }; return wantarray ? %{$Info} : $Info; }; $Ifconfig{'list'} = {'solaris' => {'ifconfig' => 'LC_ALL=C /sbin/ifconfig -a', 'function' => $SolarisList}, 'openbsd' => {'ifconfig' => 'LC_ALL=C /sbin/ifconfig -A', 'function' => $SolarisList}, 'linux' => {'ifconfig' => 'LC_ALL=C /sbin/ifconfig -a', 'function' => $LinuxList}, 'MSWin32' => {'ifconfig' => '', 'function' => $Win32List,}, }; $Ifconfig{'list'}{'freebsd'} = $Ifconfig{'list'}{'solaris'}; $Ifconfig{'list'}{'darwin'} = $Ifconfig{'list'}{'solaris'}; $Ifconfig{'list'}{'cygwin'} = $Ifconfig{'list'}{'MSWin32'}; my $UpDown = sub($$$$) { my ($CName, $Iface, $Addr, $Mask) = @_; if (!(defined($Iface) && defined($Addr) && defined($Mask))) { $@ = "Command '$CName': interface, inet address and netmask have to be defined"; return; }; my $Output = &{$RunCmd}($CName, $Iface, '', $Addr, $Mask); $Inet2Logic = undef; $Logic2Inet = undef; $Output ? return $Output : return; }; my $UpDownNewLog = sub($$$$) { my ($CName, $Iface, $Addr, $Mask) = @_; if (!(defined($Iface) && defined($Addr) && defined($Mask))) { $@ = "Command '$CName': interface, inet address and netmask have to be defined"; return; }; defined($Inet2Logic) or (defined($Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}) ? &{$Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}}() : &{$Ifconfig{'list'}{$^O}{'function'}}()) or return; my $Logic = $Inet2Logic->{$Iface}{$Addr}; my $RunIndex = 1; for(; !defined($Logic); $RunIndex++) { if ($RunIndex > $MAXLOGIC) { $@ = "Command '$CName': maximum number of logic interfaces ($MAXLOGIC) on interface '$Iface' exceeded"; return; }; defined($Logic2Inet->{$Iface}{$RunIndex}) or $Logic = $RunIndex; }; my $Output = &{$RunCmd}($CName, $Iface, $Logic, $Addr, $Mask); $Inet2Logic = undef; $Logic2Inet = undef; $Output ? return $Output : return; }; my $UpDownReqLog = sub($$$$) { my ($CName, $Iface, $Addr, $Mask) = @_; if (!(defined($Iface) && defined($Addr) && defined($Mask))) { $@ = "Command '$CName': interface, inet address and netmask have to be defined"; return; }; defined($Inet2Logic) or (defined($Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}) ? &{$Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}}() : &{$Ifconfig{'list'}{$^O}{'function'}}()) or return; my $Logic = $Inet2Logic->{$Iface}{$Addr}; if (!defined($Logic)) { $@ = "Command '$CName': can not get logic interface for interface '$Iface', inet address '$Addr'"; return; }; my $Output = &{$RunCmd}($CName, $Iface, $Logic, $Addr, $Mask); $Inet2Logic = undef; $Logic2Inet = undef; $Output ? return $Output : return; }; #my $Win32UpDown = sub($$) # { # my ($Iface, $State) = @_; # # # }; # #my $Win32Inet = sub($$$$) # { # my ($CName, $Iface, $Addr, $Mask) = @_; # # # if (!(defined($Iface) && defined($Addr) && defined($Mask))) # { # $@ = "Command '$CName': interface, inet address and netmask have to be defined"; # return; # }; # # $Win32Up($Iface) # or return; # # $Win32AddIP($Iface, $Addr, $Mask) # or return; # my $Output = &{$RunCmd}('inet', '$Iface', '', '$Addr', '$Mask'); # # $Inet2Logic = undef; # $Logic2Inet = undef; # # $Output ? return $Output : return; # }; my $PackIP = sub($) { my @Bytes = split('\.', $_[0]); return unpack("L", pack('C4', @Bytes)); }; my $Win32AddAlias = sub($$$$) { my ($CName, $Iface, $Addr, $Mask) = @_; if (!(defined($Iface) && defined($Addr) && defined($Mask))) { $@ = "Command '$CName': interface, inet address and netmask have to be defined"; return; }; defined($Inet2Logic) or (defined($Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}) ? &{$Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}}() : &{$Ifconfig{'list'}{$^O}{'function'}}()) or return; my $NTEContext = pack('L', 0); my $NTEInstance = pack('L', 0); my $Index = $Name2Index->{$Iface}; if (!defined($Index)) { $@ = "Command '$CName': can not get interface index for interface '$Iface'"; return; }; my $Res = $Win32API{'iphlpapi'}{'AddIPAddress'}->Call(&{$PackIP}($Addr), &{$PackIP}($Mask), $Index, $NTEContext, $NTEInstance); if ($Res != $Win32_NO_ERROR) { $! = $Res; $@ = &{$Win32_FormatMessage}($Res) or $@ = 'Unknown error :('; return; }; $Inet2Logic = undef; $Logic2Inet = undef; return ['Command completed successfully']; }; my $Win32RemAlias = sub($$$$) { my ($CName, $Iface, $Addr, $Mask) = @_; if (!(defined($Iface) && defined($Addr) && defined($Mask))) { $@ = "Command '$CName': interface, inet address and netmask have to be defined"; return; }; defined($Inet2Logic) or (defined($Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}) ? &{$Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}}() : &{$Ifconfig{'list'}{$^O}{'function'}}()) or return; my $Logic = $Inet2Logic->{$Iface}{$Addr}; if (!defined($Logic)) { $@ = "Command '$CName': can not get logic interface for interface '$Iface', inet address '$Addr'"; return; }; my $Res = $Win32API{'iphlpapi'}{'DeleteIPAddress'}->Call($Logic); if ($Res != $Win32_NO_ERROR) { $! = $Res; $@ = &{$Win32_FormatMessage}($Res); return; }; $Inet2Logic = undef; $Logic2Inet = undef; return ['Command completed successfully']; }; $Ifconfig{'inet'} = {'solaris' => {'ifconfig' => '/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% up', 'function' => $UpDown}, # 'MSWin32' => {'ifconfig' => '', # 'function' => $Win32Inet,}, }; $Ifconfig{'inet'}{'freebsd'} = $Ifconfig{'inet'}{'solaris'}; $Ifconfig{'inet'}{'openbsd'} = $Ifconfig{'inet'}{'solaris'}; $Ifconfig{'inet'}{'linux'} = $Ifconfig{'inet'}{'solaris'}; $Ifconfig{'inet'}{'darwin'} = $Ifconfig{'inet'}{'solaris'}; $Ifconfig{'up'} = $Ifconfig{'inet'}; $Ifconfig{'down'}{'solaris'} = {'ifconfig' => '/sbin/ifconfig %Iface% down', 'function' => $UpDown, }; $Ifconfig{'down'}{'freebsd'} = $Ifconfig{'down'}{'solaris'}; $Ifconfig{'down'}{'openbsd'} = $Ifconfig{'down'}{'solaris'}; $Ifconfig{'down'}{'linux'} = $Ifconfig{'down'}{'solaris'}; $Ifconfig{'down'}{'darwin'} = $Ifconfig{'down'}{'solaris'}; $Ifconfig{'+alias'} = {'freebsd' => {'ifconfig' => '/sbin/ifconfig %Iface% inet %Addr% netmask %Mask% alias', 'function' => $UpDown}, 'solaris' => {'ifconfig' => '/sbin/ifconfig %Iface%:%Logic% inet %Addr% netmask %Mask% up', 'function' => $UpDownNewLog}, 'MSWin32' => {'ifconfig' => '', 'function' => $Win32AddAlias,}, }; $Ifconfig{'+alias'}{'openbsd'} = $Ifconfig{'+alias'}{'freebsd'}; $Ifconfig{'+alias'}{'linux'} = $Ifconfig{'+alias'}{'solaris'}; $Ifconfig{'+alias'}{'darwin'} = $Ifconfig{'+alias'}{'freebsd'}; $Ifconfig{'+alias'}{'solaris'}{'SunOS'}{'5.8'}{'ifconfig'} = '/sbin/ifconfig %Iface%:%Logic% plumb; /sbin/ifconfig %Iface%:%Logic% inet %Addr% netmask %Mask% up'; $Ifconfig{'+alias'}{'solaris'}{'SunOS'}{'5.9'}{'ifconfig'} = $Ifconfig{'+alias'}{'solaris'}{'SunOS'}{'5.8'}{'ifconfig'}; $Ifconfig{'+alias'}{'solaris'}{'SunOS'}{'5.10'}{'ifconfig'} = $Ifconfig{'+alias'}{'solaris'}{'SunOS'}{'5.8'}{'ifconfig'}; $Ifconfig{'alias'} = $Ifconfig{'+alias'}; $Ifconfig{'-alias'} = {'freebsd' => {'ifconfig' => '/sbin/ifconfig %Iface% inet %Addr% -alias', 'function' => $UpDown}, 'solaris' => {'ifconfig' => '/sbin/ifconfig %Iface%:%Logic% down', 'function' => $UpDownReqLog}, 'MSWin32' => {'ifconfig' => '', 'function' => $Win32RemAlias,}, }; $Ifconfig{'-alias'}{'openbsd'} = $Ifconfig{'-alias'}{'freebsd'}; $Ifconfig{'-alias'}{'linux'} = $Ifconfig{'-alias'}{'solaris'}; $Ifconfig{'-alias'}{'darwin'} = $Ifconfig{'-alias'}{'freebsd'}; $Ifconfig{'-alias'}{'solaris'}{'SunOS'}{'5.9'}{'ifconfig'} = '/sbin/ifconfig %Iface%:%Logic% unplumb'; sub Ifconfig { my ($CName, $Iface, $Addr, $Mask) = @_; if (!($CName && $Ifconfig{$CName} && $Ifconfig{$CName}{$^O})) { $@ = "Command '$CName' is not defined for system '$^O'"; return; }; defined($Inet2Logic) or (defined($Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}) ? &{$Ifconfig{'list'}{$^O}{$OsName}{$OsVers}{'function'}}() : &{$Ifconfig{'list'}{$^O}{'function'}}()) or return; my $Output = (defined($Ifconfig{$CName}{$^O}{$OsName}{$OsVers}{'function'}) ? &{$Ifconfig{$CName}{$^O}{$OsName}{$OsVers}{'function'}}($CName, $Iface, $Addr, $Mask) : &{$Ifconfig{$CName}{$^O}{'function'}}($CName, $Iface, $Addr, $Mask)); $Output ? return $Output : return; }; 1; __END__ =head1 NAME Net::Ifconfig::Wrapper - provides a unified way to configure network interfaces on FreeBSD, OpenBSD, Solaris, Linux, OS X, and WinNT (from Win2K). =head1 SYNOPSIS use Net::Ifconfig::Wrapper; my $rhInfo = Net::Ifconfig::Wrapper::Ifconfig('list'); =head1 DESCRIPTION This module provides a unified way to configure the network interfaces on FreeBSD, OpenBSD, Solaris, Linux, OS X, and WinNT (from Win2K) systems. I (IPv4) and C (MAC) addresses are supported at this time>> On Unix, this module calls the system C command to gather the information. On Windows, the functions from IpHlpAPI.DLL are called. For all supported Unixes, C expects the C command to be C. See the top-level README file for a list of tested OSes. I =head1 The Net::Ifconfig::Wrapper methods =over 4 =item C, I, I
, I);> The one and only method of the C module. Does all the jobs. The particular action is described by the C<$Command> parameter. C<$Command> could be: =over 8 =item 'list' C will return a reference to a hash containing 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, ... }, ... }; I, I
, I parameters are ignored. The following shows what program is called for each OS: =over 12 =item FreeBSD C =item Solaris C =item OpenBSD C =item Linux C =item OS X C =item MSWin32 C function from C =back Known Limitations: OpenBSD: C command is not returning information about MAC addresses so we are trying to get it from C<'/usr/sbin/arp -a'> command (first I> entry). If no one present the I> address is returned. MSWin32: C function is not returning information about the interface which has address C<127.0.0.1> bound to it, so we have no way to return it. Not a limitation, but a small problem: in MSWin32, interface names are not human-readable, they look like C<{843C2077-30EC-4C56-A401-658BB1E42BC7}> (on Win2K at least). =item 'inet' This function is used to set IPv4 address on interface. It is called as Ifconfig('inet', $IfaceName, $Addr, $Mask); I> is an interface name as displayed by C<'list'> command I> is an IPv4 address in the C notation I> is an IPv4 subnet mask in the C notation In order to accomplish this, the following actual C programs are called: =over 12 =item FreeBSD C =item Solaris C =item OpenBSD C =item Linux C =item OS X C =item MSWin32: nothing :( =back Known Limitations: MSWin32: I did not find a reliable way to recognize the "main" address on the Win32 network interface, so I have disabled this functionality. If you know how, please let me know. =item 'up' Just a synonym for C<'inet'> =item 'down' This function is used to bring specified interface down. It is called as Ifconfig('inet', $IfaceName, '', ''); I> is an interface name as displayed by C<'list'> command Last two arguments are ignored. In order to accomplish this, the following programs are called: =over 12 =item FreeBSD C =item Solaris C =item OpenBSD C =item Linux C =item OS X C =item MSWin32 Sorry, this function is not possible. =back Known Limitations: MSWin32: I did not find the way to implement the C<'up'> command so I did not implement C<'down'>. =item '+alias' This function is used to set IPv4 alias address on interface. It have to be called as Ifconfig('+alias', $IfaceName, $Addr, $Mask); I> is an interface name as displayed by C<'list'> command I> is an IPv4 address in the C notation I> is an IPv4 subnet mask in the C notation In order to accomplish this, the following C programs are called: =over 12 =item FreeBSD C =item Solaris C =item OpenBSD C =item Linux C =item OS X C =item MSWin32 C function from C =back I =item 'alias' Just a synonim for C<'+alias'> =item '-alias' This function is used to remove IPv4 alias address from interface. It have to be called as Ifconfig('-alias', $IfaceName, $Addr, ''); I> is an interface name as displayed by C<'list'> command. I> is an IPv4 address in the C notation. Last argument is ignored if present. In order to accomplish this, the following C programs are called: =over 12 =item FreeBSD C =item Solaris C =item OpenBSD C =item Linux C =item OS X C =item MSWin32 C function from C =back I =back On success, the C function returns the defined value. Actually, it is a reference to the array containing the output of the actual I> program called. In case of error, C returns C<'undef'> value, and the C<$@> variable contains the error message. =back =head2 EXPORT None by default. =head1 AUTHOR Daniel Podolsky, Etpaba@cpan.orgE As of 2015-11, maintained by Martin Thurn Emthurn@cpan.orgE =head1 SEE ALSO L(8), I in I. =cut Net-Ifconfig-Wrapper-0.14/MANIFEST0000644000175000017500000000044712655413415016036 0ustar martinmartinlib/Net/Ifconfig/Wrapper.pm Makefile.PL MANIFEST This list of files README README.md t/20_list.t t/test.pl t/uni-ifconfig.pl META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Net-Ifconfig-Wrapper-0.14/README.md0000644000175000017500000000007212626321206016150 0ustar martinmartin# Net-Ifconfig-Wrapper Perl module Net::Ifconfig::Wrapper Net-Ifconfig-Wrapper-0.14/Makefile.PL0000644000175000017500000000243512655413374016662 0ustar martinmartinuse 5.008004; # TODO: convert to Module::Install use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. my %supported = ('freebsd' => 1, 'solaris' => 1, 'linux' => 1, 'openbsd' => 1, 'MSWin32' => 1, 'darwin' => 1, 'cygwin' => 1, ); $supported{$^O} or warn "\nWARNING! Your system '$^O' is not supported\b\n\n"; my $preReq = {'POSIX' => 0,}; if ( $^O eq 'MSWin32' ) { Win32::IsWinNT() or warn "\nWARNING! Only WinNT (from Win2K) is supported\b\n\n"; $preReq->{'Win32::API'} = 0; $preReq->{'Win32::WinError'} = 0; }; if ( $^O eq 'cygwin' ) { $preReq->{'Win32::API'} = 0; $preReq->{'Win32::WinError'} = 0; }; WriteMakefile( NAME => 'Net::Ifconfig::Wrapper', VERSION_FROM => 'lib/Net/Ifconfig/Wrapper.pm', # finds $VERSION PREREQ_PM => $preReq, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/Net/Ifconfig/Wrapper.pm', # retrieve abstract from module AUTHOR => 'Daniel Podolsky ') : ()), ); Net-Ifconfig-Wrapper-0.14/README0000644000175000017500000000176212626325777015601 0ustar martinmartinNet::IfConfig::Wrapper ====================== This module can be used to call the ifconfig command on different Unix systems and Windows NT systems. It provided a unified way to obtain info from ifconfig, create and delete the IP aliases on interfaces, etc. At certain times in the past, this module was tested (successfully) on the following OSes and versions: CentOS 7.1 FreeBSD 4.7 FreeBSD 4.8 FreeBSD 5.3 FreeBSD 6.2 FreeBSD 7.2 OpenBSD 3.1 OS X 10.3 (aka Panther) OS X 10.4 (aka Tiger) OS X 10.5 (aka Leopard) RedHat 6.2 RedHat 7.3 RedHat 8.0 Solaris 7 Windows 2000 Pro Windows XP Pro Windows 7 INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires these other modules: POSIX Win32::API (on Win32 or cygwin) Win32::WinError (on Win32 or cygwin) COPYRIGHT AND LICENCE Copyright: Daniel Podolsky , 2003 Licence: Same as perl itself 21 Jan 2003, Daniel Podolsky Net-Ifconfig-Wrapper-0.14/META.yml0000664000175000017500000000121612655413415016153 0ustar martinmartin--- abstract: 'provides a unified way to configure network interfaces on FreeBSD, OpenBSD, Solaris, Linux, OS X, and WinNT (from Win2K).' author: - 'Daniel Podolsky ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.1, CPAN::Meta::Converter version 2.150005' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-Ifconfig-Wrapper no_index: directory: - t - inc requires: POSIX: '0' version: '0.14' x_serialization_backend: 'CPAN::Meta::YAML version 0.016' Net-Ifconfig-Wrapper-0.14/META.json0000664000175000017500000000200712655413415016322 0ustar martinmartin{ "abstract" : "provides a unified way to configure network interfaces on FreeBSD, OpenBSD, Solaris, Linux, OS X, and WinNT (from Win2K).", "author" : [ "Daniel Podolsky " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.1, CPAN::Meta::Converter version 2.150005", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Net-Ifconfig-Wrapper", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "POSIX" : "0" } } }, "release_status" : "stable", "version" : "0.14", "x_serialization_backend" : "JSON::PP version 2.27300" }