pio 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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