class Inspec::Resources::Interfaces

def ipv4_address

def ipv4_address
  require "ipaddr" unless defined?(IPAddr)
  # Loop over interface names
  # Select those that are up and have an ipv4 address
  interfaces = names.map { |n| inspec.interface(n) }.select do |i|
    i.ipv4_address? && i.up?
  end
  addrs = interfaces.map(&:ipv4_addresses).flatten.map { |a| IPAddr.new(a) }
  # Look for progressively "better" IP addresses
  [
    # Loopback and private IP ranges
    IPAddr.new("127.0.0.0/8"),
    IPAddr.new("192.168.0.0/16"),
    IPAddr.new("172.16.0.0/12"),
    IPAddr.new("10.0.0.0/8"),
  ].each do |private_range|
    filtered_addrs = addrs.reject { |a| private_range.include?(a) }
    if filtered_addrs.empty?
      # Everything we had was a private or loopback IP. Return the "best" thing we were left with.
      return addrs.first.to_s
    end
    addrs = filtered_addrs
  end
  addrs.first.to_s
end

def scan_interfaces

def scan_interfaces
  @iface_data ||= begin
                provider = LinuxInterfaceLister.new(inspec) if inspec.os.linux?
                provider = WindowsInterfaceLister.new(inspec) if inspec.os.windows?
                provider = BsdInterfaceLister.new(inspec) if inspec.os.bsd? # includes macOS
                Array(provider && provider.scan_interfaces)
              end
end

def to_s

def to_s
  "Interfaces"
end