pio 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.travis.yml +1 -0
  4. data/CONTRIBUTING.md +12 -0
  5. data/Gemfile +26 -23
  6. data/Guardfile +5 -0
  7. data/README.md +61 -19
  8. data/Rakefile +54 -56
  9. data/lib/pio/arp/frame.rb +8 -6
  10. data/lib/pio/arp/message.rb +9 -23
  11. data/lib/pio/arp/reply.rb +6 -15
  12. data/lib/pio/arp/request.rb +7 -16
  13. data/lib/pio/arp.rb +14 -17
  14. data/lib/pio/icmp/frame.rb +131 -0
  15. data/lib/pio/icmp/message.rb +100 -0
  16. data/lib/pio/icmp/reply.rb +17 -0
  17. data/lib/pio/icmp/request.rb +17 -0
  18. data/lib/pio/icmp.rb +27 -0
  19. data/lib/pio/ipv4_address.rb +22 -39
  20. data/lib/pio/lldp/chassis_id_tlv.rb +13 -16
  21. data/lib/pio/lldp/end_of_lldpdu_value.rb +4 -5
  22. data/lib/pio/lldp/frame.rb +21 -32
  23. data/lib/pio/lldp/management_address_value.rb +3 -4
  24. data/lib/pio/lldp/optional_tlv.rb +13 -22
  25. data/lib/pio/lldp/organizationally_specific_value.rb +3 -4
  26. data/lib/pio/lldp/port_description_value.rb +3 -4
  27. data/lib/pio/lldp/port_id_tlv.rb +6 -9
  28. data/lib/pio/lldp/system_capabilities_value.rb +3 -4
  29. data/lib/pio/lldp/system_description_value.rb +3 -4
  30. data/lib/pio/lldp/system_name_value.rb +3 -4
  31. data/lib/pio/lldp/ttl_tlv.rb +6 -9
  32. data/lib/pio/lldp.rb +20 -36
  33. data/lib/pio/mac.rb +30 -53
  34. data/lib/pio/message_util.rb +19 -0
  35. data/lib/pio/type/config.reek +4 -0
  36. data/lib/pio/type/ethernet_header.rb +7 -4
  37. data/lib/pio/type/ip_address.rb +5 -8
  38. data/lib/pio/type/ipv4_header.rb +37 -0
  39. data/lib/pio/type/mac_address.rb +7 -8
  40. data/lib/pio/util.rb +21 -0
  41. data/lib/pio/version.rb +2 -2
  42. data/lib/pio.rb +4 -4
  43. data/pio.gemspec +15 -17
  44. data/pio.org +499 -76
  45. data/pio.org_archive +86 -0
  46. data/rubocop-todo.yml +9 -0
  47. data/spec/pio/arp/reply_spec.rb +106 -118
  48. data/spec/pio/arp/request_spec.rb +90 -101
  49. data/spec/pio/arp_spec.rb +105 -113
  50. data/spec/pio/icmp/reply_spec.rb +132 -0
  51. data/spec/pio/icmp/request_spec.rb +131 -0
  52. data/spec/pio/icmp_spec.rb +159 -0
  53. data/spec/pio/ipv4_address_spec.rb +87 -97
  54. data/spec/pio/lldp_spec.rb +237 -186
  55. data/spec/pio/mac_spec.rb +82 -93
  56. data/spec/spec_helper.rb +10 -13
  57. metadata +20 -2
@@ -1,11 +1,11 @@
1
- require "pio/lldp/port_description_value"
2
- require "pio/lldp/system_name_value"
3
- require "pio/lldp/system_description_value"
4
- require "pio/lldp/system_capabilities_value"
5
- require "pio/lldp/management_address_value"
6
- require "pio/lldp/organizationally_specific_value"
7
- require "pio/lldp/end_of_lldpdu_value"
8
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'pio/lldp/port_description_value'
3
+ require 'pio/lldp/system_name_value'
4
+ require 'pio/lldp/system_description_value'
5
+ require 'pio/lldp/system_capabilities_value'
6
+ require 'pio/lldp/management_address_value'
7
+ require 'pio/lldp/organizationally_specific_value'
8
+ require 'pio/lldp/end_of_lldpdu_value'
9
9
 
10
10
  module Pio
11
11
  class Lldp
@@ -17,7 +17,7 @@ module Pio
17
17
  bit9 :tlv_info_length
18
18
  choice :tlv_value,
19
19
  :read_length => :tlv_info_length,
20
- :onlyif => lambda { not end_of_lldpdu? },
20
+ :onlyif => lambda { !end_of_lldpdu? },
21
21
  :selection => :chooser do
22
22
  end_of_lldpdu_value 0
23
23
  port_description_value 4
@@ -26,40 +26,32 @@ module Pio
26
26
  system_capabilities_value 7
27
27
  management_address_value 8
28
28
  organizationally_specific_value 127
29
- string "unknown"
29
+ string 'unknown'
30
30
  end
31
31
 
32
-
33
32
  def end_of_lldpdu?
34
33
  tlv_type == 0
35
34
  end
36
35
 
37
-
38
36
  def chooser
39
37
  if valid_optional_tlv?
40
38
  tlv_type
41
39
  else
42
- "unknown"
40
+ 'unknown'
43
41
  end
44
42
  end
45
43
 
46
-
47
- ##########################################################################
48
44
  private
49
- ##########################################################################
50
-
51
45
 
52
46
  def valid_optional_tlv?
53
- optional_tlv? or end_of_lldpdu_tlv?
47
+ optional_tlv? || end_of_lldpdu_tlv?
54
48
  end
55
49
 
56
-
57
50
  def optional_tlv?
58
51
  tmp_tlv_type = tlv_type
59
- 4 <= tmp_tlv_type and tmp_tlv_type <= 127
52
+ 4 <= tmp_tlv_type && tmp_tlv_type <= 127
60
53
  end
61
54
 
62
-
63
55
  def end_of_lldpdu_tlv?
64
56
  tlv_type == 0
65
57
  end
@@ -67,7 +59,6 @@ module Pio
67
59
  end
68
60
  end
69
61
 
70
-
71
62
  ### Local variables:
72
63
  ### mode: Ruby
73
64
  ### coding: utf-8-unix
@@ -1,6 +1,6 @@
1
- require "rubygems"
2
- require "bindata"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bindata'
4
4
 
5
5
  module Pio
6
6
  class Lldp
@@ -15,7 +15,6 @@ module Pio
15
15
  end
16
16
  end
17
17
 
18
-
19
18
  ### Local variables:
20
19
  ### mode: Ruby
21
20
  ### coding: utf-8-unix
@@ -1,6 +1,6 @@
1
- require "rubygems"
2
- require "bindata"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bindata'
4
4
 
5
5
  module Pio
6
6
  class Lldp
@@ -13,7 +13,6 @@ module Pio
13
13
  end
14
14
  end
15
15
 
16
-
17
16
  ### Local variables:
18
17
  ### mode: Ruby
19
18
  ### coding: utf-8-unix
@@ -1,6 +1,6 @@
1
- require "rubygems"
2
- require "bindata"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bindata'
4
4
 
5
5
  module Pio
6
6
  class Lldp
@@ -13,7 +13,6 @@ module Pio
13
13
  uint8 :subtype, :initial_value => 7
14
14
  string :port_id, :read_length => lambda { tlv_info_length - 1 }
15
15
 
16
-
17
16
  def get
18
17
  tmp_id = port_id
19
18
 
@@ -24,10 +23,9 @@ module Pio
24
23
  end
25
24
  end
26
25
 
27
-
28
- def set value
29
- self.port_id = if value.kind_of?( Fixnum ) and subtype == 7
30
- BinData::Uint32be.new( value ).to_binary_s
26
+ def set(value)
27
+ self.port_id = if subtype == 7
28
+ BinData::Uint32be.new(value).to_binary_s
31
29
  else
32
30
  value
33
31
  end
@@ -36,7 +34,6 @@ module Pio
36
34
  end
37
35
  end
38
36
 
39
-
40
37
  ### Local variables:
41
38
  ### mode: Ruby
42
39
  ### coding: utf-8-unix
@@ -1,6 +1,6 @@
1
- require "rubygems"
2
- require "bindata"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bindata'
4
4
 
5
5
  module Pio
6
6
  class Lldp
@@ -14,7 +14,6 @@ module Pio
14
14
  end
15
15
  end
16
16
 
17
-
18
17
  ### Local variables:
19
18
  ### mode: Ruby
20
19
  ### coding: utf-8-unix
@@ -1,6 +1,6 @@
1
- require "rubygems"
2
- require "bindata"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bindata'
4
4
 
5
5
  module Pio
6
6
  class Lldp
@@ -13,7 +13,6 @@ module Pio
13
13
  end
14
14
  end
15
15
 
16
-
17
16
  ### Local variables:
18
17
  ### mode: Ruby
19
18
  ### coding: utf-8-unix
@@ -1,6 +1,6 @@
1
- require "rubygems"
2
- require "bindata"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bindata'
4
4
 
5
5
  module Pio
6
6
  class Lldp
@@ -13,7 +13,6 @@ module Pio
13
13
  end
14
14
  end
15
15
 
16
-
17
16
  ### Local variables:
18
17
  ### mode: Ruby
19
18
  ### coding: utf-8-unix
@@ -1,6 +1,6 @@
1
- require "rubygems"
2
- require "bindata"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'bindata'
4
4
 
5
5
  module Pio
6
6
  class Lldp
@@ -12,20 +12,17 @@ module Pio
12
12
  bit9 :tlv_info_length, :value => 2
13
13
  string :ttl, :read_length => :tlv_info_length
14
14
 
15
-
16
15
  def get
17
- BinData::Int16be.read( ttl )
16
+ BinData::Int16be.read(ttl)
18
17
  end
19
18
 
20
-
21
- def set value
22
- self.ttl = BinData::Int16be.new( value ).to_binary_s
19
+ def set(value)
20
+ self.ttl = BinData::Int16be.new(value).to_binary_s
23
21
  end
24
22
  end
25
23
  end
26
24
  end
27
25
 
28
-
29
26
  ### Local variables:
30
27
  ### mode: Ruby
31
28
  ### coding: utf-8-unix
data/lib/pio/lldp.rb CHANGED
@@ -1,68 +1,56 @@
1
- require "forwardable"
2
- require "pio/lldp/frame"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'English'
3
+ require 'forwardable'
4
+ require 'pio/lldp/frame'
4
5
 
5
6
  module Pio
6
7
  # LLDP frame parser and generator.
7
8
  class Lldp
8
9
  # User options for creating an LLDP frame.
9
10
  class Options
10
- def initialize options
11
+ def initialize(options)
11
12
  @options = options
12
-
13
- unless dpid
14
- raise TypeError, "Invalid DPID: #{ dpid.inspect }"
15
- end
13
+ fail TypeError, "Invalid DPID: #{ dpid.inspect }" unless dpid
16
14
  unless port_id
17
- raise TypeError, "Invalid port number: #{ port_id.inspect }"
15
+ fail TypeError, "Invalid port number: #{ port_id.inspect }"
18
16
  end
19
17
  end
20
18
 
21
-
22
19
  def to_hash
23
20
  {
24
- :destination_mac => Mac.new( destination_mac ).to_a,
25
- :source_mac => Mac.new( source_mac ).to_a,
21
+ :destination_mac => Mac.new(destination_mac).to_a,
22
+ :source_mac => Mac.new(source_mac).to_a,
26
23
  :chassis_id => dpid,
27
24
  :port_id => port_id
28
25
  }
29
26
  end
30
27
 
31
-
32
- ##########################################################################
33
28
  private
34
- ##########################################################################
35
-
36
29
 
37
30
  def dpid
38
- @options[ :dpid ]
31
+ @options[:dpid]
39
32
  end
40
33
 
41
-
42
34
  def port_id
43
- @options[ :port_number ]
35
+ @options[:port_number]
44
36
  end
45
37
 
46
-
47
38
  def destination_mac
48
- @options[ :destination_mac ] || "01:80:c2:00:00:0e"
39
+ @options[:destination_mac] || '01:80:c2:00:00:0e'
49
40
  end
50
41
 
51
-
52
42
  def source_mac
53
- @options[ :source_mac ] || "01:02:03:04:05:06"
43
+ @options[:source_mac] || '01:02:03:04:05:06'
54
44
  end
55
45
  end
56
46
 
57
-
58
47
  extend Forwardable
59
48
 
60
-
61
- def self.read raw_data
49
+ def self.read(raw_data)
62
50
  begin
63
- frame = Frame.read( raw_data )
51
+ frame = Frame.read(raw_data)
64
52
  rescue
65
- raise Pio::ParseError, $!.message
53
+ raise Pio::ParseError, $ERROR_INFO.message
66
54
  end
67
55
 
68
56
  lldp = allocate
@@ -70,12 +58,10 @@ module Pio
70
58
  lldp
71
59
  end
72
60
 
73
-
74
- def initialize options
75
- @frame = Frame.new( Options.new( options ).to_hash )
61
+ def initialize(options)
62
+ @frame = Frame.new(Options.new(options).to_hash)
76
63
  end
77
64
 
78
-
79
65
  def_delegator :@frame, :destination_mac
80
66
  def_delegator :@frame, :source_mac
81
67
  def_delegator :@frame, :ether_type
@@ -83,7 +69,7 @@ module Pio
83
69
  def_delegator :@frame, :dpid
84
70
  def_delegator :@frame, :optional_tlv
85
71
  def_delegator :@frame, :port_id
86
- alias :port_number :port_id
72
+ alias_method :port_number, :port_id
87
73
  def_delegator :@frame, :ttl
88
74
  def_delegator :@frame, :port_description
89
75
  def_delegator :@frame, :system_name
@@ -93,14 +79,12 @@ module Pio
93
79
  def_delegator :@frame, :management_address
94
80
  def_delegator :@frame, :organizationally_specific
95
81
 
96
-
97
82
  def to_binary
98
- @frame.to_binary_s + "\000" * ( 64 - @frame.num_bytes )
83
+ @frame.to_binary_s + "\000" * ( 64 - @frame.num_bytes)
99
84
  end
100
85
  end
101
86
  end
102
87
 
103
-
104
88
  ### Local variables:
105
89
  ### mode: Ruby
106
90
  ### coding: utf-8-unix
data/lib/pio/mac.rb CHANGED
@@ -1,5 +1,5 @@
1
- require "forwardable"
2
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'forwardable'
3
3
 
4
4
  module Pio
5
5
  #
@@ -9,11 +9,9 @@ module Pio
9
9
  # Raised when Ethernet address is invalid.
10
10
  class InvalidValueError < StandardError; end
11
11
 
12
-
13
12
  extend Forwardable
14
13
  def_delegator :@value, :hash
15
14
 
16
-
17
15
  #
18
16
  # Creates a {Mac} instance that encapsulates Ethernet addresses.
19
17
  #
@@ -25,22 +23,19 @@ module Pio
25
23
  # @param value [#to_str, #to_int] the value converted to an
26
24
  # Ethernet address.
27
25
  #
28
- def initialize value
29
- begin
30
- if value.respond_to?( :to_str )
31
- @value = parse_mac_string( value.to_str )
32
- elsif value.respond_to?( :to_int )
33
- @value = value.to_int
34
- validate_value_range
35
- else
36
- raise TypeError
37
- end
38
- rescue ArgumentError, TypeError
39
- raise InvalidValueError, "Invalid MAC address: #{ value.inspect }"
26
+ def initialize(value)
27
+ if value.respond_to?(:to_str)
28
+ @value = parse_mac_string(value.to_str)
29
+ elsif value.respond_to?(:to_int)
30
+ @value = value.to_int
31
+ validate_value_range
32
+ else
33
+ fail TypeError
40
34
  end
35
+ rescue ArgumentError, TypeError
36
+ raise InvalidValueError, "Invalid MAC address: #{ value.inspect }"
41
37
  end
42
38
 
43
-
44
39
  # @!group Converters
45
40
 
46
41
  #
@@ -55,7 +50,6 @@ module Pio
55
50
  @value
56
51
  end
57
52
 
58
-
59
53
  #
60
54
  # Returns the Ethernet address as 6 pairs of hexadecimal digits
61
55
  # delimited by colons.
@@ -66,10 +60,9 @@ module Pio
66
60
  # @return [String]
67
61
  #
68
62
  def to_s
69
- sprintf( "%012x", @value ).unpack( "a2" * 6 ).join( ":" )
63
+ sprintf('%012x', @value).unpack('a2' * 6).join(':')
70
64
  end
71
65
 
72
-
73
66
  #
74
67
  # Implicitly converts +obj+ to a string.
75
68
  #
@@ -85,25 +78,24 @@ module Pio
85
78
  to_s
86
79
  end
87
80
 
88
-
89
81
  #
90
82
  # Returns an Array of decimal numbers converted from Ethernet's
91
83
  # address string format.
92
84
  #
93
85
  # @example
94
- # Mac.new("11:22:33:44:55:66").to_a #=> [0x11, 0x22, 0x33, 0x44, 0x55, 0x66]
86
+ # Mac.new("11:22:33:44:55:66").to_a
87
+ # #=> [0x11, 0x22, 0x33, 0x44, 0x55, 0x66]
95
88
  #
96
89
  # @return [Array]
97
90
  #
98
91
  def to_a
99
- to_s.split( ":" ).collect do | each |
92
+ to_s.split(':').map do | each |
100
93
  each.hex
101
94
  end
102
95
  end
103
96
 
104
97
  # @!endgroup
105
98
 
106
-
107
99
  # @!group Predicates
108
100
 
109
101
  #
@@ -114,10 +106,9 @@ module Pio
114
106
  # Mac.new("00:00:00:00:00:00").multicast? #=> false
115
107
  #
116
108
  def multicast?
117
- to_a[ 0 ] & 1 == 1
109
+ to_a[0] & 1 == 1
118
110
  end
119
111
 
120
-
121
112
  #
122
113
  # Returns true if Ethernet address is a broadcast address.
123
114
  #
@@ -128,7 +119,6 @@ module Pio
128
119
  to_a.all? { | each | each == 0xff }
129
120
  end
130
121
 
131
-
132
122
  #
133
123
  # Returns +true+ if Ethernet address is an IEEE 802.1D or 802.1Q
134
124
  # reserved address. See
@@ -140,12 +130,11 @@ module Pio
140
130
  # Mac.new("11:22:33:44:55:66").reserved? #=> false
141
131
  #
142
132
  def reserved?
143
- ( to_i >> 8 ) == 0x0180c20000
133
+ ( to_i >> 8) == 0x0180c20000
144
134
  end
145
135
 
146
136
  # @!endgroup
147
137
 
148
-
149
138
  # @!group Equality
150
139
 
151
140
  #
@@ -165,15 +154,12 @@ module Pio
165
154
  #
166
155
  # @return [Boolean]
167
156
  #
168
- def == other
169
- begin
170
- to_i == Mac.new( other ).to_i
171
- rescue InvalidValueError
172
- false
173
- end
157
+ def ==(other)
158
+ to_i == Mac.new(other).to_i
159
+ rescue InvalidValueError
160
+ false
174
161
  end
175
162
 
176
-
177
163
  #
178
164
  # Returns +true+ if +obj+ and +other+ refer to the same hash key.
179
165
  # +#==+ is used for the comparison.
@@ -190,13 +176,12 @@ module Pio
190
176
  #
191
177
  # @see #==
192
178
  #
193
- def eql? other
194
- self.== other
179
+ def eql?(other)
180
+ self == other
195
181
  end
196
182
 
197
183
  # @!endgroup
198
184
 
199
-
200
185
  # @!group Debug
201
186
 
202
187
  #
@@ -211,31 +196,23 @@ module Pio
211
196
 
212
197
  # @!endgroup
213
198
 
214
-
215
- ################################################################################
216
199
  private
217
- ################################################################################
218
-
219
200
 
220
- def parse_mac_string mac
221
- octet_regex = "[0-9a-fA-F][0-9a-fA-F]"
222
- if /^(#{ octet_regex }:){5}(#{ octet_regex })$/=~ mac
223
- mac.gsub( ":", "" ).hex
201
+ def parse_mac_string(mac)
202
+ octet_regex = '[0-9a-fA-F][0-9a-fA-F]'
203
+ if /^(#{ octet_regex }:){5}(#{ octet_regex })$/ =~ mac
204
+ mac.gsub(':', '').hex
224
205
  else
225
- raise ArgumentError
206
+ fail ArgumentError
226
207
  end
227
208
  end
228
209
 
229
-
230
210
  def validate_value_range
231
- unless ( @value >= 0 and @value <= 0xffffffffffff )
232
- raise ArgumentError
233
- end
211
+ fail ArgumentError unless @value >= 0 && @value <= 0xffffffffffff
234
212
  end
235
213
  end
236
214
  end
237
215
 
238
-
239
216
  ### Local variables:
240
217
  ### mode: Ruby
241
218
  ### coding: utf-8-unix
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Pio
3
+ # Pio Message Util.
4
+ module MessageUtil
5
+ def option_hash
6
+ mandatory_options.reduce({}) do | opt, each |
7
+ klass = option_to_klass[each]
8
+ opt_pair = { each => klass.new(user_options[each]).to_a }
9
+ opt.merge opt_pair
10
+ end.merge default_options
11
+ end
12
+ end
13
+ end
14
+
15
+ ### Local variables:
16
+ ### mode: Ruby
17
+ ### coding: utf-8
18
+ ### indent-tabs-mode: nil
19
+ ### End:
@@ -0,0 +1,4 @@
1
+ TooManyStatements:
2
+ exclude:
3
+ - ipv4_header
4
+ enabled: true
@@ -1,14 +1,17 @@
1
- require "pio/type/mac_address"
2
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'pio/type/mac_address'
3
3
 
4
4
  module Pio
5
5
  module Type
6
+ #
7
+ # Adds ethernet_header macro.
8
+ #
6
9
  module EthernetHeader
7
- def ethernet_header options
10
+ def ethernet_header(options)
8
11
  class_eval do
9
12
  mac_address :destination_mac
10
13
  mac_address :source_mac
11
- uint16 :ether_type, :value => options[ :ether_type ]
14
+ uint16 :ether_type, :value => options[:ether_type]
12
15
  end
13
16
  end
14
17
  end
@@ -1,6 +1,6 @@
1
- require "bindata"
2
- require "pio/ipv4_address"
3
-
1
+ # -*- coding: utf-8 -*-
2
+ require 'bindata'
3
+ require 'pio/ipv4_address'
4
4
 
5
5
  module Pio
6
6
  module Type
@@ -8,20 +8,17 @@ module Pio
8
8
  class IpAddress < BinData::Primitive
9
9
  array :octets, :type => :uint8, :initial_length => 4
10
10
 
11
-
12
- def set value
11
+ def set(value)
13
12
  self.octets = value
14
13
  end
15
14
 
16
-
17
15
  def get
18
- IPv4Address.new octets.collect { | each | "%d" % each }.join( "." )
16
+ IPv4Address.new octets.map { | each | sprintf('%d', each) }.join('.')
19
17
  end
20
18
  end
21
19
  end
22
20
  end
23
21
 
24
-
25
22
  ### Local variables:
26
23
  ### mode: Ruby
27
24
  ### coding: utf-8-unix