pio 0.11.2 → 0.12.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/CHANGELOG.md +9 -0
- data/features/exact_match.feature +38 -0
- data/features/packet_data/{packet_in.raw → packet_in_arp_request.raw} +0 -0
- data/features/packet_data/packet_in_cbench.raw +0 -0
- data/features/packet_in_read.feature +2 -2
- data/features/step_definitions/packet_data_steps.rb +4 -0
- data/lib/pio.rb +1 -0
- data/lib/pio/arp/message.rb +4 -17
- data/lib/pio/exact_match.rb +106 -0
- data/lib/pio/ipv4_address.rb +1 -3
- data/lib/pio/type/ethernet_header.rb +29 -2
- data/lib/pio/type/ipv4_header.rb +5 -4
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +4 -4
- metadata +18 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bb4195ca95f655a64ce7c02ec9884a3bad1fd7c
|
4
|
+
data.tar.gz: 33cd84c8eb3e5289672c80e27d27b9c189b71303
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cea7f5346912379c9f0cf5800a8f57d997694126679c241dacefaeb0f4bcc0597f5debfd63ca151d8e2226418b59beba0aa8fabab5cb60068f4ba0751dffedad
|
7
|
+
data.tar.gz: 98b9e42fc3995ba700d0d1d75bc852bd3bd9a4a1c30b538802b6b56b8d80f95ce53d0711226bd778aca87d1f7d3736976d124fd98add04843302a6d8847c2e12
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
Feature: Pio::ExactMatch.new
|
2
|
+
Scenario: packet_in_arp_request.raw
|
3
|
+
Given a packet data file "packet_in_arp_request.raw"
|
4
|
+
When I try to create an exact match from the packet
|
5
|
+
And the parsed data have the following field and value:
|
6
|
+
| field | value |
|
7
|
+
| wildcards | {} |
|
8
|
+
| in_port | 1 |
|
9
|
+
| dl_src | ac:5d:10:31:37:79 |
|
10
|
+
| dl_dst | ff:ff:ff:ff:ff:ff |
|
11
|
+
| dl_vlan | 65535 |
|
12
|
+
| dl_vlan_pcp | 0 |
|
13
|
+
| dl_type | 2054 |
|
14
|
+
| nw_tos | 0 |
|
15
|
+
| nw_proto | 1 |
|
16
|
+
| nw_src | 192.168.2.254 |
|
17
|
+
| nw_dst | 192.168.2.5 |
|
18
|
+
| tp_src | 0 |
|
19
|
+
| tp_dst | 0 |
|
20
|
+
|
21
|
+
Scenario: packet_in_cbench.raw (ARP request)
|
22
|
+
Given a packet data file "packet_in_cbench.raw"
|
23
|
+
When I try to create an exact match from the packet
|
24
|
+
And the parsed data have the following field and value:
|
25
|
+
| field | value |
|
26
|
+
| wildcards | {} |
|
27
|
+
| in_port | 1 |
|
28
|
+
| dl_src | 00:00:00:00:00:01 |
|
29
|
+
| dl_dst | 80:00:00:00:00:01 |
|
30
|
+
| dl_vlan | 65535 |
|
31
|
+
| dl_vlan_pcp | 0 |
|
32
|
+
| dl_type | 2048 |
|
33
|
+
| nw_tos | 0 |
|
34
|
+
| nw_proto | 255 |
|
35
|
+
| nw_src | 192.168.0.40 |
|
36
|
+
| nw_dst | 192.168.1.40 |
|
37
|
+
| tp_src | 31256 |
|
38
|
+
| tp_dst | 22635 |
|
File without changes
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Feature: Pio::PacketIn.read
|
2
|
-
Scenario:
|
3
|
-
Given a packet data file "
|
2
|
+
Scenario: packet_in_arp_request.raw
|
3
|
+
Given a packet data file "packet_in_arp_request.raw"
|
4
4
|
When I try to parse the file with "PacketIn" class
|
5
5
|
Then it should finish successfully
|
6
6
|
And the parsed data have the following field and value:
|
@@ -25,6 +25,10 @@ When(/^I try to parse the file with "(.*?)" class$/) do |parser|
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
When(/^I try to create an exact match from the packet$/) do
|
29
|
+
@result = Pio::ExactMatch.new(Pio::PacketIn.read(IO.read(@raw)))
|
30
|
+
end
|
31
|
+
|
28
32
|
Then(/^it should finish successfully$/) do
|
29
33
|
# Noop.
|
30
34
|
end
|
data/lib/pio.rb
CHANGED
data/lib/pio/arp/message.rb
CHANGED
@@ -1,32 +1,19 @@
|
|
1
|
-
require 'forwardable'
|
2
1
|
require 'pio/arp/format'
|
3
2
|
|
4
3
|
module Pio
|
5
4
|
class Arp
|
6
5
|
# Base class of ARP Request and Reply
|
7
6
|
class Message
|
8
|
-
extend Forwardable
|
9
|
-
|
10
|
-
def_delegators :@format, :destination_mac
|
11
|
-
def_delegators :@format, :source_mac
|
12
|
-
def_delegators :@format, :ether_type
|
13
|
-
def_delegators :@format, :hardware_type
|
14
|
-
def_delegators :@format, :protocol_type
|
15
|
-
def_delegators :@format, :hardware_length
|
16
|
-
def_delegators :@format, :protocol_length
|
17
|
-
def_delegators :@format, :operation
|
18
|
-
def_delegators :@format, :sender_hardware_address
|
19
|
-
def_delegators :@format, :sender_protocol_address
|
20
|
-
def_delegators :@format, :target_hardware_address
|
21
|
-
def_delegators :@format, :target_protocol_address
|
22
|
-
def_delegators :@format, :to_binary
|
23
|
-
|
24
7
|
private_class_method :new
|
25
8
|
|
26
9
|
def initialize(user_options)
|
27
10
|
options = self.class.const_get(:Options).new(user_options.dup.freeze)
|
28
11
|
@format = Arp::Format.new(options.to_hash)
|
29
12
|
end
|
13
|
+
|
14
|
+
def method_missing(method, *args)
|
15
|
+
@format.__send__ method, *args
|
16
|
+
end
|
30
17
|
end
|
31
18
|
end
|
32
19
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'pio/match'
|
2
|
+
require 'pio/type/ethernet_header'
|
3
|
+
|
4
|
+
module Pio
|
5
|
+
# OpenFlow 1.0 exact match
|
6
|
+
class ExactMatch
|
7
|
+
# Pio::PacketIn#data parser
|
8
|
+
class PacketInDataParser
|
9
|
+
# Ethernet header parser
|
10
|
+
class EthernetHeaderParser < BinData::Record
|
11
|
+
extend Pio::Type::EthernetHeader
|
12
|
+
|
13
|
+
endian :big
|
14
|
+
|
15
|
+
ethernet_header
|
16
|
+
rest :payload
|
17
|
+
end
|
18
|
+
|
19
|
+
# IPv4 packet parser
|
20
|
+
class IPv4Packet < BinData::Record
|
21
|
+
extend Pio::Type::EthernetHeader
|
22
|
+
extend Type::IPv4Header
|
23
|
+
|
24
|
+
endian :big
|
25
|
+
|
26
|
+
ethernet_header
|
27
|
+
ipv4_header
|
28
|
+
|
29
|
+
uint16 :transport_source_port
|
30
|
+
uint16 :transport_destination_port
|
31
|
+
rest :rest
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.read(raw_data)
|
35
|
+
ethernet_header = EthernetHeaderParser.read(raw_data)
|
36
|
+
case ethernet_header.ether_type
|
37
|
+
when 0x0800
|
38
|
+
IPv4Packet.read raw_data
|
39
|
+
when 0x0806
|
40
|
+
Pio::Arp.read raw_data
|
41
|
+
else
|
42
|
+
fail 'Failed to parse packet_in data.'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
extend Forwardable
|
48
|
+
|
49
|
+
# rubocop:disable MethodLength
|
50
|
+
# rubocop:disable AbcSize
|
51
|
+
def initialize(packet_in)
|
52
|
+
data = PacketInDataParser.read(packet_in.data)
|
53
|
+
case data
|
54
|
+
when PacketInDataParser::IPv4Packet
|
55
|
+
options = {
|
56
|
+
in_port: packet_in.in_port,
|
57
|
+
dl_src: data.source_mac,
|
58
|
+
dl_dst: data.destination_mac,
|
59
|
+
dl_vlan: data.vlan_vid,
|
60
|
+
dl_vlan_pcp: data.vlan_pcp,
|
61
|
+
dl_type: data.ether_type,
|
62
|
+
nw_tos: data.ip_type_of_service,
|
63
|
+
nw_proto: data.ip_protocol,
|
64
|
+
nw_src: data.ip_source_address,
|
65
|
+
nw_dst: data.ip_destination_address,
|
66
|
+
tp_src: data.transport_source_port,
|
67
|
+
tp_dst: data.transport_destination_port
|
68
|
+
}
|
69
|
+
when Arp::Request
|
70
|
+
options = {
|
71
|
+
in_port: packet_in.in_port,
|
72
|
+
dl_src: data.source_mac,
|
73
|
+
dl_dst: data.destination_mac,
|
74
|
+
dl_vlan: data.vlan_vid,
|
75
|
+
dl_vlan_pcp: data.vlan_pcp,
|
76
|
+
dl_type: data.ether_type,
|
77
|
+
nw_tos: 0,
|
78
|
+
nw_proto: data.operation,
|
79
|
+
nw_src: data.sender_protocol_address,
|
80
|
+
nw_dst: data.target_protocol_address,
|
81
|
+
tp_src: 0,
|
82
|
+
tp_dst: 0
|
83
|
+
}
|
84
|
+
end
|
85
|
+
@match = Pio::Match.new(options)
|
86
|
+
end
|
87
|
+
# rubocop:enable MethodLength
|
88
|
+
# rubocop:enable AbcSize
|
89
|
+
|
90
|
+
def_delegator :@match, :wildcards
|
91
|
+
def_delegator :@match, :in_port
|
92
|
+
def_delegator :@match, :dl_src
|
93
|
+
def_delegator :@match, :dl_dst
|
94
|
+
def_delegator :@match, :dl_vlan
|
95
|
+
def_delegator :@match, :dl_vlan_pcp
|
96
|
+
def_delegator :@match, :dl_type
|
97
|
+
def_delegator :@match, :nw_tos
|
98
|
+
def_delegator :@match, :nw_proto
|
99
|
+
def_delegator :@match, :nw_src
|
100
|
+
def_delegator :@match, :nw_dst
|
101
|
+
def_delegator :@match, :tp_src
|
102
|
+
def_delegator :@match, :tp_dst
|
103
|
+
def_delegator :@match, :to_binary_s
|
104
|
+
def_delegator :@match, :to_binary_s, :to_binary
|
105
|
+
end
|
106
|
+
end
|
data/lib/pio/ipv4_address.rb
CHANGED
@@ -4,13 +4,40 @@ module Pio
|
|
4
4
|
module Type
|
5
5
|
# Adds ethernet_header macro.
|
6
6
|
module EthernetHeader
|
7
|
-
|
7
|
+
# rubocop:disable MethodLength
|
8
|
+
# rubocop:disable AbcSize
|
9
|
+
def ethernet_header(options = { ether_type: 0x0800 })
|
8
10
|
class_eval do
|
9
11
|
mac_address :destination_mac
|
10
12
|
mac_address :source_mac
|
11
|
-
uint16 :
|
13
|
+
uint16 :ether_type_internal, initial_value: options[:ether_type]
|
14
|
+
|
15
|
+
bit3 :vlan_pcp_internal, onlyif: -> { vlan? }
|
16
|
+
bit1 :vlan_cfi, onlyif: -> { vlan? }
|
17
|
+
bit12 :vlan_vid_internal, onlyif: -> { vlan? }
|
18
|
+
|
19
|
+
uint16 :ether_type_vlan, onlyif: -> { vlan? },
|
20
|
+
initial_value: options[:ether_type]
|
21
|
+
|
22
|
+
def ether_type
|
23
|
+
ether_type_internal
|
24
|
+
end
|
25
|
+
|
26
|
+
def vlan_vid
|
27
|
+
vlan? ? vlan_vid_internal : 0xffff
|
28
|
+
end
|
29
|
+
|
30
|
+
def vlan_pcp
|
31
|
+
vlan? ? vlan_pcp_internal : 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def vlan?
|
35
|
+
ether_type == 0x8100
|
36
|
+
end
|
12
37
|
end
|
13
38
|
end
|
39
|
+
# rubocop:enable MethodLength
|
40
|
+
# rubocop:enable AbcSize
|
14
41
|
end
|
15
42
|
end
|
16
43
|
end
|
data/lib/pio/type/ipv4_header.rb
CHANGED
@@ -7,22 +7,23 @@ module Pio
|
|
7
7
|
# This method smells of :reek:TooManyStatements
|
8
8
|
# rubocop:disable MethodLength
|
9
9
|
# rubocop:disable AbcSize
|
10
|
-
def ipv4_header(options)
|
10
|
+
def ipv4_header(options = {})
|
11
11
|
class_eval do
|
12
12
|
bit4 :ip_version, initial_value: 0x4
|
13
13
|
bit4 :ip_header_length, initial_value: 0x5
|
14
14
|
uint8 :ip_type_of_service, initial_value: 0
|
15
15
|
uint16be :ip_total_length,
|
16
|
-
initial_value: options[:ip_total_length]
|
16
|
+
initial_value: options[:ip_total_length] || 0
|
17
17
|
uint16be :ip_identifier, initial_value: 0
|
18
18
|
bit3 :ip_flag, initial_value: 0
|
19
19
|
bit13 :ip_fragment, initial_value: 0
|
20
20
|
uint8 :ip_ttl, initial_value: 128
|
21
|
-
uint8 :ip_protocol,
|
21
|
+
uint8 :ip_protocol, initial_value: options[:ip_protocol] || 0
|
22
22
|
uint16be :ip_header_checksum,
|
23
|
-
initial_value: options[:ip_header_checksum]
|
23
|
+
initial_value: options[:ip_header_checksum] || 0
|
24
24
|
ip_address :ip_source_address
|
25
25
|
ip_address :ip_destination_address
|
26
|
+
string :option, read_length: -> { 20 - ip_header_length * 4 }
|
26
27
|
end
|
27
28
|
end
|
28
29
|
# rubocop:enable AbcSize
|
data/lib/pio/version.rb
CHANGED
data/pio.gemspec
CHANGED
@@ -57,12 +57,12 @@ Gem::Specification.new do |gem|
|
|
57
57
|
|
58
58
|
# Test
|
59
59
|
gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.6'
|
60
|
-
gem.add_development_dependency 'coveralls', '~> 0.7.
|
60
|
+
gem.add_development_dependency 'coveralls', '~> 0.7.9'
|
61
61
|
gem.add_development_dependency 'cucumber', '~> 1.3.18'
|
62
|
-
gem.add_development_dependency 'flay', '~> 2.6.
|
63
|
-
gem.add_development_dependency 'flog', '~> 4.3.
|
62
|
+
gem.add_development_dependency 'flay', '~> 2.6.1'
|
63
|
+
gem.add_development_dependency 'flog', '~> 4.3.2'
|
64
64
|
gem.add_development_dependency 'reek', '~> 1.6.4'
|
65
|
-
gem.add_development_dependency 'rspec', '~> 3.
|
65
|
+
gem.add_development_dependency 'rspec', '~> 3.2.0'
|
66
66
|
gem.add_development_dependency 'rspec-given', '~> 3.6.0'
|
67
67
|
gem.add_development_dependency 'rubocop', '~> 0.28.0'
|
68
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yasuhito Takamiya
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
@@ -240,14 +240,14 @@ dependencies:
|
|
240
240
|
requirements:
|
241
241
|
- - ~>
|
242
242
|
- !ruby/object:Gem::Version
|
243
|
-
version: 0.7.
|
243
|
+
version: 0.7.9
|
244
244
|
type: :development
|
245
245
|
prerelease: false
|
246
246
|
version_requirements: !ruby/object:Gem::Requirement
|
247
247
|
requirements:
|
248
248
|
- - ~>
|
249
249
|
- !ruby/object:Gem::Version
|
250
|
-
version: 0.7.
|
250
|
+
version: 0.7.9
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
252
|
name: cucumber
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -268,28 +268,28 @@ dependencies:
|
|
268
268
|
requirements:
|
269
269
|
- - ~>
|
270
270
|
- !ruby/object:Gem::Version
|
271
|
-
version: 2.6.
|
271
|
+
version: 2.6.1
|
272
272
|
type: :development
|
273
273
|
prerelease: false
|
274
274
|
version_requirements: !ruby/object:Gem::Requirement
|
275
275
|
requirements:
|
276
276
|
- - ~>
|
277
277
|
- !ruby/object:Gem::Version
|
278
|
-
version: 2.6.
|
278
|
+
version: 2.6.1
|
279
279
|
- !ruby/object:Gem::Dependency
|
280
280
|
name: flog
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
282
282
|
requirements:
|
283
283
|
- - ~>
|
284
284
|
- !ruby/object:Gem::Version
|
285
|
-
version: 4.3.
|
285
|
+
version: 4.3.2
|
286
286
|
type: :development
|
287
287
|
prerelease: false
|
288
288
|
version_requirements: !ruby/object:Gem::Requirement
|
289
289
|
requirements:
|
290
290
|
- - ~>
|
291
291
|
- !ruby/object:Gem::Version
|
292
|
-
version: 4.3.
|
292
|
+
version: 4.3.2
|
293
293
|
- !ruby/object:Gem::Dependency
|
294
294
|
name: reek
|
295
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -310,14 +310,14 @@ dependencies:
|
|
310
310
|
requirements:
|
311
311
|
- - ~>
|
312
312
|
- !ruby/object:Gem::Version
|
313
|
-
version: 3.
|
313
|
+
version: 3.2.0
|
314
314
|
type: :development
|
315
315
|
prerelease: false
|
316
316
|
version_requirements: !ruby/object:Gem::Requirement
|
317
317
|
requirements:
|
318
318
|
- - ~>
|
319
319
|
- !ruby/object:Gem::Version
|
320
|
-
version: 3.
|
320
|
+
version: 3.2.0
|
321
321
|
- !ruby/object:Gem::Dependency
|
322
322
|
name: rspec-given
|
323
323
|
requirement: !ruby/object:Gem::Requirement
|
@@ -385,6 +385,7 @@ files:
|
|
385
385
|
- features/arp_read.feature
|
386
386
|
- features/dhcp_read.feature
|
387
387
|
- features/echo_read.feature
|
388
|
+
- features/exact_match.feature
|
388
389
|
- features/features_read.feature
|
389
390
|
- features/flow_mod_read.feature
|
390
391
|
- features/hello_read.feature
|
@@ -418,7 +419,8 @@ files:
|
|
418
419
|
- features/packet_data/icmp.pcap
|
419
420
|
- features/packet_data/lldp.detailed.pcap
|
420
421
|
- features/packet_data/lldp.minimal.pcap
|
421
|
-
- features/packet_data/
|
422
|
+
- features/packet_data/packet_in_arp_request.raw
|
423
|
+
- features/packet_data/packet_in_cbench.raw
|
422
424
|
- features/packet_data/packet_out.raw
|
423
425
|
- features/packet_data/port_mod.raw
|
424
426
|
- features/packet_data/port_stats_reply.raw
|
@@ -463,6 +465,7 @@ files:
|
|
463
465
|
- lib/pio/dhcp/request.rb
|
464
466
|
- lib/pio/echo.rb
|
465
467
|
- lib/pio/enqueue.rb
|
468
|
+
- lib/pio/exact_match.rb
|
466
469
|
- lib/pio/features.rb
|
467
470
|
- lib/pio/flow_mod.rb
|
468
471
|
- lib/pio/hello.rb
|
@@ -583,7 +586,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
583
586
|
version: '0'
|
584
587
|
requirements: []
|
585
588
|
rubyforge_project:
|
586
|
-
rubygems_version: 2.
|
589
|
+
rubygems_version: 2.2.2
|
587
590
|
signing_key:
|
588
591
|
specification_version: 4
|
589
592
|
summary: Packet parser and generator.
|
@@ -638,12 +641,12 @@ test_files:
|
|
638
641
|
- features/packet_data/flow_mod_modify_strict.raw
|
639
642
|
- features/packet_data/flow_mod_add.raw
|
640
643
|
- features/packet_data/features_reply.raw
|
641
|
-
- features/packet_data/packet_in.raw
|
642
644
|
- features/packet_data/aggregate_stats_reply.raw
|
643
645
|
- features/packet_data/queue_get_config_reply.raw
|
644
646
|
- features/packet_data/arp.pcap
|
645
647
|
- features/packet_data/features_request.raw
|
646
648
|
- features/packet_data/flow_stats_request.raw
|
649
|
+
- features/packet_data/packet_in_arp_request.raw
|
647
650
|
- features/packet_data/port_stats_request.raw
|
648
651
|
- features/packet_data/flow_mod_delete_strict.raw
|
649
652
|
- features/packet_data/barrier_reply.raw
|
@@ -658,6 +661,7 @@ test_files:
|
|
658
661
|
- features/packet_data/port_stats_reply.raw
|
659
662
|
- features/packet_data/packet_out.raw
|
660
663
|
- features/packet_data/table_stats_reply.raw
|
664
|
+
- features/packet_data/packet_in_cbench.raw
|
661
665
|
- features/packet_data/queue_get_config_request.raw
|
662
666
|
- features/packet_data/error.raw
|
663
667
|
- features/packet_data/vendor_stats_request.raw
|
@@ -673,6 +677,7 @@ test_files:
|
|
673
677
|
- features/packet_data/lldp.detailed.pcap
|
674
678
|
- features/packet_data/aggregate_stats_request.raw
|
675
679
|
- features/packet_data/echo_request.raw
|
680
|
+
- features/exact_match.feature
|
676
681
|
- features/icmp_read.feature
|
677
682
|
- features/arp_read.feature
|
678
683
|
- features/step_definitions/pending_steps.rb
|