lib/inspec/resources/routing_table.rb
# fetches the routing information for the system
fetches the routing information for the system
fetches the routing information for the system
def fetch_routing_information
      utility = find_netstat_or_error
      fetch_route_cmd = "#{utility} -rn"
      cmd = inspec.command(fetch_route_cmd)
      raise Inspec::Exceptions::ResourceFailed, "Executing netstat failed: #{cmd.stderr}" if cmd.exit_status.to_i != 0
      raw_route_info = cmd.stdout.split("\n")
      raw_route_info.shift until raw_route_info[0] =~ /Destination/i
      raw_route_info.map! { |info| info.strip.split }
      destination_index, gateway_index, interface_index = -1, -1, -1
      raw_route_info[0].shift if inspec.os.windows?
      raw_route_info[0].each_with_index do |header, index|
        if header =~ /Destination/i
          destination_index = index
        elsif header =~ /Gateway/i
          gateway_index = index
        elsif header =~ /Iface|Netif|Interface/i
          interface_index = index
        end
      end
      raw_route_info.shift
      if destination_index != -1 && gateway_index != -1 && interface_index != -1
        raw_route_info.each do |info|
          if !info[destination_index].nil? && !info[gateway_index].nil? && !info[interface_index].nil?
            if @routing_info.key?(info[destination_index])
              @routing_info[info[destination_index]] << [info[gateway_index], info[interface_index]]
            else
              @routing_info[info[destination_index]] = [[info[gateway_index], info[interface_index]]]
            end
          end
        end
      end
    end
def fetch_routing_information utility = find_netstat_or_error fetch_route_cmd = "#{utility} -rn" cmd = inspec . command ( fetch_route_cmd ) raise Inspec :: Exceptions :: ResourceFailed , "Executing netstat failed: #{cmd.stderr}" if cmd . exit_status . to_i != 0 raw_route_info = cmd . stdout . split ( "\n" ) raw_route_info . shift until raw_route_info [ 0 ] =~ / Destination /i raw_route_info . map! { | info | info . strip . split } destination_index , gateway_index , interface_index = - 1 , - 1 , - 1 raw_route_info [ 0 ] . shift if inspec . os . windows? raw_route_info [ 0 ] . each_with_index do | header , index | if header =~ / Destination /i destination_index = index elsif header =~ / Gateway /i gateway_index = index elsif header =~ / Iface|Netif|Interface /i interface_index = index end end raw_route_info . shift if destination_index != - 1 && gateway_index != - 1 && interface_index != - 1 raw_route_info . each do | info | if ! info [ destination_index ] . nil? && ! info [ gateway_index ] . nil? && ! info [ interface_index ] . nil? if @routing_info . key? ( info [ destination_index ] ) @routing_info [ info [ destination_index ] ] << [ info [ gateway_index ] , info [ interface_index ] ] else @routing_info [ info [ destination_index ] ] = [ [ info [ gateway_index ] , info [ interface_index ] ] ] end end end end end
fetches the routing information for the system
fetches the routing information for the system
# check if netstat is available on the system # the command to fetch the routing information # execute the above netstat command # raise error if the exit status is not zero; # Todo: # Improve logic to fetch destination, gateway & interface efficiently. # The below logic assumes the following: # 1. destination, gateway & interface header is present as Destination, Gateway & (Iface or Netif or Interface) respectively. #    (Netif on BSD, Darwin,Iface on linux & Interface on Windows) # 2. there is no blank data for any columns or the blank data are present after the interface column. # cmd.stdout is the standard out of netstat -rn; split on new line to get the rows # since raw_route_info contains some row before the header (i.e. Destination Gateway ...); remove those rows # split each rows based on space to get the individual columns # raw_route_info is now array of arrays with the routing information # these variables will store the indices where destination, gateway and interface are present # The headers in windows are as: # Network Destination        Netmask          Gateway       Interface  Metric # Splitting on space makes "Network Destination" to be two separate values as "Network" & "Destination" # Remove "Network" value to apply the logic of finding index # find the indices of destination, gateway and interface; # because the position of gateway & interface varies with operating system # remove the initial header consisting of Destination, Gateway, Mask, ... since this is of no use # check the indices are assigned with some index and not -1 # iterate through the route_info; and find destination, gateway and interface from each row # if value exists at the destination_index, gateway_index, and interface_index; store the value in @routing_info # if the destination_key is already present, append the gateway & interface; else create new array and add them