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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +46 -12
- data/README.md +131 -116
- data/Rakefile +7 -92
- data/examples/arp_new.rb +16 -0
- data/examples/arp_read.rb +4 -0
- data/examples/dhcp_new.rb +30 -0
- data/examples/dhcp_read.rb +4 -0
- data/examples/icmp_new.rb +21 -0
- data/examples/icmp_read.rb +4 -0
- data/examples/lldp_new.rb +4 -0
- data/examples/lldp_read.rb +4 -0
- data/lib/pio.rb +6 -12
- data/lib/pio/arp.rb +7 -19
- data/lib/pio/arp/frame.rb +8 -12
- data/lib/pio/arp/message.rb +12 -25
- data/lib/pio/arp/reply.rb +30 -30
- data/lib/pio/arp/request.rb +30 -29
- data/lib/pio/dhcp.rb +58 -0
- data/lib/pio/dhcp/ack.rb +12 -0
- data/lib/pio/dhcp/boot_reply.rb +16 -0
- data/lib/pio/dhcp/boot_reply_options.rb +75 -0
- data/lib/pio/dhcp/boot_request.rb +16 -0
- data/lib/pio/dhcp/boot_request_options.rb +69 -0
- data/lib/pio/dhcp/common_options.rb +71 -0
- data/lib/pio/dhcp/csum_util.rb +83 -0
- data/lib/pio/dhcp/dhcp_field.rb +48 -0
- data/lib/pio/dhcp/dhcp_tlv_options.rb +84 -0
- data/lib/pio/dhcp/discover.rb +12 -0
- data/lib/pio/dhcp/field_util.rb +102 -0
- data/lib/pio/dhcp/frame.rb +95 -0
- data/lib/pio/dhcp/message.rb +79 -0
- data/lib/pio/dhcp/offer.rb +12 -0
- data/lib/pio/dhcp/optional_tlv.rb +74 -0
- data/lib/pio/dhcp/request.rb +12 -0
- data/lib/pio/dhcp/type/dhcp_client_id.rb +21 -0
- data/lib/pio/dhcp/type/dhcp_param_list.rb +22 -0
- data/lib/pio/dhcp/type/dhcp_string.rb +21 -0
- data/lib/pio/icmp.rb +7 -18
- data/lib/pio/icmp/frame.rb +38 -40
- data/lib/pio/icmp/message.rb +10 -61
- data/lib/pio/icmp/options.rb +25 -0
- data/lib/pio/icmp/reply.rb +34 -7
- data/lib/pio/icmp/request.rb +43 -7
- data/lib/pio/ipv4_address.rb +5 -8
- data/lib/pio/lldp.rb +22 -62
- data/lib/pio/lldp/chassis_id_tlv.rb +7 -13
- data/lib/pio/lldp/end_of_lldpdu_value.rb +3 -9
- data/lib/pio/lldp/frame.rb +6 -12
- data/lib/pio/lldp/management_address_value.rb +4 -10
- data/lib/pio/lldp/optional_tlv.rb +5 -10
- data/lib/pio/lldp/options.rb +37 -0
- data/lib/pio/lldp/organizationally_specific_value.rb +2 -8
- data/lib/pio/lldp/port_description_value.rb +2 -8
- data/lib/pio/lldp/port_id_tlv.rb +6 -12
- data/lib/pio/lldp/system_capabilities_value.rb +2 -8
- data/lib/pio/lldp/system_description_value.rb +2 -8
- data/lib/pio/lldp/system_name_value.rb +2 -8
- data/lib/pio/lldp/ttl_tlv.rb +5 -11
- data/lib/pio/mac.rb +4 -9
- data/lib/pio/message_type_selector.rb +22 -0
- data/lib/pio/options.rb +65 -0
- data/lib/pio/parse_error.rb +6 -0
- data/lib/pio/type/ethernet_header.rb +3 -2
- data/lib/pio/type/ip_address.rb +4 -9
- data/lib/pio/type/ipv4_header.rb +12 -17
- data/lib/pio/type/mac_address.rb +5 -10
- data/lib/pio/type/udp_header.rb +18 -0
- data/lib/pio/version.rb +3 -8
- data/pio.gemspec +12 -10
- data/spec/pio/arp/reply/options_spec.rb +145 -0
- data/spec/pio/arp/reply_spec.rb +77 -113
- data/spec/pio/arp/request/options_spec.rb +115 -0
- data/spec/pio/arp/request_spec.rb +74 -96
- data/spec/pio/arp_spec.rb +71 -105
- data/spec/pio/dhcp/ack_spec.rb +189 -0
- data/spec/pio/dhcp/discover_spec.rb +165 -0
- data/spec/pio/dhcp/offer_spec.rb +189 -0
- data/spec/pio/dhcp/request_spec.rb +173 -0
- data/spec/pio/dhcp_spec.rb +609 -0
- data/spec/pio/icmp/reply_spec.rb +102 -95
- data/spec/pio/icmp/request_spec.rb +86 -78
- data/spec/pio/icmp_spec.rb +153 -146
- data/spec/pio/ipv4_address_spec.rb +2 -7
- data/spec/pio/lldp/options_spec.rb +188 -0
- data/spec/pio/lldp_spec.rb +181 -208
- data/spec/pio/mac_spec.rb +3 -8
- data/spec/spec_helper.rb +4 -10
- metadata +69 -17
- data/.gitignore +0 -20
- data/.rspec +0 -3
- data/.rubocop.yml +0 -1
- data/.travis.yml +0 -13
- data/Gemfile +0 -37
- data/Guardfile +0 -24
- data/lib/pio/message_util.rb +0 -19
- data/lib/pio/type/config.reek +0 -4
- data/lib/pio/util.rb +0 -21
- data/pio.org +0 -668
- data/pio.org_archive +0 -943
- data/rubocop-todo.yml +0 -9
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
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, :
|
11
|
+
bit7 :tlv_type, value: 1
|
12
12
|
bit9(:tlv_info_length,
|
13
|
-
:
|
14
|
-
uint8 :subtype, :
|
13
|
+
value: -> { subtype.num_bytes + chassis_id.length })
|
14
|
+
uint8 :subtype, initial_value: 7
|
15
15
|
string(:chassis_id,
|
16
|
-
:
|
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
|
-
|
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
|
-
#
|
2
|
-
|
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, :
|
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:
|
data/lib/pio/lldp/frame.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
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 :
|
19
|
+
ethernet_header ether_type: 0x88cc
|
20
20
|
chassis_id_tlv :chassis_id
|
21
21
|
port_id_tlv :port_id
|
22
|
-
ttl_tlv :ttl, :
|
22
|
+
ttl_tlv :ttl, initial_value: 120
|
23
23
|
array(:optional_tlv,
|
24
|
-
:
|
25
|
-
:
|
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
|
-
#
|
2
|
-
|
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, :
|
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, :
|
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
|
-
#
|
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
|
-
:
|
20
|
-
:
|
21
|
-
:
|
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
|
-
#
|
2
|
-
|
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
|
-
#
|
2
|
-
|
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:
|
data/lib/pio/lldp/port_id_tlv.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
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, :
|
12
|
-
bit9 :tlv_info_length, :
|
13
|
-
uint8 :subtype, :
|
14
|
-
string :port_id, :
|
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
|
-
#
|
2
|
-
|
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
|
-
#
|
2
|
-
|
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
|
-
#
|
2
|
-
|
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:
|
data/lib/pio/lldp/ttl_tlv.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
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, :
|
12
|
-
bit9 :tlv_info_length, :
|
13
|
-
string :ttl, :
|
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
|
-
#
|
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
|
-
|
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
|
-
%
|
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
|
data/lib/pio/options.rb
ADDED
@@ -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
|