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
@@ -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: