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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0a56473e633e294a1756d819645ccee51e6440cd
4
- data.tar.gz: 8d6d9fc9c7625281475858f76e090a9e4f1038d6
3
+ metadata.gz: 2bb4195ca95f655a64ce7c02ec9884a3bad1fd7c
4
+ data.tar.gz: 33cd84c8eb3e5289672c80e27d27b9c189b71303
5
5
  SHA512:
6
- metadata.gz: 1fadec47b009cab08eb3565b864952f050aa2a82477b2e9298a760691958fc998cdcf34ddc5fdbade680b5849e9e79c6ee61b8ab452b43e803ec64c3bfda93df
7
- data.tar.gz: 5dcb89e55d28bc69dd59325829ac1bb740bfbde2516980aa41af5f15aafb01fac17e3f6d4224503e5c18a07f05a9c38473735076192863c6bf2ddbec1b6663e3
6
+ metadata.gz: cea7f5346912379c9f0cf5800a8f57d997694126679c241dacefaeb0f4bcc0597f5debfd63ca151d8e2226418b59beba0aa8fabab5cb60068f4ba0751dffedad
7
+ data.tar.gz: 98b9e42fc3995ba700d0d1d75bc852bd3bd9a4a1c30b538802b6b56b8d80f95ce53d0711226bd778aca87d1f7d3736976d124fd98add04843302a6d8847c2e12
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## develop (unreleased)
4
+
5
+
6
+ ## 0.12.0 (2/5/2015)
7
+
8
+ ### New features
9
+ * [#123](https://github.com/trema/pio/pull/123): Add new class `Pio::ExactMatch`.
10
+
11
+
3
12
  ## 0.11.2 (1/29/2015)
4
13
 
5
14
  ### Bugs fixed
@@ -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 |
@@ -1,6 +1,6 @@
1
1
  Feature: Pio::PacketIn.read
2
- Scenario: packet_in.raw
3
- Given a packet data file "packet_in.raw"
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
@@ -3,6 +3,7 @@ require 'pio/parse_error'
3
3
  require 'pio/arp'
4
4
  require 'pio/dhcp'
5
5
  require 'pio/echo'
6
+ require 'pio/exact_match'
6
7
  require 'pio/features'
7
8
  require 'pio/flow_mod'
8
9
  require 'pio/hello'
@@ -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
@@ -26,10 +26,8 @@ module Pio
26
26
  @value = IPAddr.new(addr, Socket::AF_INET)
27
27
  when String
28
28
  @value = IPAddr.new(addr)
29
- when IPv4Address
30
- @value = addr.value
31
29
  else
32
- fail TypeError, "Invalid IPv4 address: #{addr.inspect}"
30
+ @value = addr.value
33
31
  end
34
32
  end
35
33
 
@@ -4,13 +4,40 @@ module Pio
4
4
  module Type
5
5
  # Adds ethernet_header macro.
6
6
  module EthernetHeader
7
- def ethernet_header(options)
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 :ether_type, value: options[:ether_type]
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
@@ -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, value: options[: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
@@ -1,5 +1,5 @@
1
1
  # Base module.
2
2
  module Pio
3
3
  # gem version.
4
- VERSION = '0.11.2'.freeze
4
+ VERSION = '0.12.0'.freeze
5
5
  end
@@ -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.3'
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.0'
63
- gem.add_development_dependency 'flog', '~> 4.3.1'
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.1.0'
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.11.2
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-01-29 00:00:00.000000000 Z
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.3
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.3
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.0
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.0
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.1
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.1
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.1.0
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.1.0
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/packet_in.raw
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.4.3
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