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,6 @@
1
+ # encoding: utf-8
2
+
3
+ module Pio
4
+ # Raised when the packet data is in wrong format.
5
+ class ParseError < StandardError; end
6
+ end
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
+
2
3
  require 'pio/type/mac_address'
3
4
 
4
5
  module Pio
@@ -11,7 +12,7 @@ module Pio
11
12
  class_eval do
12
13
  mac_address :destination_mac
13
14
  mac_address :source_mac
14
- uint16 :ether_type, :value => options[:ether_type]
15
+ uint16 :ether_type, value: options[:ether_type]
15
16
  end
16
17
  end
17
18
  end
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
+
2
3
  require 'bindata'
3
4
  require 'pio/ipv4_address'
4
5
 
@@ -6,21 +7,15 @@ module Pio
6
7
  module Type
7
8
  # IP address
8
9
  class IpAddress < BinData::Primitive
9
- array :octets, :type => :uint8, :initial_length => 4
10
+ array :octets, type: :uint8, initial_length: 4
10
11
 
11
12
  def set(value)
12
13
  self.octets = value
13
14
  end
14
15
 
15
16
  def get
16
- IPv4Address.new octets.map { | each | sprintf('%d', each) }.join('.')
17
+ IPv4Address.new octets.map { | each | format('%d', each) }.join('.')
17
18
  end
18
19
  end
19
20
  end
20
21
  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/type/ip_address'
3
4
 
4
5
  module Pio
@@ -9,18 +10,18 @@ module Pio
9
10
  def ipv4_header(options)
10
11
  endian :big
11
12
  class_eval do
12
- bit4 :ip_version, :initial_value => 0x4
13
- bit4 :ip_header_length, :initial_value => 0x5
14
- uint8 :ip_type_of_service, :initial_value => 0
13
+ bit4 :ip_version, initial_value: 0x4
14
+ bit4 :ip_header_length, initial_value: 0x5
15
+ uint8 :ip_type_of_service, initial_value: 0
15
16
  uint16be :ip_total_length,
16
- :initial_value => options[:ip_total_length]
17
- uint16be :ip_identifier, :initial_value => 0
18
- bit3 :ip_flag, :initial_value => 0
19
- bit13 :ip_fragment, :initial_value => 0
20
- uint8 :ip_ttl, :initial_value => 128
21
- uint8 :ip_protocol, :value => options[:ip_protocol]
17
+ initial_value: options[:ip_total_length]
18
+ uint16be :ip_identifier, initial_value: 0
19
+ bit3 :ip_flag, initial_value: 0
20
+ bit13 :ip_fragment, initial_value: 0
21
+ uint8 :ip_ttl, initial_value: 128
22
+ uint8 :ip_protocol, value: options[:ip_protocol]
22
23
  uint16be :ip_header_checksum,
23
- :initial_value => options[:ip_header_checksum]
24
+ initial_value: options[:ip_header_checksum]
24
25
  ip_address :ip_source_address
25
26
  ip_address :ip_destination_address
26
27
  end
@@ -29,9 +30,3 @@ module Pio
29
30
  end
30
31
  end
31
32
  end
32
-
33
- ### Local variables:
34
- ### mode: Ruby
35
- ### coding: utf-8-unix
36
- ### indent-tabs-mode: nil
37
- ### End:
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
+
2
3
  require 'bindata'
3
4
  require 'pio/mac'
4
5
 
@@ -6,23 +7,17 @@ module Pio
6
7
  module Type
7
8
  # MAC address
8
9
  class MacAddress < BinData::Primitive
9
- array :octets, :type => :uint8, :initial_length => 6
10
+ array :octets, type: :uint8, initial_length: 6
10
11
 
11
12
  def set(value)
12
- self.octets = value
13
+ self.octets = value.to_a
13
14
  end
14
15
 
15
16
  def get
16
17
  Mac.new(octets.reduce('') do |str, each|
17
- str + sprintf('%02x', each)
18
+ str + format('%02x', each)
18
19
  end.hex)
19
20
  end
20
21
  end
21
22
  end
22
23
  end
23
-
24
- ### Local variables:
25
- ### mode: Ruby
26
- ### coding: utf-8-unix
27
- ### indent-tabs-mode: nil
28
- ### End:
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module Pio
4
+ module Type
5
+ # UDP Header Format.
6
+ module UdpHeader
7
+ def udp_header(options)
8
+ endian :big
9
+ class_eval do
10
+ uint16be :udp_src_port
11
+ uint16be :udp_dst_port
12
+ uint16be :udp_length, initial_value: options[:udp_length]
13
+ uint16be :udp_checksum, initial_value: options[:udp_checksum]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/pio/version.rb CHANGED
@@ -1,12 +1,7 @@
1
- # -*- coding: utf-8 -*-
1
+ # encoding: utf-8
2
+
2
3
  # Base module.
3
4
  module Pio
4
5
  # gem version.
5
- VERSION = '0.3.0'
6
+ VERSION = '0.4.0'.freeze
6
7
  end
7
-
8
- ### Local variables:
9
- ### mode: Ruby
10
- ### coding: utf-8
11
- ### indent-tabs-mode: nil
12
- ### End:
data/pio.gemspec CHANGED
@@ -1,8 +1,10 @@
1
+ # encoding: utf-8
2
+
1
3
  lib = File.expand_path('../lib', __FILE__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'pio/version'
4
6
 
5
- Gem::Specification.new do | gem |
7
+ Gem::Specification.new do |gem|
6
8
  gem.name = 'pio'
7
9
  gem.version = Pio::VERSION
8
10
  gem.summary = 'Packet parser and generator.'
@@ -14,18 +16,18 @@ Gem::Specification.new do | gem |
14
16
  gem.email = ['yasuhito@gmail.com']
15
17
  gem.homepage = 'http://github.com/trema/pio'
16
18
 
17
- gem.files = `git ls-files`.split("\n")
19
+ gem.files = %w(CONTRIBUTING.md LICENSE Rakefile pio.gemspec)
20
+ gem.files += Dir.glob('lib/**/*.rb')
21
+ gem.files += Dir.glob('bin/**/*')
22
+ gem.files += Dir.glob('spec/**/*')
23
+ gem.files += Dir.glob('examples/**/*')
18
24
 
19
25
  gem.require_paths = ['lib']
20
26
 
21
27
  gem.extra_rdoc_files = ['README.md']
22
- gem.test_files = `git ls-files -- {spec,features}/*`.split("\n")
28
+ gem.test_files = Dir.glob('spec/**/*')
23
29
 
24
- gem.add_dependency 'bindata', '~> 1.6.0'
30
+ gem.required_ruby_version = '>= 1.9.3'
31
+ gem.add_dependency 'bindata', '~> 2.0.0'
32
+ gem.add_development_dependency 'bundler', '~> 1.6.0'
25
33
  end
26
-
27
- ### Local variables:
28
- ### mode: Ruby
29
- ### coding: utf-8-unix
30
- ### indent-tabs-mode: nil
31
- ### End:
@@ -0,0 +1,145 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pio'
4
+
5
+ describe Pio::Arp::Reply::Options, '.new' do
6
+ Given(:mandatory_options) do
7
+ {
8
+ source_mac: 0x00169d1d9cc4,
9
+ destination_mac: 0x002682ebead1,
10
+ sender_protocol_address: 0xc0a85303,
11
+ target_protocol_address: 0xc0a853fe
12
+ }
13
+ end
14
+
15
+ context 'with all mandatory options' do
16
+ Given(:options) do
17
+ Pio::Arp::Reply::Options.new(mandatory_options)
18
+ end
19
+
20
+ describe '#to_hash' do
21
+ When(:result) { options.to_hash }
22
+
23
+ Then { result[:source_mac] == Pio::Mac.new(0x00169d1d9cc4) }
24
+ Then { result[:destination_mac] == Pio::Mac.new(0x002682ebead1) }
25
+ Then do
26
+ result[:sender_protocol_address] == Pio::IPv4Address.new(0xc0a85303)
27
+ end
28
+ Then do
29
+ result[:target_protocol_address] == Pio::IPv4Address.new(0xc0a853fe)
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'when source_mac is not passed' do
35
+ Given(:user_options) do
36
+ mandatory_options.delete(:source_mac)
37
+ mandatory_options
38
+ end
39
+
40
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
41
+
42
+ Then do
43
+ result ==
44
+ Failure(ArgumentError, 'The source_mac option should be passed.')
45
+ end
46
+ end
47
+
48
+ context 'with source_mac = nil' do
49
+ Given(:user_options) do
50
+ mandatory_options.update(source_mac: nil)
51
+ mandatory_options
52
+ end
53
+
54
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
55
+
56
+ Then do
57
+ result ==
58
+ Failure(ArgumentError, "The source_mac option shouldn't be nil.")
59
+ end
60
+ end
61
+
62
+ context 'when destination_mac is not passed' do
63
+ Given(:user_options) do
64
+ mandatory_options.delete(:destination_mac)
65
+ mandatory_options
66
+ end
67
+
68
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
69
+
70
+ Then do
71
+ result ==
72
+ Failure(ArgumentError, 'The destination_mac option should be passed.')
73
+ end
74
+ end
75
+
76
+ context 'with destination_mac = nil' do
77
+ Given(:user_options) do
78
+ mandatory_options.update(destination_mac: nil)
79
+ mandatory_options
80
+ end
81
+
82
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
83
+
84
+ Then do
85
+ result ==
86
+ Failure(ArgumentError, "The destination_mac option shouldn't be nil.")
87
+ end
88
+ end
89
+
90
+ context 'when sender_protocol_address is not passed' do
91
+ Given(:user_options) do
92
+ mandatory_options.delete(:sender_protocol_address)
93
+ mandatory_options
94
+ end
95
+
96
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
97
+
98
+ Then do
99
+ result == Failure(ArgumentError,
100
+ 'The sender_protocol_address option should be passed.')
101
+ end
102
+ end
103
+
104
+ context 'with sender_protocol_address = nil' do
105
+ Given(:user_options) do
106
+ mandatory_options.update(sender_protocol_address: nil)
107
+ mandatory_options
108
+ end
109
+
110
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
111
+
112
+ Then do
113
+ result == Failure(ArgumentError,
114
+ "The sender_protocol_address option shouldn't be nil.")
115
+ end
116
+ end
117
+
118
+ context 'when target_protocol_address is not passed' do
119
+ Given(:user_options) do
120
+ mandatory_options.delete(:target_protocol_address)
121
+ mandatory_options
122
+ end
123
+
124
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
125
+
126
+ Then do
127
+ result == Failure(ArgumentError,
128
+ 'The target_protocol_address option should be passed.')
129
+ end
130
+ end
131
+
132
+ context 'with target_protocol_address = nil' do
133
+ Given(:user_options) do
134
+ mandatory_options.update(target_protocol_address: nil)
135
+ mandatory_options
136
+ end
137
+
138
+ When(:result) { Pio::Arp::Reply::Options.new(user_options) }
139
+
140
+ Then do
141
+ result == Failure(ArgumentError,
142
+ "The target_protocol_address option shouldn't be nil.")
143
+ end
144
+ end
145
+ end
@@ -1,137 +1,101 @@
1
- # -*- coding: utf-8 -*-
2
- require 'pio/arp/reply'
1
+ # encoding: utf-8
3
2
 
4
- describe Pio::Arp::Reply do
5
- context '.new' do
6
- subject do
3
+ require 'pio'
4
+
5
+ describe Pio::ARP::Reply do
6
+ Then { Pio::ARP::Reply == Pio::Arp::Reply }
7
+ end
8
+
9
+ describe Pio::Arp::Reply, '.new' do
10
+ ARP_REPLY_DUMP =
11
+ [
12
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # destination mac address
13
+ 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # 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, 0x02, # operational code
20
+ 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # sender hardware address
21
+ 0xc0, 0xa8, 0x53, 0xfe, # sender protocol address
22
+ 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # target hardware address
23
+ 0xc0, 0xa8, 0x53, 0x03, # 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_reply) do
7
32
  Pio::Arp::Reply.new(
8
- :source_mac => source_mac,
9
- :destination_mac => destination_mac,
10
- :sender_protocol_address => sender_protocol_address,
11
- :target_protocol_address => target_protocol_address
33
+ source_mac: '00:16:9d:1d:9c:c4',
34
+ destination_mac: '00:26:82:eb:ea:d1',
35
+ sender_protocol_address: '192.168.83.254',
36
+ target_protocol_address: '192.168.83.3'
12
37
  )
13
38
  end
14
39
 
15
- let(:arp_reply_dump) do
16
- [
17
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # destination mac address
18
- 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # source mac address
19
- 0x08, 0x06, # ethernet type
20
- 0x00, 0x01, # arp hardware type
21
- 0x08, 0x00, # arp protocol type
22
- 0x06, # hardware address size
23
- 0x04, # protocol address size
24
- 0x00, 0x02, # operational code
25
- 0x00, 0x16, 0x9d, 0x1d, 0x9c, 0xc4, # sender hardware address
26
- 0xc0, 0xa8, 0x53, 0xfe, # sender protocol address
27
- 0x00, 0x26, 0x82, 0xeb, 0xea, 0xd1, # target hardware address
28
- 0xc0, 0xa8, 0x53, 0x03, # target protocol address
29
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # padding
30
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32
- 0x00, 0x00, 0x00, 0x00,
33
- ].pack('C*')
34
- end
35
-
36
- context 'with Integer MAC and IP address' do
37
- let(:source_mac) { 0x00169d1d9cc4 }
38
- let(:destination_mac) { 0x002682ebead1 }
39
- let(:sender_protocol_address) { 0xc0a853fe }
40
- let(:target_protocol_address) { 0xc0a85303 }
41
-
42
- context '#to_binary' do
43
- it 'returns an Arp Reply binary String' do
44
- expect(subject.to_binary).to eq arp_reply_dump
45
- end
40
+ describe '#to_binary' do
41
+ When(:result) { arp_reply.to_binary }
46
42
 
47
- it 'returns a valid ether frame with size = 64' do
48
- expect(subject.to_binary.size).to eq 64
49
- end
50
- end
43
+ Then { result == ARP_REPLY_DUMP }
44
+ And { result.size == 64 }
51
45
  end
46
+ end
52
47
 
53
- context 'with String MAC and Integer IP address' do
54
- let(:source_mac) { '00:16:9d:1d:9c:c4' }
55
- let(:destination_mac) { '00:26:82:eb:ea:d1' }
56
- let(:sender_protocol_address) { 0xc0a853fe }
57
- let(:target_protocol_address) { 0xc0a85303 }
58
-
59
- context '#to_binary' do
60
- it 'returns an Arp Reply binary String' do
61
- expect(subject.to_binary).to eq arp_reply_dump
62
- end
63
-
64
- it 'returns a valid ether frame with size = 64' do
65
- expect(subject.to_binary.size).to eq 64
66
- end
67
- end
48
+ context 'with Integer MAC address and IP address' do
49
+ Given(:arp_reply) do
50
+ Pio::Arp::Reply.new(
51
+ source_mac: 0x00169d1d9cc4,
52
+ destination_mac: 0x002682ebead1,
53
+ sender_protocol_address: 0xc0a853fe,
54
+ target_protocol_address: 0xc0a85303
55
+ )
68
56
  end
69
57
 
70
- context 'when Integer MAC and String IP address' do
71
- let(:source_mac) { 0x00169d1d9cc4 }
72
- let(:destination_mac) { 0x002682ebead1 }
73
- let(:sender_protocol_address) { '192.168.83.254' }
74
- let(:target_protocol_address) { '192.168.83.3' }
58
+ describe '#to_binary' do
59
+ When(:result) { arp_reply.to_binary }
75
60
 
76
- context '#to_binary' do
77
- it 'returns an Arp Reply binary String' do
78
- expect(subject.to_binary).to eq arp_reply_dump
79
- end
80
-
81
- it 'returns a valid ether frame with size = 64' do
82
- expect(subject.to_binary.size).to eq 64
83
- end
84
- end
61
+ Then { result == ARP_REPLY_DUMP }
62
+ And { result.size == 64 }
85
63
  end
64
+ end
86
65
 
87
- context 'when :source_mac is not set' do
88
- let(:source_mac) { nil }
89
- let(:destination_mac) { 0x002682ebead1 }
90
- let(:sender_protocol_address) { '192.168.83.3' }
91
- let(:target_protocol_address) { '192.168.83.254' }
92
-
93
- it 'raises an invalid MAC address error' do
94
- expect { subject }.to raise_error('Invalid MAC address: nil')
95
- end
66
+ context 'with String MAC and Integer IP address' do
67
+ Given(:arp_reply) do
68
+ Pio::Arp::Reply.new(
69
+ source_mac: '00:16:9d:1d:9c:c4',
70
+ destination_mac: '00:26:82:eb:ea:d1',
71
+ sender_protocol_address: 0xc0a853fe,
72
+ target_protocol_address: 0xc0a85303
73
+ )
96
74
  end
97
75
 
98
- context 'when :destination_mac is not set' do
99
- let(:source_mac) { 0x00169d1d9cc4 }
100
- let(:destination_mac) { nil }
101
- let(:sender_protocol_address) { '192.168.83.3' }
102
- let(:target_protocol_address) { '192.168.83.254' }
76
+ describe '#to_binary' do
77
+ When(:result) { arp_reply.to_binary }
103
78
 
104
- it 'raises an invalid MAC address error' do
105
- expect { subject }.to raise_error('Invalid MAC address: nil')
106
- end
79
+ Then { result == ARP_REPLY_DUMP }
80
+ And { result.size == 64 }
107
81
  end
82
+ end
108
83
 
109
- context 'when :sender_protocol_address is not set' do
110
- let(:source_mac) { 0x00169d1d9cc4 }
111
- let(:destination_mac) { 0x002682ebead1 }
112
- let(:sender_protocol_address) { nil }
113
- let(:target_protocol_address) { '192.168.83.254' }
114
-
115
- it 'raises an invalid IPv4 address error' do
116
- expect { subject }.to raise_error('Invalid IPv4 address: nil')
117
- end
84
+ context 'with Integer MAC and String IP address' do
85
+ Given(:arp_reply) do
86
+ Pio::Arp::Reply.new(
87
+ source_mac: 0x00169d1d9cc4,
88
+ destination_mac: 0x002682ebead1,
89
+ sender_protocol_address: '192.168.83.254',
90
+ target_protocol_address: '192.168.83.3'
91
+ )
118
92
  end
119
93
 
120
- context 'when :target_protocol_address is not set' do
121
- let(:source_mac) { 0x00169d1d9cc4 }
122
- let(:destination_mac) { 0x002682ebead1 }
123
- let(:sender_protocol_address) { '192.168.83.3' }
124
- let(:target_protocol_address) { nil }
94
+ describe '#to_binary' do
95
+ When(:result) { arp_reply.to_binary }
125
96
 
126
- it 'raises an invalid IPv4 address error' do
127
- expect { subject }.to raise_error('Invalid IPv4 address: nil')
128
- end
97
+ Then { result == ARP_REPLY_DUMP }
98
+ And { result.size == 64 }
129
99
  end
130
100
  end
131
101
  end
132
-
133
- ### Local variables:
134
- ### mode: Ruby
135
- ### coding: utf-8-unix
136
- ### indent-tabs-mode: nil
137
- ### End: