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
@@ -0,0 +1,115 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio'
4
+
5
+ describe Pio::Arp::Request::Options, '.new' do
6
+ Given(:mandatory_options) do
7
+ {
8
+ source_mac: 0x002682ebead1,
9
+ sender_protocol_address: 0xc0a85303,
10
+ target_protocol_address: 0xc0a853fe
11
+ }
12
+ end
13
+
14
+ context 'with all mandatory options' do
15
+ Given(:options) do
16
+ Pio::Arp::Request::Options.new(mandatory_options)
17
+ end
18
+
19
+ describe '#to_hash' do
20
+ When(:result) { options.to_hash }
21
+
22
+ Then { result[:source_mac] == Pio::Mac.new(0x002682ebead1) }
23
+ Then do
24
+ result[:sender_protocol_address] == Pio::IPv4Address.new(0xc0a85303)
25
+ end
26
+ Then do
27
+ result[:target_protocol_address] == Pio::IPv4Address.new(0xc0a853fe)
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'when source_mac is not passed' do
33
+ Given(:user_options) do
34
+ mandatory_options.delete(:source_mac)
35
+ mandatory_options
36
+ end
37
+
38
+ When(:result) { Pio::Arp::Request::Options.new(user_options) }
39
+
40
+ Then do
41
+ result ==
42
+ Failure(ArgumentError, 'The source_mac option should be passed.')
43
+ end
44
+ end
45
+
46
+ context 'with source_mac = nil' do
47
+ Given(:user_options) do
48
+ mandatory_options.update(source_mac: nil)
49
+ mandatory_options
50
+ end
51
+
52
+ When(:result) { Pio::Arp::Request::Options.new(user_options) }
53
+
54
+ Then do
55
+ result ==
56
+ Failure(ArgumentError, "The source_mac option shouldn't be nil.")
57
+ end
58
+ end
59
+
60
+ context 'when sender_protocol_address is not passed' do
61
+ Given(:user_options) do
62
+ mandatory_options.delete(:sender_protocol_address)
63
+ mandatory_options
64
+ end
65
+
66
+ When(:result) { Pio::Arp::Request::Options.new(user_options) }
67
+
68
+ Then do
69
+ result == Failure(ArgumentError,
70
+ 'The sender_protocol_address option should be passed.')
71
+ end
72
+ end
73
+
74
+ context 'with sender_protocol_address = nil' do
75
+ Given(:user_options) do
76
+ mandatory_options.update(sender_protocol_address: nil)
77
+ mandatory_options
78
+ end
79
+
80
+ When(:result) { Pio::Arp::Request::Options.new(user_options) }
81
+
82
+ Then do
83
+ result == Failure(ArgumentError,
84
+ "The sender_protocol_address option shouldn't be nil.")
85
+ end
86
+ end
87
+
88
+ context 'when target_protocol_address is not passed' do
89
+ Given(:user_options) do
90
+ mandatory_options.delete(:target_protocol_address)
91
+ mandatory_options
92
+ end
93
+
94
+ When(:result) { Pio::Arp::Request::Options.new(user_options) }
95
+
96
+ Then do
97
+ result == Failure(ArgumentError,
98
+ 'The target_protocol_address option should be passed.')
99
+ end
100
+ end
101
+
102
+ context 'with target_protocol_address = nil' do
103
+ Given(:user_options) do
104
+ mandatory_options.update(target_protocol_address: nil)
105
+ mandatory_options
106
+ end
107
+
108
+ When(:result) { Pio::Arp::Request::Options.new(user_options) }
109
+
110
+ Then do
111
+ result == Failure(ArgumentError,
112
+ "The target_protocol_address option shouldn't be nil.")
113
+ end
114
+ end
115
+ end
@@ -1,119 +1,97 @@
1
- # -*- coding: utf-8 -*-
2
- require 'pio/arp/request'
1
+ # encoding: utf-8
3
2
 
4
- describe Pio::Arp::Request do
5
- context '.new' do
6
- subject do
3
+ require 'pio'
4
+
5
+ describe Pio::ARP::Request do
6
+ Then { Pio::ARP::Request == Pio::Arp::Request }
7
+ end
8
+
9
+ describe Pio::Arp::Request, '.new' do
10
+ ARP_REQUEST_DUMP =
11
+ [
12
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination mac address
13
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source mac address
14
+ 0x08, 0x06, # ethernet type
15
+ 0x00, 0x01, # arp hardware type
16
+ 0x08, 0x00, # arp protocol type
17
+ 0x06, # hardware address size
18
+ 0x04, # protocol address size
19
+ 0x00, 0x01, # operational code
20
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # sender hardware address
21
+ 0xc0, 0xa8, 0x53, 0x03, # sender protocol address
22
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # target hardware address
23
+ 0xc0, 0xa8, 0x53, 0xfe, # target protocol address
24
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # padding
25
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27
+ 0x00, 0x00, 0x00, 0x00
28
+ ].pack('C*')
29
+
30
+ context 'with String MAC and IP address' do
31
+ Given(:arp_request) do
7
32
  Pio::Arp::Request.new(
8
- :source_mac => source_mac,
9
- :sender_protocol_address => sender_protocol_address,
10
- :target_protocol_address => target_protocol_address
33
+ source_mac: '00:26:82:eb:ea:d1',
34
+ sender_protocol_address: '192.168.83.3',
35
+ target_protocol_address: '192.168.83.254'
11
36
  )
12
37
  end
13
38
 
14
- let(:arp_request_dump) do
15
- [
16
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination mac address
17
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source mac address
18
- 0x08, 0x06, # ethernet type
19
- 0x00, 0x01, # arp hardware type
20
- 0x08, 0x00, # arp protocol type
21
- 0x06, # hardware address size
22
- 0x04, # protocol address size
23
- 0x00, 0x01, # operational code
24
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # sender hardware address
25
- 0xc0, 0xa8, 0x53, 0x03, # sender protocol address
26
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # target hardware address
27
- 0xc0, 0xa8, 0x53, 0xfe, # target protocol address
28
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # padding
29
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31
- 0x00, 0x00, 0x00, 0x00,
32
- ].pack('C*')
33
- end
34
-
35
- context 'with Integer MAC and IP address' do
36
- let(:source_mac) { 0x002682ebead1 }
37
- let(:sender_protocol_address) { 0xc0a85303 }
38
- let(:target_protocol_address) { 0xc0a853fe }
39
+ describe '#to_binary' do
40
+ When(:result) { arp_request.to_binary }
39
41
 
40
- context '#to_binary' do
41
- it 'returns an Arp Request binary String' do
42
- expect(subject.to_binary).to eq arp_request_dump
43
- end
44
-
45
- it 'returns a valid ether frame with size = 64' do
46
- expect(subject.to_binary.size).to eq 64
47
- end
48
- end
42
+ Then { result == ARP_REQUEST_DUMP }
43
+ And { result.size == 64 }
49
44
  end
45
+ end
50
46
 
51
- context 'with String MAC and IP address' do
52
- let(:source_mac) { '00:26:82:eb:ea:d1' }
53
- let(:sender_protocol_address) { 0xc0a85303 }
54
- let(:target_protocol_address) { 0xc0a853fe }
55
-
56
- context '#to_binary' do
57
- it 'returns an Arp Request binary String' do
58
- expect(subject.to_binary).to eq arp_request_dump
59
- end
60
-
61
- it 'returns a valid ether frame with size = 64' do
62
- expect(subject.to_binary.size).to eq 64
63
- end
64
- end
47
+ context 'with Integer MAC address and IP address' do
48
+ Given(:arp_request) do
49
+ Pio::Arp::Request.new(
50
+ source_mac: 0x002682ebead1,
51
+ sender_protocol_address: 0xc0a85303,
52
+ target_protocol_address: 0xc0a853fe
53
+ )
65
54
  end
66
55
 
67
- context 'with Integer MAC and String IP address' do
68
- let(:source_mac) { 0x002682ebead1 }
69
- let(:sender_protocol_address) { '192.168.83.3' }
70
- let(:target_protocol_address) { '192.168.83.254' }
56
+ describe '#to_binary' do
57
+ When(:result) { arp_request.to_binary }
71
58
 
72
- context '#to_binary' do
73
- it 'returns an Arp Request binary String' do
74
- expect(subject.to_binary).to eq arp_request_dump
75
- end
59
+ Then { result == ARP_REQUEST_DUMP }
60
+ And { result.size == 64 }
61
+ end
62
+ end
76
63
 
77
- it 'returns a valid ether frame with size = 64' do
78
- expect(subject.to_binary.size).to eq 64
79
- end
80
- end
64
+ context 'with String MAC and Integer IP address' do
65
+ Given(:arp_request) do
66
+ Pio::Arp::Request.new(
67
+ source_mac: '00:26:82:eb:ea:d1',
68
+ sender_protocol_address: 0xc0a85303,
69
+ target_protocol_address: 0xc0a853fe
70
+ )
81
71
  end
82
72
 
83
- context 'when :source_mac is not set' do
84
- let(:source_mac) { nil }
85
- let(:sender_protocol_address) { '192.168.83.3' }
86
- let(:target_protocol_address) { '192.168.83.254' }
73
+ describe '#to_binary' do
74
+ When(:result) { arp_request.to_binary }
87
75
 
88
- it 'raises an invalid MAC address error' do
89
- expect { subject }.to raise_error('Invalid MAC address: nil')
90
- end
76
+ Then { result == ARP_REQUEST_DUMP }
77
+ And { result.size == 64 }
91
78
  end
79
+ end
92
80
 
93
- context 'when :sender_protocol_address is not set' do
94
- let(:source_mac) { 0x002682ebead1 }
95
- let(:sender_protocol_address) { nil }
96
- let(:target_protocol_address) { '192.168.83.254' }
97
-
98
- it 'raises an invalid IPv4 address error' do
99
- expect { subject }.to raise_error('Invalid IPv4 address: nil')
100
- end
81
+ context 'with Integer MAC and String IP address' do
82
+ Given(:arp_request) do
83
+ Pio::Arp::Request.new(
84
+ source_mac: 0x002682ebead1,
85
+ sender_protocol_address: '192.168.83.3',
86
+ target_protocol_address: '192.168.83.254'
87
+ )
101
88
  end
102
89
 
103
- context 'when :target_protocol_address is not set' do
104
- let(:source_mac) { 0x002682ebead1 }
105
- let(:sender_protocol_address) { '192.168.83.254' }
106
- let(:target_protocol_address) { nil }
90
+ describe '#to_binary' do
91
+ When(:result) { arp_request.to_binary }
107
92
 
108
- it 'raises an invalid IPv4 address error' do
109
- expect { subject }.to raise_error('Invalid IPv4 address: nil')
110
- end
93
+ Then { result == ARP_REQUEST_DUMP }
94
+ And { result.size == 64 }
111
95
  end
112
96
  end
113
97
  end
114
-
115
- ### Local variables:
116
- ### mode: Ruby
117
- ### coding: utf-8-unix
118
- ### indent-tabs-mode: nil
119
- ### End:
data/spec/pio/arp_spec.rb CHANGED
@@ -1,127 +1,93 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
+
2
3
  require 'pio'
3
4
 
4
- describe Pio::Arp do
5
- context '.read' do
6
- subject { Pio::Arp.read(data.pack('C*')) }
5
+ describe Pio::ARP do
6
+ Then { Pio::ARP == Pio::Arp }
7
+ end
7
8
 
8
- context 'with an ARP Request packet' do
9
- let(:data) do
9
+ describe Pio::Arp do
10
+ describe '.read' do
11
+ context 'with an Arp Request packet' do
12
+ Given(:arp_request_dump) do
10
13
  [
11
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination mac address
12
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source mac address
13
- 0x08, 0x06, # ethernet type
14
- 0x00, 0x01, # arp hardware type
15
- 0x08, 0x00, # arp protocol type
16
- 0x06, # hardware address size
17
- 0x04, # protocol address size
18
- 0x00, 0x01, # operational code
19
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # sender hardware address
20
- 0xc0, 0xa8, 0x53, 0x03, # sender protocol address
21
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # target hardware address
22
- 0xc0, 0xa8, 0x53, 0xfe, # target protocol address
23
- ]
14
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # destination mac address
15
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # source mac address
16
+ 0x08, 0x06, # ethernet type
17
+ 0x00, 0x01, # arp hardware type
18
+ 0x08, 0x00, # arp protocol type
19
+ 0x06, # hardware address size
20
+ 0x04, # protocol address size
21
+ 0x00, 0x01, # operational code
22
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # sender hardware address
23
+ 0xc0, 0xa8, 0x53, 0x03, # sender protocol address
24
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # target hardware address
25
+ 0xc0, 0xa8, 0x53, 0xfe, # target protocol address
26
+ ].pack('C*')
24
27
  end
25
28
 
26
- its(:class) { should be Pio::Arp::Request }
27
- its('destination_mac.to_s') { should eq 'ff:ff:ff:ff:ff:ff' }
28
- its('source_mac.to_s') { should eq '00:26:82:eb:ea:d1' }
29
- its(:ether_type) { should eq 0x0806 }
30
- its(:hardware_type) { should eq 1 }
31
- its(:protocol_type) { should eq 0x800 }
32
- its(:hardware_length) { should eq 6 }
33
- its(:protocol_length) { should eq 4 }
34
- its(:operation) { should eq 1 }
35
- its('sender_hardware_address.to_s') { should eq '00:26:82:eb:ea:d1' }
36
- its('sender_protocol_address.to_s') { should eq '192.168.83.3' }
37
- its('target_hardware_address.to_s') { should eq '00:00:00:00:00:00' }
38
- its('target_protocol_address.to_s') { should eq '192.168.83.254' }
39
- end
40
-
41
- context 'with an ARP Reply packet' do
42
- let(:data) do
43
- [
44
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # destination mac address
45
- 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # source mac address
46
- 0x08, 0x06, # ethernet type
47
- 0x00, 0x01, # arp hardware type
48
- 0x08, 0x00, # arp protocol type
49
- 0x06, # hardware address size
50
- 0x04, # protocol address size
51
- 0x00, 0x02, # operational code
52
- 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # sender hardware address
53
- 0xc0, 0xa8, 0x53, 0xfe, # sender protocol address
54
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # target hardware address
55
- 0xc0, 0xa8, 0x53, 0x03, # target protocol address
56
- ]
29
+ When(:arp_request) do
30
+ Pio::Arp.read(arp_request_dump)
57
31
  end
58
32
 
59
- its(:class) { should be Pio::Arp::Reply }
60
- its('destination_mac.to_s') { should eq '00:26:82:eb:ea:d1' }
61
- its('source_mac.to_s') { should eq '00:16:9d:1d:9c:c4' }
62
- its(:ether_type) { should eq 0x0806 }
63
- its(:hardware_type) { should eq 1 }
64
- its(:protocol_type) { should eq 0x800 }
65
- its(:hardware_length) { should eq 6 }
66
- its(:protocol_length) { should eq 4 }
67
- its(:operation) { should eq 2 }
68
- its('sender_hardware_address.to_s') { should eq '00:16:9d:1d:9c:c4' }
69
- its('sender_protocol_address.to_s') { should eq '192.168.83.254' }
70
- its('target_hardware_address.to_s') { should eq '00:26:82:eb:ea:d1' }
71
- its('target_protocol_address.to_s') { should eq '192.168.83.3' }
33
+ Then { arp_request.class == Pio::Arp::Request }
34
+ Then { arp_request.destination_mac.to_s == 'ff:ff:ff:ff:ff:ff' }
35
+ Then { arp_request.source_mac.to_s == '00:26:82:eb:ea:d1' }
36
+ Then { arp_request.ether_type == 0x0806 }
37
+ Then { arp_request.hardware_type == 1 }
38
+ Then { arp_request.protocol_type == 0x800 }
39
+ Then { arp_request.hardware_length == 6 }
40
+ Then { arp_request.protocol_length == 4 }
41
+ Then { arp_request.operation == 1 }
42
+ Then { arp_request.sender_hardware_address.to_s == '00:26:82:eb:ea:d1' }
43
+ Then { arp_request.sender_protocol_address.to_s == '192.168.83.3' }
44
+ Then { arp_request.target_hardware_address.to_s == '00:00:00:00:00:00' }
45
+ Then { arp_request.target_protocol_address.to_s == '192.168.83.254' }
72
46
  end
73
47
 
74
- context 'with an ARP Request captured in real environment' do
75
- let(:data) do
48
+ context 'with an Arp Reply packet' do
49
+ Given(:arp_reply_dump) do
76
50
  [
77
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5c, 0x9a, 0xd8, 0xea,
78
- 0x37, 0x32, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
79
- 0x00, 0x01, 0x5c, 0x9a, 0xd8, 0xea, 0x37, 0x32, 0xc0, 0xa8,
80
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
81
- 0x00, 0xfe
82
- ]
51
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # destination mac address
52
+ 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # source mac address
53
+ 0x08, 0x06, # ethernet type
54
+ 0x00, 0x01, # arp hardware type
55
+ 0x08, 0x00, # arp protocol type
56
+ 0x06, # hardware address size
57
+ 0x04, # protocol address size
58
+ 0x00, 0x02, # operational code
59
+ 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # sender hardware address
60
+ 0xc0, 0xa8, 0x53, 0xfe, # sender protocol address
61
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # target hardware address
62
+ 0xc0, 0xa8, 0x53, 0x03, # target protocol address
63
+ ].pack('C*')
83
64
  end
84
- it { expect { subject }.not_to raise_error }
85
- end
86
65
 
87
- context 'with an ARP Request from a real OpenFlow switch' do
88
- let(:data) do
89
- [
90
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22, 0x33, 0x44,
91
- 0x55, 0x66, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
92
- 0x00, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xc0, 0xa8,
93
- 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
94
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96
- 0x00, 0x00, 0x00, 0x00
97
- ]
66
+ When(:arp_reply) do
67
+ Pio::Arp.read(arp_reply_dump)
98
68
  end
99
- it { expect { subject }.not_to raise_error }
100
- end
101
69
 
102
- context 'with an ARP Reply captured in real environment' do
103
- let(:data) do
104
- [
105
- 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x5c, 0x9a, 0xd8, 0xea,
106
- 0x37, 0x32, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
107
- 0x00, 0x02, 0x5c, 0x9a, 0xd8, 0xea, 0x37, 0x32, 0xc0, 0xa8,
108
- 0x00, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xc0, 0xa8,
109
- 0x00, 0xfe
110
- ]
111
- end
112
- it { expect { subject }.not_to raise_error }
70
+ Then { arp_reply.class == Pio::Arp::Reply }
71
+ Then { arp_reply.destination_mac.to_s == '00:26:82:eb:ea:d1' }
72
+ Then { arp_reply.source_mac.to_s == '00:16:9d:1d:9c:c4' }
73
+ Then { arp_reply.ether_type == 0x0806 }
74
+ Then { arp_reply.hardware_type == 1 }
75
+ Then { arp_reply.protocol_type == 0x800 }
76
+ Then { arp_reply.hardware_length == 6 }
77
+ Then { arp_reply.protocol_length == 4 }
78
+ Then { arp_reply.operation == 2 }
79
+ Then { arp_reply.sender_hardware_address.to_s == '00:16:9d:1d:9c:c4' }
80
+ Then { arp_reply.sender_protocol_address.to_s == '192.168.83.254' }
81
+ Then { arp_reply.target_hardware_address.to_s == '00:26:82:eb:ea:d1' }
82
+ Then { arp_reply.target_protocol_address.to_s == '192.168.83.3' }
113
83
  end
114
84
 
115
85
  context 'with an invalid ARP packet' do
116
- let(:data) { [] }
86
+ When(:result) do
87
+ Pio::Arp.read('')
88
+ end
117
89
 
118
- it { expect { subject }.to raise_error(Pio::ParseError) }
90
+ Then { result == Failure(Pio::ParseError, 'End of file reached') }
119
91
  end
120
92
  end
121
93
  end
122
-
123
- ### Local variables:
124
- ### mode: Ruby
125
- ### coding: utf-8-unix
126
- ### indent-tabs-mode: nil
127
- ### End: