# # Author:: Kaustubh Deorukhkar () # Author:: Prabhu Das () # Author:: Isa Farnik () # Copyright:: Copyright (c) 2013-2016 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Ohai.plugin(:Network) do require "ipaddr" provides "network", "counters/network", "macaddress" # Helpers def hex_to_dec_netmask(netmask) # example '0xffff0000' -> '255.255.0.0' dec = netmask[2..3].to_i(16).to_s(10) [4, 6, 8].each { |n| dec = dec + "." + netmask[n..n + 1].to_i(16).to_s(10) } dec end collect_data(:aix) do # Loads following information. # :default_interface, :default_gateway - route -n get 0 # :interfaces # => routes(netstat -nr | grep en0) # => addresses (ifconfig en0 or lsattr -El en0), macaddress (entstat -d en0 = Hardware Address: be:42:80:00:b0:05) # => flags (ifconfig en0) # => state up/down (ifconfig/lsattr) # => arp (arp -an) iface = Mash.new network Mash.new unless network network[:interfaces] = Mash.new unless network[:interfaces] # We unfortunately have to do things a bit different here, if ohai is running # within a WPAR. For instance, the WPAR isn't aware of some of its own networking # minutia such as default gateway/route. unless shell_out("uname -W").stdout.to_i > 0 # :default_interface, :default_gateway - route -n get 0 so = shell_out("netstat -rn |grep default") so.stdout.lines.each do |line| items = line.split(" ") if items[0] == "default" network[:default_gateway] = items[1] network[:default_interface] = items[5] end end end # Splits the ifconfig output to 1 line per interface if_so = shell_out("ifconfig -a") if_so.stdout.gsub(/\n(\w+\d+)/, '___\1').split("___").each do |intraface| splat = intraface.split(":") interface = splat[0] line = splat[1..-1][0] iface[interface] = Mash.new iface[interface][:state] = (line.include?("/ iface[interface][:flags] = $1.split(",") iface[interface][:metric] = $1 if lin =~ /metric\s(\S+)/ else # We have key value pairs. if lin =~ /inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\/(\d{1,2}))?/ tmp_addr, tmp_prefix = $1, $3 if tmp_prefix.nil? netmask = hex_to_dec_netmask($1) if lin =~ /netmask\s(\S+)\s/ unless netmask tmp_prefix ||= "32" netmask = IPAddr.new("255.255.255.255").mask(tmp_prefix.to_i).to_s end else netmask = IPAddr.new("255.255.255.255").mask(tmp_prefix.to_i).to_s end iface[interface][:addresses] = Mash.new unless iface[interface][:addresses] iface[interface][:addresses][tmp_addr] = { "family" => "inet", "prefixlen" => tmp_prefix } iface[interface][:addresses][tmp_addr][:netmask] = netmask if lin =~ /broadcast\s(\S+)\s/ iface[interface][:addresses][tmp_addr][:broadcast] = $1 end elsif lin =~ /inet6 ([a-f0-9\:]+)%?([\d]*)\/?(\d*)?/ # TODO do we have more properties on inet6 in aix? broadcast iface[interface][:addresses] = Mash.new unless iface[interface][:addresses] iface[interface][:addresses][$1] = { "family" => "inet6", "zone_index" => $2, "prefixlen" => $3 } else # load all key-values, example "tcp_sendspace 131072 tcp_recvspace 131072 rfc1323 1" properties = lin.split n = properties.length / 2 - 1 (0..n).each do |i| iface[interface][properties[i * 2]] = properties[(i * 2 + 1)] end end end end # Query macaddress e_so = shell_out("entstat -d #{interface} | grep \"Hardware Address\"") iface[interface][:addresses] = Mash.new unless iface[interface][:addresses] e_so.stdout.lines.each do |line| if line =~ /Hardware Address: (\S+)/ iface[interface][:addresses][$1.upcase] = { "family" => "lladdr" } macaddress $1.upcase unless shell_out("uname -W").stdout.to_i > 0 end end end #ifconfig stdout # Query routes information %w{inet inet6}.each do |family| so_n = shell_out("netstat -nrf #{family}") so_n.stdout.lines.each do |line| if line =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)/ interface = $6 iface[interface][:routes] = Array.new unless iface[interface][:routes] iface[interface][:routes] << Mash.new( :destination => $1, :family => family, :via => $2, :flags => $3) end end end # List the arp entries in system. so = shell_out("arp -an") count = 0 so.stdout.lines.each do |line| network[:arp] = Mash.new unless network[:arp] if line =~ /\s*(\S+) \((\S+)\) at ([a-fA-F0-9\:]+) \[(\w+)\] stored in bucket/ network[:arp][count] = Mash.new unless network[:arp][count] network[:arp][count][:remote_host] = $1 network[:arp][count][:remote_ip] = $2 network[:arp][count][:remote_mac] = $3.downcase count += 1 end end network["interfaces"] = iface end end