pio 0.21.1 → 0.22.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: d143e0e583d6916c1375465b6add97ae65ff1436
4
- data.tar.gz: ea651e9a42b7cd0df2077047e5d2c45dc985ef01
3
+ metadata.gz: 06006d882906e150385cbe2e7932eb0d741277ee
4
+ data.tar.gz: 8b4f1fefee8d39a6e1ce9d173ace7284d5535d9f
5
5
  SHA512:
6
- metadata.gz: dbb88254d9e82879c3b95ef23b29b146253bea2084b02500181cd170d78cbd7dc14f84c6e2affef58bc66b136f6319966f2f450a2bdc0c7ffb5db122f060306c
7
- data.tar.gz: 9e9a071f4e4d3970773b11ccfaaf0d11128389eedd960d033f8383964d324b077755e2825107b2b793ce0ef158ec8d473237bd155603d47cacffc5698045676b
6
+ metadata.gz: 0e70773ffec96c1647cccc8b2a93b262f9655e3c3294e1ca6ee911385279a2fdb293357402eb5abb7f25e462785499b775cb82424fa4bb32859f71a257273aaf
7
+ data.tar.gz: d3c9c2353d742e752924726a77f9f91ab24c1dfdfe5870b651409c1b990eb75723ace6a39289316032571407a4edaca75c8ecfe6bd38ce3cb6c5e6b1f8833af1
data/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  ## develop (unreleased)
4
4
 
5
5
 
6
+ ## 0.22.0 (6/25/2015)
7
+ ### New features
8
+ * [#177](https://github.com/trema/pio/pull/177): Add new class `Pio::PacketIn` (OpenFlow1.3).
9
+ * [#173](https://github.com/trema/pio/pull/173): Add new classes `Pio::Match::VlanVid`, `Pio::Match::VlanPcp`.
10
+ * [#174](https://github.com/trema/pio/pull/174): Add new classes `Pio::Match::IpDscp`, `Pio::Match::IpEcn`.
11
+ * [#178](https://github.com/trema/pio/pull/178): Add new classes `Pio::Match::SctpSourcePort`, `Pio::Match::SctpDestinationPort`.
12
+ * [#180](https://github.com/trema/pio/pull/180): Add new classes `Pio::Match::Icmpv4Type`, `Pio::Match::Icmpv4Code`.
13
+
14
+
6
15
  ## 0.21.1 (6/24/2015)
7
16
  ### Bugs fixed
8
17
  * [#179](https://github.com/trema/pio/pull/179): Fix wrong OXM length.
data/README.md CHANGED
@@ -35,6 +35,7 @@ supports the following packet formats:
35
35
  - [Echo Reply](https://relishapp.com/trema/pio/docs/open-flow13/pio-echo-reply)
36
36
  - [Features Request](https://relishapp.com/trema/pio/docs/open-flow13/pio-features-request)
37
37
  - [Features Reply](https://relishapp.com/trema/pio/docs/open-flow13/pio-features-reply)
38
+ - [Packet In](https://relishapp.com/trema/pio/docs/open-flow13/pio-packetin)
38
39
  - [Flow Mod](https://relishapp.com/trema/pio/docs/open-flow13/pio-flowmod)
39
40
 
40
41
  ## Features Overview
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'bundler/gem_tasks'
2
2
 
3
3
  RELISH_PROJECT = 'trema/pio'
4
- FLAY_THRESHOLD = 346
4
+ FLAY_THRESHOLD = 398
5
5
 
6
6
  task default: :travis
7
7
  task test: [:spec, :cucumber]
@@ -232,6 +232,54 @@ Feature: Pio::Match
232
232
  | ip_protocol | 17 |
233
233
  | udp_destination_port | 3333 |
234
234
 
235
+ Scenario: new(ether_type: 0x0800, ip_protocol: 132, sctp_source_port: 22)
236
+ When I try to create an OpenFlow message with:
237
+ """
238
+ Pio::Match.new(ether_type: 0x0800, ip_protocol: 132, sctp_source_port: 22)
239
+ """
240
+ Then it should finish successfully
241
+ And the message have the following fields and values:
242
+ | field | value |
243
+ | ether_type | 2048 |
244
+ | ip_protocol | 132 |
245
+ | sctp_source_port | 22 |
246
+
247
+ Scenario: new(ether_type: 0x0800, ip_protocol: 132, sctp_destination_port: 22)
248
+ When I try to create an OpenFlow message with:
249
+ """
250
+ Pio::Match.new(ether_type: 0x0800, ip_protocol: 132, sctp_destination_port: 22)
251
+ """
252
+ Then it should finish successfully
253
+ And the message have the following fields and values:
254
+ | field | value |
255
+ | ether_type | 2048 |
256
+ | ip_protocol | 132 |
257
+ | sctp_destination_port | 22 |
258
+
259
+ Scenario: new(ether_type: 0x0800, ip_protocol: 1, icmpv4_type: 8)
260
+ When I try to create an OpenFlow message with:
261
+ """
262
+ Pio::Match.new(ether_type: 0x0800, ip_protocol: 1, icmpv4_type: 8)
263
+ """
264
+ Then it should finish successfully
265
+ And the message have the following fields and values:
266
+ | field | value |
267
+ | ether_type | 2048 |
268
+ | ip_protocol | 1 |
269
+ | icmpv4_type | 8 |
270
+
271
+ Scenario: new(ether_type: 0x0800, ip_protocol: 1, icmpv4_code: 0)
272
+ When I try to create an OpenFlow message with:
273
+ """
274
+ Pio::Match.new(ether_type: 0x0800, ip_protocol: 1, icmpv4_code: 0)
275
+ """
276
+ Then it should finish successfully
277
+ And the message have the following fields and values:
278
+ | field | value |
279
+ | ether_type | 2048 |
280
+ | ip_protocol | 1 |
281
+ | icmpv4_code | 0 |
282
+
235
283
  Scenario: new(ether_type: 0x86dd, ipv6_source_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee')
236
284
  When I try to create an OpenFlow message with:
237
285
  """
@@ -445,6 +493,42 @@ Feature: Pio::Match
445
493
  | ip_protocol | 17 |
446
494
  | udp_destination_port | 3333 |
447
495
 
496
+ Scenario: read (file: open_flow13/oxm_sctp_source_field.raw)
497
+ When I try to parse a file named "open_flow13/oxm_sctp_source_field.raw" with "Pio::Match" class
498
+ Then it should finish successfully
499
+ And the message have the following fields and values:
500
+ | field | value |
501
+ | ether_type | 2048 |
502
+ | ip_protocol | 132 |
503
+ | sctp_source_port | 22 |
504
+
505
+ Scenario: read (file: open_flow13/oxm_sctp_destination_field.raw)
506
+ When I try to parse a file named "open_flow13/oxm_sctp_destination_field.raw" with "Pio::Match" class
507
+ Then it should finish successfully
508
+ And the message have the following fields and values:
509
+ | field | value |
510
+ | ether_type | 2048 |
511
+ | ip_protocol | 132 |
512
+ | sctp_destination_port | 22 |
513
+
514
+ Scenario: read (file: open_flow13/oxm_icmpv4_type_field.raw)
515
+ When I try to parse a file named "open_flow13/oxm_icmpv4_type_field.raw" with "Pio::Match" class
516
+ Then it should finish successfully
517
+ And the message have the following fields and values:
518
+ | field | value |
519
+ | ether_type | 2048 |
520
+ | ip_protocol | 1 |
521
+ | icmpv4_type | 8 |
522
+
523
+ Scenario: read (file: open_flow13/oxm_icmpv4_code_field.raw)
524
+ When I try to parse a file named "open_flow13/oxm_icmpv4_code_field.raw" with "Pio::Match" class
525
+ Then it should finish successfully
526
+ And the message have the following fields and values:
527
+ | field | value |
528
+ | ether_type | 2048 |
529
+ | ip_protocol | 1 |
530
+ | icmpv4_code | 0 |
531
+
448
532
  Scenario: read (file: open_flow13/oxm_ipv6_source_field.raw)
449
533
  When I try to parse a file named "open_flow13/oxm_ipv6_source_field.raw" with "Pio::Match" class
450
534
  Then it should finish successfully
@@ -0,0 +1,80 @@
1
+ Feature: Pio::PacketIn
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::PacketIn.new
9
+ """
10
+ Then it should finish successfully
11
+ And the message have the following fields and values:
12
+ | field | value |
13
+ | class | Pio::PacketIn |
14
+ | ofp_version | 4 |
15
+ | message_type | 10 |
16
+ | message_length | 34 |
17
+ | transaction_id | 0 |
18
+ | xid | 0 |
19
+ | buffer_id | 0 |
20
+ | total_len | 0 |
21
+ | reason | :no_match |
22
+ | table_id | 0 |
23
+ | cookie | 0 |
24
+ | match.match_fields.size | 0 |
25
+ | raw_data.length | 0 |
26
+
27
+ Scenario: new (raw_data = ARP request)
28
+ When I try to create an OpenFlow message with:
29
+ """
30
+ data_dump = [
31
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0x5d, 0x10, 0x31, 0x37,
32
+ 0x79, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
33
+ 0xac, 0x5d, 0x10, 0x31, 0x37, 0x79, 0xc0, 0xa8, 0x02, 0xfe, 0xff,
34
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa8, 0x02, 0x05, 0x00, 0x00,
35
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36
+ 0x00, 0x00, 0x00, 0x00, 0x00
37
+ ].pack('C*')
38
+
39
+ Pio::PacketIn.new(raw_data: data_dump)
40
+ """
41
+ Then it should finish successfully
42
+ And the message have the following fields and values:
43
+ | field | value |
44
+ | class | Pio::PacketIn |
45
+ | ofp_version | 4 |
46
+ | message_type | 10 |
47
+ | message_length | 94 |
48
+ | transaction_id | 0 |
49
+ | xid | 0 |
50
+ | buffer_id | 0 |
51
+ | total_len | 60 |
52
+ | reason | :no_match |
53
+ | table_id | 0 |
54
+ | cookie | 0 |
55
+ | match.match_fields.size | 0 |
56
+ | raw_data.length | 60 |
57
+ | source_mac | ac:5d:10:31:37:79 |
58
+ | destination_mac | ff:ff:ff:ff:ff:ff |
59
+
60
+ Scenario: read
61
+ When I try to parse a file named "open_flow13/packet_in.raw" with "PacketIn" class
62
+ Then it should finish successfully
63
+ And the message have the following fields and values:
64
+ | field | value |
65
+ | class | Pio::PacketIn |
66
+ | ofp_version | 4 |
67
+ | message_type | 10 |
68
+ | message_length | 102 |
69
+ | transaction_id | 123 |
70
+ | xid | 123 |
71
+ | buffer_id.to_hex | 0xcafebabe |
72
+ | total_len | 60 |
73
+ | reason | :no_match |
74
+ | table_id | 0 |
75
+ | cookie | 0 |
76
+ | match.match_fields.size | 1 |
77
+ | match.match_fields[0].in_port | 1 |
78
+ | raw_data.length | 60 |
79
+ | source_mac | ac:5d:10:31:37:79 |
80
+ | destination_mac | ff:ff:ff:ff:ff:ff |
Binary file
Binary file
@@ -1,4 +1,5 @@
1
1
  require 'pio/open_flow10/match'
2
+ require 'pio/parser'
2
3
 
3
4
  module Pio
4
5
  # OpenFlow 1.0 exact match
@@ -8,7 +9,7 @@ module Pio
8
9
  def initialize(packet_in)
9
10
  data = packet_in.data
10
11
  case data
11
- when PacketIn::DataParser::IPv4Packet
12
+ when Pio::Parser::IPv4Packet
12
13
  options = {
13
14
  in_port: packet_in.in_port,
14
15
  ether_source_address: packet_in.source_mac,
@@ -3,6 +3,7 @@ require 'pio/ethernet_header'
3
3
  require 'pio/ipv4_header'
4
4
  require 'pio/open_flow'
5
5
  require 'pio/parse_error'
6
+ require 'pio/parser'
6
7
 
7
8
  # Base module.
8
9
  module Pio
@@ -44,49 +45,6 @@ module Pio
44
45
  10 + raw_data.length
45
46
  end
46
47
  end
47
-
48
- # Pio::PacketIn#raw_data parser
49
- class DataParser
50
- # Ethernet header parser
51
- class EtherTypeParser < BinData::Record
52
- endian :big
53
-
54
- mac_address :destination_mac
55
- mac_address :source_mac
56
- uint16 :ether_type
57
- end
58
-
59
- # IPv4 packet parser
60
- class IPv4Packet < BinData::Record
61
- include EthernetHeader
62
- include IPv4Header
63
-
64
- endian :big
65
-
66
- ethernet_header ether_type: EtherType::IPV4
67
- ipv4_header
68
-
69
- uint16 :transport_source_port
70
- uint16 :transport_destination_port
71
- rest :rest
72
- end
73
-
74
- # rubocop:disable MethodLength
75
- def self.read(raw_data)
76
- ethernet_header = EtherTypeParser.read(raw_data)
77
- case ethernet_header.ether_type
78
- when EthernetHeader::EtherType::IPV4, EthernetHeader::EtherType::VLAN
79
- IPv4Packet.read raw_data
80
- when EthernetHeader::EtherType::ARP
81
- Pio::Arp.read raw_data
82
- when EthernetHeader::EtherType::LLDP
83
- Pio::Lldp.read raw_data
84
- else
85
- fail 'Failed to parse packet_in data.'
86
- end
87
- end
88
- # rubocop:enable MethodLength
89
- end
90
48
  end
91
49
 
92
50
  OpenFlow::Message.factory(PacketIn, OpenFlow::PACKET_IN) do
@@ -101,7 +59,7 @@ module Pio
101
59
  alias_method :dpid=, :datapath_id=
102
60
 
103
61
  def data
104
- @data ||= PacketIn::DataParser.read(raw_data)
62
+ @data ||= Pio::Parser.read(raw_data)
105
63
  end
106
64
 
107
65
  def lldp?
@@ -7,16 +7,17 @@ module Pio
7
7
  end
8
8
 
9
9
  require 'pio/open_flow13/apply'
10
- require 'pio/open_flow13/goto_table'
11
- require 'pio/open_flow13/write_metadata'
12
- require 'pio/open_flow13/meter'
13
10
  require 'pio/open_flow13/echo'
14
11
  require 'pio/open_flow13/features_reply'
15
12
  require 'pio/open_flow13/features_request'
16
13
  require 'pio/open_flow13/flow_mod'
14
+ require 'pio/open_flow13/goto_table'
17
15
  require 'pio/open_flow13/hello'
18
16
  require 'pio/open_flow13/match'
17
+ require 'pio/open_flow13/meter'
18
+ require 'pio/open_flow13/packet_in'
19
19
  require 'pio/open_flow13/send_out_port'
20
+ require 'pio/open_flow13/write_metadata'
20
21
 
21
22
  # Base module.
22
23
  module Pio
@@ -296,6 +296,58 @@ module Pio
296
296
  end
297
297
  end
298
298
 
299
+ # The value of OXM_OF_SCTP_SRC
300
+ class SctpSourcePort < BinData::Record
301
+ OXM_FIELD = 17
302
+
303
+ endian :big
304
+
305
+ uint16 :sctp_source_port
306
+
307
+ def length
308
+ 2
309
+ end
310
+ end
311
+
312
+ # The value of OXM_OF_SCTP_DST
313
+ class SctpDestinationPort < BinData::Record
314
+ OXM_FIELD = 18
315
+
316
+ endian :big
317
+
318
+ uint16 :sctp_destination_port
319
+
320
+ def length
321
+ 2
322
+ end
323
+ end
324
+
325
+ # The value of OXM_OF_ICMPV4_TYPE
326
+ class Icmpv4Type < BinData::Record
327
+ OXM_FIELD = 19
328
+
329
+ endian :big
330
+
331
+ uint8 :icmpv4_type
332
+
333
+ def length
334
+ 1
335
+ end
336
+ end
337
+
338
+ # The value of OXM_OF_ICMPV4_CODE
339
+ class Icmpv4Code < BinData::Record
340
+ OXM_FIELD = 20
341
+
342
+ endian :big
343
+
344
+ uint8 :icmpv4_code
345
+
346
+ def length
347
+ 1
348
+ end
349
+ end
350
+
299
351
  # The value of OXM_OF_IPV6_SRC
300
352
  class Ipv6SourceAddress < BinData::Record
301
353
  OXM_FIELD = 26
@@ -384,6 +436,10 @@ module Pio
384
436
  tcp_destination_port TcpDestinationPort
385
437
  udp_source_port UdpSourcePort
386
438
  udp_destination_port UdpDestinationPort
439
+ sctp_source_port SctpSourcePort
440
+ sctp_destination_port SctpDestinationPort
441
+ icmpv4_type Icmpv4Type
442
+ icmpv4_code Icmpv4Code
387
443
  ipv6_source_address Ipv6SourceAddress
388
444
  masked_ipv6_source_address MaskedIpv6SourceAddress
389
445
  ipv6_destination_address Ipv6DestinationAddress
@@ -442,6 +498,14 @@ module Pio
442
498
  UdpSourcePort
443
499
  when UdpDestinationPort::OXM_FIELD
444
500
  UdpDestinationPort
501
+ when SctpSourcePort::OXM_FIELD
502
+ SctpSourcePort
503
+ when SctpDestinationPort::OXM_FIELD
504
+ SctpDestinationPort
505
+ when Icmpv4Type::OXM_FIELD
506
+ Icmpv4Type
507
+ when Icmpv4Code::OXM_FIELD
508
+ Icmpv4Code
445
509
  when Ipv6SourceAddress::OXM_FIELD
446
510
  masked? ? MaskedIpv6SourceAddress : Ipv6SourceAddress
447
511
  when Ipv6DestinationAddress::OXM_FIELD
@@ -507,7 +571,8 @@ module Pio
507
571
 
508
572
  [:in_port, :ether_type, :ip_protocol, :vlan_vid, :vlan_pcp,
509
573
  :ip_dscp, :ip_ecn, :tcp_source_port, :tcp_destination_port,
510
- :udp_source_port, :udp_destination_port].each do |each|
574
+ :udp_source_port, :udp_destination_port, :sctp_source_port,
575
+ :sctp_destination_port, :icmpv4_type, :icmpv4_code].each do |each|
511
576
  next unless user_attrs.key?(each)
512
577
  klass = Match.const_get(each.to_s.split('_').map(&:capitalize).join)
513
578
  @match_fields << { oxm_field: klass.const_get(:OXM_FIELD),
@@ -0,0 +1,87 @@
1
+ # Base module.
2
+ module Pio
3
+ remove_const :PacketIn
4
+
5
+ # OpenFlow 1.3 PacketIn message parser and generator
6
+ class PacketIn
7
+ # OpenFlow 1.3 PacketIn message format
8
+ class Format < BinData::Record
9
+ # OpenFlow 1.3 PacketIn message body
10
+ class Body < BinData::Record
11
+ # Why is this packet being sent to the controller?
12
+ # (enum ofp_packet_in_reason)
13
+ class Reason < BinData::Primitive
14
+ REASONS = { no_match: 0, action: 1, invalid_ttl: 2 }
15
+
16
+ uint8 :reason
17
+
18
+ def get
19
+ REASONS.invert.fetch(reason)
20
+ end
21
+
22
+ def set(value)
23
+ self.reason = REASONS.fetch(value)
24
+ end
25
+ end
26
+
27
+ endian :big
28
+
29
+ uint32 :buffer_id
30
+ uint16 :total_len, initial_value: -> { raw_data.length }
31
+ reason :reason
32
+ uint8 :table_id
33
+ uint64 :cookie
34
+ oxm :match
35
+ string :padding, length: 2
36
+ hide :padding
37
+ string :raw_data, read_length: :total_len
38
+
39
+ def length
40
+ 16 + match.length + padding.length + raw_data.length
41
+ end
42
+
43
+ def data
44
+ @data ||= Pio::Parser.read(raw_data)
45
+ end
46
+
47
+ def method_missing(method, *args)
48
+ data.__send__(method, *args).snapshot
49
+ end
50
+ end
51
+
52
+ extend Forwardable
53
+
54
+ endian :big
55
+
56
+ open_flow_header :open_flow_header,
57
+ ofp_version_value: 4, message_type_value: 10
58
+ body :body
59
+
60
+ def_delegators :open_flow_header, :ofp_version
61
+ def_delegators :open_flow_header, :message_type
62
+ def_delegators :open_flow_header, :message_length
63
+ def_delegators :open_flow_header, :transaction_id
64
+ def_delegator :open_flow_header, :transaction_id, :xid
65
+
66
+ def method_missing(method, *args, &block)
67
+ body.__send__ method, *args, &block
68
+ end
69
+ end
70
+
71
+ def self.read(raw_data)
72
+ allocate.tap do |message|
73
+ message.instance_variable_set(:@format, Format.read(raw_data))
74
+ end
75
+ end
76
+
77
+ def initialize(user_attrs = {})
78
+ header_attrs = OpenFlowHeader::Options.parse(user_attrs)
79
+ body_attrs = { raw_data: user_attrs[:raw_data] }
80
+ @format = Format.new(open_flow_header: header_attrs, body: body_attrs)
81
+ end
82
+
83
+ def method_missing(method, *args, &block)
84
+ @format.__send__ method, *args, &block
85
+ end
86
+ end
87
+ end
data/lib/pio/parser.rb ADDED
@@ -0,0 +1,44 @@
1
+ module Pio
2
+ # Raw data parser.
3
+ class Parser
4
+ # Ethernet header parser
5
+ class EtherTypeParser < BinData::Record
6
+ endian :big
7
+
8
+ mac_address :destination_mac
9
+ mac_address :source_mac
10
+ uint16 :ether_type
11
+ end
12
+
13
+ # IPv4 packet parser
14
+ class IPv4Packet < BinData::Record
15
+ include EthernetHeader
16
+ include IPv4Header
17
+
18
+ endian :big
19
+
20
+ ethernet_header ether_type: EtherType::IPV4
21
+ ipv4_header
22
+
23
+ uint16 :transport_source_port
24
+ uint16 :transport_destination_port
25
+ rest :rest
26
+ end
27
+
28
+ # rubocop:disable MethodLength
29
+ def self.read(raw_data)
30
+ ethernet_header = EtherTypeParser.read(raw_data)
31
+ case ethernet_header.ether_type
32
+ when EthernetHeader::EtherType::IPV4, EthernetHeader::EtherType::VLAN
33
+ IPv4Packet.read raw_data
34
+ when EthernetHeader::EtherType::ARP
35
+ Pio::Arp.read raw_data
36
+ when EthernetHeader::EtherType::LLDP
37
+ Pio::Lldp.read raw_data
38
+ else
39
+ fail 'Failed to parse packet_in data.'
40
+ end
41
+ end
42
+ # rubocop:enable MethodLength
43
+ end
44
+ end
data/lib/pio/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # Base module.
2
2
  module Pio
3
3
  # gem version.
4
- VERSION = '0.21.1'.freeze
4
+ VERSION = '0.22.0'.freeze
5
5
  end
data/pio.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |gem|
31
31
  gem.add_dependency 'bindata', '~> 2.1.0'
32
32
 
33
33
  gem.add_development_dependency 'rake'
34
- gem.add_development_dependency 'bundler', '~> 1.10.3'
34
+ gem.add_development_dependency 'bundler', '~> 1.10.5'
35
35
  gem.add_development_dependency 'pry', '~> 0.10.1'
36
36
 
37
37
  # Guard
@@ -46,18 +46,18 @@ Gem::Specification.new do |gem|
46
46
  gem.add_development_dependency 'terminal-notifier-guard', '~> 1.6.4'
47
47
 
48
48
  # Docs
49
- gem.add_development_dependency 'inch', '~> 0.6.2'
49
+ gem.add_development_dependency 'inch', '~> 0.6.3'
50
50
  gem.add_development_dependency 'relish', '~> 0.7.1'
51
51
  gem.add_development_dependency 'yard', '~> 0.8.7.6'
52
52
 
53
53
  # Test
54
54
  gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.7'
55
- gem.add_development_dependency 'coveralls', '~> 0.8.1'
55
+ gem.add_development_dependency 'coveralls', '~> 0.8.2'
56
56
  gem.add_development_dependency 'cucumber', '~> 2.0.0'
57
57
  gem.add_development_dependency 'flay', '~> 2.6.1'
58
58
  gem.add_development_dependency 'flog', '~> 4.3.2'
59
59
  gem.add_development_dependency 'reek', '~> 2.2.1'
60
- gem.add_development_dependency 'rspec', '~> 3.2.0'
60
+ gem.add_development_dependency 'rspec', '~> 3.3.0'
61
61
  gem.add_development_dependency 'rspec-given', '~> 3.7.0'
62
- gem.add_development_dependency 'rubocop', '~> 0.32.0'
62
+ gem.add_development_dependency 'rubocop', '~> 0.32.1'
63
63
  end
@@ -291,6 +291,118 @@ describe Pio::OpenFlow13::Match do
291
291
  And { match.match_fields[1].masked? == false }
292
292
  And { match.match_fields[1].oxm_length == 4 }
293
293
  end
294
+
295
+ context 'with ether_type: 0x0800, ip_protocol: 132, sctp_source_port: 22' do
296
+ When(:match) do
297
+ Pio::OpenFlow13::Match.new(
298
+ ether_type: 0x0800,
299
+ ip_protocol: 132,
300
+ sctp_source_port: 22
301
+ )
302
+ end
303
+ Then { match.ether_type == 0x0800 }
304
+ Then { match.ip_protocol == 132 }
305
+ Then { match.sctp_source_port == 22 }
306
+ And { match.class == Pio::OpenFlow13::Match }
307
+ And { match.length == 24 }
308
+ And { match.match_type == Pio::OpenFlow13::MATCH_TYPE_OXM }
309
+ And { match.match_length == 21 }
310
+ And { match.match_fields.size == 3 }
311
+ And do
312
+ match.match_fields[2].oxm_class ==
313
+ Pio::OpenFlow13::Match::OXM_CLASS_OPENFLOW_BASIC
314
+ end
315
+ And do
316
+ match.match_fields[2].oxm_field ==
317
+ Pio::OpenFlow13::Match::SctpSourcePort::OXM_FIELD
318
+ end
319
+ And { match.match_fields[2].masked? == false }
320
+ And { match.match_fields[0].oxm_length == 2 }
321
+ end
322
+
323
+ context 'with ether_type: 0x0800, ip_protocol: 132, sctp_destination_port: 22' do
324
+ When(:match) do
325
+ Pio::OpenFlow13::Match.new(
326
+ ether_type: 0x0800,
327
+ ip_protocol: 132,
328
+ sctp_destination_port: 22
329
+ )
330
+ end
331
+ Then { match.ether_type == 0x0800 }
332
+ Then { match.ip_protocol == 132 }
333
+ Then { match.sctp_destination_port == 22 }
334
+ And { match.class == Pio::OpenFlow13::Match }
335
+ And { match.length == 24 }
336
+ And { match.match_type == Pio::OpenFlow13::MATCH_TYPE_OXM }
337
+ And { match.match_length == 21 }
338
+ And { match.match_fields.size == 3 }
339
+ And do
340
+ match.match_fields[2].oxm_class ==
341
+ Pio::OpenFlow13::Match::OXM_CLASS_OPENFLOW_BASIC
342
+ end
343
+ And do
344
+ match.match_fields[2].oxm_field ==
345
+ Pio::OpenFlow13::Match::SctpDestinationPort::OXM_FIELD
346
+ end
347
+ And { match.match_fields[2].masked? == false }
348
+ And { match.match_fields[0].oxm_length == 2 }
349
+ end
350
+
351
+ context 'with ether_type: 0x0800, ip_protocol: 1, icmpv4_type: 8' do
352
+ When(:match) do
353
+ Pio::OpenFlow13::Match.new(
354
+ ether_type: 0x0800,
355
+ ip_protocol: 1,
356
+ icmpv4_type: 8
357
+ )
358
+ end
359
+ Then { match.ether_type == 0x0800 }
360
+ Then { match.ip_protocol == 1 }
361
+ Then { match.icmpv4_type == 8 }
362
+ And { match.class == Pio::OpenFlow13::Match }
363
+ And { match.length == 24 }
364
+ And { match.match_type == Pio::OpenFlow13::MATCH_TYPE_OXM }
365
+ And { match.match_length == 20 }
366
+ And { match.match_fields.size == 3 }
367
+ And do
368
+ match.match_fields[2].oxm_class ==
369
+ Pio::OpenFlow13::Match::OXM_CLASS_OPENFLOW_BASIC
370
+ end
371
+ And do
372
+ match.match_fields[2].oxm_field ==
373
+ Pio::OpenFlow13::Match::Icmpv4Type::OXM_FIELD
374
+ end
375
+ And { match.match_fields[2].masked? == false }
376
+ And { match.match_fields[2].oxm_length == 1 }
377
+ end
378
+
379
+ context 'with ether_type: 0x0800, ip_protocol: 1, icmpv4_code: 0' do
380
+ When(:match) do
381
+ Pio::OpenFlow13::Match.new(
382
+ ether_type: 0x0800,
383
+ ip_protocol: 1,
384
+ icmpv4_code: 0
385
+ )
386
+ end
387
+ Then { match.ether_type == 0x0800 }
388
+ Then { match.ip_protocol == 1 }
389
+ Then { match.icmpv4_code == 0 }
390
+ And { match.class == Pio::OpenFlow13::Match }
391
+ And { match.length == 24 }
392
+ And { match.match_type == Pio::OpenFlow13::MATCH_TYPE_OXM }
393
+ And { match.match_length == 20 }
394
+ And { match.match_fields.size == 3 }
395
+ And do
396
+ match.match_fields[2].oxm_class ==
397
+ Pio::OpenFlow13::Match::OXM_CLASS_OPENFLOW_BASIC
398
+ end
399
+ And do
400
+ match.match_fields[2].oxm_field ==
401
+ Pio::OpenFlow13::Match::Icmpv4Code::OXM_FIELD
402
+ end
403
+ And { match.match_fields[2].masked? == false }
404
+ And { match.match_fields[2].oxm_length == 1 }
405
+ end
294
406
  end
295
407
 
296
408
  def read_raw_data_file(name)
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.21.1
4
+ version: 0.22.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-06-24 00:00:00.000000000 Z
11
+ date: 2015-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: 1.10.3
47
+ version: 1.10.5
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: 1.10.3
54
+ version: 1.10.5
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - ~>
200
200
  - !ruby/object:Gem::Version
201
- version: 0.6.2
201
+ version: 0.6.3
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - ~>
207
207
  - !ruby/object:Gem::Version
208
- version: 0.6.2
208
+ version: 0.6.3
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: relish
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -254,14 +254,14 @@ dependencies:
254
254
  requirements:
255
255
  - - ~>
256
256
  - !ruby/object:Gem::Version
257
- version: 0.8.1
257
+ version: 0.8.2
258
258
  type: :development
259
259
  prerelease: false
260
260
  version_requirements: !ruby/object:Gem::Requirement
261
261
  requirements:
262
262
  - - ~>
263
263
  - !ruby/object:Gem::Version
264
- version: 0.8.1
264
+ version: 0.8.2
265
265
  - !ruby/object:Gem::Dependency
266
266
  name: cucumber
267
267
  requirement: !ruby/object:Gem::Requirement
@@ -324,14 +324,14 @@ dependencies:
324
324
  requirements:
325
325
  - - ~>
326
326
  - !ruby/object:Gem::Version
327
- version: 3.2.0
327
+ version: 3.3.0
328
328
  type: :development
329
329
  prerelease: false
330
330
  version_requirements: !ruby/object:Gem::Requirement
331
331
  requirements:
332
332
  - - ~>
333
333
  - !ruby/object:Gem::Version
334
- version: 3.2.0
334
+ version: 3.3.0
335
335
  - !ruby/object:Gem::Dependency
336
336
  name: rspec-given
337
337
  requirement: !ruby/object:Gem::Requirement
@@ -352,14 +352,14 @@ dependencies:
352
352
  requirements:
353
353
  - - ~>
354
354
  - !ruby/object:Gem::Version
355
- version: 0.32.0
355
+ version: 0.32.1
356
356
  type: :development
357
357
  prerelease: false
358
358
  version_requirements: !ruby/object:Gem::Requirement
359
359
  requirements:
360
360
  - - ~>
361
361
  - !ruby/object:Gem::Version
362
- version: 0.32.0
362
+ version: 0.32.1
363
363
  description: Pure ruby packet parser and generator.
364
364
  email:
365
365
  - yasuhito@gmail.com
@@ -514,6 +514,8 @@ files:
514
514
  - features/open_flow13/oxm_ether_destination_field.raw
515
515
  - features/open_flow13/oxm_ether_source_field.raw
516
516
  - features/open_flow13/oxm_ether_type_field.raw
517
+ - features/open_flow13/oxm_icmpv4_code_field.raw
518
+ - features/open_flow13/oxm_icmpv4_type_field.raw
517
519
  - features/open_flow13/oxm_in_phy_port_field.raw
518
520
  - features/open_flow13/oxm_in_port_field.raw
519
521
  - features/open_flow13/oxm_ip_dscp_field.raw
@@ -531,6 +533,8 @@ files:
531
533
  - features/open_flow13/oxm_metadata_field.raw
532
534
  - features/open_flow13/oxm_metadata_masked_field.raw
533
535
  - features/open_flow13/oxm_no_fields.raw
536
+ - features/open_flow13/oxm_sctp_destination_field.raw
537
+ - features/open_flow13/oxm_sctp_source_field.raw
534
538
  - features/open_flow13/oxm_tcp_destination_field.raw
535
539
  - features/open_flow13/oxm_tcp_field.raw
536
540
  - features/open_flow13/oxm_tcp_source_field.raw
@@ -539,6 +543,9 @@ files:
539
543
  - features/open_flow13/oxm_udp_source_field.raw
540
544
  - features/open_flow13/oxm_vlan_pcp_field.raw
541
545
  - features/open_flow13/oxm_vlan_vid_field.raw
546
+ - features/open_flow13/packet_in.feature
547
+ - features/open_flow13/packet_in.raw
548
+ - features/open_flow13/packet_out.raw
542
549
  - features/open_flow13/send_out_port.feature
543
550
  - features/open_flow13/send_out_port.raw
544
551
  - features/open_flow13/write_metadata.feature
@@ -638,10 +645,12 @@ files:
638
645
  - lib/pio/open_flow13/hello.rb
639
646
  - lib/pio/open_flow13/match.rb
640
647
  - lib/pio/open_flow13/meter.rb
648
+ - lib/pio/open_flow13/packet_in.rb
641
649
  - lib/pio/open_flow13/send_out_port.rb
642
650
  - lib/pio/open_flow13/write_metadata.rb
643
651
  - lib/pio/options.rb
644
652
  - lib/pio/parse_error.rb
653
+ - lib/pio/parser.rb
645
654
  - lib/pio/payload.rb
646
655
  - lib/pio/pcap.rb
647
656
  - lib/pio/type/ip_address.rb
@@ -857,6 +866,8 @@ test_files:
857
866
  - features/open_flow13/oxm_ether_destination_field.raw
858
867
  - features/open_flow13/oxm_ether_source_field.raw
859
868
  - features/open_flow13/oxm_ether_type_field.raw
869
+ - features/open_flow13/oxm_icmpv4_code_field.raw
870
+ - features/open_flow13/oxm_icmpv4_type_field.raw
860
871
  - features/open_flow13/oxm_in_phy_port_field.raw
861
872
  - features/open_flow13/oxm_in_port_field.raw
862
873
  - features/open_flow13/oxm_ip_dscp_field.raw
@@ -874,6 +885,8 @@ test_files:
874
885
  - features/open_flow13/oxm_metadata_field.raw
875
886
  - features/open_flow13/oxm_metadata_masked_field.raw
876
887
  - features/open_flow13/oxm_no_fields.raw
888
+ - features/open_flow13/oxm_sctp_destination_field.raw
889
+ - features/open_flow13/oxm_sctp_source_field.raw
877
890
  - features/open_flow13/oxm_tcp_destination_field.raw
878
891
  - features/open_flow13/oxm_tcp_field.raw
879
892
  - features/open_flow13/oxm_tcp_source_field.raw
@@ -882,6 +895,9 @@ test_files:
882
895
  - features/open_flow13/oxm_udp_source_field.raw
883
896
  - features/open_flow13/oxm_vlan_pcp_field.raw
884
897
  - features/open_flow13/oxm_vlan_vid_field.raw
898
+ - features/open_flow13/packet_in.feature
899
+ - features/open_flow13/packet_in.raw
900
+ - features/open_flow13/packet_out.raw
885
901
  - features/open_flow13/send_out_port.feature
886
902
  - features/open_flow13/send_out_port.raw
887
903
  - features/open_flow13/write_metadata.feature