1package Ocsinventory::Agent::Backend::OS::BSD::Networks; 2 3use strict; 4 5sub check { 6 my $params = shift; 7 my $common = $params->{common}; 8 $common->can_run("ifconfig") && $common->can_load("Net::IP qw(:PROC)") 9} 10 11 12sub _ipdhcp { 13 my $if = shift; 14 15 my $path; 16 my $ipdhcp; 17 my $leasepath; 18 19 foreach ( # XXX BSD paths 20 "/var/db/dhclient.leases.%s", 21 "/var/db/dhclient.leases", 22 # Linux path for some kFreeBSD based GNU system 23 "/var/lib/dhcp3/dhclient.%s.leases", 24 "/var/lib/dhcp3/dhclient.%s.leases", 25 "/var/lib/dhcp/dhclient.leases") { 26 27 $leasepath = sprintf($_,$if); 28 last if (-e $leasepath); 29 } 30 return undef unless -e $leasepath; 31 32 if (open DHCP, $leasepath) { 33 my $lease; 34 my $dhcp; 35 my $expire; 36 # find the last lease for the interface with its expire date 37 while(<DHCP>){ 38 $lease = 1 if(/lease\s*{/i); 39 $lease = 0 if(/^\s*}\s*$/); 40 if ($lease) { #inside a lease section 41 if (/interface\s+"(.+?)"\s*/){ 42 $dhcp = ($1 =~ /^$if$/); 43 } 44 #Server IP 45 if (/option\s+dhcp-server-identifier\s+(\d{1,3}(?:\.\d{1,3}){3})\s*;/x) { 46 $ipdhcp = $1; 47 } 48 if (/^\s*expire\s*\d\s*(\d*)\/(\d*)\/(\d*)\s*(\d*):(\d*):(\d*)/x) { 49 $expire=sprintf "%04d%02d%02d%02d%02d%02d",$1,$2,$3,$4,$5,$6; 50 } 51 } 52 } 53 close DHCP or warn; 54 chomp (my $currenttime = `date +"%Y%m%d%H%M%S"`); 55 undef $ipdhcp unless $currenttime <= $expire; 56 } else { 57 warn "Can't open $leasepath\n"; 58 } 59 return $ipdhcp; 60} 61 62# Initialise the distro entry 63sub run { 64 my $params = shift; 65 my $common = $params->{common}; 66 67 my $description; 68 my $duplex; 69 my $ipaddress; 70 my $ipmask; 71 my $ipsubnet; 72 my $ipaddress6; 73 my $ipmask6; 74 my $ipsubnet6; 75 my $macaddr; 76 my $mtu; 77 my $speed; 78 my $status; 79 my $type; 80 81 82 my @ifconfig = `ifconfig -a`; # -a option required on *BSD 83 84 # first make the list available interfaces 85 # too bad there's no -l option on OpenBSD 86 my @list; 87 foreach (@ifconfig){ 88 # skip loopback, pseudo-devices and point-to-point interfaces 89 next if /^(lo|fwe|vmnet|sit|pflog|pfsync|enc|strip|plip|sl|ppp)\d+/; 90 if (/^(\S+):/) { push @list , $1; } # new interface name 91 } 92 93 # for each interface get it's parameters 94 foreach $description (@list) { 95 $ipaddress = $ipmask = $macaddr = $status = $type = $mtu = $speed = $ipaddress6 = $ipmask6 = $ipsubnet6 = undef; 96 # search interface infos 97 @ifconfig = `ifconfig $description`; 98 foreach (@ifconfig){ 99 $ipaddress = $1 if /inet (\S+)/i; 100 if (/inet6 ([\w:]+)\S* prefixlen (\d+)/) { 101 $ipaddress6=$1; 102 $ipmask6=getIPNetmaskV6($2); 103 $ipsubnet6=getSubnetAddressIPv6($ipaddress6,$ipmask6); 104 } 105 $ipmask = $1 if /netmask\s+(\S+)/i; 106 $macaddr = $2 if /(address:|ether|lladdr)\s+(\S+)/i; 107 $status = 1 if /<UP/i; 108 $type = $1 if /media:\s+(\S+)/i; 109 $speed = $1 if /media:\s+\S+\s\S+\s\((\d+)/i; # Ethernet autoselect (1000baseT <full-duplex>) 110 $mtu = $1 if /mtu (\d+)/i; 111 } 112 113 # In BSD, netmask is given in hex form 114 my $binmask = sprintf("%b", oct($ipmask)); 115 $ipmask = ip_bintoip($binmask,4); 116 117 if ($description & $ipaddress ) { 118 $common->addNetwork({ 119 DESCRIPTION => $description, 120 IPADDRESS => $ipaddress, 121 IPDHCP => _ipdhcp($description), 122 IPGATEWAY => getRoute($ipaddress), 123 IPMASK => $ipmask, 124 IPSUBNET => getSubnetAddressIPv4($ipaddress,$ipmask), 125 MACADDR => $macaddr, 126 MTU => $mtu, 127 SPEED => getSpeed($speed), 128 STATUS => $status?"Up":"Down", 129 TYPE => $type, 130 }); 131 # Set default gateway in hardware info 132 $common->setHardware({ 133 DEFAULTGATEWAY => getRoute($ipaddress6) 134 }); 135 } else { 136 $common->addNetwork({ 137 DESCRIPTION => $description, 138 IPADDRESS => $ipaddress6, 139 IPDHCP => _ipdhcp($description), 140 IPGATEWAY => getRoute($ipaddress6), 141 IPMASK => getIPNetmaskV6($ipaddress6), 142 IPSUBNET => getSubnetAddressIPv6($ipaddress6,$ipmask6), 143 MACADDR => $macaddr, 144 MTU => $mtu, 145 SPEED => getSpeed($speed), 146 STATUS => $status?"Up":"Down", 147 TYPE => $type, 148 }); 149 # Set default gateway in hardware info 150 $common->setHardware({ 151 DEFAULTGATEWAY => getRoute($ipaddress6) 152 }); 153 } 154 } 155} 156 157sub getSpeed{ 158 my ($speed)=@_; 159 160 return unless $speed; 161 162 if ($speed gt 100 ){ 163 $speed = ($speed/1000)." Gbps"; 164 } else { 165 $speed = $speed." Mbps"; 166 } 167 168 return $speed; 169 170} 171 172sub getSubnetAddressIPv4 { 173 my ($address,$mask)=@_; 174 175 return undef unless $address && $mask; 176 177 my $binaddress=ip_iptobin($address, 4); 178 my $binmask=ip_iptobin($mask, 4); 179 my $binsubnet=$binaddress & $binmask; 180 181 return ip_bintoip($binsubnet, 4); 182} 183 184sub getSubnetAddressIPv6 { 185 my ($address,$mask)=@_; 186 187 return undef unless $address && $mask; 188 189 my $binaddress = ip_iptobin(ip_expand_address($address, 6),6); 190 my $binmask = ip_iptobin(ip_expand_address($mask, 6),6); 191 my $binsubnet = $binaddress & $binmask; 192 193 return ip_compress_address(ip_bintoip($binsubnet, 6),6); 194} 195 196sub getIPNetmaskV6 { 197 my ($prefix) = @_; 198 199 return undef unless $prefix; 200 return ip_compress_address(ip_bintoip(ip_get_mask($prefix, 6), 6),6); 201} 202 203sub getRoute { 204 # Looking for the gateway 205 # 'route show' doesn't work on FreeBSD so we use netstat 206 # XXX IPV4 only 207 my ($prefix) = @_; 208 my $route; 209 210 return undef unless $prefix; 211 212 if (ip_is_ipv4($prefix)) { 213 for (`netstat -rn -f inet`){ 214 $route = $1 if /^default\s+(\S+)/i; 215 } 216 } elsif (ip_is_ipv6($prefix)) { 217 for (`netstat -rn -f inet6`){ 218 $route = $1 if /^default\s+(\S+)/i; 219 } 220 } 221 return $route; 222} 223 2241; 225__END__ 226 227=head1 NAME 228 229OCSInventory::Agent::Backend::OS::BSD::Networks - Network-related information 230 231=head1 DESCRIPTION 232 233This module retrieves network information. 234 235=head1 FUNCTIONS 236 237=head2 getSpeed 238 239Returns the speed of the card. 240 241=head2 getRoute 242 243Returns the gateway 244 245=head2 getIPNetmaskV4 246 247Returns the IP v4 network mask 248 249=head2 getIPNetmaskV6 250 251Returns the IP v6 network mask 252 253=head2 getSubnetAddressIPv4 254 255Returns the subnet of ip v4 network 256 257=head2 getSubnetAddressIPv6 258 259Returns the subnet of ip v6 network 260