lib/net/ip/route.rb in net-ip-0.0.2 vs lib/net/ip/route.rb in net-ip-0.0.3

- old
+ new

@@ -1,86 +1,92 @@ module Net module IP + # Class for working with routing table entries. class Route attr_accessor :type, :prefix, :dev, :scope, :metric, :proto, :src, :via, :weight, :table, :error - def to_s - str = "" - str << type << " " if type != "unicast" - str << prefix << " " + extend Enumerable - str << "via #{via} " if via + # Create a new route object + # @example Create a default route + # Net::IP::Route.new(:prefix => 'default', :via => '192.168.0.1') + # @example Create a normal route + # Net::IP::Route.new(:prefix => '10.0.0.0/8', :dev => 'eth0') + # @note This does NOT add the entry to the routing table. See {add_route} for creating new routes in the routing table. + # @param params {Hash} + def initialize(params = {}) + params.each do |k,v| + send("#{k}=", v) + end + end - str << "dev #{dev} " if dev - - str << " table #{table} " if table - str << " proto #{proto} " if proto - str << " scope #{scope} " if scope - - str << " src #{src} " if src - str << " metric #{metric} " if metric - - str << " error #{error}" if error - - str + # Enumerate all routes + # @yield {Route} + # @return {void} + def self.each(&block) + RouteParser.parse(`ip route`).each {|r| yield(new(r))} end + # Get a list of all routes + # @return {Array<Route>} def self.all - parse(`ip route show table 0`) + RouteParser.parse(`ip route`).collect {|r| new(r)} end -private + # Get a list of all default gateway routes + # @return {Array<Route>} + def self.find_gateways + find_all {|r| r.prefix == "default"} + end - def self.parse_line(line) - route = new + # Update the list of default gateways + # @example Change the default gateway to 192.168.0.1 + # gateway = Net::IP::Route.new(:prefix => 'default', :via => '192.168.0.1') + # Net::IP::Route.update_gateways([gateway]) + # @param gateways {Array<Route>} List of default gateways to use. + # @return {void} + def self.update_gateways(gateways) + params = gateways.collect {|gateway| "nexthop " + gateway.build_param_string} + result = `ip route replace default #{params.join(" ")}` + raise result unless $?.success? + end - if line =~ /^(unicast|unreachable|blackhole|prohibit|local|broadcast|throw|nat|via|anycast|multicast)\s+/ - route.type = $1 - line = line[$1.length..-1] - else - route.type = "unicast" - end - - route.prefix = line.split.first - route.dev = $1 if line =~ /\s+dev\s+([^\s]+)/ - route.scope = $1 if line =~ /\s+scope\s+([^\s]+)/ - route.metric = $1 if line =~ /\s+metric\s+([^\s]+)/ - route.proto = $1 if line =~ /\s+proto\s+([^\s]+)/ - route.src = $1 if line =~ /\s+src\s+([^\s]+)/ - route.via = $1 if line =~ /\s+via\s+([^\s]+)/ - route.weight = $1 if line =~ /\s+weight\s+([^\s]+)/ - route.table = $1 if line =~ /\s+table\s+([^\s]+)/ - route.error = $1 if line =~ /\s+error\s+([^\s]+)/ - - route + # Add a route to the routing table + # @example Create a route to the 10.0.0.0/8 network + # route = Net::IP::Route.new(:prefix => '10.0.0.0/8', :dev => 'eth0') + # Net::IP::Route.add_route(route) + # @param route {Route} Route to add to the table. + # @return {void} + def self.add_route(route) + result = `ip route add #{route.build_param_string}` + raise result unless $?.success? end - def self.parse_data(data, &block) - in_default = false - data.each_line do |line| - if in_default == true - if line.start_with? "\t" - yield(parse_line(line.strip.gsub("nexthop", "default"))) - else - in_default = false - end - elsif line.strip == "default" - in_default = true - end - - unless in_default - yield(parse_line(line.strip)) - end - end + # Flush the routing table based on a selector + # @example Flush the routing table cache + # Net::IP::Route.flush(:cache) + # @param selector {String} The selector string. + # @return {void} + def self.flush(selector) + result = `ip route flush #{selector}` + raise result unless $?.success? end - def self.parse(data) - list = [] - parse_data(data) do |route| - list << route - end - list +private + + def build_param_string + str = "" + str << "via #{via} " if via + str << "dev #{dev} " if dev + str << "weight #{weight}" if weight + str << " table #{table} " if table + str << " proto #{proto} " if proto + str << " scope #{scope} " if scope + str << " src #{src} " if src + str << " metric #{metric} " if metric + str << " error #{error}" if error + str end end end end