-package Ocsinventory::Agent::Backend::OS::Linux::Network::Networks;
-
-use strict;
-use warnings;
-use Data::Dumper;
-use File::stat;
-use Time::Local;
-
-sub check {
- my $params = shift;
- my $common = $params->{common};
- return unless ($common->can_run("ifconfig") || $common->can_run("ip")) && $common->can_run("route") && $common->can_load("Net::IP qw(:PROC)");
- 1;
-}
-
-sub getLeaseFile {
-
- my $if = @_;
- my @directories = qw(
- /var/db
- /var/lib/dhclient
- /var/lib/dhcp3
- /var/lib/dhcp
- /var/lib/NetworkManager
- );
- my @patterns = ("*$if*.lease", "*.lease", "dhclient.leases.$if");
- my @files;
-
- foreach my $directory (@directories) {
- next unless -d $directory;
- foreach my $pattern (@patterns) {
- push @files,
- grep { -s $_ }
- glob("$directory/$pattern");
- }
- }
- return unless @files;
- @files =
- map {$_->[0]}
- sort {$a->[1]->ctime()<=>$b->[1]->ctime()}
- map {[$_,stat($_)]}
- @files;
- return $files[-1];
-
-}
-
-sub _ipdhcp {
-
- my $if = shift;
- my $path;
- my $dhcp;
- my $ipdhcp;
- my $leasepath;
-
- if( $leasepath = getLeaseFile($if) ) {
- if (open DHCP, $leasepath) {
- my $lease;
- while(<DHCP>){
- $lease = 1 if(/lease\s*{/i);
- $lease = 0 if(/^\s*}\s*$/);
- #Interface name
- if ($lease) { #inside a lease section
- if (/interface\s+"(.+?)"\s*/){
- $dhcp = ($1 =~ /^$if$/);
- }
- #Server IP
- if (/option\s+dhcp-server-identifier\s+(\d{1,3}(?:\.\d{1,3}){3})\s*;/ and $dhcp){
- $ipdhcp = $1;
- }
- }
- }
- close DHCP or warn;
- } else {
- warn "Can't open $leasepath\n";
- }
- }
- return $ipdhcp;
-}
-
-# Initialise the distro entry
-sub run {
-
- my $params = shift;
- my $common = $params->{common};
- my $logger = $params->{logger};
-
- my $description;
- my $driver;
- my $ipaddress;
- my $ipgateway;
- my $ipmask;
- my $ipsubnet;
- my $macaddr;
- my $pcislot;
- my $status;
- my $type;
- my $virtualdev;
- my $settings;
- my $speed;
- my $current_speed;
- my $duplex;
- my $ssid;
- my $bssid;
- my $mode;
- my $version;
- my $bitrate;
- my $address;
- my $mask4;
- my $mask6;
- my $binip;
- my $binmask;
- my $binsubnet;
- my $mtu;
-
- my %gateway;
-
- if ($common->can_run("ip")){
- my @ipLink = `ip -o link`;
- foreach my $line (`ip -o addr`) {
- $ipsubnet = $ipaddress = $ipmask = $ipgateway = $macaddr = $status = $type = $speed = $duplex = $driver = $pcislot = $virtualdev = $mtu = undef;
- $description = "";
- if ($line =~ /lo.*(127\.0\.0\.1\/8)/) { # ignore default loopback interface
- next;
- }
- if ($line =~ /lo.*(::1\/128)/) { # ignore default loopback interface
- next;
- }
-
- $description = $1 if ($line =~ /\d:\s+([\w\d]+)\s+/i);
-
- if ($line =~ /inet (\S+)\/(\d{2})/i){
- $ipaddress = $1;
- $mask4 = $2;
- } elsif ($line =~ /inet6 (\S+)\/(\d{2})/i){
- $ipaddress = $1;
- $mask6 = $2;
- }
-
- if (ip_is_ipv4($ipaddress)){
- foreach (`route -n`) {
- if (/^(\d+\.\d+\.\d+\.\d+)\s+(\d+\.\d+\.\d+\.\d+)/) {
- $gateway{$1} = $2;
- }
- }
-
- if (defined ($gateway{'0.0.0.0'})) {
- $common->setHardware({
- DEFAULTGATEWAY => $gateway{'0.0.0.0'}
- });
- }
-
-
- $ipmask = ip_bintoip(ip_get_mask($mask4,4),4) if $mask4;
- $binip = ip_iptobin($ipaddress,4) if $ipaddress;
- $binmask = ip_iptobin($ipmask,4) if $ipmask;
- $binsubnet = $binip & $binmask if ($binip && $binmask);
- $ipsubnet = ip_bintoip($binsubnet,4) if $binsubnet;
- } elsif (ip_is_ipv6($ipaddress)) {
-
- foreach (`route -nA inet6`) {
- if(/^(\S+)\/\d{1,3}\s+(\S+)/) {
- next if ($1 eq $2);
- $gateway{$1} = $2;
- }
- }
-
- $ipmask = ip_bintoip(ip_get_mask($mask6,6),6) if $mask6;;
- $binip = ip_iptobin(ip_expand_address($ipaddress,6),6) if $ipaddress;
- $binmask = ip_iptobin(ip_expand_address($ipmask,6),6) if $ipmask;
- $binsubnet = $binip & $binmask if ($binip && $binmask);
- $ipsubnet = ip_compress_address(ip_bintoip($binsubnet,6),6) if $binsubnet;
- }
-
- my @line1 = split " ", $line;
- my @linkData = split " ", (grep {/$line1[1]/} @ipLink)[0];
- $macaddr = uc $linkData[-3];
- $mtu = $linkData[4];
-
- if ($linkData[2] =~ /,UP/) {
- $status = "UP";
- } else {
- $status = "DOWN";
- }
-
- $type = $linkData[-4];
- if ($type =~ /ether/){
- $type = "Ethernet";
- } elsif ($type =~ /loopback/) {
- $type = "Loopback";
- }
-
- $ipgateway = $gateway{$ipsubnet} if $ipsubnet;
- # replace '0.0.0.0' and '::' (ie 'default gateway') by the default gateway IP address if it exists
- if (defined($ipgateway) and $ipgateway eq '0.0.0.0' and defined($gateway{'0.0.0.0'})) {
- $ipgateway = $gateway{'0.0.0.0'};
- }
- if (defined($ipgateway) and $ipgateway eq '::' and defined($gateway{'::'})) {
- $ipgateway = $gateway{'::'};
- }
-
- if (open UEVENT, "</sys/class/net/$description/device/uevent") {
- foreach (<UEVENT>) {
- $driver = $1 if /^DRIVER=(\S+)/;
- $pcislot = $1 if /^PCI_SLOT_NAME=(\S+)/;
- }
- close UEVENT;
- }
-
- # Retrieve speed from /sys/class/net/$description/speed
- if ( ! -z "/sys/class/net/$description/speed") {
- if(open SPEED, "</sys/class/net/$description/speed") {
- foreach (<SPEED>){
- $current_speed=$_;
- }
- close SPEED;
- }
-
- if (defined $current_speed) {
- chomp($current_speed);
- if ($current_speed eq "65535"){
- $current_speed = 0;
- } elsif ( $current_speed gt 100 ){
- $speed = ($current_speed/1000)." Gbps";
- } else {
- $speed = $current_speed." Mbps";
- }
- }
- }
-
- # Retrieve duplex from /sys/class/net/$description/duplex
- if (open DUPLEX, "</sys/class/net/$description/duplex"){
- foreach (<DUPLEX>){
- $duplex=chomp($_);
- }
- close DUPLEX;
- }
-
- # Reliable way to get the info
- if (-d "/sys/devices/virtual/net/") {
- $virtualdev = (-d "/sys/devices/virtual/net/$description")?"1":"0";
- } elsif ($common->can_run("brctl")) {
- # Let's guess
- my %bridge;
- foreach (`brctl show`) {
- next if /^bridge name/;
- $bridge{$1} = 1 if /^(\w+)\s/;
- }
- if ($pcislot) {
- $virtualdev = "1";
- } elsif ($bridge{$description}) {
- $virtualdev = "0";
- }
- $type = "bridge";
- }
-
- if (-d "/sys/class/net/$description/wireless"){
- my @wifistatus = `iwconfig $description`;
- foreach my $line (@wifistatus){
- $ssid = $1 if ($line =~ /ESSID:(\S+)/);
- $version = $1 if ($line =~ /IEEE (\S+)/);
- $mode = $1 if ($line =~ /Mode:(\S+)/);
- $bssid = $1 if ($line =~ /Access Point: (\S+)/);
- $bitrate = $1 if ($line =~ /Bit\sRate=\s*(\S+\sMb\/s)/i);
- }
- $type = "Wifi";
- }
- if ($description ne "") {
- if ($type eq "Wifi") {
- $common->addNetwork({
- DESCRIPTION => $description,
- DRIVER => $driver,
- IPADDRESS => $ipaddress,
- IPDHCP => _ipdhcp($description),
- IPGATEWAY => $ipgateway,
- IPMASK => $ipmask,
- IPSUBNET => $ipsubnet,
- MACADDR => $macaddr,
- PCISLOT => $pcislot,
- STATUS => $status,
- TYPE => $type,
- SPEED => $bitrate,
- SSID => $ssid,
- BSSID => $bssid,
- IEEE => $version,
- MODE => $mode,
- });
- } else {
- $common->addNetwork({
- DESCRIPTION => $description,
- DRIVER => $driver,
- IPADDRESS => $ipaddress,
- IPDHCP => _ipdhcp($description),
- IPGATEWAY => $ipgateway,
- IPMASK => $ipmask,
- IPSUBNET => $ipsubnet,
- MACADDR => $macaddr,
- PCISLOT => $pcislot,
- STATUS => $status,
- TYPE => $type,
- VIRTUALDEV => $virtualdev,
- DUPLEX => $duplex?"Full":"Half",
- SPEED => $speed,
- MTU => $mtu,
- });
- }
- }
- }
- }
-
- elsif ($common->can_run("ifconfig")){
- foreach my $line (`ifconfig -a`) {
- if ($line =~ /^$/ && $description && $macaddr) {
- # end of interface section
- # I write the entry
- if (ip_is_ipv4($ipaddress)){
- foreach (`route -n`) {
- if (/^(\d+\.\d+\.\d+\.\d+)\s+(\d+\.\d+\.\d+\.\d+)/) {
- $gateway{$1} = $2;
- }
- }
-
- if (defined ($gateway{'0.0.0.0'})) {
- $common->setHardware({
- DEFAULTGATEWAY => $gateway{'0.0.0.0'}
- });
- }
-
- $binip = ip_iptobin ($ipaddress ,4) if $ipaddress;
- $binmask = ip_iptobin ($ipmask,4) if $ipmask;
- $binsubnet = $binip & $binmask if ($binip && $binmask);
- $ipsubnet = ip_bintoip($binsubnet,4) if $binsubnet;
- } elsif (ip_is_ipv6($ipaddress)) {
- # Table de routage IPv6 du noyau
- # Destination Next Hop Flag Met Ref Use If
- # fe80::/64 [::] U 256 0 0 wlp6s0
- # foreach (`route -6`) {
- # if (/^(\S+\/\d{2})\s+(\S+)/) {
- # $gateway{$1} = $2;
- # }
- #}
- #if (defined ($gateway{'fe80::/64'})) {
- # $common->setHardware({
- # DEFAULTGATEWAY => $gateway{'fe80::/64'}
- # });
- #}
-
- foreach (`route -nA inet6`) {
- if(/^(\S+)\/\d{1,3}\s+(\S+)/) {
- next if ($1 eq $2);
- $gateway{$1} = $2;
- }
- }
-
-
- $ipmask = ip_bintoip(ip_get_mask($mask6,6),6) if $mask6;;
- $binip = ip_iptobin(ip_expand_address($ipaddress,6),6) if $ipaddress;
- $binmask = ip_iptobin(ip_expand_address($ipmask,6),6) if $ipmask;
- $binsubnet = $binip & $binmask if ($binip && $binmask);
- $ipsubnet = ip_compress_address(ip_bintoip($binsubnet,6),6) if $binsubnet;
- }
-
- $ipgateway = $gateway{$ipsubnet} if $ipsubnet;
-
- if (-d "/sys/class/net/$description/wireless"){
- my @wifistatus = `iwconfig $description`;
- foreach my $line (@wifistatus){
- $ssid = $1 if ($line =~ /ESSID:(\S+)/);
- $version = $1 if ($line =~ /IEEE (\S+)/);
- $mode = $1 if ($line =~ /Mode:(\S+)/);
- $bssid = $1 if ($line =~ /Access Point: (\S+)/);
- $bitrate = $1 if ($line =~ /Bit\sRate=\s*(\S+\sMb\/s)/i);
- }
- $type = "Wifi";
- }
-
- if (-f "/sys/class/net/$description/mode"){
- $type = "infiniband";
- }
-
- # replace '0.0.0.0' and '::' (ie 'default gateway') by the default gateway IP address if it exists
- if (defined($ipgateway) and $ipgateway eq '0.0.0.0' and defined($gateway{'0.0.0.0'})) {
- $ipgateway = $gateway{'0.0.0.0'};
- }
- if (defined($ipgateway) and $ipgateway eq '::' and defined($gateway{'::'})) {
- $ipgateway = $gateway{'::'};
- }
-
- if (open UEVENT, "</sys/class/net/$description/device/uevent") {
- foreach (<UEVENT>) {
- $driver = $1 if /^DRIVER=(\S+)/;
- $pcislot = $1 if /^PCI_SLOT_NAME=(\S+)/;
- }
- close UEVENT;
- }
-
- # Retrieve speed from /sys/class/net/$description/speed
- if ( ! -z "/sys/class/net/$description/speed") {
- open SPEED, "</sys/class/net/$description/speed";
- foreach (<SPEED>){
- $current_speed=$_;
- }
- close SPEED;
- chomp($current_speed);
-
- $current_speed=0 if $current_speed eq "";
- if ($current_speed eq "65535"){
- $current_speed = 0;
- }
- if ($current_speed gt 100 ){
- $speed = ($current_speed/1000)." Gbps";
- } else {
- $speed = $current_speed." Mbps";
- }
- }
-
- # Retrieve duplex from /sys/class/net/$description/duplex
- if (! -z "/sys/class/net/$description/duplex") {
- open DUPLEX, "</sys/class/net/$description/duplex";
- foreach (<DUPLEX>){
- $duplex=chomp($_);
- }
- close DUPLEX;
- }
-
- # Reliable way to get the info
- if (-d "/sys/devices/virtual/net/") {
- $virtualdev = (-d "/sys/devices/virtual/net/$description")?"1":"0";
- } elsif ($common->can_run("brctl")) {
- # Let's guess
- my %bridge;
- foreach (`brctl show`) {
- next if /^bridge name/;
- $bridge{$1} = 1 if /^(\w+)\s/;
- }
- if ($pcislot) {
- $virtualdev = "1";
- } elsif ($bridge{$description}) {
- $virtualdev = "0";
- }
- $type = "bridge";
- }
-
- if ($type eq "Wifi") {
- $common->addNetwork({
- DESCRIPTION => $description,
- DRIVER => $driver,
- IPADDRESS => $ipaddress,
- IPDHCP => _ipdhcp($description),
- IPGATEWAY => $ipgateway,
- IPMASK => $ipmask,
- IPSUBNET => $ipsubnet,
- MACADDR => $macaddr,
- PCISLOT => $pcislot,
- STATUS => $status,
- TYPE => $type,
- SPEED => $bitrate,
- SSID => $ssid,
- BSSID => $bssid,
- IEEE => $version,
- MODE => $mode,
- });
- } else {
- $common->addNetwork({
- DESCRIPTION => $description,
- DRIVER => $driver,
- IPADDRESS => $ipaddress,
- IPDHCP => _ipdhcp($description),
- IPGATEWAY => $ipgateway,
- IPMASK => $ipmask,
- IPSUBNET => $ipsubnet,
- MACADDR => $macaddr,
- PCISLOT => $pcislot,
- STATUS => $status,
- TYPE => $type,
- VIRTUALDEV => $virtualdev,
- DUPLEX => $duplex?"Full":"Half",
- SPEED => $speed,
- MTU => $mtu,
- });
- }
- }
-
- if ($line =~ /^$/) { # End of section
- $description = $driver = $ipaddress = $ipgateway = $ipmask = $ipsubnet = $macaddr = $pcislot = $status = $type = $virtualdev = $speed = $duplex = $mtu = undef;
- } else { # In a section
- if ($line =~ /^(\S+):\s\S+\s*mtu\s(\d+)/) {
- $description = $1; # Interface name
- $mtu = $2;
- }
-
- $description = $1 if($line =~ /^(\w+)\s+/); # Interface name
-
- # BUG: ipv4 address gets overwritten by ipv6 address but we want all ip addresses
- if ($line =~ /inet add?r:(\S+)/i || $line =~ /^\s*inet\s+(\S+)/i || $line =~ /inet (\S+)\s+netmask/i){
- $ipaddress=$1;
- } elsif ($line =~ /inet6 (\S+)\s+prefixlen\s+(\d{2})/i){
- $ipaddress=$1;
- $mask6=$2;
- }
- if ($line =~ /\S*mask:(\S+)/i || $line =~ /\S*netmask (\S+)\s/i){
- $ipmask=$1;
- }
- $macaddr = $1 if ($line =~ /hwadd?r\s+(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})/i || $line =~ /ether\s+(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})/i);
- $status = 1 if ($line =~ /^\s+UP\s/ || $line =~ /flags=.*[<,]UP[,>]/);
- $type = $1 if ($line =~ /link encap:(\S+)/i);
- $type = $2 if ($line =~ /^\s+(loop|ether).*\((\S+)\)/i);
- $mtu = $1 if ($line =~ /MTU:(\d+)/i);
- }
- }
- }
-}
-
-1;
-