class Facter::Resolvers::Windows::Networking

Private Class Methods

adapter_down?(adapter) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 55
def adapter_down?(adapter)
  adapter[:OperStatus] != NetworkingFFI::IF_OPER_STATUS_UP ||
    ![NetworkingFFI::IF_TYPE_ETHERNET_CSMACD, NetworkingFFI::IF_TYPE_IEEE80211].include?(adapter[:IfType])
end
add_ip_data(addr, unicast, sock_addr, bindings) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 117
def add_ip_data(addr, unicast, sock_addr, bindings)
  result = find_bindings(sock_addr, unicast, addr)
  return unless result

  bindings[:ipv6] << result if sock_addr[:sa_family] == NetworkingFFI::AF_INET6
  bindings[:ipv4] << result if sock_addr[:sa_family] == NetworkingFFI::AF_INET
end
build_interface_info(adapter_address, name) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 85
def build_interface_info(adapter_address, name)
  hash = {}

  hash[:dhcp] = retrieve_dhcp_server(adapter_address)
  hash[:mtu] = adapter_address[:Mtu]

  bindings = find_ip_addresses(adapter_address[:FirstUnicastAddress], name)
  hash[:bindings] = bindings[:ipv4] unless bindings[:ipv4].empty?
  hash[:bindings6] = bindings[:ipv6] unless bindings[:ipv6].empty?
  hash[:mac] = NetworkUtils.find_mac_address(adapter_address)
  hash
end
find_bindings(sock_addr, unicast, addr) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 125
def find_bindings(sock_addr, unicast, addr)
  return unless [NetworkingFFI::AF_INET, NetworkingFFI::AF_INET6].include?(sock_addr[:sa_family])

  Facter::Util::Resolvers::Networking.build_binding(addr, unicast[:OnLinkPrefixLength])
end
find_ip_addresses(unicast_addresses, name) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 98
def find_ip_addresses(unicast_addresses, name)
  bindings = {}
  bindings[:ipv6] = []
  bindings[:ipv4] = []

  IpAdapterUnicastAddressLH.read_list(unicast_addresses) do |unicast|
    addr = NetworkUtils.address_to_string(unicast[:Address])
    unless addr
      unicast = IpAdapterUnicastAddressLH.new(unicast[:Next])
      next
    end

    sock_addr = SockAddr.new(unicast[:Address][:lpSockaddr])
    add_ip_data(addr, unicast, sock_addr, bindings)
    find_primary_interface(sock_addr, name, addr)
  end
  bindings
end
find_primary_interface(sock_addr, name, addr) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 131
def find_primary_interface(sock_addr, name, addr)
  if !@fact_list[:primary_interface] &&
     ([NetworkingFFI::AF_INET, NetworkingFFI::AF_INET6].include?(sock_addr[:sa_family]) &&
     !::Facter::Util::Resolvers::Networking.ignored_ip_address(addr))
    @fact_list[:primary_interface] = name.to_s
  end
end
get_adapter_addresses(size_ptr, adapter_addresses, flags) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 36
def get_adapter_addresses(size_ptr, adapter_addresses, flags)
  error = nil
  3.times do
    error = NetworkingFFI::GetAdaptersAddresses(NetworkingFFI::AF_UNSPEC, flags,
                                                FFI::Pointer::NULL, adapter_addresses, size_ptr)
    break if error == NetworkingFFI::ERROR_SUCCES

    if error == NetworkingFFI::ERROR_BUFFER_OVERFLOW
      adapter_addresses = FFI::MemoryPointer.new(IpAdapterAddressesLh.size, NetworkingFFI::BUFFER_LENGTH)
    else
      @log.debug 'Unable to retrieve networking facts!'
      return nil
    end
  end
  return nil unless error.zero?

  adapter_addresses
end
iterate_list(adapter_addresses) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 67
def iterate_list(adapter_addresses)
  net_interface = {}
  IpAdapterAddressesLh.read_list(adapter_addresses) do |adapter_address|
    if adapter_down?(adapter_address)
      adapter_address = IpAdapterAddressesLh.new(adapter_address[:Next])
      next
    end
    if !@fact_list[:domain] || @fact_list[:domain].empty?
      @fact_list[:domain] = adapter_address[:DnsSuffix]
                            .read_wide_string_without_length(replace_invalid_chars: true)
    end
    name = adapter_address[:FriendlyName].read_wide_string_without_length(replace_invalid_chars: true)
    net_interface[name] = build_interface_info(adapter_address, name)
  end

  @fact_list[:interfaces] = net_interface unless net_interface.empty?
end
post_resolve(fact_name, _options) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 13
def post_resolve(fact_name, _options)
  @fact_list.fetch(fact_name) { read_network_information(fact_name) }
end
read_network_information(fact_name) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 17
def read_network_information(fact_name)
  require_relative '../../../facter/resolvers/windows/ffi/networking_ffi'

  size_ptr = FFI::MemoryPointer.new(NetworkingFFI::BUFFER_LENGTH)
  adapter_addresses = FFI::MemoryPointer.new(IpAdapterAddressesLh.size, NetworkingFFI::BUFFER_LENGTH)
  flags = NetworkingFFI::GAA_FLAG_SKIP_ANYCAST |
          NetworkingFFI::GAA_FLAG_SKIP_MULTICAST | NetworkingFFI::GAA_FLAG_SKIP_DNS_SERVER

  return unless (adapter_addresses = get_adapter_addresses(size_ptr, adapter_addresses, flags))

  retrieve_domain_from_registry

  iterate_list(adapter_addresses)

  Facter::Util::Resolvers::Networking.expand_main_bindings(@fact_list)

  @fact_list[fact_name]
end
retrieve_dhcp_server(adapter) click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 60
def retrieve_dhcp_server(adapter)
  if !(adapter[:Flags] & NetworkingFFI::IP_ADAPTER_DHCP_ENABLED).zero? &&
     adapter[:Union][:Struct][:Length] >= IpAdapterAddressesLh.size
    NetworkUtils.address_to_string(adapter[:Dhcpv4Server])
  end
end
retrieve_domain_from_registry() click to toggle source
# File lib/facter/resolvers/windows/networking.rb, line 139
def retrieve_domain_from_registry
  ::Win32::Registry::HKEY_LOCAL_MACHINE.open(
    'SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters'
  ) do |key|
    domain = key['Domain']
    @fact_list[:domain] = domain if domain
  end
rescue Win32::Registry::Error
  @log.debug('Could not read TCPIP Parameters from registry')
  nil
end