From 3dba6e2274d2ec899e92649d731da25e7b8580c7 Mon Sep 17 00:00:00 2001 From: Guillaume Rousse Date: Tue, 17 Apr 2012 23:24:43 +0200 Subject: [PATCH] handle multiple addresses per interface This allow to handle IPv6 addresses and IPv4 aliases (bug #1565). This make status management consistent with Linux code. Close: #1565 Reported-by: Egor Morozov --- .../Task/Inventory/Input/BSD/Networks.pm | 79 ++++++++++----- t/inventory/bsd/networks.t | 98 +++++++++---------- 2 files changed, 105 insertions(+), 72 deletions(-) diff --git a/lib/FusionInventory/Agent/Task/Inventory/Input/BSD/Networks.pm b/lib/FusionInventory/Agent/Task/Inventory/Input/BSD/Networks.pm index 6e23255e1e..b2f71e8cc2 100644 --- a/lib/FusionInventory/Agent/Task/Inventory/Input/BSD/Networks.pm +++ b/lib/FusionInventory/Agent/Task/Inventory/Input/BSD/Networks.pm @@ -66,42 +66,77 @@ sub _parseIfconfig { my $handle = getFileHandle(@_); return unless $handle; - my @interfaces; - my $interface; + my @interfaces; # global list of interfaces + my @addresses; # per-interface list of addresses + my $interface; # current interface while (my $line = <$handle>) { - if ($line =~ /^(\S+):/) { - # new interface - push @interfaces, $interface if $interface; + if ($line =~ /^(\S+): flags=\d+<([^>]+)> metric \d+ mtu (\d+)/) { + + if (@addresses) { + push @interfaces, @addresses; + undef @addresses; + } else { + push @interfaces, $interface if $interface; + } + $interface = { - STATUS => 'Down', - DESCRIPTION => $1 + DESCRIPTION => $1, + MTU => $3 }; - } + my $flags = $2; - if ($line =~ /inet ($ip_address_pattern)/) { - $interface->{IPADDRESS} = $1; - } - if ($line =~ /netmask 0x($hex_ip_address_pattern)/) { - $interface->{IPMASK} = hex2canonical($1); - } - if ($line =~ /(?:address:|ether|lladdr) ($mac_address_pattern)/) { + foreach my $flag (split(/,/, $flags)) { + next unless $flag eq 'UP' || $flag eq 'DOWN'; + $interface->{STATUS} = ucfirst(lc($flag)); + } + } elsif ($line =~ /(?:address:|ether|lladdr) ($mac_address_pattern)/) { $interface->{MACADDR} = $1; + + } elsif ($line =~ /inet ($ip_address_pattern) (?:--> $ip_address_pattern )?netmask 0x($hex_ip_address_pattern)/) { + my $address = $1; + my $mask = hex2canonical($2); + my $subnet = getSubnetAddress($address, $mask); + + push @addresses, { + IPADDRESS => $address, + IPMASK => $mask, + IPSUBNET => $subnet, + STATUS => $interface->{STATUS}, + DESCRIPTION => $interface->{DESCRIPTION}, + MACADDR => $interface->{MACADDR}, + MTU => $interface->{MTU} + }; + } elsif ($line =~ /inet6 ([\w:]+)\S* prefixlen (\d+)/) { + my $address = $1; + my $mask = getNetworkMaskIPv6($2); + my $subnet = getSubnetAddressIPv6($address, $mask); + + push @addresses, { + IPADDRESS6 => $address, + IPMASK6 => $mask, + IPSUBNET6 => $subnet, + STATUS => $interface->{STATUS}, + DESCRIPTION => $interface->{DESCRIPTION}, + MACADDR => $interface->{MACADDR}, + MTU => $interface->{MTU} + }; + } - if ($line =~ /mtu (\S+)/) { - $interface->{MTU} = $1; - } + if ($line =~ /media (\S+)/) { $interface->{TYPE} = $1; - } - if ($line =~ /{STATUS} = 'Up'; + $_->{TYPE} = $1 foreach @addresses; } } close $handle; # last interface - push @interfaces, $interface if $interface; + if (@addresses) { + push @interfaces, @addresses; + } else { + push @interfaces, $interface if $interface; + } return @interfaces; } diff --git a/t/inventory/bsd/networks.t b/t/inventory/bsd/networks.t index 1e464bdf73..fc00c0a002 100755 --- a/t/inventory/bsd/networks.t +++ b/t/inventory/bsd/networks.t @@ -10,88 +10,86 @@ use FusionInventory::Agent::Task::Inventory::Input::BSD::Networks; my %ifconfig_tests = ( 'freebsd-8.1' => [ { - MTU => '1500', - IPMASK => '255.255.255.192', - MACADDR => 'c8:0a:a9:3f:35:fa', DESCRIPTION => 're0', STATUS => 'Up', - IPADDRESS => '129.132.95.98' + MTU => '1500', + MACADDR => 'c8:0a:a9:3f:35:fa', + IPADDRESS => '129.132.95.98', + IPMASK => '255.255.255.192', + IPSUBNET => '129.132.95.64', }, { + DESCRIPTION => 'fwe0', MTU => '1500', MACADDR => '02:24:1b:9d:ca:01', - DESCRIPTION => 'fwe0', - STATUS => 'Down' }, { - MTU => '1500', DESCRIPTION => 'fwip0', - STATUS => 'Down' + MTU => '1500', }, { - MTU => '16384', - IPMASK => '255.0.0.0', DESCRIPTION => 'lo0', + MTU => '16384', STATUS => 'Up', - IPADDRESS => '127.0.0.1' + MACADDR => undef, + IPADDRESS6 => 'fe80::1', + IPMASK6 => 'ffff:ffff:ffff:ffff::', + IPSUBNET6 => 'fe80::', }, { - MTU => '1500', - MACADDR => '0a:00:27:00:00:00', - DESCRIPTION => 'vboxnet0', - STATUS => 'Down' - }, - { - MTU => '1500', - IPMASK => '255.255.255.255', - DESCRIPTION => 'tun0', - STATUS => 'Up', - IPADDRESS => '192.168.200.6' - } - ], - 'solaris-10' => [ - { - MTU => '8232', DESCRIPTION => 'lo0', STATUS => 'Up', - IPADDRESS => '127.0.0.1' + MTU => '16384', + MACADDR => undef, + IPADDRESS6 => '::1', + IPMASK6 => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + IPSUBNET6 => '::1', }, { - MTU => '1500', - DESCRIPTION => 'aggr1', + DESCRIPTION => 'lo0', STATUS => 'Up', - IPADDRESS => '130.79.0.1' + MTU => '16384', + MACADDR => undef, + IPADDRESS => '127.0.0.1', + IPSUBNET => '127.0.0.0', + IPMASK => '255.0.0.0', }, { + DESCRIPTION => 'vboxnet0', MTU => '1500', - DESCRIPTION => 'e1000g0', - STATUS => 'Up', - IPADDRESS => '130.79.0.2' + MACADDR => '0a:00:27:00:00:00', }, { - MTU => '1500', - DESCRIPTION => 'e1000g2', + DESCRIPTION => 'tun0', STATUS => 'Up', - IPADDRESS => '130.79.0.3' - }, - { MTU => '1500', - DESCRIPTION => 'e1000g3', - STATUS => 'Up', - IPADDRESS => '192.168.19.1' - }, + MACADDR => undef, + IPADDRESS => '192.168.200.6', + IPSUBNET => '192.168.200.6', + IPMASK => '255.255.255.255', + } + ], + 'freebsd-bis' => [ { - MTU => '1500', - DESCRIPTION => 'e1000g4', + DESCRIPTION => 're0', STATUS => 'Up', - IPADDRESS => '130.79.255.1' + MTU => '1500', + MACADDR => '00:ab:cd:ef:1a:00', + IPADDRESS => '192.168.10.10', + IPMASK => '255.255.255.0', + IPSUBNET => '192.168.10.0', + }, { - MTU => '1500', - DESCRIPTION => 'igb0', + DESCRIPTION => 're0', STATUS => 'Up', - IPADDRESS => '192.168.20.1' - } + MTU => '1500', + MACADDR => '00:ab:cd:ef:1a:00', + IPADDRESS => '192.168.10.11', + IPMASK => '255.255.255.255', + IPSUBNET => '192.168.10.11', + + } ] );