File Coverage

blib/lib/FusionInventory/Agent/Task/Inventory/Linux/Networks.pm
Criterion Covered Total %
statement 29 118 24.5
branch 10 60 16.6
condition 0 3 0.0
subroutine 7 13 53.8
pod 0 2 0.0
total 46 196 23.4


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Task::Inventory::Linux::Networks;
2              
3 2     2   34206389 use strict;
  2         7  
  2         71  
4 2     2   9 use warnings;
  2         2  
  2         69  
5              
6 2     2   727 use FusionInventory::Agent::Tools;
  2         5  
  2         338  
7 2     2   737 use FusionInventory::Agent::Tools::Network;
  2         4  
  2         286  
8 2     2   821 use FusionInventory::Agent::Tools::Unix;
  2         3  
  2         119  
9 2     2   735 use FusionInventory::Agent::Tools::Linux;
  2         4  
  2         2049  
10              
11             sub isEnabled {
12 0     0 0 0 my (%params) = @_;
13 0 0       0 return 0 if $params{no_category}->{network};
14 0         0 return 1;
15             }
16              
17             sub doInventory {
18 0     0 0 0 my (%params) = @_;
19              
20 0         0 my $inventory = $params{inventory};
21 0         0 my $logger = $params{logger};
22              
23 0         0 my $routes = getRoutingTable(command => 'netstat -nr', logger => $logger);
24 0         0 my $default = $routes->{'0.0.0.0'};
25              
26 0         0 my @interfaces = _getInterfaces(logger => $logger);
27 0         0 foreach my $interface (@interfaces) {
28             # if the default gateway address and the interface address belongs to
29             # the same network, that's the gateway for this network
30             $interface->{IPGATEWAY} = $default if isSameNetwork(
31             $default, $interface->{IPADDRESS}, $interface->{IPMASK}
32 0 0       0 );
33              
34 0         0 $inventory->addEntry(
35             section => 'NETWORKS',
36             entry => $interface
37             );
38             }
39              
40             $inventory->setHardware({
41 0         0 DEFAULTGATEWAY => $default
42             });
43             }
44              
45             sub _getInterfaces {
46 0     0   0 my (%params) = @_;
47              
48 0         0 my $logger = $params{logger};
49              
50 0         0 my @interfaces = _getInterfacesBase(logger => $logger);
51              
52 0         0 foreach my $interface (@interfaces) {
53             $interface->{IPSUBNET} = getSubnetAddress(
54             $interface->{IPADDRESS},
55             $interface->{IPMASK}
56 0         0 );
57              
58             $interface->{IPDHCP} = getIpDhcp(
59             $logger,
60             $interface->{DESCRIPTION}
61 0         0 );
62              
63             # check if it is a physical interface
64 0 0       0 if (-d "/sys/class/net/$interface->{DESCRIPTION}/device") {
65 0         0 my $info = _getUevent($interface->{DESCRIPTION});
66             $interface->{DRIVER} = $info->{DRIVER}
67 0 0       0 if $info->{DRIVER};
68             $interface->{PCISLOT} = $info->{PCI_SLOT_NAME}
69 0 0       0 if $info->{PCI_SLOT_NAME};
70             $interface->{PCIID} =
71             $info->{PCI_ID} . ':' . $info->{PCI_SUBSYS_ID}
72 0 0 0     0 if $info->{PCI_SUBSYS_ID} && $info->{PCI_ID};
73              
74 0         0 $interface->{VIRTUALDEV} = 0;
75              
76             # check if it is a wifi interface, otherwise assume ethernet
77 0 0       0 if (-d "/sys/class/net/$interface->{DESCRIPTION}/wireless") {
    0          
78 0         0 $interface->{TYPE} = 'wifi';
79 0         0 my $info = _parseIwconfig(name => $interface->{DESCRIPTION});
80 0         0 $interface->{WIFI_MODE} = $info->{mode};
81 0         0 $interface->{WIFI_SSID} = $info->{SSID};
82 0         0 $interface->{WIFI_BSSID} = $info->{BSSID};
83 0         0 $interface->{WIFI_VERSION} = $info->{version};
84             } elsif (-f "/sys/class/net/$interface->{DESCRIPTION}/mode") {
85 0         0 $interface->{TYPE} = 'infiniband';
86             } else {
87 0         0 $interface->{TYPE} = 'ethernet';
88             }
89              
90             } else {
91 0         0 $interface->{VIRTUALDEV} = 1;
92              
93 0 0       0 if ($interface->{DESCRIPTION} eq 'lo') {
94 0         0 $interface->{TYPE} = 'loopback';
95             }
96              
97 0 0       0 if ($interface->{DESCRIPTION} =~ m/^ppp/) {
98 0         0 $interface->{TYPE} = 'dialup';
99             }
100              
101             # check if it is an alias or a tagged interface
102 0 0       0 if ($interface->{DESCRIPTION} =~ m/^([\w\d]+)[:.]\d+$/) {
103 0         0 $interface->{TYPE} = 'alias';
104 0         0 $interface->{BASE} = $1;
105             }
106             # check if is is a bridge
107 0 0       0 if (-d "/sys/class/net/$interface->{DESCRIPTION}/brif") {
108 0         0 $interface->{SLAVES} = _getSlaves($interface->{DESCRIPTION});
109 0         0 $interface->{TYPE} = 'bridge';
110             }
111              
112             # check if it is a bonding master
113 0 0       0 if (-d "/sys/class/net/$interface->{DESCRIPTION}/bonding") {
114 0         0 $interface->{SLAVES} = _getSlaves($interface->{DESCRIPTION});
115 0         0 $interface->{TYPE} = 'aggregate';
116             }
117             }
118              
119             # check if it is a bonding slave
120 0 0       0 if (-d "/sys/class/net/$interface->{DESCRIPTION}/bonding_slave") {
121 0         0 $interface->{MACADDR} = getFirstMatch(
122             command => "ethtool -P $interface->{DESCRIPTION}",
123             pattern => qr/^Permanent address: ($mac_address_pattern)$/,
124             logger => $logger
125             );
126             }
127              
128 0 0       0 if (-r "/sys/class/net/$interface->{DESCRIPTION}/speed") {
129 0         0 my $speed = getFirstLine(
130             file => "/sys/class/net/$interface->{DESCRIPTION}/speed"
131             );
132 0 0       0 $interface->{SPEED} = $speed if $speed;
133             }
134             # On older kernels, we should try ethtool system call for speed
135 0 0       0 if (!$interface->{SPEED}) {
136 0         0 $logger->debug("looking for interface speed from syscall:");
137             my $infos = getInterfacesInfosFromIoctl(
138             interface => $interface->{DESCRIPTION},
139 0         0 logger => $logger
140             );
141 0 0       0 if ($infos->{SPEED}) {
142             $logger->debug_result(
143             action => 'retrieving interface speed from syscall',
144             data => $infos->{SPEED}
145 0         0 );
146 0         0 $interface->{SPEED} = $infos->{SPEED};
147             } else {
148 0         0 $logger->debug_result(
149             action => 'retrieving interface speed from syscall',
150             status => 'syscall failed'
151             );
152             }
153             }
154             }
155              
156 0         0 return @interfaces;
157             }
158              
159             sub _getInterfacesBase {
160 0     0   0 my (%params) = @_;
161              
162 0         0 my $logger = $params{logger};
163 0         0 $logger->debug("retrieving interfaces list:");
164              
165 0 0       0 if (canRun('/sbin/ip')) {
166 0         0 my @interfaces = getInterfacesFromIp(logger => $logger);
167 0         0 $logger->debug_result(
168             action => 'running /sbin/ip command',
169             data => scalar @interfaces
170             );
171 0 0       0 return @interfaces if @interfaces;
172             } else {
173 0         0 $logger->debug_result(
174             action => 'running /sbin/ip command',
175             status => 'command not available'
176             );
177             }
178              
179 0 0       0 if (canRun('/sbin/ifconfig')) {
180 0         0 my @interfaces = getInterfacesFromIfconfig(logger => $logger);
181 0         0 $logger->debug_result(
182             action => 'running /sbin/ifconfig command',
183             data => scalar @interfaces
184             );
185 0 0       0 return @interfaces if @interfaces;
186             } else {
187 0         0 $logger->debug_result(
188             action => 'running /sbin/ifconfig command',
189             status => 'command not available'
190             );
191             }
192              
193 0         0 return;
194             }
195              
196             sub _getSlaves {
197 0     0   0 my ($name) = @_;
198              
199             my @slaves =
200 0         0 map { $_ =~ /\/lower_(\w+)$/ }
  0         0  
201             glob("/sys/class/net/$name/lower_*");
202              
203 0         0 return join (",", @slaves);
204             }
205              
206             sub _getUevent {
207 0     0   0 my ($name) = @_;
208              
209 0         0 my $file = "/sys/class/net/$name/device/uevent";
210 0         0 my $handle = getFileHandle(file => $file);
211 0 0       0 return unless $handle;
212              
213 0         0 my $info;
214 0         0 while (my $line = <$handle>) {
215 0 0       0 next unless $line =~ /^(\w+)=(\S+)$/;
216 0         0 $info->{$1} = $2;
217             }
218 0         0 close $handle;
219              
220 0         0 return $info;
221             }
222              
223             sub _parseIwconfig {
224 2     2   7219 my (%params) = @_;
225              
226             my $handle = getFileHandle(
227             %params,
228 2 50       12 command => $params{name} ? "iwconfig $params{name}" : undef
229             );
230 2 50       5 return unless $handle;
231              
232 2         2 my $info;
233 2         22 while (my $line = <$handle>) {
234 14 100       31 $info->{version} = $1
235             if $line =~ /IEEE (\S+)/;
236 14 100       22 $info->{SSID} = $1
237             if $line =~ /ESSID:"([^"]+)"/;
238 14 100       24 $info->{mode} = $1
239             if $line =~ /Mode:(\S+)/;
240 14 100       89 $info->{BSSID} = $1
241             if $line =~ /Access Point: ($mac_address_pattern)/;
242             }
243              
244 2         36 close $handle;
245              
246 2         7 return $info;
247             }
248              
249             1;