pio 0.3.0 → 0.4.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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +46 -12
  3. data/README.md +131 -116
  4. data/Rakefile +7 -92
  5. data/examples/arp_new.rb +16 -0
  6. data/examples/arp_read.rb +4 -0
  7. data/examples/dhcp_new.rb +30 -0
  8. data/examples/dhcp_read.rb +4 -0
  9. data/examples/icmp_new.rb +21 -0
  10. data/examples/icmp_read.rb +4 -0
  11. data/examples/lldp_new.rb +4 -0
  12. data/examples/lldp_read.rb +4 -0
  13. data/lib/pio.rb +6 -12
  14. data/lib/pio/arp.rb +7 -19
  15. data/lib/pio/arp/frame.rb +8 -12
  16. data/lib/pio/arp/message.rb +12 -25
  17. data/lib/pio/arp/reply.rb +30 -30
  18. data/lib/pio/arp/request.rb +30 -29
  19. data/lib/pio/dhcp.rb +58 -0
  20. data/lib/pio/dhcp/ack.rb +12 -0
  21. data/lib/pio/dhcp/boot_reply.rb +16 -0
  22. data/lib/pio/dhcp/boot_reply_options.rb +75 -0
  23. data/lib/pio/dhcp/boot_request.rb +16 -0
  24. data/lib/pio/dhcp/boot_request_options.rb +69 -0
  25. data/lib/pio/dhcp/common_options.rb +71 -0
  26. data/lib/pio/dhcp/csum_util.rb +83 -0
  27. data/lib/pio/dhcp/dhcp_field.rb +48 -0
  28. data/lib/pio/dhcp/dhcp_tlv_options.rb +84 -0
  29. data/lib/pio/dhcp/discover.rb +12 -0
  30. data/lib/pio/dhcp/field_util.rb +102 -0
  31. data/lib/pio/dhcp/frame.rb +95 -0
  32. data/lib/pio/dhcp/message.rb +79 -0
  33. data/lib/pio/dhcp/offer.rb +12 -0
  34. data/lib/pio/dhcp/optional_tlv.rb +74 -0
  35. data/lib/pio/dhcp/request.rb +12 -0
  36. data/lib/pio/dhcp/type/dhcp_client_id.rb +21 -0
  37. data/lib/pio/dhcp/type/dhcp_param_list.rb +22 -0
  38. data/lib/pio/dhcp/type/dhcp_string.rb +21 -0
  39. data/lib/pio/icmp.rb +7 -18
  40. data/lib/pio/icmp/frame.rb +38 -40
  41. data/lib/pio/icmp/message.rb +10 -61
  42. data/lib/pio/icmp/options.rb +25 -0
  43. data/lib/pio/icmp/reply.rb +34 -7
  44. data/lib/pio/icmp/request.rb +43 -7
  45. data/lib/pio/ipv4_address.rb +5 -8
  46. data/lib/pio/lldp.rb +22 -62
  47. data/lib/pio/lldp/chassis_id_tlv.rb +7 -13
  48. data/lib/pio/lldp/end_of_lldpdu_value.rb +3 -9
  49. data/lib/pio/lldp/frame.rb +6 -12
  50. data/lib/pio/lldp/management_address_value.rb +4 -10
  51. data/lib/pio/lldp/optional_tlv.rb +5 -10
  52. data/lib/pio/lldp/options.rb +37 -0
  53. data/lib/pio/lldp/organizationally_specific_value.rb +2 -8
  54. data/lib/pio/lldp/port_description_value.rb +2 -8
  55. data/lib/pio/lldp/port_id_tlv.rb +6 -12
  56. data/lib/pio/lldp/system_capabilities_value.rb +2 -8
  57. data/lib/pio/lldp/system_description_value.rb +2 -8
  58. data/lib/pio/lldp/system_name_value.rb +2 -8
  59. data/lib/pio/lldp/ttl_tlv.rb +5 -11
  60. data/lib/pio/mac.rb +4 -9
  61. data/lib/pio/message_type_selector.rb +22 -0
  62. data/lib/pio/options.rb +65 -0
  63. data/lib/pio/parse_error.rb +6 -0
  64. data/lib/pio/type/ethernet_header.rb +3 -2
  65. data/lib/pio/type/ip_address.rb +4 -9
  66. data/lib/pio/type/ipv4_header.rb +12 -17
  67. data/lib/pio/type/mac_address.rb +5 -10
  68. data/lib/pio/type/udp_header.rb +18 -0
  69. data/lib/pio/version.rb +3 -8
  70. data/pio.gemspec +12 -10
  71. data/spec/pio/arp/reply/options_spec.rb +145 -0
  72. data/spec/pio/arp/reply_spec.rb +77 -113
  73. data/spec/pio/arp/request/options_spec.rb +115 -0
  74. data/spec/pio/arp/request_spec.rb +74 -96
  75. data/spec/pio/arp_spec.rb +71 -105
  76. data/spec/pio/dhcp/ack_spec.rb +189 -0
  77. data/spec/pio/dhcp/discover_spec.rb +165 -0
  78. data/spec/pio/dhcp/offer_spec.rb +189 -0
  79. data/spec/pio/dhcp/request_spec.rb +173 -0
  80. data/spec/pio/dhcp_spec.rb +609 -0
  81. data/spec/pio/icmp/reply_spec.rb +102 -95
  82. data/spec/pio/icmp/request_spec.rb +86 -78
  83. data/spec/pio/icmp_spec.rb +153 -146
  84. data/spec/pio/ipv4_address_spec.rb +2 -7
  85. data/spec/pio/lldp/options_spec.rb +188 -0
  86. data/spec/pio/lldp_spec.rb +181 -208
  87. data/spec/pio/mac_spec.rb +3 -8
  88. data/spec/spec_helper.rb +4 -10
  89. metadata +69 -17
  90. data/.gitignore +0 -20
  91. data/.rspec +0 -3
  92. data/.rubocop.yml +0 -1
  93. data/.travis.yml +0 -13
  94. data/Gemfile +0 -37
  95. data/Guardfile +0 -24
  96. data/lib/pio/message_util.rb +0 -19
  97. data/lib/pio/type/config.reek +0 -4
  98. data/lib/pio/util.rb +0 -21
  99. data/pio.org +0 -668
  100. data/pio.org_archive +0 -943
  101. data/rubocop-todo.yml +0 -9
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -8,12 +8,12 @@ module Pio
8
8
  class ChassisIdTlv < BinData::Primitive
9
9
  endian :big
10
10
 
11
- bit7 :tlv_type, :value => 1
11
+ bit7 :tlv_type, value: 1
12
12
  bit9(:tlv_info_length,
13
- :value => lambda { subtype.num_bytes + chassis_id.length })
14
- uint8 :subtype, :initial_value => 7
13
+ value: -> { subtype.num_bytes + chassis_id.length })
14
+ uint8 :subtype, initial_value: 7
15
15
  string(:chassis_id,
16
- :read_length => lambda { tlv_info_length - subtype.num_bytes })
16
+ read_length: -> { tlv_info_length - subtype.num_bytes })
17
17
 
18
18
  def get
19
19
  tmp_chassis_id = chassis_id
@@ -40,15 +40,9 @@ module Pio
40
40
 
41
41
  def mac_address
42
42
  chassis_id.unpack('C6').map do |each|
43
- sprintf '%02x', each
43
+ format '%02x', each
44
44
  end.join('').hex
45
45
  end
46
46
  end
47
47
  end
48
48
  end
49
-
50
- ### Local variables:
51
- ### mode: Ruby
52
- ### coding: utf-8-unix
53
- ### indent-tabs-mode: nil
54
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -8,13 +8,7 @@ module Pio
8
8
  class EndOfLldpduValue < BinData::Record
9
9
  endian :big
10
10
 
11
- stringz :tlv_info_string, :length => 0, :value => ''
11
+ stringz :tlv_info_string, length: 0, value: ''
12
12
  end
13
13
  end
14
14
  end
15
-
16
- ### Local variables:
17
- ### mode: Ruby
18
- ### coding: utf-8-unix
19
- ### indent-tabs-mode: nil
20
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  require 'pio/lldp/chassis_id_tlv'
@@ -16,13 +16,13 @@ module Pio
16
16
 
17
17
  endian :big
18
18
 
19
- ethernet_header :ether_type => 0x88cc
19
+ ethernet_header ether_type: 0x88cc
20
20
  chassis_id_tlv :chassis_id
21
21
  port_id_tlv :port_id
22
- ttl_tlv :ttl, :initial_value => 120
22
+ ttl_tlv :ttl, initial_value: 120
23
23
  array(:optional_tlv,
24
- :type => :optional_tlv,
25
- :read_until => lambda { element.end_of_lldpdu? })
24
+ type: :optional_tlv,
25
+ read_until: -> { element.end_of_lldpdu? })
26
26
 
27
27
  def dpid
28
28
  chassis_id.to_i
@@ -68,9 +68,3 @@ module Pio
68
68
  end
69
69
  end
70
70
  end
71
-
72
- ### Local variables:
73
- ### mode: Ruby
74
- ### coding: utf-8-unix
75
- ### indent-tabs-mode: nil
76
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -10,17 +10,11 @@ module Pio
10
10
 
11
11
  uint8 :string_length
12
12
  uint8 :subtype
13
- string :management_address, :read_length => lambda { string_length - 1 }
13
+ string :management_address, read_length: -> { string_length - 1 }
14
14
  uint8 :interface_numbering_subtype
15
15
  uint32 :interface_number
16
16
  uint8 :oid_string_length
17
- string :object_identifier, :read_length => lambda { oid_string_length }
17
+ string :object_identifier, read_length: -> { oid_string_length }
18
18
  end
19
19
  end
20
20
  end
21
-
22
- ### Local variables:
23
- ### mode: Ruby
24
- ### coding: utf-8-unix
25
- ### indent-tabs-mode: nil
26
- ### End:
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
+
2
3
  require 'pio/lldp/port_description_value'
3
4
  require 'pio/lldp/system_name_value'
4
5
  require 'pio/lldp/system_description_value'
@@ -16,9 +17,9 @@ module Pio
16
17
  bit7 :tlv_type
17
18
  bit9 :tlv_info_length
18
19
  choice :tlv_value,
19
- :read_length => :tlv_info_length,
20
- :onlyif => lambda { !end_of_lldpdu? },
21
- :selection => :chooser do
20
+ read_length: :tlv_info_length,
21
+ onlyif: -> { !end_of_lldpdu? },
22
+ selection: :chooser do
22
23
  end_of_lldpdu_value 0
23
24
  port_description_value 4
24
25
  system_name_value 5
@@ -58,9 +59,3 @@ module Pio
58
59
  end
59
60
  end
60
61
  end
61
-
62
- ### Local variables:
63
- ### mode: Ruby
64
- ### coding: utf-8-unix
65
- ### indent-tabs-mode: nil
66
- ### End:
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio/options'
4
+
5
+ module Pio
6
+ class Lldp
7
+ # User options for creating an LLDP frame.
8
+ class Options < Pio::Options
9
+ mandatory_option :dpid
10
+ mandatory_option :port_number
11
+ option :destination_mac
12
+ option :source_mac
13
+
14
+ DEFAULT_DESTINATION_MAC = '01:80:c2:00:00:0e'.freeze
15
+ DEFAULT_SOURCE_MAC = '01:02:03:04:05:06'.freeze
16
+
17
+ def initialize(options)
18
+ validate options
19
+ @dpid = options[:dpid].freeze
20
+ @port_id = options[:port_number].freeze
21
+ @destination_mac =
22
+ Mac.new(options[:destination_mac] || DEFAULT_DESTINATION_MAC).freeze
23
+ @source_mac =
24
+ Mac.new(options[:source_mac] || DEFAULT_SOURCE_MAC).freeze
25
+ end
26
+
27
+ def to_hash
28
+ {
29
+ chassis_id: @dpid,
30
+ port_id: @port_id,
31
+ destination_mac: @destination_mac,
32
+ source_mac: @source_mac
33
+ }.freeze
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -14,9 +14,3 @@ module Pio
14
14
  end
15
15
  end
16
16
  end
17
-
18
- ### Local variables:
19
- ### mode: Ruby
20
- ### coding: utf-8-unix
21
- ### indent-tabs-mode: nil
22
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -12,9 +12,3 @@ module Pio
12
12
  end
13
13
  end
14
14
  end
15
-
16
- ### Local variables:
17
- ### mode: Ruby
18
- ### coding: utf-8-unix
19
- ### indent-tabs-mode: nil
20
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -8,10 +8,10 @@ module Pio
8
8
  class PortIdTlv < BinData::Primitive
9
9
  endian :big
10
10
 
11
- bit7 :tlv_type, :value => 2
12
- bit9 :tlv_info_length, :initial_value => lambda { port_id.num_bytes + 1 }
13
- uint8 :subtype, :initial_value => 7
14
- string :port_id, :read_length => lambda { tlv_info_length - 1 }
11
+ bit7 :tlv_type, value: 2
12
+ bit9 :tlv_info_length, initial_value: -> { port_id.num_bytes + 1 }
13
+ uint8 :subtype, initial_value: 7
14
+ string :port_id, read_length: -> { tlv_info_length - 1 }
15
15
 
16
16
  def get
17
17
  tmp_id = port_id
@@ -33,9 +33,3 @@ module Pio
33
33
  end
34
34
  end
35
35
  end
36
-
37
- ### Local variables:
38
- ### mode: Ruby
39
- ### coding: utf-8-unix
40
- ### indent-tabs-mode: nil
41
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -13,9 +13,3 @@ module Pio
13
13
  end
14
14
  end
15
15
  end
16
-
17
- ### Local variables:
18
- ### mode: Ruby
19
- ### coding: utf-8-unix
20
- ### indent-tabs-mode: nil
21
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -12,9 +12,3 @@ module Pio
12
12
  end
13
13
  end
14
14
  end
15
-
16
- ### Local variables:
17
- ### mode: Ruby
18
- ### coding: utf-8-unix
19
- ### indent-tabs-mode: nil
20
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -12,9 +12,3 @@ module Pio
12
12
  end
13
13
  end
14
14
  end
15
-
16
- ### Local variables:
17
- ### mode: Ruby
18
- ### coding: utf-8-unix
19
- ### indent-tabs-mode: nil
20
- ### End:
@@ -1,5 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
- require 'rubygems'
1
+ # encoding: utf-8
2
+
3
3
  require 'bindata'
4
4
 
5
5
  module Pio
@@ -8,9 +8,9 @@ module Pio
8
8
  class TtlTlv < BinData::Primitive
9
9
  endian :big
10
10
 
11
- bit7 :tlv_type, :value => 3
12
- bit9 :tlv_info_length, :value => 2
13
- string :ttl, :read_length => :tlv_info_length
11
+ bit7 :tlv_type, value: 3
12
+ bit9 :tlv_info_length, value: 2
13
+ string :ttl, read_length: :tlv_info_length
14
14
 
15
15
  def get
16
16
  BinData::Int16be.read(ttl)
@@ -22,9 +22,3 @@ module Pio
22
22
  end
23
23
  end
24
24
  end
25
-
26
- ### Local variables:
27
- ### mode: Ruby
28
- ### coding: utf-8-unix
29
- ### indent-tabs-mode: nil
30
- ### End:
data/lib/pio/mac.rb CHANGED
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
+
2
3
  require 'forwardable'
3
4
 
4
5
  module Pio
@@ -60,7 +61,7 @@ module Pio
60
61
  # @return [String]
61
62
  #
62
63
  def to_s
63
- sprintf('%012x', @value).unpack('a2' * 6).join(':')
64
+ format('%012x', @value).unpack('a2' * 6).join(':')
64
65
  end
65
66
 
66
67
  #
@@ -191,7 +192,7 @@ module Pio
191
192
  # @return [String]
192
193
  #
193
194
  def inspect
194
- %{#<#{ self.class }:#{ __id__ } "#{ to_s }">}
195
+ %(#<#{self.class}:#{__id__} "#{self}">)
195
196
  end
196
197
 
197
198
  # @!endgroup
@@ -212,9 +213,3 @@ module Pio
212
213
  end
213
214
  end
214
215
  end
215
-
216
- ### Local variables:
217
- ### mode: Ruby
218
- ### coding: utf-8-unix
219
- ### indent-tabs-mode: nil
220
- ### End:
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'English'
4
+
5
+ module Pio
6
+ # Macros for defining message types.
7
+ module MessageTypeSelector
8
+ def message_type(options)
9
+ const_set(:MESSAGE_TYPE, options)
10
+ end
11
+
12
+ def read(raw_data)
13
+ begin
14
+ frame = const_get(:Frame).read(raw_data)
15
+ rescue
16
+ raise Pio::ParseError, $ERROR_INFO.message
17
+ end
18
+
19
+ const_get(:MESSAGE_TYPE)[frame.message_type].create_from frame
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ module Pio
4
+ # User options utility.
5
+ class Options
6
+ def self.mandatory_option(name)
7
+ unless const_defined?(:MANDATORY_OPTIONS)
8
+ const_set(:MANDATORY_OPTIONS, [])
9
+ end
10
+ const_get(:MANDATORY_OPTIONS) << name
11
+ end
12
+
13
+ def self.option(name)
14
+ const_set(:OPTIONS, []) unless const_defined?(:OPTIONS)
15
+ const_get(:OPTIONS) << name
16
+ end
17
+
18
+ private
19
+
20
+ def validate(user_options)
21
+ check_unknown user_options
22
+ check_mandatory user_options
23
+ end
24
+
25
+ def mandatory_options
26
+ klass = self.class
27
+ if klass.const_defined?(:MANDATORY_OPTIONS)
28
+ klass.const_get(:MANDATORY_OPTIONS)
29
+ else
30
+ []
31
+ end
32
+ end
33
+
34
+ def options
35
+ klass = self.class
36
+ if klass.const_defined?(:OPTIONS)
37
+ klass.const_get(:OPTIONS)
38
+ else
39
+ []
40
+ end
41
+ end
42
+
43
+ def check_unknown(user_options)
44
+ valid_options = mandatory_options + options
45
+ user_options.keys.each do |each|
46
+ fail "Unknown option: #{each}." unless valid_options.include?(each)
47
+ end
48
+ end
49
+
50
+ def check_mandatory(user_options)
51
+ self.class.const_get(:MANDATORY_OPTIONS).each do |each|
52
+ check_existence(user_options, each)
53
+ end
54
+ end
55
+
56
+ def check_existence(user_options, key)
57
+ value = user_options.fetch(key) do |missing_key|
58
+ fail ArgumentError, "The #{missing_key} option should be passed."
59
+ end
60
+ unless value
61
+ fail(ArgumentError, "The #{key} option shouldn't be #{value.inspect}.")
62
+ end
63
+ end
64
+ end
65
+ end