pio 0.20.0 → 0.20.1
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/CHANGELOG.md +5 -0
- data/Rakefile +2 -2
- data/features/open_flow13/match.feature +370 -0
- data/features/open_flow13/oxm_ether_destination_field.raw +0 -0
- data/features/open_flow13/oxm_ether_source_field.raw +0 -0
- data/features/open_flow13/oxm_ether_type_field.raw +0 -0
- data/features/open_flow13/oxm_in_phy_port_field.raw +0 -0
- data/features/open_flow13/oxm_in_port_field.raw +0 -0
- data/features/open_flow13/oxm_ipv4_destination_field.raw +0 -0
- data/features/open_flow13/oxm_ipv4_source_field.raw +0 -0
- data/features/open_flow13/oxm_ipv6_destination_field.raw +0 -0
- data/features/open_flow13/oxm_ipv6_source_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ether_destination_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ether_source_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv4_destination_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv4_source_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv6_destination_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv6_source_field.raw +0 -0
- data/features/open_flow13/oxm_metadata_field.raw +0 -0
- data/features/open_flow13/oxm_metadata_masked_field.raw +0 -0
- data/features/open_flow13/oxm_no_fields.raw +0 -0
- data/features/open_flow13/oxm_tcp_destination_field.raw +0 -0
- data/features/open_flow13/oxm_tcp_field.raw +0 -0
- data/features/open_flow13/oxm_tcp_source_field.raw +0 -0
- data/features/open_flow13/oxm_udp_destination_field.raw +0 -0
- data/features/open_flow13/oxm_udp_field.raw +0 -0
- data/features/open_flow13/oxm_udp_source_field.raw +0 -0
- data/lib/pio/ipv4_header.rb +0 -2
- data/lib/pio/open_flow/message.rb +18 -54
- data/lib/pio/open_flow10/packet_in.rb +1 -1
- data/lib/pio/open_flow13/match.rb +452 -0
- data/lib/pio/open_flow13.rb +7 -0
- data/lib/pio/type/ipv6_address.rb +21 -0
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +8 -8
- data/spec/pio/mac_spec.rb +2 -2
- data/spec/pio/open_flow13/match_spec.rb +387 -0
- data/spec/pio/packet_out_spec.rb +1 -2
- metadata +73 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 551bcb08d55075cf2011017a19170798d5167746
|
4
|
+
data.tar.gz: 9e942d01521924f91651b676a907c13fa27def1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d2883d13e351d0ab48bad139e84207c22b53ad95a91699dd4dc2e8e43ac7b0546629eed23619156e3ec58b25515987599e88242e6a4ef1a25bbc2c4cccaebe8
|
7
|
+
data.tar.gz: a1b385371ab740497deb3780db2954df7061ef6a6e9b9116df46ed0e40f970121638d3c6ec4862801b6d38de40814ce0e1a19ad9c866499ca3d2b51a1052126f
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,11 @@
|
|
3
3
|
## develop (unreleased)
|
4
4
|
|
5
5
|
|
6
|
+
## 0.20.1 (6/10/2015)
|
7
|
+
### Bugs fixed
|
8
|
+
* [#167](https://github.com/trema/pio/pull/167): Fix PacketIn accessor methods (raw_data = VLAN tagged UDP).
|
9
|
+
|
10
|
+
|
6
11
|
## 0.20.0 (4/22/2015)
|
7
12
|
### New features
|
8
13
|
* [#138](https://github.com/trema/pio/pull/138): Add new class `Pio::Features::Request`.
|
data/Rakefile
CHANGED
@@ -29,8 +29,8 @@ task :dump do
|
|
29
29
|
unless ENV['PACKET_FILE']
|
30
30
|
fail 'Usage: rake PACKET_FILE="foobar.{pcap,raw}" dump'
|
31
31
|
end
|
32
|
-
packet_file =
|
33
|
-
|
32
|
+
packet_file =
|
33
|
+
File.join(File.dirname(__FILE__), 'features/', ENV['PACKET_FILE'])
|
34
34
|
case File.extname(packet_file)
|
35
35
|
when '.raw'
|
36
36
|
dump_in_hex(IO.read(packet_file))
|
@@ -0,0 +1,370 @@
|
|
1
|
+
Feature: Pio::Match
|
2
|
+
Background:
|
3
|
+
Given I use OpenFlow 1.3
|
4
|
+
|
5
|
+
Scenario: new
|
6
|
+
When I try to create an OpenFlow message with:
|
7
|
+
"""
|
8
|
+
Pio::Match.new
|
9
|
+
"""
|
10
|
+
Then it should finish successfully
|
11
|
+
And the message have the following fields and values:
|
12
|
+
| field | value |
|
13
|
+
| match_fields | [] |
|
14
|
+
|
15
|
+
Scenario: new(in_port: 1)
|
16
|
+
When I try to create an OpenFlow message with:
|
17
|
+
"""
|
18
|
+
Pio::Match.new(in_port: 1)
|
19
|
+
"""
|
20
|
+
Then it should finish successfully
|
21
|
+
And the message have the following fields and values:
|
22
|
+
| field | value |
|
23
|
+
| in_port | 1 |
|
24
|
+
|
25
|
+
Scenario: new(ether_source_address: '01:02:03:04:05:06')
|
26
|
+
When I try to create an OpenFlow message with:
|
27
|
+
"""
|
28
|
+
Pio::Match.new(ether_source_address: '01:02:03:04:05:06')
|
29
|
+
"""
|
30
|
+
Then it should finish successfully
|
31
|
+
And the message have the following fields and values:
|
32
|
+
| field | value |
|
33
|
+
| ether_source_address | 01:02:03:04:05:06 |
|
34
|
+
|
35
|
+
Scenario: new(ether_destination_address: '01:02:03:04:05:06')
|
36
|
+
When I try to create an OpenFlow message with:
|
37
|
+
"""
|
38
|
+
Pio::Match.new(ether_destination_address: '01:02:03:04:05:06')
|
39
|
+
"""
|
40
|
+
Then it should finish successfully
|
41
|
+
And the message have the following fields and values:
|
42
|
+
| field | value |
|
43
|
+
| ether_destination_address | 01:02:03:04:05:06 |
|
44
|
+
|
45
|
+
Scenario: new(ether_source_address: '01:02:03:04:05:06', ether_source_address_mask: 'ff:ff:ff:00:00:00')
|
46
|
+
When I try to create an OpenFlow message with:
|
47
|
+
"""
|
48
|
+
Pio::Match.new(ether_source_address: '01:02:03:04:05:06', ether_source_address_mask: 'ff:ff:ff:00:00:00')
|
49
|
+
"""
|
50
|
+
Then it should finish successfully
|
51
|
+
And the message have the following fields and values:
|
52
|
+
| field | value |
|
53
|
+
| ether_source_address | 01:02:03:04:05:06 |
|
54
|
+
| ether_source_address_mask | ff:ff:ff:00:00:00 |
|
55
|
+
|
56
|
+
Scenario: new(ether_destination_address: '01:02:03:04:05:06', ether_destination_address_mask: 'ff:ff:ff:00:00:00')
|
57
|
+
When I try to create an OpenFlow message with:
|
58
|
+
"""
|
59
|
+
Pio::Match.new(ether_destination_address: '01:02:03:04:05:06', ether_destination_address_mask: 'ff:ff:ff:00:00:00')
|
60
|
+
"""
|
61
|
+
Then it should finish successfully
|
62
|
+
And the message have the following fields and values:
|
63
|
+
| field | value |
|
64
|
+
| ether_destination_address | 01:02:03:04:05:06 |
|
65
|
+
| ether_destination_address_mask | ff:ff:ff:00:00:00 |
|
66
|
+
|
67
|
+
Scenario: new(ether_type: 0x0800)
|
68
|
+
When I try to create an OpenFlow message with:
|
69
|
+
"""
|
70
|
+
Pio::Match.new(ether_type: 0x0800)
|
71
|
+
"""
|
72
|
+
Then it should finish successfully
|
73
|
+
And the message have the following fields and values:
|
74
|
+
| field | value |
|
75
|
+
| ether_type | 2048 |
|
76
|
+
|
77
|
+
Scenario: new(ether_type: 0x0800, ipv4_source_address: '192.168.0.1')
|
78
|
+
When I try to create an OpenFlow message with:
|
79
|
+
"""
|
80
|
+
Pio::Match.new(ether_type: 0x0800, ipv4_source_address: '192.168.0.1')
|
81
|
+
"""
|
82
|
+
Then it should finish successfully
|
83
|
+
And the message have the following fields and values:
|
84
|
+
| field | value |
|
85
|
+
| ether_type | 2048 |
|
86
|
+
| ipv4_source_address | 192.168.0.1 |
|
87
|
+
|
88
|
+
Scenario: new(ether_type: 0x0800, ipv4_destination_address: '192.168.0.1')
|
89
|
+
When I try to create an OpenFlow message with:
|
90
|
+
"""
|
91
|
+
Pio::Match.new(ether_type: 0x0800, ipv4_destination_address: '192.168.0.1')
|
92
|
+
"""
|
93
|
+
Then it should finish successfully
|
94
|
+
And the message have the following fields and values:
|
95
|
+
| field | value |
|
96
|
+
| ether_type | 2048 |
|
97
|
+
| ipv4_destination_address | 192.168.0.1 |
|
98
|
+
|
99
|
+
Scenario: new(ether_type: 0x0800, ipv4_source_address: '192.168.0.1', ivp4_source_address_mask: '255.255.0.0')
|
100
|
+
When I try to create an OpenFlow message with:
|
101
|
+
"""
|
102
|
+
Pio::Match.new(ether_type: 0x0800, ipv4_source_address: '192.168.0.1', ipv4_source_address_mask: '255.255.0.0')
|
103
|
+
"""
|
104
|
+
Then it should finish successfully
|
105
|
+
And the message have the following fields and values:
|
106
|
+
| field | value |
|
107
|
+
| ether_type | 2048 |
|
108
|
+
| ipv4_source_address | 192.168.0.1 |
|
109
|
+
| ipv4_source_address_mask | 255.255.0.0 |
|
110
|
+
|
111
|
+
Scenario: new(ether_type: 0x0800, ipv4_destination_address: '192.168.0.1', ivp4_destination_address_mask: '255.255.0.0')
|
112
|
+
When I try to create an OpenFlow message with:
|
113
|
+
"""
|
114
|
+
Pio::Match.new(ether_type: 0x0800, ipv4_destination_address: '192.168.0.1', ipv4_destination_address_mask: '255.255.0.0')
|
115
|
+
"""
|
116
|
+
Then it should finish successfully
|
117
|
+
And the message have the following fields and values:
|
118
|
+
| field | value |
|
119
|
+
| ether_type | 2048 |
|
120
|
+
| ipv4_destination_address | 192.168.0.1 |
|
121
|
+
| ipv4_destination_address_mask | 255.255.0.0 |
|
122
|
+
|
123
|
+
Scenario: new(ether_type: 0x0800, ip_protocol: 6, tcp_source_port: 1111)
|
124
|
+
When I try to create an OpenFlow message with:
|
125
|
+
"""
|
126
|
+
Pio::Match.new(ether_type: 0x0800, ip_protocol: 6, tcp_source_port: 1111)
|
127
|
+
"""
|
128
|
+
Then it should finish successfully
|
129
|
+
And the message have the following fields and values:
|
130
|
+
| field | value |
|
131
|
+
| ether_type | 2048 |
|
132
|
+
| ip_protocol | 6 |
|
133
|
+
| tcp_source_port | 1111 |
|
134
|
+
|
135
|
+
Scenario: new(ether_type: 0x0800, ip_protocol: 6, tcp_destination_port: 80)
|
136
|
+
When I try to create an OpenFlow message with:
|
137
|
+
"""
|
138
|
+
Pio::Match.new(ether_type: 0x0800, ip_protocol: 6, tcp_destination_port: 80)
|
139
|
+
"""
|
140
|
+
Then it should finish successfully
|
141
|
+
And the message have the following fields and values:
|
142
|
+
| field | value |
|
143
|
+
| ether_type | 2048 |
|
144
|
+
| ip_protocol | 6 |
|
145
|
+
| tcp_destination_port | 80 |
|
146
|
+
|
147
|
+
Scenario: new(ether_type: 0x0800, ip_protocol: 17, udp_source_port: 2222)
|
148
|
+
When I try to create an OpenFlow message with:
|
149
|
+
"""
|
150
|
+
Pio::Match.new(ether_type: 0x0800, ip_protocol: 17, udp_source_port: 2222)
|
151
|
+
"""
|
152
|
+
Then it should finish successfully
|
153
|
+
And the message have the following fields and values:
|
154
|
+
| field | value |
|
155
|
+
| ether_type | 2048 |
|
156
|
+
| ip_protocol | 17 |
|
157
|
+
| udp_source_port | 2222 |
|
158
|
+
|
159
|
+
Scenario: new(ether_type: 0x0800, ip_protocol: 17, udp_destination_port: 3333)
|
160
|
+
When I try to create an OpenFlow message with:
|
161
|
+
"""
|
162
|
+
Pio::Match.new(ether_type: 0x0800, ip_protocol: 17, udp_destination_port: 3333)
|
163
|
+
"""
|
164
|
+
Then it should finish successfully
|
165
|
+
And the message have the following fields and values:
|
166
|
+
| field | value |
|
167
|
+
| ether_type | 2048 |
|
168
|
+
| ip_protocol | 17 |
|
169
|
+
| udp_destination_port | 3333 |
|
170
|
+
|
171
|
+
Scenario: new(ether_type: 0x86dd, ipv6_source_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee')
|
172
|
+
When I try to create an OpenFlow message with:
|
173
|
+
"""
|
174
|
+
Pio::Match.new(ether_type: 0x86dd, ipv6_source_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee')
|
175
|
+
"""
|
176
|
+
Then it should finish successfully
|
177
|
+
And the message have the following fields and values:
|
178
|
+
| field | value |
|
179
|
+
| ether_type | 34525 |
|
180
|
+
| ipv6_source_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
181
|
+
|
182
|
+
Scenario: new(ether_type: 0x86dd, ipv6_source_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee', ipv6_source_address_mask: 'ffff:ffff:ffff:ffff::')
|
183
|
+
When I try to create an OpenFlow message with:
|
184
|
+
"""
|
185
|
+
Pio::Match.new(ether_type: 0x86dd, ipv6_source_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee', ipv6_source_address_mask: 'ffff:ffff:ffff:ffff::')
|
186
|
+
"""
|
187
|
+
Then it should finish successfully
|
188
|
+
And the message have the following fields and values:
|
189
|
+
| field | value |
|
190
|
+
| ether_type | 34525 |
|
191
|
+
| ipv6_source_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
192
|
+
| ipv6_source_address_mask | ffff:ffff:ffff:ffff:: |
|
193
|
+
|
194
|
+
Scenario: new(ether_type: 0x86dd, ipv6_destination_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee')
|
195
|
+
When I try to create an OpenFlow message with:
|
196
|
+
"""
|
197
|
+
Pio::Match.new(ether_type: 0x86dd, ipv6_destination_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee')
|
198
|
+
"""
|
199
|
+
Then it should finish successfully
|
200
|
+
And the message have the following fields and values:
|
201
|
+
| field | value |
|
202
|
+
| ether_type | 34525 |
|
203
|
+
| ipv6_destination_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
204
|
+
|
205
|
+
Scenario: new(ether_type: 0x86dd, ipv6_destination_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee', ipv6_destination_address_mask: 'ffff:ffff:ffff:ffff::')
|
206
|
+
When I try to create an OpenFlow message with:
|
207
|
+
"""
|
208
|
+
Pio::Match.new(ether_type: 0x86dd, ipv6_destination_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee', ipv6_destination_address_mask: 'ffff:ffff:ffff:ffff::')
|
209
|
+
"""
|
210
|
+
Then it should finish successfully
|
211
|
+
And the message have the following fields and values:
|
212
|
+
| field | value |
|
213
|
+
| ether_type | 34525 |
|
214
|
+
| ipv6_destination_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
215
|
+
| ipv6_destination_address_mask | ffff:ffff:ffff:ffff:: |
|
216
|
+
|
217
|
+
Scenario: read (file: open_flow13/oxm_no_fields.raw)
|
218
|
+
When I try to parse a file named "open_flow13/oxm_no_fields.raw" with "Pio::Match" class
|
219
|
+
Then it should finish successfully
|
220
|
+
And the message have the following fields and values:
|
221
|
+
| field | value |
|
222
|
+
| match_fields | [] |
|
223
|
+
|
224
|
+
Scenario: read (file: open_flow13/oxm_in_port_field.raw)
|
225
|
+
When I try to parse a file named "open_flow13/oxm_in_port_field.raw" with "Pio::Match" class
|
226
|
+
Then it should finish successfully
|
227
|
+
And the message have the following fields and values:
|
228
|
+
| field | value |
|
229
|
+
| in_port | 1 |
|
230
|
+
|
231
|
+
Scenario: read (file: open_flow13/oxm_ether_destination_field.raw)
|
232
|
+
When I try to parse a file named "open_flow13/oxm_ether_destination_field.raw" with "Pio::Match" class
|
233
|
+
Then it should finish successfully
|
234
|
+
And the message have the following fields and values:
|
235
|
+
| field | value |
|
236
|
+
| ether_destination_address | ff:ff:ff:ff:ff:ff |
|
237
|
+
|
238
|
+
Scenario: read (file: open_flow13/oxm_ether_source_field.raw)
|
239
|
+
When I try to parse a file named "open_flow13/oxm_ether_source_field.raw" with "Pio::Match" class
|
240
|
+
Then it should finish successfully
|
241
|
+
And the message have the following fields and values:
|
242
|
+
| field | value |
|
243
|
+
| ether_source_address | 01:02:03:04:05:06 |
|
244
|
+
|
245
|
+
Scenario: read (file: open_flow13/oxm_masked_ether_destination_field.raw)
|
246
|
+
When I try to parse a file named "open_flow13/oxm_masked_ether_destination_field.raw" with "Pio::Match" class
|
247
|
+
Then it should finish successfully
|
248
|
+
And the message have the following fields and values:
|
249
|
+
| field | value |
|
250
|
+
| ether_destination_address | ff:ff:ff:ff:ff:ff |
|
251
|
+
| ether_destination_address_mask | ff:ff:ff:00:00:00 |
|
252
|
+
|
253
|
+
Scenario: read (file: open_flow13/oxm_masked_ether_source_field.raw)
|
254
|
+
When I try to parse a file named "open_flow13/oxm_masked_ether_source_field.raw" with "Pio::Match" class
|
255
|
+
Then it should finish successfully
|
256
|
+
And the message have the following fields and values:
|
257
|
+
| field | value |
|
258
|
+
| ether_source_address | 01:02:03:04:05:06 |
|
259
|
+
| ether_source_address_mask | ff:ff:ff:00:00:00 |
|
260
|
+
|
261
|
+
Scenario: read (file: open_flow13/oxm_ether_type_field.raw)
|
262
|
+
When I try to parse a file named "open_flow13/oxm_ether_type_field.raw" with "Pio::Match" class
|
263
|
+
Then it should finish successfully
|
264
|
+
And the message have the following fields and values:
|
265
|
+
| field | value |
|
266
|
+
| ether_type | 0 |
|
267
|
+
|
268
|
+
Scenario: read (file: open_flow13/oxm_ipv4_source_field.raw)
|
269
|
+
When I try to parse a file named "open_flow13/oxm_ipv4_source_field.raw" with "Pio::Match" class
|
270
|
+
Then it should finish successfully
|
271
|
+
And the message have the following fields and values:
|
272
|
+
| field | value |
|
273
|
+
| ether_type | 2048 |
|
274
|
+
| ipv4_source_address | 1.2.3.4 |
|
275
|
+
|
276
|
+
Scenario: read (file: open_flow13/oxm_ipv4_destination_field.raw)
|
277
|
+
When I try to parse a file named "open_flow13/oxm_ipv4_destination_field.raw" with "Pio::Match" class
|
278
|
+
Then it should finish successfully
|
279
|
+
And the message have the following fields and values:
|
280
|
+
| field | value |
|
281
|
+
| ether_type | 2048 |
|
282
|
+
| ipv4_destination_address | 11.22.33.44 |
|
283
|
+
|
284
|
+
Scenario: read (file: open_flow13/oxm_masked_ipv4_source_field.raw)
|
285
|
+
When I try to parse a file named "open_flow13/oxm_masked_ipv4_source_field.raw" with "Pio::Match" class
|
286
|
+
Then it should finish successfully
|
287
|
+
And the message have the following fields and values:
|
288
|
+
| field | value |
|
289
|
+
| ether_type | 2048 |
|
290
|
+
| ipv4_source_address | 1.2.3.4 |
|
291
|
+
| ipv4_source_address_mask | 255.255.0.0 |
|
292
|
+
|
293
|
+
Scenario: read (file: open_flow13/oxm_masked_ipv4_destination_field.raw)
|
294
|
+
When I try to parse a file named "open_flow13/oxm_masked_ipv4_destination_field.raw" with "Pio::Match" class
|
295
|
+
Then it should finish successfully
|
296
|
+
And the message have the following fields and values:
|
297
|
+
| field | value |
|
298
|
+
| ether_type | 2048 |
|
299
|
+
| ipv4_destination_address | 11.22.33.44 |
|
300
|
+
| ipv4_destination_address_mask | 255.255.255.0 |
|
301
|
+
|
302
|
+
Scenario: read (file: open_flow13/oxm_tcp_source_field.raw)
|
303
|
+
When I try to parse a file named "open_flow13/oxm_tcp_source_field.raw" with "Pio::Match" class
|
304
|
+
Then it should finish successfully
|
305
|
+
And the message have the following fields and values:
|
306
|
+
| field | value |
|
307
|
+
| ether_type | 2048 |
|
308
|
+
| ip_protocol | 6 |
|
309
|
+
| tcp_source_port | 1111 |
|
310
|
+
|
311
|
+
Scenario: read (file: open_flow13/oxm_tcp_destination_field.raw)
|
312
|
+
When I try to parse a file named "open_flow13/oxm_tcp_destination_field.raw" with "Pio::Match" class
|
313
|
+
Then it should finish successfully
|
314
|
+
And the message have the following fields and values:
|
315
|
+
| field | value |
|
316
|
+
| ether_type | 2048 |
|
317
|
+
| ip_protocol | 6 |
|
318
|
+
| tcp_destination_port | 80 |
|
319
|
+
|
320
|
+
Scenario: read (file: open_flow13/oxm_udp_source_field.raw)
|
321
|
+
When I try to parse a file named "open_flow13/oxm_udp_source_field.raw" with "Pio::Match" class
|
322
|
+
Then it should finish successfully
|
323
|
+
And the message have the following fields and values:
|
324
|
+
| field | value |
|
325
|
+
| ether_type | 2048 |
|
326
|
+
| ip_protocol | 17 |
|
327
|
+
| udp_source_port | 2222 |
|
328
|
+
|
329
|
+
Scenario: read (file: open_flow13/oxm_udp_destination_field.raw)
|
330
|
+
When I try to parse a file named "open_flow13/oxm_udp_destination_field.raw" with "Pio::Match" class
|
331
|
+
Then it should finish successfully
|
332
|
+
And the message have the following fields and values:
|
333
|
+
| field | value |
|
334
|
+
| ether_type | 2048 |
|
335
|
+
| ip_protocol | 17 |
|
336
|
+
| udp_destination_port | 3333 |
|
337
|
+
|
338
|
+
Scenario: read (file: open_flow13/oxm_ipv6_source_field.raw)
|
339
|
+
When I try to parse a file named "open_flow13/oxm_ipv6_source_field.raw" with "Pio::Match" class
|
340
|
+
Then it should finish successfully
|
341
|
+
And the message have the following fields and values:
|
342
|
+
| field | value |
|
343
|
+
| ether_type | 34525 |
|
344
|
+
| ipv6_source_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
345
|
+
|
346
|
+
Scenario: read (file: open_flow13/oxm_masked_ipv6_source_field.raw)
|
347
|
+
When I try to parse a file named "open_flow13/oxm_masked_ipv6_source_field.raw" with "Pio::Match" class
|
348
|
+
Then it should finish successfully
|
349
|
+
And the message have the following fields and values:
|
350
|
+
| field | value |
|
351
|
+
| ether_type | 34525 |
|
352
|
+
| ipv6_source_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
353
|
+
| ipv6_source_address_mask | ffff:ffff:ffff:ffff:: |
|
354
|
+
|
355
|
+
Scenario: read (file: open_flow13/oxm_ipv6_destination_field.raw)
|
356
|
+
When I try to parse a file named "open_flow13/oxm_ipv6_destination_field.raw" with "Pio::Match" class
|
357
|
+
Then it should finish successfully
|
358
|
+
And the message have the following fields and values:
|
359
|
+
| field | value |
|
360
|
+
| ether_type | 34525 |
|
361
|
+
| ipv6_destination_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
362
|
+
|
363
|
+
Scenario: read (file: open_flow13/oxm_masked_ipv6_destination_field.raw)
|
364
|
+
When I try to parse a file named "open_flow13/oxm_masked_ipv6_destination_field.raw" with "Pio::Match" class
|
365
|
+
Then it should finish successfully
|
366
|
+
And the message have the following fields and values:
|
367
|
+
| field | value |
|
368
|
+
| ether_type | 34525 |
|
369
|
+
| ipv6_destination_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
|
370
|
+
| ipv6_destination_address_mask | ffff:ffff:ffff:ffff:: |
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/pio/ipv4_header.rb
CHANGED
@@ -13,7 +13,6 @@ module Pio
|
|
13
13
|
include Payload
|
14
14
|
|
15
15
|
# rubocop:disable MethodLength
|
16
|
-
# rubocop:disable AbcSize
|
17
16
|
# This method smells of :reek:TooManyStatements
|
18
17
|
def self.included(klass)
|
19
18
|
def klass.ipv4_header(options = {})
|
@@ -33,7 +32,6 @@ module Pio
|
|
33
32
|
end
|
34
33
|
end
|
35
34
|
# rubocop:enable MethodLength
|
36
|
-
# rubocop:enable AbcSize
|
37
35
|
|
38
36
|
private
|
39
37
|
|
@@ -6,20 +6,12 @@ require 'pio/parse_error'
|
|
6
6
|
module Pio
|
7
7
|
module OpenFlow
|
8
8
|
# Defines shortcuts to OpenFlow header fields.
|
9
|
+
# rubocop:disable MethodLength
|
9
10
|
class Message
|
10
11
|
def self.factory(klass, message_type, &block)
|
11
12
|
klass.extend Forwardable
|
12
13
|
klass.module_eval(&block) if block
|
13
|
-
klass.module_eval
|
14
|
-
klass.module_eval(&_define_open_flow_accessors)
|
15
|
-
klass.module_eval(&_define_self_read)
|
16
|
-
klass.module_eval(&_define_initialize)
|
17
|
-
klass.module_eval(&_define_to_binary)
|
18
|
-
end
|
19
|
-
|
20
|
-
# rubocop:disable MethodLength
|
21
|
-
def self._format_class(klass, message_type)
|
22
|
-
%(
|
14
|
+
klass.module_eval <<-EOT, __FILE__, __LINE__
|
23
15
|
class Format < BinData::Record
|
24
16
|
endian :big
|
25
17
|
|
@@ -36,13 +28,7 @@ module Pio
|
|
36
28
|
def self.format
|
37
29
|
const_get :Format
|
38
30
|
end
|
39
|
-
)
|
40
|
-
end
|
41
|
-
# rubocop:enable MethodLength
|
42
31
|
|
43
|
-
# rubocop:disable MethodLength
|
44
|
-
def self._define_open_flow_accessors
|
45
|
-
proc do
|
46
32
|
def_delegators :@format, :snapshot
|
47
33
|
def_delegators :snapshot, :open_flow_header
|
48
34
|
def_delegators :open_flow_header, :ofp_version
|
@@ -53,61 +39,39 @@ module Pio
|
|
53
39
|
|
54
40
|
def_delegators :snapshot, :body
|
55
41
|
def_delegator :snapshot, :body, :user_data
|
56
|
-
end
|
57
|
-
end
|
58
|
-
# rubocop:enable MethodLength
|
59
42
|
|
60
|
-
def self._define_self_read
|
61
|
-
proc do
|
62
43
|
def self.read(raw_data)
|
63
44
|
allocate.tap do |message|
|
64
45
|
message.instance_variable_set(:@format, format.read(raw_data))
|
65
46
|
end
|
66
47
|
rescue BinData::ValidityError
|
67
48
|
message_name = name.split('::')[1..-1].join(' ')
|
68
|
-
raise Pio::ParseError, "Invalid
|
49
|
+
raise Pio::ParseError, "Invalid \#{message_name} message."
|
69
50
|
end
|
70
|
-
end
|
71
|
-
end
|
72
51
|
|
73
|
-
# rubocop:disable MethodLength
|
74
|
-
# rubocop:disable AbcSize
|
75
|
-
def self._define_initialize
|
76
|
-
proc do
|
77
52
|
def initialize(user_options = {})
|
78
53
|
header_options = OpenFlowHeader::Options.parse(user_options)
|
79
|
-
body_options =
|
54
|
+
body_options = if user_options.respond_to?(:fetch)
|
55
|
+
user_options.delete :transaction_id
|
56
|
+
user_options.delete :xid
|
57
|
+
dpid = user_options[:dpid]
|
58
|
+
user_options[:datapath_id] = dpid if dpid
|
59
|
+
if user_options.keys.size > 1
|
60
|
+
user_options
|
61
|
+
else
|
62
|
+
user_options[:user_data] || ''
|
63
|
+
end
|
64
|
+
else
|
65
|
+
''
|
66
|
+
end
|
80
67
|
@format = self.class.format.new(open_flow_header: header_options,
|
81
68
|
body: body_options)
|
82
69
|
end
|
83
70
|
|
84
|
-
private
|
85
|
-
|
86
|
-
def parse_body_options(options)
|
87
|
-
if options.respond_to?(:fetch)
|
88
|
-
options.delete :transaction_id
|
89
|
-
options.delete :xid
|
90
|
-
dpid = options[:dpid]
|
91
|
-
options[:datapath_id] = dpid if dpid
|
92
|
-
if options.keys.size > 1
|
93
|
-
options
|
94
|
-
else
|
95
|
-
options[:user_data] || ''
|
96
|
-
end
|
97
|
-
else
|
98
|
-
''
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
# rubocop:enable MethodLength
|
104
|
-
# rubocop:enable AbcSize
|
105
|
-
|
106
|
-
def self._define_to_binary
|
107
|
-
proc do
|
108
71
|
def_delegator :@format, :to_binary_s, :to_binary
|
109
|
-
|
72
|
+
EOT
|
110
73
|
end
|
74
|
+
# rubocop:enable MethodLength
|
111
75
|
end
|
112
76
|
end
|
113
77
|
end
|
@@ -75,7 +75,7 @@ module Pio
|
|
75
75
|
def self.read(raw_data)
|
76
76
|
ethernet_header = EtherTypeParser.read(raw_data)
|
77
77
|
case ethernet_header.ether_type
|
78
|
-
when EthernetHeader::EtherType::IPV4
|
78
|
+
when EthernetHeader::EtherType::IPV4, EthernetHeader::EtherType::VLAN
|
79
79
|
IPv4Packet.read raw_data
|
80
80
|
when EthernetHeader::EtherType::ARP
|
81
81
|
Pio::Arp.read raw_data
|