Module: Facter::Resolvers::Aix::FfiHelper

Defined in:
lib/facter/resolvers/aix/ffi/ffi_helper.rb

Overview

Since:

  • 2.0.0

Defined Under Namespace

Modules: Libc

Constant Summary collapse

KINFO_GET_AVENRUN =

Since:

  • 2.0.0

1
KINFO_READ =

Since:

  • 2.0.0

8 << 8
KINFO_RT =

Since:

  • 2.0.0

1 << 8
KINFO_RT_IFLIST =

Since:

  • 2.0.0

KINFO_RT | 3

Class Method Summary collapse

Class Method Details

.address_to_string(sockaddr, mask = nil) ⇒ Object

Since:

  • 2.0.0



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/facter/resolvers/aix/ffi/ffi_helper.rb', line 126

def self.address_to_string(sockaddr, mask = nil)
  if sockaddr[:sa_family] == FFI::AF_INET
    in_addr_ip = FFI::SockaddrIn.new(sockaddr.to_ptr)

    if mask && sockaddr[:sa_family] == mask[:sa_family]
      in_addr_mask = FFI::SockaddrIn.new(mask.to_ptr)
      in_addr_ip[:sin_addr][:s_addr] &= in_addr_mask[:sin_addr][:s_addr]
    end

    buffer = ::FFI::MemoryPointer.new(:char, FFI::INET_ADDRSTRLEN)
    Libc.inet_ntop(FFI::AF_INET, in_addr_ip[:sin_addr].to_ptr, buffer, 16)

    buffer
  elsif sockaddr[:sa_family] == FFI::AF_INET6
    in_addr_ip = FFI::SockaddrIn6.new(sockaddr.to_ptr)
    if mask && sockaddr[:sa_family] == mask[:sa_family]
      in_addr_mask = FFI::SockaddrIn6.new(sockaddr.to_ptr)
      16.times do |i|
        in_addr_ip[:sin6_addr][:u6_addr8][i] &= in_addr_mask[:sin6_addr][:u6_addr8][i]
      end
    end

    buffer = ::FFI::MemoryPointer.new(:char, FFI::INET6_ADDRSTRLEN)
    Libc.inet_ntop(FFI::AF_INET6, in_addr_ip[:sin6_addr].to_ptr, buffer, 16)

    buffer
  end
end

.logObject

Since:

  • 2.0.0



155
156
157
# File 'lib/facter/resolvers/aix/ffi/ffi_helper.rb', line 155

def self.log
  @log ||= Log.new(self)
end

.read_interfacesObject

Since:

  • 2.0.0



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/facter/resolvers/aix/ffi/ffi_helper.rb', line 39

def self.read_interfaces
  ksize = Libc.getkerninfo(KINFO_RT_IFLIST, nil, nil, 0)

  log.debug('getkerninfo call was unsuccessful') if ksize.zero?

  ksize_ptr = ::FFI::MemoryPointer.new(:int, ksize.size)
  ksize_ptr.write_int(ksize)

  result_ptr = ::FFI::MemoryPointer.new(:char, ksize)

  res = Libc.getkerninfo(KINFO_RT_IFLIST, result_ptr, ksize_ptr, 0)
  log.debug('getkerninfo call was unsuccessful') if res == -1

  cursor = 0

  interfaces = {}
  while cursor < ksize_ptr.read_int
    hdr = FFI::IfMsghdr.new(result_ptr + cursor)

    case hdr[:ifm_type]
    when FFI::RTM_IFINFO
      link_addr = FFI::SockaddrDl.new(hdr.to_ptr + hdr.size)

      interface_name = link_addr[:sdl_data].to_s[0, link_addr[:sdl_nlen]]
      interfaces[interface_name] ||= {}

    when FFI::RTM_NEWADDR
      addresses = {}
      addr_cursor = cursor + hdr.size
      FFI::RTAX_LIST.each do |key|
        xand = hdr[:ifm_addrs] & FFI::RTA_LIST[key]
        next unless xand != 0

        sockaddr = FFI::Sockaddr.new(result_ptr + addr_cursor)
        addresses[key] = sockaddr
        roundup_nr = roundup(sockaddr)
        addr_cursor += roundup_nr
      end

      family = FFI::AF_UNSPEC

      addresses.each_value do |addr|
        if family != FFI::AF_UNSPEC &&
           addr[:sa_family] != FFI::AF_UNSPEC &&
           family != addr[:sa_family]
          family = FFI::AF_MAX
          break
        end
        family = addr[:sa_family]
      end

      if addresses[FFI::RTAX_NETMASK][:sa_len]
        addresses[FFI::RTAX_NETMASK][:sa_family] = family
        netmask = address_to_string(addresses[FFI::RTAX_NETMASK])
      end

      address = address_to_string(addresses[FFI::RTAX_IFA]) if addresses[FFI::RTAX_IFA][:sa_len]

      if addresses[FFI::RTAX_NETMASK][:sa_len] && addresses[FFI::RTAX_IFA][:sa_len]
        network = address_to_string(addresses[FFI::RTAX_IFA], addresses[FFI::RTAX_NETMASK])
      end

      bindings = family == FFI::AF_INET ? :bindings : :bindings6
      interfaces[interface_name][bindings] ||= []
      interfaces[interface_name][bindings] << {
        netmask: netmask.read_string,
        address: address.read_string,
        network: network.read_string
      }
    else
      log.debug("got an unknown RT_IFLIST message: #{hdr[:ifm_type]}")
    end

    cursor += hdr[:ifm_msglen]
  end

  interfaces
end

.read_load_averagesObject

Since:

  • 2.0.0



29
30
31
32
33
34
35
36
37
# File 'lib/facter/resolvers/aix/ffi/ffi_helper.rb', line 29

def self.read_load_averages
  averages = ::FFI::MemoryPointer.new(:long_long, 3)
  averages_size = ::FFI::MemoryPointer.new(:int, 1)
  averages_size.write_int(averages.size)

  return if Libc.getkerninfo(KINFO_READ | KINFO_GET_AVENRUN, averages, averages_size, 0).negative?

  averages.read_array_of_long_long(3).map { |x| (x / 65_536.0) }
end

.roundup(sockaddr) ⇒ Object

Since:

  • 2.0.0



118
119
120
121
122
123
124
# File 'lib/facter/resolvers/aix/ffi/ffi_helper.rb', line 118

def self.roundup(sockaddr)
  if sockaddr[:sa_len].positive?
    1 + ((sockaddr[:sa_len] - 1) | (1.size - 1))
  else
    1.size
  end
end