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