pio 0.21.1 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
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