net-ip 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +20 -5
- data/lib/net/ip/route/collection.rb +68 -0
- data/lib/net/ip/route/parser.rb +61 -0
- data/lib/net/ip/route.rb +13 -70
- data/lib/net/ip/rule/collection.rb +41 -0
- data/lib/net/ip/rule/parser.rb +30 -0
- data/lib/net/ip/rule.rb +23 -0
- data/lib/net/ip/version.rb +1 -1
- data/lib/net/ip.rb +13 -2
- data/net-ip.gemspec +1 -1
- data/spec/net/ip/{route_parser_spec.rb → route/parser_spec.rb} +8 -8
- data/spec/net/ip/{sample1 → route/sample1} +0 -0
- data/spec/net/ip/{sample2 → route/sample2} +0 -0
- data/spec/net/ip/{sample3 → route/sample3} +0 -0
- data/spec/net/ip/{sample4 → route/sample4} +0 -0
- data/spec/net/ip/route_spec.rb +4 -0
- data/spec/net/ip/rule/parser_spec.rb +58 -0
- data/spec/net/ip/rule/sample1 +3 -0
- data/spec/net/ip/rule/sample2 +13 -0
- data/spec/net/ip/rule_spec.rb +11 -0
- metadata +88 -82
- data/lib/net/ip/route_parser.rb +0 -57
data/README.md
CHANGED
@@ -4,20 +4,22 @@
|
|
4
4
|
[](https://codeclimate.com/github/jbussdieker/ruby-net-ip)
|
5
5
|
[](http://badge.fury.io/rb/net-ip)
|
6
6
|
|
7
|
-
Tools for working with IP routes
|
7
|
+
Tools for working with IP routes and rules
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
|
11
|
+
### Routes
|
12
|
+
|
11
13
|
````ruby
|
12
14
|
require 'net/ip'
|
13
15
|
|
14
|
-
Net::IP
|
16
|
+
Net::IP.routes.flush(:cache)
|
15
17
|
|
16
|
-
Net::IP
|
18
|
+
Net::IP.routes.each do |route|
|
17
19
|
puts route
|
18
20
|
end
|
19
21
|
|
20
|
-
Net::IP
|
22
|
+
Net::IP.routes.find_gateways.each do |gateway|
|
21
23
|
puts gateway.via
|
22
24
|
end
|
23
25
|
|
@@ -25,5 +27,18 @@ gws = ["192.168.0.1", "192.168.0.2"].collect do |ip|
|
|
25
27
|
Net::IP::Route.new(:via => ip, :dev => "eth0", :weight => 1)
|
26
28
|
end
|
27
29
|
|
28
|
-
Net::IP
|
30
|
+
Net::IP.routes.update_gateways(gws)
|
31
|
+
````
|
32
|
+
|
33
|
+
### Rules
|
34
|
+
|
35
|
+
````ruby
|
36
|
+
require 'net/ip'
|
37
|
+
|
38
|
+
Net::IP.rules.each do |rule|
|
39
|
+
puts rule
|
40
|
+
end
|
41
|
+
|
42
|
+
rule = Net::IP::Rule.new(:to => '1.1.1.1', :table => 'custom')
|
43
|
+
Net::IP.rules.add(rule)
|
29
44
|
````
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "net/ip/route"
|
2
|
+
require "net/ip/route/parser"
|
3
|
+
|
4
|
+
module Net
|
5
|
+
module IP
|
6
|
+
class Route
|
7
|
+
class Collection
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def initialize(table = "main")
|
11
|
+
@table = table
|
12
|
+
end
|
13
|
+
|
14
|
+
# Enumerate all routes
|
15
|
+
# @yield {Route}
|
16
|
+
# @return {void}
|
17
|
+
def each(&block)
|
18
|
+
Parser.parse(`ip route show table #{@table}`).each {|r| yield(Route.new(r))}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get a list of all routes
|
22
|
+
# @return {Array<Route>}
|
23
|
+
def all
|
24
|
+
Parser.parse(`ip route show table #{@table}`).collect {|r| Route.new(r)}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get a list of all default gateway routes
|
28
|
+
# @return {Array<Route>}
|
29
|
+
def gateways
|
30
|
+
find_all {|r| r.prefix == "default"}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Update the list of default gateways
|
34
|
+
# @example Change the default gateway to 192.168.0.1
|
35
|
+
# gateway = Net::IP::Route.new(:prefix => 'default', :via => '192.168.0.1')
|
36
|
+
# Net::IP::Route.update_gateways([gateway])
|
37
|
+
# @param gateways {Array<Route>} List of default gateways to use.
|
38
|
+
# @return {void}
|
39
|
+
def update_gateways(gateways)
|
40
|
+
params = gateways.collect {|gateway| "nexthop " + gateway.to_params}
|
41
|
+
result = `ip route replace default #{params.join(" ")}`
|
42
|
+
raise result unless $?.success?
|
43
|
+
end
|
44
|
+
|
45
|
+
# Add a route to the routing table
|
46
|
+
# @example Create a route to the 10.0.0.0/8 network
|
47
|
+
# route = Net::IP::Route.new(:prefix => '10.0.0.0/8', :dev => 'eth0')
|
48
|
+
# Net::IP::Route.add_route(route)
|
49
|
+
# @param route {Route} Route to add to the table.
|
50
|
+
# @return {void}
|
51
|
+
def add(route)
|
52
|
+
result = `ip route add #{route.to_params}`
|
53
|
+
raise result unless $?.success?
|
54
|
+
end
|
55
|
+
|
56
|
+
# Flush the routing table based on a selector
|
57
|
+
# @example Flush the routing table cache
|
58
|
+
# Net::IP::Route.flush(:cache)
|
59
|
+
# @param selector {String} The selector string.
|
60
|
+
# @return {void}
|
61
|
+
def flush(selector)
|
62
|
+
result = `ip route flush #{selector}`
|
63
|
+
raise result unless $?.success?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "net/ip/route"
|
2
|
+
|
3
|
+
module Net
|
4
|
+
module IP
|
5
|
+
class Route
|
6
|
+
# Parses routing table entries
|
7
|
+
class Parser
|
8
|
+
# Parse a routing table entry into a hash
|
9
|
+
#
|
10
|
+
# @param line {String}
|
11
|
+
# @return {Hash}
|
12
|
+
def self.parse_line(line)
|
13
|
+
params = {}
|
14
|
+
|
15
|
+
if line =~ /^(unicast|unreachable|blackhole|prohibit|local|broadcast|throw|nat|via|anycast|multicast)\s+/
|
16
|
+
params[:type] = $1
|
17
|
+
line = line[$1.length..-1]
|
18
|
+
end
|
19
|
+
|
20
|
+
params[:prefix] = line.split.first
|
21
|
+
params[:dev] = $1 if line =~ /\s+dev\s+([^\s]+)/
|
22
|
+
params[:scope] = $1 if line =~ /\s+scope\s+([^\s]+)/
|
23
|
+
params[:metric] = $1 if line =~ /\s+metric\s+([^\s]+)/
|
24
|
+
params[:proto] = $1 if line =~ /\s+proto\s+([^\s]+)/
|
25
|
+
params[:src] = $1 if line =~ /\s+src\s+([^\s]+)/
|
26
|
+
params[:via] = $1 if line =~ /\s+via\s+([^\s]+)/
|
27
|
+
params[:weight] = $1 if line =~ /\s+weight\s+([^\s]+)/
|
28
|
+
params[:table] = $1 if line =~ /\s+table\s+([^\s]+)/
|
29
|
+
params[:error] = $1 if line =~ /\s+error\s+([^\s]+)/
|
30
|
+
|
31
|
+
params
|
32
|
+
end
|
33
|
+
|
34
|
+
# Parse the output of ip route into an array of hashes
|
35
|
+
#
|
36
|
+
# @param data {String}
|
37
|
+
# @return {Array}
|
38
|
+
def self.parse(data)
|
39
|
+
list = []
|
40
|
+
in_default = false
|
41
|
+
data.each_line do |line|
|
42
|
+
if in_default == true
|
43
|
+
if line.start_with? "\t"
|
44
|
+
list << parse_line(line.strip.gsub("nexthop", "default"))
|
45
|
+
else
|
46
|
+
in_default = false
|
47
|
+
end
|
48
|
+
elsif line.strip == "default"
|
49
|
+
in_default = true
|
50
|
+
end
|
51
|
+
|
52
|
+
unless in_default
|
53
|
+
list << parse_line(line.strip)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
list
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/net/ip/route.rb
CHANGED
@@ -2,89 +2,32 @@ module Net
|
|
2
2
|
module IP
|
3
3
|
# Class for working with routing table entries.
|
4
4
|
class Route
|
5
|
-
|
6
|
-
:proto, :src, :via, :weight, :table, :error
|
7
|
-
|
8
|
-
extend Enumerable
|
5
|
+
attr_reader :prefix
|
9
6
|
|
10
7
|
# Create a new route object
|
11
8
|
# @example Create a default route
|
12
9
|
# Net::IP::Route.new(:prefix => 'default', :via => '192.168.0.1')
|
13
10
|
# @example Create a normal route
|
14
11
|
# Net::IP::Route.new(:prefix => '10.0.0.0/8', :dev => 'eth0')
|
15
|
-
# @note This does NOT add the entry to the routing table. See {
|
12
|
+
# @note This does NOT add the entry to the routing table. See {Route::Collection#add} for creating new routes in the routing table.
|
16
13
|
# @param params {Hash}
|
17
14
|
def initialize(params = {})
|
18
15
|
params.each do |k,v|
|
19
|
-
|
16
|
+
instance_variable_set("@#{k}", v)
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
23
|
-
|
24
|
-
# @yield {Route}
|
25
|
-
# @return {void}
|
26
|
-
def self.each(&block)
|
27
|
-
RouteParser.parse(`ip route`).each {|r| yield(new(r))}
|
28
|
-
end
|
29
|
-
|
30
|
-
# Get a list of all routes
|
31
|
-
# @return {Array<Route>}
|
32
|
-
def self.all
|
33
|
-
RouteParser.parse(`ip route`).collect {|r| new(r)}
|
34
|
-
end
|
35
|
-
|
36
|
-
# Get a list of all default gateway routes
|
37
|
-
# @return {Array<Route>}
|
38
|
-
def self.find_gateways
|
39
|
-
find_all {|r| r.prefix == "default"}
|
40
|
-
end
|
41
|
-
|
42
|
-
# Update the list of default gateways
|
43
|
-
# @example Change the default gateway to 192.168.0.1
|
44
|
-
# gateway = Net::IP::Route.new(:prefix => 'default', :via => '192.168.0.1')
|
45
|
-
# Net::IP::Route.update_gateways([gateway])
|
46
|
-
# @param gateways {Array<Route>} List of default gateways to use.
|
47
|
-
# @return {void}
|
48
|
-
def self.update_gateways(gateways)
|
49
|
-
params = gateways.collect {|gateway| "nexthop " + gateway.build_param_string}
|
50
|
-
result = `ip route replace default #{params.join(" ")}`
|
51
|
-
raise result unless $?.success?
|
52
|
-
end
|
53
|
-
|
54
|
-
# Add a route to the routing table
|
55
|
-
# @example Create a route to the 10.0.0.0/8 network
|
56
|
-
# route = Net::IP::Route.new(:prefix => '10.0.0.0/8', :dev => 'eth0')
|
57
|
-
# Net::IP::Route.add_route(route)
|
58
|
-
# @param route {Route} Route to add to the table.
|
59
|
-
# @return {void}
|
60
|
-
def self.add_route(route)
|
61
|
-
result = `ip route add #{route.build_param_string}`
|
62
|
-
raise result unless $?.success?
|
63
|
-
end
|
64
|
-
|
65
|
-
# Flush the routing table based on a selector
|
66
|
-
# @example Flush the routing table cache
|
67
|
-
# Net::IP::Route.flush(:cache)
|
68
|
-
# @param selector {String} The selector string.
|
69
|
-
# @return {void}
|
70
|
-
def self.flush(selector)
|
71
|
-
result = `ip route flush #{selector}`
|
72
|
-
raise result unless $?.success?
|
73
|
-
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
def build_param_string
|
20
|
+
def to_params
|
78
21
|
str = ""
|
79
|
-
str << "via #{via} " if via
|
80
|
-
str << "dev #{dev} " if dev
|
81
|
-
str << "weight #{weight}" if weight
|
82
|
-
str << " table #{table} " if table
|
83
|
-
str << " proto #{proto} " if proto
|
84
|
-
str << " scope #{scope} " if scope
|
85
|
-
str << " src #{src} " if src
|
86
|
-
str << " metric #{metric} " if metric
|
87
|
-
str << " error #{error}" if error
|
22
|
+
str << "via #{@via} " if @via
|
23
|
+
str << "dev #{@dev} " if @dev
|
24
|
+
str << "weight #{@weight}" if @weight
|
25
|
+
str << " table #{@table} " if @table
|
26
|
+
str << " proto #{@proto} " if @proto
|
27
|
+
str << " scope #{@scope} " if @scope
|
28
|
+
str << " src #{@src} " if @src
|
29
|
+
str << " metric #{@metric} " if @metric
|
30
|
+
str << " error #{@error}" if @error
|
88
31
|
str
|
89
32
|
end
|
90
33
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "net/ip/rule"
|
2
|
+
require "net/ip/rule/parser"
|
3
|
+
|
4
|
+
module Net
|
5
|
+
module IP
|
6
|
+
class Rule
|
7
|
+
class Collection
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
# Enumerate all rules
|
11
|
+
# @yield {Rule}
|
12
|
+
# @return {void}
|
13
|
+
def each(&block)
|
14
|
+
Parser.parse(`ip rule list`).each {|r| yield(Rule.new(r))}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add a rule to the ip rule list
|
18
|
+
# @example Create a rule for 1.2.3.4 to use routing table 'custom'
|
19
|
+
# rule = Net::IP::Rule.new(:to => '1.2.3.4', :table => 'custom')
|
20
|
+
# Net::IP.rules.add_rule(rule)
|
21
|
+
# @param rule {Rule} Rule to add to the list.
|
22
|
+
# @return {void}
|
23
|
+
def add(rule)
|
24
|
+
result = `ip rule add #{rule.to_params}`
|
25
|
+
raise result unless $?.success?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Delete a rule from the ip rule list
|
29
|
+
# @example Delete a rule for 1.2.3.4 using routing table 'custom'
|
30
|
+
# rule = Net::IP::Rule.new(:to => '1.2.3.4', :table => 'custom')
|
31
|
+
# Net::IP.rules.delete_rule(rule)
|
32
|
+
# @param rule {Rule} Rule to delete from the list.
|
33
|
+
# @return {void}
|
34
|
+
def delete(rule)
|
35
|
+
result = `ip rule delete #{rule.to_params}`
|
36
|
+
raise result unless $?.success?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Net
|
2
|
+
module IP
|
3
|
+
class Rule
|
4
|
+
class Parser
|
5
|
+
# Parse a rule entry into a hash
|
6
|
+
#
|
7
|
+
# @param line {String}
|
8
|
+
# @return {Hash}
|
9
|
+
def self.parse_line(line)
|
10
|
+
params = {}
|
11
|
+
params[:priority] = $1 if line =~ /^(\d+):\t/
|
12
|
+
params[:from] = $1 if line =~ /\s+from\s+([^\s]+)\s+/
|
13
|
+
params[:to] = $1 if line =~ /\s+to\s+([^\s]+)\s+/
|
14
|
+
params[:lookup] = $1 if line =~ /\s+lookup\s+([^\s]+)\s+/
|
15
|
+
params[:realms] = $1 if line =~ /\s+realms\s+([^\s]+)\s+/
|
16
|
+
params[:map_to] = $1 if line =~ /\s+map-to\s+([^\s]+)\s+/
|
17
|
+
params
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse(data)
|
21
|
+
list = []
|
22
|
+
data.split("\n").each do |line|
|
23
|
+
list << parse_line(line)
|
24
|
+
end
|
25
|
+
list
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/net/ip/rule.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Net
|
2
|
+
module IP
|
3
|
+
# Class for working with ip rules.
|
4
|
+
class Rule
|
5
|
+
# Create a new rule object
|
6
|
+
# @example Create a rule to use a different route table
|
7
|
+
# Net::IP::Rule.new(:to => '1.2.3.4', :table => 'custom')
|
8
|
+
# @note This does NOT add the entry to the ip rules. See {Rule::Collection#add} for creating new rules in the ip rule list.
|
9
|
+
# @param params {Hash}
|
10
|
+
def initialize(params = {})
|
11
|
+
params.each do |k,v|
|
12
|
+
instance_variable_set("@#{k}", v)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_params
|
17
|
+
str = ""
|
18
|
+
str << "priority #{@priority} " if @priority
|
19
|
+
str
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/net/ip/version.rb
CHANGED
data/lib/net/ip.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
require "net/ip/version"
|
2
|
-
require "net/ip/
|
3
|
-
require "net/ip/
|
2
|
+
require "net/ip/route/collection"
|
3
|
+
require "net/ip/rule/collection"
|
4
4
|
|
5
5
|
module Net
|
6
6
|
module IP
|
7
|
+
# Get list of routes
|
8
|
+
# @return {Route::Collection}
|
9
|
+
def self.routes
|
10
|
+
Route::Collection.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get list of rules
|
14
|
+
# @return {Rule::Collection}
|
15
|
+
def self.rules
|
16
|
+
Rule::Collection.new
|
17
|
+
end
|
7
18
|
end
|
8
19
|
end
|
data/net-ip.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Net::IP::VERSION
|
9
9
|
spec.authors = ["Joshua Bussdieker"]
|
10
10
|
spec.email = ["jbussdieker@gmail.com"]
|
11
|
-
spec.summary = %q{Tools for working with IP routes}
|
11
|
+
spec.summary = %q{Tools for working with IP routes and rules}
|
12
12
|
spec.homepage = "http://github.com/jbussdieker/ruby-net-ip"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'net/ip/
|
1
|
+
require 'net/ip/route/parser'
|
2
2
|
|
3
|
-
describe Net::IP::
|
3
|
+
describe Net::IP::Route::Parser do
|
4
4
|
context "line parser" do
|
5
5
|
def test_parse_line(line, field, expect)
|
6
|
-
h = Net::IP::
|
6
|
+
h = Net::IP::Route::Parser.parse_line(line)
|
7
7
|
h[field].should eql(expect)
|
8
8
|
end
|
9
9
|
|
@@ -46,11 +46,11 @@ describe Net::IP::RouteParser do
|
|
46
46
|
|
47
47
|
context "parser" do
|
48
48
|
def test_parse(file, expect)
|
49
|
-
Net::IP::
|
49
|
+
Net::IP::Route::Parser.parse(File.read(file)).should eql(expect)
|
50
50
|
end
|
51
51
|
|
52
52
|
it "handles sample 1" do
|
53
|
-
test_parse("spec/net/ip/sample1", [
|
53
|
+
test_parse("spec/net/ip/route/sample1", [
|
54
54
|
{:prefix=>"default", :dev=>"eth0", :proto=>"static", :via=>"192.168.0.1"},
|
55
55
|
{:prefix=>"169.254.0.0/16", :dev=>"eth0", :scope=>"link", :metric=>"1000"},
|
56
56
|
{:prefix=>"192.168.0.0/24", :dev=>"eth0", :scope=>"link", :metric=>"1", :proto=>"kernel", :src=>"192.168.0.15"}
|
@@ -58,7 +58,7 @@ describe Net::IP::RouteParser do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it "handles sample 2" do
|
61
|
-
test_parse("spec/net/ip/sample2", [
|
61
|
+
test_parse("spec/net/ip/route/sample2", [
|
62
62
|
{:prefix=>"default", :dev=>"eth0", :via=>"10.0.61.225", :weight=>"1"},
|
63
63
|
{:prefix=>"default", :dev=>"eth0", :via=>"10.0.45.153", :weight=>"1"},
|
64
64
|
{:prefix=>"10.0.0.0", :dev=>"eth0", :via=>"10.0.0.1"},
|
@@ -68,7 +68,7 @@ describe Net::IP::RouteParser do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it "handles sample 3" do
|
71
|
-
test_parse("spec/net/ip/sample3", [
|
71
|
+
test_parse("spec/net/ip/route/sample3", [
|
72
72
|
{:prefix=>"default", :dev=>"eth0", :via=>"10.0.35.196"},
|
73
73
|
{:prefix=>"10.0.0.0", :dev=>"eth0", :via=>"10.0.0.1"},
|
74
74
|
{:prefix=>"10.0.0.0/18", :dev=>"eth0", :scope=>"link", :proto=>"kernel", :src=>"10.0.58.155"},
|
@@ -77,7 +77,7 @@ describe Net::IP::RouteParser do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
it "handles sample 4" do
|
80
|
-
test_parse("spec/net/ip/sample4", [
|
80
|
+
test_parse("spec/net/ip/route/sample4", [
|
81
81
|
{:prefix=>"default", :dev=>"eth0", :via=>"192.168.0.1"},
|
82
82
|
{:prefix=>"169.254.0.0/16", :dev=>"eth0", :scope=>"link", :metric=>"1000"},
|
83
83
|
{:prefix=>"192.168.0.0/24", :dev=>"eth0", :scope=>"link", :metric=>"1", :proto=>"kernel", :src=>"192.168.0.15"},
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/net/ip/route_spec.rb
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'net/ip/rule/parser'
|
2
|
+
|
3
|
+
describe Net::IP::Rule::Parser do
|
4
|
+
context "line parser" do
|
5
|
+
def test_parse_line(line, field, expect)
|
6
|
+
h = Net::IP::Rule::Parser.parse_line(line)
|
7
|
+
h[field].should eql(expect)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should parse priority" do
|
11
|
+
test_parse_line("0: from all lookup local ", :priority, "0")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should parse from" do
|
15
|
+
test_parse_line("0: from all lookup local ", :from, "all")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should parse lookup" do
|
19
|
+
test_parse_line("0: from all lookup local ", :lookup, "local")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should parse to" do
|
23
|
+
test_parse_line("32756: from all to 1.2.3.1 lookup custom ", :to, "1.2.3.1")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "parser" do
|
28
|
+
def test_parse(file, expect)
|
29
|
+
Net::IP::Rule::Parser.parse(File.read(file)).should eql(expect)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "handles sample 1" do
|
33
|
+
test_parse("spec/net/ip/rule/sample1", [
|
34
|
+
{:priority=>"0", :from=>"all", :lookup=>"local"},
|
35
|
+
{:priority=>"32766", :from=>"all", :lookup=>"main"},
|
36
|
+
{:priority=>"32767", :from=>"all", :lookup=>"default"}
|
37
|
+
])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "handles sample 2" do
|
41
|
+
test_parse("spec/net/ip/rule/sample2", [
|
42
|
+
{:priority=>"0", :from=>"all", :lookup=>"local"},
|
43
|
+
{:priority=>"32756", :from=>"all", :to=>"1.2.3.1", :lookup=>"custom"},
|
44
|
+
{:priority=>"32757", :from=>"all", :to=>"1.2.3.2", :lookup=>"custom"},
|
45
|
+
{:priority=>"32758", :from=>"all", :to=>"1.2.3.3", :lookup=>"custom"},
|
46
|
+
{:priority=>"32759", :from=>"all", :to=>"1.2.3.4", :lookup=>"custom"},
|
47
|
+
{:priority=>"32760", :from=>"all", :to=>"1.2.3.5", :lookup=>"custom"},
|
48
|
+
{:priority=>"32761", :from=>"all", :to=>"1.2.3.6", :lookup=>"custom"},
|
49
|
+
{:priority=>"32762", :from=>"all", :to=>"1.2.3.7", :lookup=>"custom"},
|
50
|
+
{:priority=>"32763", :from=>"all", :to=>"1.2.3.8", :lookup=>"custom"},
|
51
|
+
{:priority=>"32764", :from=>"all", :to=>"1.2.3.9", :lookup=>"custom"},
|
52
|
+
{:priority=>"32765", :from=>"all", :to=>"1.2.3.10", :lookup=>"custom"},
|
53
|
+
{:priority=>"32766", :from=>"all", :lookup=>"main"},
|
54
|
+
{:priority=>"32767", :from=>"all", :lookup=>"default"}
|
55
|
+
])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
0: from all lookup local
|
2
|
+
32756: from all to 1.2.3.1 lookup custom
|
3
|
+
32757: from all to 1.2.3.2 lookup custom
|
4
|
+
32758: from all to 1.2.3.3 lookup custom
|
5
|
+
32759: from all to 1.2.3.4 lookup custom
|
6
|
+
32760: from all to 1.2.3.5 lookup custom
|
7
|
+
32761: from all to 1.2.3.6 lookup custom
|
8
|
+
32762: from all to 1.2.3.7 lookup custom
|
9
|
+
32763: from all to 1.2.3.8 lookup custom
|
10
|
+
32764: from all to 1.2.3.9 lookup custom
|
11
|
+
32765: from all to 1.2.3.10 lookup custom
|
12
|
+
32766: from all lookup main
|
13
|
+
32767: from all lookup default
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'net/ip/rule'
|
2
|
+
|
3
|
+
describe Net::IP::Rule do
|
4
|
+
it "should be creatable" do
|
5
|
+
Net::IP::Rule.new.should be_kind_of(Net::IP::Rule)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be convert to_params" do
|
9
|
+
Net::IP::Rule.new(:priority => '1').to_params.should eql("priority 1 ")
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,75 +1,71 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ip
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 4
|
10
|
-
version: 0.0.4
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Joshua Bussdieker
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
12
|
+
date: 2013-08-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
22
17
|
none: false
|
23
|
-
requirements:
|
18
|
+
requirements:
|
24
19
|
- - ~>
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
|
27
|
-
segments:
|
28
|
-
- 1
|
29
|
-
- 3
|
30
|
-
version: "1.3"
|
31
|
-
name: bundler
|
32
|
-
prerelease: false
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
33
22
|
type: :development
|
34
|
-
|
35
|
-
|
36
|
-
version_requirements: &id002 !ruby/object:Gem::Requirement
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
25
|
none: false
|
38
|
-
requirements:
|
39
|
-
- -
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
|
42
|
-
|
43
|
-
- 0
|
44
|
-
version: "0"
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
45
31
|
name: rake
|
46
|
-
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
47
38
|
type: :development
|
48
|
-
|
49
|
-
|
50
|
-
version_requirements: &id003 !ruby/object:Gem::Requirement
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
41
|
none: false
|
52
|
-
requirements:
|
53
|
-
- -
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
|
56
|
-
|
57
|
-
- 0
|
58
|
-
version: "0"
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
59
47
|
name: rspec
|
60
|
-
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
61
54
|
type: :development
|
62
|
-
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
63
62
|
description:
|
64
|
-
email:
|
63
|
+
email:
|
65
64
|
- jbussdieker@gmail.com
|
66
65
|
executables: []
|
67
|
-
|
68
66
|
extensions: []
|
69
|
-
|
70
67
|
extra_rdoc_files: []
|
71
|
-
|
72
|
-
files:
|
68
|
+
files:
|
73
69
|
- .gitignore
|
74
70
|
- .travis.yml
|
75
71
|
- Gemfile
|
@@ -78,52 +74,62 @@ files:
|
|
78
74
|
- Rakefile
|
79
75
|
- lib/net/ip.rb
|
80
76
|
- lib/net/ip/route.rb
|
81
|
-
- lib/net/ip/
|
77
|
+
- lib/net/ip/route/collection.rb
|
78
|
+
- lib/net/ip/route/parser.rb
|
79
|
+
- lib/net/ip/rule.rb
|
80
|
+
- lib/net/ip/rule/collection.rb
|
81
|
+
- lib/net/ip/rule/parser.rb
|
82
82
|
- lib/net/ip/version.rb
|
83
83
|
- net-ip.gemspec
|
84
|
-
- spec/net/ip/
|
84
|
+
- spec/net/ip/route/parser_spec.rb
|
85
|
+
- spec/net/ip/route/sample1
|
86
|
+
- spec/net/ip/route/sample2
|
87
|
+
- spec/net/ip/route/sample3
|
88
|
+
- spec/net/ip/route/sample4
|
85
89
|
- spec/net/ip/route_spec.rb
|
86
|
-
- spec/net/ip/
|
87
|
-
- spec/net/ip/
|
88
|
-
- spec/net/ip/
|
89
|
-
- spec/net/ip/
|
90
|
+
- spec/net/ip/rule/parser_spec.rb
|
91
|
+
- spec/net/ip/rule/sample1
|
92
|
+
- spec/net/ip/rule/sample2
|
93
|
+
- spec/net/ip/rule_spec.rb
|
90
94
|
homepage: http://github.com/jbussdieker/ruby-net-ip
|
91
|
-
licenses:
|
95
|
+
licenses:
|
92
96
|
- MIT
|
93
97
|
post_install_message:
|
94
98
|
rdoc_options: []
|
95
|
-
|
96
|
-
require_paths:
|
99
|
+
require_paths:
|
97
100
|
- lib
|
98
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
102
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
|
104
|
-
segments:
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
segments:
|
105
108
|
- 0
|
106
|
-
|
107
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
hash: -1307484347518193870
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
111
|
none: false
|
109
|
-
requirements:
|
110
|
-
- -
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
|
113
|
-
segments:
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
segments:
|
114
117
|
- 0
|
115
|
-
|
118
|
+
hash: -1307484347518193870
|
116
119
|
requirements: []
|
117
|
-
|
118
120
|
rubyforge_project:
|
119
121
|
rubygems_version: 1.8.25
|
120
122
|
signing_key:
|
121
123
|
specification_version: 3
|
122
|
-
summary: Tools for working with IP routes
|
123
|
-
test_files:
|
124
|
-
- spec/net/ip/
|
124
|
+
summary: Tools for working with IP routes and rules
|
125
|
+
test_files:
|
126
|
+
- spec/net/ip/route/parser_spec.rb
|
127
|
+
- spec/net/ip/route/sample1
|
128
|
+
- spec/net/ip/route/sample2
|
129
|
+
- spec/net/ip/route/sample3
|
130
|
+
- spec/net/ip/route/sample4
|
125
131
|
- spec/net/ip/route_spec.rb
|
126
|
-
- spec/net/ip/
|
127
|
-
- spec/net/ip/
|
128
|
-
- spec/net/ip/
|
129
|
-
- spec/net/ip/
|
132
|
+
- spec/net/ip/rule/parser_spec.rb
|
133
|
+
- spec/net/ip/rule/sample1
|
134
|
+
- spec/net/ip/rule/sample2
|
135
|
+
- spec/net/ip/rule_spec.rb
|
data/lib/net/ip/route_parser.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
module Net
|
2
|
-
module IP
|
3
|
-
# Parses routing table entries
|
4
|
-
class RouteParser
|
5
|
-
# Parse a routing table entry into a hash
|
6
|
-
#
|
7
|
-
# @param line {String}
|
8
|
-
# @return {Hash}
|
9
|
-
def self.parse_line(line)
|
10
|
-
params = {}
|
11
|
-
|
12
|
-
if line =~ /^(unicast|unreachable|blackhole|prohibit|local|broadcast|throw|nat|via|anycast|multicast)\s+/
|
13
|
-
params[:type] = $1
|
14
|
-
line = line[$1.length..-1]
|
15
|
-
end
|
16
|
-
|
17
|
-
params[:prefix] = line.split.first
|
18
|
-
params[:dev] = $1 if line =~ /\s+dev\s+([^\s]+)/
|
19
|
-
params[:scope] = $1 if line =~ /\s+scope\s+([^\s]+)/
|
20
|
-
params[:metric] = $1 if line =~ /\s+metric\s+([^\s]+)/
|
21
|
-
params[:proto] = $1 if line =~ /\s+proto\s+([^\s]+)/
|
22
|
-
params[:src] = $1 if line =~ /\s+src\s+([^\s]+)/
|
23
|
-
params[:via] = $1 if line =~ /\s+via\s+([^\s]+)/
|
24
|
-
params[:weight] = $1 if line =~ /\s+weight\s+([^\s]+)/
|
25
|
-
params[:table] = $1 if line =~ /\s+table\s+([^\s]+)/
|
26
|
-
params[:error] = $1 if line =~ /\s+error\s+([^\s]+)/
|
27
|
-
|
28
|
-
params
|
29
|
-
end
|
30
|
-
|
31
|
-
# Parse the output of ip route into an array of hashes
|
32
|
-
#
|
33
|
-
# @param data {String}
|
34
|
-
# @return {Array}
|
35
|
-
def self.parse(data)
|
36
|
-
list = []
|
37
|
-
in_default = false
|
38
|
-
data.each_line do |line|
|
39
|
-
if in_default == true
|
40
|
-
if line.start_with? "\t"
|
41
|
-
list << parse_line(line.strip.gsub("nexthop", "default"))
|
42
|
-
else
|
43
|
-
in_default = false
|
44
|
-
end
|
45
|
-
elsif line.strip == "default"
|
46
|
-
in_default = true
|
47
|
-
end
|
48
|
-
|
49
|
-
unless in_default
|
50
|
-
list << parse_line(line.strip)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
list
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|