pio 0.19.0 → 0.20.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/README.md +20 -18
- data/features/{packet_data/arp-storm.pcap → arp-storm.pcap} +0 -0
- data/features/arp.feature +1 -1
- data/features/{packet_data/arp.pcap → arp.pcap} +0 -0
- data/features/dhcp.feature +210 -3
- data/features/{packet_data/dhcp.pcap → dhcp.pcap} +0 -0
- data/features/icmp.feature +1 -1
- data/features/{packet_data/icmp.pcap → icmp.pcap} +0 -0
- data/features/{packet_data/lldp.detailed.pcap → lldp.detailed.pcap} +0 -0
- data/features/lldp.feature +5 -5
- data/features/{packet_data/lldp.minimal.pcap → lldp.minimal.pcap} +0 -0
- data/features/{packet_data → open_flow10}/aggregate_stats_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/aggregate_stats_request.raw +0 -0
- data/features/{packet_data → open_flow10}/barrier_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/barrier_request.raw +0 -0
- data/features/{packet_data → open_flow10}/desc_stats_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/desc_stats_request.raw +0 -0
- data/features/open_flow10/echo_reply.feature +10 -10
- data/features/{packet_data → open_flow10}/echo_reply.raw +0 -0
- data/features/open_flow10/echo_request.feature +10 -10
- data/features/{packet_data → open_flow10}/echo_request.raw +0 -0
- data/features/{packet_data → open_flow10}/error.raw +0 -0
- data/features/open_flow10/exact_match.feature +33 -33
- data/features/open_flow10/features_reply.feature +71 -71
- data/features/{packet_data → open_flow10}/features_reply.raw +0 -0
- data/features/open_flow10/features_request.feature +9 -9
- data/features/{packet_data → open_flow10}/features_request.raw +0 -0
- data/features/open_flow10/flow_mod.feature +167 -167
- data/features/{packet_data → open_flow10}/flow_mod_add.raw +0 -0
- data/features/{packet_data → open_flow10}/flow_mod_delete.raw +0 -0
- data/features/{packet_data → open_flow10}/flow_mod_delete_strict.raw +0 -0
- data/features/{packet_data → open_flow10}/flow_mod_modify.raw +0 -0
- data/features/{packet_data → open_flow10}/flow_mod_modify_strict.raw +0 -0
- data/features/{packet_data → open_flow10}/flow_removed.raw +0 -0
- data/features/{packet_data → open_flow10}/flow_stats_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/flow_stats_request.raw +0 -0
- data/features/{packet_data → open_flow10}/get_config_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/get_config_request.raw +0 -0
- data/features/open_flow10/hello.feature +9 -9
- data/features/{packet_data → open_flow10}/hello.raw +0 -0
- data/features/open_flow10/packet_in.feature +4 -4
- data/features/{packet_data → open_flow10}/packet_in_arp_request.raw +0 -0
- data/features/{packet_data → open_flow10}/packet_in_cbench.raw +0 -0
- data/features/open_flow10/packet_out.feature +3 -3
- data/features/{packet_data → open_flow10}/packet_out.raw +0 -0
- data/features/{packet_data → open_flow10}/port_mod.raw +0 -0
- data/features/{packet_data → open_flow10}/port_stats_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/port_stats_request.raw +0 -0
- data/features/open_flow10/port_status.feature +3 -3
- data/features/{packet_data → open_flow10}/port_status.raw +0 -0
- data/features/{packet_data → open_flow10}/queue_get_config_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/queue_get_config_request.raw +0 -0
- data/features/{packet_data → open_flow10}/set_config.raw +0 -0
- data/features/{packet_data → open_flow10}/table_stats_reply.raw +0 -0
- data/features/{packet_data → open_flow10}/table_stats_request.raw +0 -0
- data/features/{packet_data → open_flow10}/vendor.raw +0 -0
- data/features/{packet_data → open_flow10}/vendor_stats_request.raw +0 -0
- data/features/open_flow13/echo_reply.feature +64 -61
- data/features/{packet_data/echo13_reply_body.raw → open_flow13/echo_reply_body.raw} +0 -0
- data/features/{packet_data/echo13_reply_no_body.raw → open_flow13/echo_reply_no_body.raw} +0 -0
- data/features/open_flow13/echo_request.feature +64 -61
- data/features/{packet_data/echo13_request_body.raw → open_flow13/echo_request_body.raw} +0 -0
- data/features/{packet_data/echo13_request_no_body.raw → open_flow13/echo_request_no_body.raw} +0 -0
- data/features/open_flow13/features_reply.feature +53 -0
- data/features/open_flow13/features_reply.raw +0 -0
- data/features/open_flow13/features_request.feature +89 -0
- data/features/open_flow13/features_request.raw +0 -0
- data/features/open_flow13/hello.feature +26 -23
- data/features/{packet_data/hello13_no_version_bitmap.raw → open_flow13/hello_no_version_bitmap.raw} +0 -0
- data/features/{packet_data/hello13_version_bitmap.raw → open_flow13/hello_version_bitmap.raw} +0 -0
- data/features/step_definitions/open_flow_steps.rb +3 -0
- data/features/step_definitions/packet_data_steps.rb +9 -9
- data/features/udp.feature +3 -3
- data/features/{packet_data/udp_no_payload.raw → udp_no_payload.raw} +0 -0
- data/features/{packet_data/udp_with_payload.raw → udp_with_payload.raw} +0 -0
- data/lib/pio.rb +1 -9
- data/lib/pio/open_flow/actions.rb +8 -8
- data/lib/pio/open_flow/open_flow_header.rb +10 -0
- data/lib/pio/open_flow10.rb +15 -0
- data/lib/pio/open_flow10/echo.rb +15 -0
- data/lib/pio/open_flow10/exact_match.rb +51 -0
- data/lib/pio/{features.rb → open_flow10/features.rb} +8 -7
- data/lib/pio/{flow_mod.rb → open_flow10/flow_mod.rb} +1 -1
- data/lib/pio/{hello.rb → open_flow10/hello.rb} +0 -0
- data/lib/pio/{match.rb → open_flow10/match.rb} +46 -43
- data/lib/pio/{packet_in.rb → open_flow10/packet_in.rb} +0 -0
- data/lib/pio/{packet_out.rb → open_flow10/packet_out.rb} +0 -0
- data/lib/pio/{port_status.rb → open_flow10/port_status.rb} +0 -0
- data/lib/pio/open_flow13.rb +12 -0
- data/lib/pio/{echo.rb → open_flow13/echo.rb} +9 -13
- data/lib/pio/open_flow13/features_reply.rb +91 -0
- data/lib/pio/open_flow13/features_request.rb +54 -0
- data/lib/pio/{hello13.rb → open_flow13/hello.rb} +4 -1
- data/lib/pio/{set_eth_addr.rb → set_ether_address.rb} +7 -7
- data/lib/pio/{set_ip_addr.rb → set_ip_address.rb} +7 -7
- data/lib/pio/set_ip_tos.rb +1 -1
- data/lib/pio/set_transport_port.rb +2 -2
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +2 -2
- data/spec/pio/flow_mod_spec.rb +45 -45
- data/spec/pio/match_spec.rb +122 -120
- data/spec/pio/{hello13_spec.rb → open_flow13/hello_spec.rb} +11 -11
- data/spec/pio/packet_out_spec.rb +19 -19
- data/spec/pio/set_ether_destination_address_spec.rb +28 -0
- data/spec/pio/set_ether_source_address_spec.rb +28 -0
- data/spec/pio/set_ip_destination_address_spec.rb +27 -0
- data/spec/pio/set_ip_source_address_spec.rb +25 -0
- data/spec/pio/set_transport_destination_port_spec.rb +44 -0
- data/spec/pio/set_transport_source_port_spec.rb +44 -0
- data/spec/pio/wildcards_spec.rb +23 -21
- metadata +179 -165
- data/bin/byebug +0 -16
- data/lib/pio/exact_match.rb +0 -51
- data/spec/pio/set_eth_dst_addr_spec.rb +0 -28
- data/spec/pio/set_eth_src_addr_spec.rb +0 -28
- data/spec/pio/set_ip_dst_addr_spec.rb +0 -25
- data/spec/pio/set_ip_src_addr_spec.rb +0 -25
- data/spec/pio/set_transport_dst_port_spec.rb +0 -42
- data/spec/pio/set_transport_src_port_spec.rb +0 -42
|
File without changes
|
data/features/{packet_data/echo13_request_no_body.raw → open_flow13/echo_request_no_body.raw}
RENAMED
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Feature: Pio::Features::Reply
|
|
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::Features::Reply.new(
|
|
9
|
+
dpid: 0x123,
|
|
10
|
+
n_buffers: 0x100,
|
|
11
|
+
n_tables: 0xfe,
|
|
12
|
+
capabilities: [:flow_stats, :table_stats, :port_stats, :group_stats, :ip_reasm, :queue_stats, :port_blocked]
|
|
13
|
+
)
|
|
14
|
+
"""
|
|
15
|
+
Then it should finish successfully
|
|
16
|
+
And the message have the following fields and values:
|
|
17
|
+
| field | value |
|
|
18
|
+
| class | Pio::Features::Reply |
|
|
19
|
+
| ofp_version | 4 |
|
|
20
|
+
| message_type | 6 |
|
|
21
|
+
| message_length | 32 |
|
|
22
|
+
| transaction_id | 0 |
|
|
23
|
+
| xid | 0 |
|
|
24
|
+
| datapath_id | 291 |
|
|
25
|
+
| dpid | 291 |
|
|
26
|
+
| n_buffers | 256 |
|
|
27
|
+
| n_tables | 254 |
|
|
28
|
+
| auxiliary_id | 0 |
|
|
29
|
+
| capabilities | [:flow_stats, :table_stats, :port_stats, :group_stats, :ip_reasm, :queue_stats, :port_blocked] |
|
|
30
|
+
| reserved | 0 |
|
|
31
|
+
|
|
32
|
+
Scenario: read
|
|
33
|
+
When I try to parse a file named "open_flow13/features_reply.raw" with "Pio::Features::Reply" class
|
|
34
|
+
Then it should finish successfully
|
|
35
|
+
And the message have the following fields and values:
|
|
36
|
+
| field | value |
|
|
37
|
+
| class | Pio::Features::Reply |
|
|
38
|
+
| ofp_version | 4 |
|
|
39
|
+
| message_type | 6 |
|
|
40
|
+
| message_length | 32 |
|
|
41
|
+
| transaction_id | 0 |
|
|
42
|
+
| xid | 0 |
|
|
43
|
+
| datapath_id | 281474976710657 |
|
|
44
|
+
| dpid | 281474976710657 |
|
|
45
|
+
| n_buffers | 256 |
|
|
46
|
+
| n_tables | 1 |
|
|
47
|
+
| auxiliary_id | 0 |
|
|
48
|
+
| capabilities | [:flow_stats, :table_stats, :port_stats, :group_stats, :ip_reasm, :queue_stats, :port_blocked] |
|
|
49
|
+
| reserved | 0 |
|
|
50
|
+
|
|
51
|
+
Scenario: parse error
|
|
52
|
+
When I try to parse a file named "open_flow10/echo_request.raw" with "Pio::Features::Reply" class
|
|
53
|
+
Then it should fail with "Pio::ParseError", "Invalid Features Reply 1.3 message."
|
|
Binary file
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Feature: Pio::Features::Request
|
|
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::Features::Request.new
|
|
9
|
+
"""
|
|
10
|
+
Then it should finish successfully
|
|
11
|
+
And the message have the following fields and values:
|
|
12
|
+
| field | value |
|
|
13
|
+
| class | Pio::Features::Request |
|
|
14
|
+
| ofp_version | 4 |
|
|
15
|
+
| message_type | 5 |
|
|
16
|
+
| message_length | 8 |
|
|
17
|
+
| transaction_id | 0 |
|
|
18
|
+
| xid | 0 |
|
|
19
|
+
| body | |
|
|
20
|
+
|
|
21
|
+
Scenario: new(transaction_id: 123)
|
|
22
|
+
When I try to create an OpenFlow message with:
|
|
23
|
+
"""
|
|
24
|
+
Pio::Features::Request.new(transaction_id: 123)
|
|
25
|
+
"""
|
|
26
|
+
Then it should finish successfully
|
|
27
|
+
And the message have the following fields and values:
|
|
28
|
+
| field | value |
|
|
29
|
+
| class | Pio::Features::Request |
|
|
30
|
+
| ofp_version | 4 |
|
|
31
|
+
| message_type | 5 |
|
|
32
|
+
| message_length | 8 |
|
|
33
|
+
| transaction_id | 123 |
|
|
34
|
+
| xid | 123 |
|
|
35
|
+
| body | |
|
|
36
|
+
|
|
37
|
+
Scenario: new(xid: 123)
|
|
38
|
+
When I try to create an OpenFlow message with:
|
|
39
|
+
"""
|
|
40
|
+
Pio::Features::Request.new(xid: 123)
|
|
41
|
+
"""
|
|
42
|
+
Then it should finish successfully
|
|
43
|
+
And the message have the following fields and values:
|
|
44
|
+
| field | value |
|
|
45
|
+
| class | Pio::Features::Request |
|
|
46
|
+
| ofp_version | 4 |
|
|
47
|
+
| message_type | 5 |
|
|
48
|
+
| message_length | 8 |
|
|
49
|
+
| transaction_id | 123 |
|
|
50
|
+
| xid | 123 |
|
|
51
|
+
| body | |
|
|
52
|
+
|
|
53
|
+
Scenario: new(xid: -1) and error
|
|
54
|
+
When I try to create an OpenFlow message with:
|
|
55
|
+
"""
|
|
56
|
+
Pio::Features::Request.new(xid: -1)
|
|
57
|
+
"""
|
|
58
|
+
Then it should fail with "ArgumentError", "Transaction ID should be an unsigned 32-bit integer."
|
|
59
|
+
|
|
60
|
+
Scenario: new(xid: 2**32) and error
|
|
61
|
+
When I try to create an OpenFlow message with:
|
|
62
|
+
"""
|
|
63
|
+
Pio::Features::Request.new(xid: 2**32)
|
|
64
|
+
"""
|
|
65
|
+
Then it should fail with "ArgumentError", "Transaction ID should be an unsigned 32-bit integer."
|
|
66
|
+
|
|
67
|
+
Scenario: new(unknown_attr: 'foo') and error
|
|
68
|
+
When I try to create an OpenFlow message with:
|
|
69
|
+
"""
|
|
70
|
+
Pio::Features::Request.new(unknown_attr: 'foo')
|
|
71
|
+
"""
|
|
72
|
+
Then it should fail with "RuntimeError", "Unknown keyword: unknown_attr"
|
|
73
|
+
|
|
74
|
+
Scenario: read
|
|
75
|
+
When I try to parse a file named "open_flow13/features_request.raw" with "Pio::Features::Request" class
|
|
76
|
+
Then it should finish successfully
|
|
77
|
+
And the message have the following fields and values:
|
|
78
|
+
| field | value |
|
|
79
|
+
| class | Pio::Features::Request |
|
|
80
|
+
| ofp_version | 4 |
|
|
81
|
+
| message_type | 5 |
|
|
82
|
+
| message_length | 8 |
|
|
83
|
+
| transaction_id | 0 |
|
|
84
|
+
| xid | 0 |
|
|
85
|
+
| body | |
|
|
86
|
+
|
|
87
|
+
Scenario: parse error
|
|
88
|
+
When I try to parse a file named "open_flow10/hello.raw" with "Pio::Features::Request" class
|
|
89
|
+
Then it should fail with "Pio::ParseError", "Invalid Features Request 1.3 message."
|
|
Binary file
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
Feature: Hello
|
|
2
|
-
|
|
1
|
+
Feature: Pio::Hello
|
|
2
|
+
Background:
|
|
3
|
+
Given I use OpenFlow 1.3
|
|
4
|
+
|
|
5
|
+
Scenario: new
|
|
3
6
|
When I try to create an OpenFlow message with:
|
|
4
7
|
"""
|
|
5
|
-
Pio::
|
|
8
|
+
Pio::Hello.new
|
|
6
9
|
"""
|
|
7
10
|
Then it should finish successfully
|
|
8
11
|
And the message have the following fields and values:
|
|
9
12
|
| field | value |
|
|
10
|
-
| class |
|
|
13
|
+
| class | Pio::Hello |
|
|
11
14
|
| ofp_version | 4 |
|
|
12
15
|
| message_type | 0 |
|
|
13
16
|
| message_length | 16 |
|
|
@@ -15,15 +18,15 @@ Feature: Hello
|
|
|
15
18
|
| xid | 0 |
|
|
16
19
|
| supported_versions | [:open_flow13] |
|
|
17
20
|
|
|
18
|
-
Scenario:
|
|
21
|
+
Scenario: new(transaction_id: 123)
|
|
19
22
|
When I try to create an OpenFlow message with:
|
|
20
23
|
"""
|
|
21
|
-
Pio::
|
|
24
|
+
Pio::Hello.new(transaction_id: 123)
|
|
22
25
|
"""
|
|
23
26
|
Then it should finish successfully
|
|
24
27
|
And the message have the following fields and values:
|
|
25
28
|
| field | value |
|
|
26
|
-
| class |
|
|
29
|
+
| class | Pio::Hello |
|
|
27
30
|
| ofp_version | 4 |
|
|
28
31
|
| message_type | 0 |
|
|
29
32
|
| message_length | 16 |
|
|
@@ -31,15 +34,15 @@ Feature: Hello
|
|
|
31
34
|
| xid | 123 |
|
|
32
35
|
| supported_versions | [:open_flow13] |
|
|
33
36
|
|
|
34
|
-
Scenario:
|
|
37
|
+
Scenario: new(xid: 123)
|
|
35
38
|
When I try to create an OpenFlow message with:
|
|
36
39
|
"""
|
|
37
|
-
Pio::
|
|
40
|
+
Pio::Hello.new(xid: 123)
|
|
38
41
|
"""
|
|
39
42
|
Then it should finish successfully
|
|
40
43
|
And the message have the following fields and values:
|
|
41
44
|
| field | value |
|
|
42
|
-
| class |
|
|
45
|
+
| class | Pio::Hello |
|
|
43
46
|
| ofp_version | 4 |
|
|
44
47
|
| message_type | 0 |
|
|
45
48
|
| message_length | 16 |
|
|
@@ -47,25 +50,25 @@ Feature: Hello
|
|
|
47
50
|
| xid | 123 |
|
|
48
51
|
| supported_versions | [:open_flow13] |
|
|
49
52
|
|
|
50
|
-
Scenario:
|
|
51
|
-
When I try to parse a file named "
|
|
53
|
+
Scenario: read (no version bitmap)
|
|
54
|
+
When I try to parse a file named "open_flow13/hello_no_version_bitmap.raw" with "Pio::Hello" class
|
|
52
55
|
Then it should finish successfully
|
|
53
56
|
And the message have the following fields and values:
|
|
54
|
-
| field |
|
|
55
|
-
| class | Pio::
|
|
56
|
-
| ofp_version |
|
|
57
|
-
| message_type |
|
|
58
|
-
| message_length |
|
|
59
|
-
| transaction_id |
|
|
60
|
-
| xid |
|
|
61
|
-
| supported_versions |
|
|
57
|
+
| field | value |
|
|
58
|
+
| class | Pio::Hello |
|
|
59
|
+
| ofp_version | 4 |
|
|
60
|
+
| message_type | 0 |
|
|
61
|
+
| message_length | 8 |
|
|
62
|
+
| transaction_id | 0 |
|
|
63
|
+
| xid | 0 |
|
|
64
|
+
| supported_versions | [] |
|
|
62
65
|
|
|
63
|
-
Scenario:
|
|
64
|
-
When I try to parse a file named "
|
|
66
|
+
Scenario: read
|
|
67
|
+
When I try to parse a file named "open_flow13/hello_version_bitmap.raw" with "Pio::Hello" class
|
|
65
68
|
Then it should finish successfully
|
|
66
69
|
And the message have the following fields and values:
|
|
67
70
|
| field | value |
|
|
68
|
-
| class |
|
|
71
|
+
| class | Pio::Hello |
|
|
69
72
|
| ofp_version | 4 |
|
|
70
73
|
| message_type | 0 |
|
|
71
74
|
| message_length | 16 |
|
data/features/{packet_data/hello13_no_version_bitmap.raw → open_flow13/hello_no_version_bitmap.raw}
RENAMED
|
File without changes
|
data/features/{packet_data/hello13_version_bitmap.raw → open_flow13/hello_version_bitmap.raw}
RENAMED
|
File without changes
|
|
@@ -11,9 +11,9 @@ When(/^I try to create an OpenFlow message with:$/) do |ruby_code|
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
# rubocop:disable LineLength
|
|
14
|
-
When(/^I try to parse a file named "(
|
|
15
|
-
|
|
16
|
-
raw_data = IO.read(
|
|
14
|
+
When(/^I try to parse a file named "(.*?\.raw)" with "(.*?)" class$/) do |path, klass|
|
|
15
|
+
full_path = File.expand_path(File.join(__dir__, '..', path))
|
|
16
|
+
raw_data = IO.read(full_path)
|
|
17
17
|
parser_klass = Pio.const_get(klass)
|
|
18
18
|
begin
|
|
19
19
|
@result = parser_klass.read(raw_data)
|
|
@@ -24,9 +24,9 @@ end
|
|
|
24
24
|
# rubocop:enable LineLength
|
|
25
25
|
|
|
26
26
|
# rubocop:disable LineLength
|
|
27
|
-
When(/^I try to parse a file named "(
|
|
28
|
-
|
|
29
|
-
pcap = Pio::Pcap::Frame.read(IO.read(
|
|
27
|
+
When(/^I try to parse a file named "(.*?\.pcap)" with "(.*?)" class$/) do |path, klass|
|
|
28
|
+
full_path = File.expand_path(File.join(__dir__, '..', path))
|
|
29
|
+
pcap = Pio::Pcap::Frame.read(IO.read(full_path))
|
|
30
30
|
parser_klass = Pio.const_get(klass)
|
|
31
31
|
begin
|
|
32
32
|
@result = pcap.records.each_with_object([]) do |each, result|
|
|
@@ -47,9 +47,9 @@ Then(/^it should fail with "([^"]*)", "([^"]*)"$/) do |error, message|
|
|
|
47
47
|
expect(@last_error.message).to eq(message)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
When(/^I create an exact match from "(.*?)"$/) do |
|
|
51
|
-
|
|
52
|
-
@result = Pio::ExactMatch.new(Pio::PacketIn.read(IO.read(
|
|
50
|
+
When(/^I create an exact match from "(.*?)"$/) do |path|
|
|
51
|
+
full_path = File.expand_path(File.join(__dir__, '..', path))
|
|
52
|
+
@result = Pio::ExactMatch.new(Pio::PacketIn.read(IO.read(full_path)))
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
Then(/^the packet have the following fields and values:$/) do |table|
|
data/features/udp.feature
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Feature:
|
|
2
|
-
Scenario: dhcp.pcap
|
|
3
|
-
When I try to parse a file named "dhcp.pcap" with "Udp" class
|
|
1
|
+
Feature: Pio::Udp
|
|
2
|
+
Scenario: parse dhcp.pcap
|
|
3
|
+
When I try to parse a file named "dhcp.pcap" with "Pio::Udp" class
|
|
4
4
|
Then it should finish successfully
|
|
5
5
|
And the message #1 have the following fields and values:
|
|
6
6
|
| field | value |
|
|
File without changes
|
|
File without changes
|
data/lib/pio.rb
CHANGED
|
@@ -2,16 +2,8 @@ require 'pio/parse_error'
|
|
|
2
2
|
|
|
3
3
|
require 'pio/arp'
|
|
4
4
|
require 'pio/dhcp'
|
|
5
|
-
require 'pio/echo'
|
|
6
|
-
require 'pio/exact_match'
|
|
7
|
-
require 'pio/features'
|
|
8
|
-
require 'pio/flow_mod'
|
|
9
|
-
require 'pio/hello'
|
|
10
|
-
require 'pio/hello13'
|
|
11
5
|
require 'pio/icmp'
|
|
12
6
|
require 'pio/lldp'
|
|
13
7
|
require 'pio/mac'
|
|
14
|
-
require 'pio/
|
|
15
|
-
require 'pio/packet_out'
|
|
16
|
-
require 'pio/port_status'
|
|
8
|
+
require 'pio/open_flow10'
|
|
17
9
|
require 'pio/udp'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require 'bindata'
|
|
2
2
|
require 'pio/enqueue'
|
|
3
3
|
require 'pio/send_out_port'
|
|
4
|
-
require 'pio/
|
|
5
|
-
require 'pio/
|
|
4
|
+
require 'pio/set_ether_address'
|
|
5
|
+
require 'pio/set_ip_address'
|
|
6
6
|
require 'pio/set_ip_tos'
|
|
7
7
|
require 'pio/set_transport_port'
|
|
8
8
|
require 'pio/set_vlan_priority'
|
|
@@ -18,13 +18,13 @@ module Pio
|
|
|
18
18
|
1 => Pio::SetVlanVid,
|
|
19
19
|
2 => Pio::SetVlanPriority,
|
|
20
20
|
3 => Pio::StripVlanHeader,
|
|
21
|
-
4 => Pio::
|
|
22
|
-
5 => Pio::
|
|
23
|
-
6 => Pio::
|
|
24
|
-
7 => Pio::
|
|
21
|
+
4 => Pio::SetEtherSourceAddr,
|
|
22
|
+
5 => Pio::SetEtherDestinationAddr,
|
|
23
|
+
6 => Pio::SetIpSourceAddress,
|
|
24
|
+
7 => Pio::SetIpDestinationAddress,
|
|
25
25
|
8 => Pio::SetIpTos,
|
|
26
|
-
9 => Pio::
|
|
27
|
-
10 => Pio::
|
|
26
|
+
9 => Pio::SetTransportSourcePort,
|
|
27
|
+
10 => Pio::SetTransportDestinationPort,
|
|
28
28
|
11 => Pio::Enqueue
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -2,6 +2,16 @@ require 'bindata'
|
|
|
2
2
|
require 'pio/open_flow/transaction_id'
|
|
3
3
|
|
|
4
4
|
module Pio
|
|
5
|
+
# OpenFlow message header parser
|
|
6
|
+
class OpenFlowHeaderParser < BinData::Record
|
|
7
|
+
endian :big
|
|
8
|
+
|
|
9
|
+
uint8 :ofp_version
|
|
10
|
+
uint8 :message_type
|
|
11
|
+
uint16 :message_length
|
|
12
|
+
transaction_id :transaction_id
|
|
13
|
+
end
|
|
14
|
+
|
|
5
15
|
# OpenFlow message header.
|
|
6
16
|
class OpenFlowHeader < BinData::Record
|
|
7
17
|
endian :big
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Pio
|
|
2
|
+
# OpenFlow specific types.
|
|
3
|
+
module OpenFlow
|
|
4
|
+
VERSION = 1
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
require 'pio/open_flow10/echo'
|
|
9
|
+
require 'pio/open_flow10/exact_match'
|
|
10
|
+
require 'pio/open_flow10/features'
|
|
11
|
+
require 'pio/open_flow10/flow_mod'
|
|
12
|
+
require 'pio/open_flow10/hello'
|
|
13
|
+
require 'pio/open_flow10/packet_in'
|
|
14
|
+
require 'pio/open_flow10/packet_out'
|
|
15
|
+
require 'pio/open_flow10/port_status'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
require 'pio/open_flow'
|
|
3
|
+
|
|
4
|
+
module Pio
|
|
5
|
+
# OpenFlow 1.0 Echo Request and Reply message.
|
|
6
|
+
module Echo
|
|
7
|
+
# OpenFlow 1.0 Echo Request message.
|
|
8
|
+
class Request; end
|
|
9
|
+
OpenFlow::Message.factory(Request, OpenFlow::ECHO_REQUEST)
|
|
10
|
+
|
|
11
|
+
# OpenFlow 1.0 Echo Reply message.
|
|
12
|
+
class Reply; end
|
|
13
|
+
OpenFlow::Message.factory(Reply, OpenFlow::ECHO_REPLY)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'pio/open_flow10/match'
|
|
2
|
+
|
|
3
|
+
module Pio
|
|
4
|
+
# OpenFlow 1.0 exact match
|
|
5
|
+
class ExactMatch
|
|
6
|
+
# rubocop:disable MethodLength
|
|
7
|
+
# rubocop:disable AbcSize
|
|
8
|
+
def initialize(packet_in)
|
|
9
|
+
data = packet_in.data
|
|
10
|
+
case data
|
|
11
|
+
when PacketIn::DataParser::IPv4Packet
|
|
12
|
+
options = {
|
|
13
|
+
in_port: packet_in.in_port,
|
|
14
|
+
ether_source_address: packet_in.source_mac,
|
|
15
|
+
ether_destination_address: packet_in.destination_mac,
|
|
16
|
+
vlan_vid: data.vlan_vid,
|
|
17
|
+
vlan_priority: data.vlan_pcp,
|
|
18
|
+
ether_type: data.ether_type,
|
|
19
|
+
ip_tos: data.ip_type_of_service,
|
|
20
|
+
ip_protocol: data.ip_protocol,
|
|
21
|
+
ip_source_address: data.ip_source_address,
|
|
22
|
+
ip_destination_address: data.ip_destination_address,
|
|
23
|
+
transport_source_port: data.transport_source_port,
|
|
24
|
+
transport_destination_port: data.transport_destination_port
|
|
25
|
+
}
|
|
26
|
+
when Arp::Request
|
|
27
|
+
options = {
|
|
28
|
+
in_port: packet_in.in_port,
|
|
29
|
+
ether_source_address: packet_in.source_mac,
|
|
30
|
+
ether_destination_address: packet_in.destination_mac,
|
|
31
|
+
vlan_vid: data.vlan_vid,
|
|
32
|
+
vlan_priority: data.vlan_pcp,
|
|
33
|
+
ether_type: data.ether_type,
|
|
34
|
+
ip_tos: 0,
|
|
35
|
+
ip_protocol: data.operation,
|
|
36
|
+
ip_source_address: data.sender_protocol_address,
|
|
37
|
+
ip_destination_address: data.target_protocol_address,
|
|
38
|
+
transport_source_port: 0,
|
|
39
|
+
transport_destination_port: 0
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
@match = Pio::Match.new(options)
|
|
43
|
+
end
|
|
44
|
+
# rubocop:enable MethodLength
|
|
45
|
+
# rubocop:enable AbcSize
|
|
46
|
+
|
|
47
|
+
def method_missing(method, *args, &block)
|
|
48
|
+
@match.__send__ method, *args, &block
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|