pio 0.2.7 → 0.3.0

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.
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