This file is indexed.

/usr/lib/ruby/vendor_ruby/ohai/plugins/network.rb is in ohai 8.4.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 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
117
118
119
120
121
122
123
124
125
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#
# Author:: Adam Jacob (<adam@opscode.com>)
# Copyright:: Copyright (c) 2008 Opscode, 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.
#

require 'ipaddress'
require 'ohai/mixin/network_constants'

Ohai.plugin(:NetworkAddresses) do
  include Ohai::Mixin::NetworkConstants

  provides "ipaddress", "ip6address", "macaddress"

  depends "network/interfaces"

  def sorted_ips(family = "inet")
    raise "bad family #{family}" unless [ "inet", "inet6" ].include? family

    # going to use that later to sort by scope
    scope_prio = [ "global", "site", "link", "host", "node", nil ]

    ipaddresses = []
    # ipaddresses going to hold #{family} ipaddresses and their scope
    Mash[network['interfaces']].each do |iface, iface_v|
      next if iface_v.nil? or not iface_v.has_key? 'addresses'
      iface_v['addresses'].each do |addr, addr_v|
        next if addr_v.nil? or not addr_v.has_key? "family" or addr_v['family'] != family
        ipaddresses <<  {
          :ipaddress => addr_v["prefixlen"] ? IPAddress("#{addr}/#{addr_v["prefixlen"]}") : IPAddress("#{addr}/#{addr_v["netmask"]}"),
          :scope => addr_v["scope"].nil? ? nil : addr_v["scope"].downcase,
          :iface => iface
        }
      end
    end

    # sort ip addresses by scope, by prefixlen and then by ip address
    # 128 - prefixlen: longest prefixes first
    ipaddresses.sort_by do |v|
      [ ( scope_prio.index(v[:scope]) or 999999 ),
        128 - v[:ipaddress].prefix.to_i,
        ( family == "inet" ? v[:ipaddress].to_u32 : v[:ipaddress].to_u128 )
      ]
    end
  end

  def find_ip(family = "inet")
    ips=sorted_ips(family)

    # return if there isn't any #{family} address !
    return [ nil, nil ] if ips.empty?

    # shortcuts to access default #{family} interface and gateway
    int_attr = Ohai::Mixin::NetworkConstants::FAMILIES[family] +"_interface"
    gw_attr = Ohai::Mixin::NetworkConstants::FAMILIES[family] + "_gateway"

    # If we have a default interface that has addresses,
    # populate the short-cut attributes ipaddress, ip6address and macaddress
    if network[int_attr]

      # working with the address(es) of the default network interface
      gw_if_ips = ips.select do |v|
        v[:iface] == network[int_attr]
      end
      if gw_if_ips.empty?
        Ohai::Log.warn("[#{family}] no ip address on #{network[int_attr]}")
      elsif network[gw_attr] and
          network["interfaces"][network[int_attr]] and
          network["interfaces"][network[int_attr]]["addresses"]
        if [ "0.0.0.0", "::", /^fe80:/ ].any? { |pat| pat === network[gw_attr] }
          # link level default route
          Ohai::Log.debug("link level default #{family} route, picking ip from #{network[gw_attr]}")
          r = gw_if_ips.first
        else
          # checking network masks
          r = gw_if_ips.select do |v|
            network_contains_address(network[gw_attr], v[:ipaddress], v[:iface])
          end.first
          if r.nil?
            r = gw_if_ips.first
            Ohai::Log.debug("[#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking #{r[:ipaddress]}")
          else
            Ohai::Log.debug("[#{family}] Using default interface #{network[int_attr]} and default gateway #{network[gw_attr]} to set the default ip to #{r[:ipaddress]}")
          end
        end
      else
        # return the first ip address on network[int_attr]
        r = gw_if_ips.first
      end
    else
      r = ips.first
      Ohai::Log.debug("[#{family}] no default interface, picking the first ipaddress")
    end

    return [ nil, nil ] if r.nil? or r.empty?

    [ r[:ipaddress].to_s, r[:iface] ]
  end

  def find_mac_from_iface(iface)
    r = network["interfaces"][iface]["addresses"].select{|k,v| v["family"]=="lladdr"}
    r.nil? or r.first.nil? ? nil : r.first.first
  end

  def network_contains_address(address_to_match, ipaddress, iface)
    # address_to_match: String
    # ipaddress: IPAddress
    # iface: String
    if peer = network["interfaces"][iface]["addresses"][ipaddress.to_s][:peer]
      IPAddress(peer) == IPAddress(address_to_match)
    else
      ipaddress.include? IPAddress(address_to_match)
    end
  end

  # ipaddress, ip6address and macaddress can be set by the #{os}::network plugin
  # atm it is expected macaddress is set at the same time than ipaddress
  # if ipaddress is set and macaddress is nil, that means the interface
  # ipaddress is bound to has the NOARP flag

  collect_data do
    results = {}

    network Mash.new unless network
    network[:interfaces] = Mash.new unless network[:interfaces]
    counters Mash.new unless counters
    counters[:network] = Mash.new unless counters[:network]

    # inet family is treated before inet6
    Ohai::Mixin::NetworkConstants::FAMILIES.keys.sort.each do |family|
      r = {}
      ( r["ip"], r["iface"] ) = find_ip(family)
      r["mac"] = find_mac_from_iface(r["iface"]) unless r["iface"].nil?
      # don't overwrite attributes if they've already been set by the "#{os}::network" plugin
      if family == "inet" and ipaddress.nil?
        if r["ip"].nil?
          Ohai::Log.warn("unable to detect ipaddress")
          # i don't issue this warning if r["ip"] exists and r["mac"].nil?
          # as it could be a valid setup with a NOARP default_interface
          Ohai::Log.warn("unable to detect macaddress")
        else
          ipaddress r["ip"]
          macaddress r["mac"]
        end
      elsif family == "inet6" and ip6address.nil?
        if r["ip"].nil?
          Ohai::Log.debug("unable to detect ip6address")
        else
          ip6address r["ip"]
          if r["mac"] and macaddress.nil? and ipaddress.nil?
            Ohai::Log.debug("macaddress set to #{r["mac"]} from the ipv6 setup")
            macaddress r["mac"]
          end
        end
      end
      results[family] = r
    end

    if results["inet"]["iface"] and results["inet6"]["iface"] and
        results["inet"]["iface"] != results["inet6"]["iface"]
      Ohai::Log.debug("ipaddress and ip6address are set from different interfaces (#{results["inet"]["iface"]} & #{results["inet6"]["iface"]}), macaddress has been set using the ipaddress interface")
    end
  end
end