Created
August 11, 2021 03:13
-
-
Save kuredev/f6e197e764485909959584d18481aec2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "ipaddr" | |
class RouteTable | |
def initialize(routes) | |
@routes = routes | |
end | |
# IPAddr or nil | |
# nil -> direct connected | |
def next_hop_route_entry(dst_addr) | |
return nil if direct_connected?(dst_addr) | |
# デフォルトルートの場合 | |
default_routes = @routes.select { |route| route.direct_network_addr.nil? } | |
# デフォルトルートのうち、メトリクス値が無いのがあった場合はそれを返す | |
top_priority_route = default_routes.find { |default_routes| default_routes.metric.nil? } | |
return top_priority_route unless top_priority_route.nil? | |
# 最もメトリクス値が小さいデフォルトルートのエントリを返す | |
default_routes.min_by do |default_route| | |
default_route.metric | |
end | |
end | |
private | |
def direct_connected?(dst_addr) | |
@routes.find do |route| | |
next if route.direct_network_addr.nil? | |
route.direct_network_addr.include?(IPAddr.new(dst_addr)) | |
end | |
end | |
end | |
class RouteEntry | |
attr_reader :direct_network_addr, :next_hop_addr, :next_hop_device, :direct_network_addr, :direct_network_device, :metric | |
# ex) | |
# default via 172.31.0.1 dev eth0 | |
# 172.18.0.0/16 dev br-8140256d9f85 proto kernel scope link src 172.18.0.1 linkdown | |
# 172.31.34.0/24 dev eth2 proto kernel scope link src 172.31.34.23 | |
def initialize(route_string: nil) | |
@route_string = route_string | |
parse_route_from_string unless @route_string.empty? | |
end | |
def to_s | |
"direct_connected: #{@direct_connected}, next_hop_addr: #{@next_hop_addr}, " + \ | |
"next_hop_device: #{@next_hop_device}, direct_network_addr: #{@direct_network_addr}, " + \ | |
"direct_network_device: #{@direct_network_device}" | |
end | |
private | |
def parse_route_from_string | |
params = @route_string.split(" ") | |
if params[0] == "default" | |
@direct_connected = true | |
@next_hop_addr = IPAddr.new(params[2]) | |
@next_hop_device = params[4] | |
@direct_network_addr = nil | |
@direct_network_device = nil | |
@metric = params[6] # metric 値がない(最優先のルート)場合は nil | |
else | |
@direct_connected = false | |
@next_hop_addr = nil | |
@next_hop_device = nil | |
@direct_network_addr = IPAddr.new(params[0]) | |
@direct_network_device = params[2] | |
@metric = nil | |
end | |
end | |
end | |
output = `ip route` | |
routes_string = output.split("\n") | |
routes = routes_string.map do |route_string| | |
RouteEntry.new(route_string: route_string) | |
end | |
rt = RouteTable.new(routes) | |
pp rt.next_hop_route_entry("8.8.8.8") # #<RouteEntry 172.31.0.1/255.255.255.255> | |
pp rt.next_hop_route_entry("172.31.34.1") # nil |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
NextHopのアドレスを取得するスクリプト