pio 0.8.2 → 0.9.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: cf86d154a2025304879d8c6d252b71a2eda73ef8
4
- data.tar.gz: 18e3dda3e1ca8061b51d9ef4d8db29e0ffbde9c8
3
+ metadata.gz: ddcd50819881ef3e84f8efe948b846b346527afc
4
+ data.tar.gz: 8e66cab7abcc66b81908bc278fc4a0ac3b91519f
5
5
  SHA512:
6
- metadata.gz: 3a66499af05e0a468ca0d272237d6fabf489f868407d78d62c43083d30b2c7ee01e3b66cdff45533adb44e6aa11a45027e0074934a0b551de68188a53cd0cad9
7
- data.tar.gz: 49e01b280cddef5a2400f46a19ef1d622c0da2eeeb4165c1a53fdc5e86b892b95110b027868c6def6f92127dfd95f395bb86ea51b2f162b66e7014688e90ebcb
6
+ metadata.gz: f12db68f58ac7b90230f5fd4fb190ec0d939ad9c2895305393066b08e37d8ad5aa3604558f179fc5d29f8b5c25beb26faa4697b3ecfdb8cda2c856d718ba9cb6
7
+ data.tar.gz: 969ee297aa80eb58ad0e5f3a3aff999f49aea84eb2ef88db78058bc77aed050154faaa43eeb78530641bd336024efed1044589b8c8e7a12771c0d5be5bcd5b84
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.0 (12/22/2014)
4
+
5
+ ### New features
6
+ * [#102](https://github.com/trema/pio/pull/102): Added new class `Pio::PacketIn`.
7
+
8
+
3
9
  ## 0.8.2 (12/18/2014)
4
10
 
5
11
  ### Bugs fixed
data/README.md CHANGED
@@ -21,6 +21,7 @@ supports the following packet formats:
21
21
  - Hello
22
22
  - Echo
23
23
  - Features
24
+ - Packet-In
24
25
  - (…currently there are just a few formats supported but I'm sure this list will grow)
25
26
 
26
27
  ## Features Overview
@@ -248,6 +249,41 @@ generate an Features Request/Reply message like below:
248
249
  )
249
250
  reply.to_binary # => Features Reply message in binary format.
250
251
 
252
+ ### Packet-In
253
+
254
+ To parse an OpenFlow 1.0 Packet-In message, use the API
255
+ `Pio::PacketIn.read` and you can access each field of the parsed
256
+ Packet-In message.
257
+
258
+ require 'pio'
259
+
260
+ packet_in = Pio::PacketIn.read(binary_data)
261
+ packet_in.in_port # => 1
262
+ packet_in.buffer_id # => 4294967040
263
+
264
+ Also you can use `Pio::PacketIn#new` to generate a Packet-In message
265
+ like below:
266
+
267
+ require 'pio'
268
+
269
+ data_dump = [
270
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0x5d, 0x10, 0x31, 0x37,
271
+ 0x79, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
272
+ 0xac, 0x5d, 0x10, 0x31, 0x37, 0x79, 0xc0, 0xa8, 0x02, 0xfe, 0xff,
273
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa8, 0x02, 0x05, 0x00, 0x00,
274
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275
+ 0x00, 0x00, 0x00, 0x00, 0x00
276
+ ].pack('C*')
277
+
278
+ packet_in = Pio::PacketIn.new(
279
+ transaction_id: 0,
280
+ buffer_id: 0xffffff00,
281
+ in_port: 1,
282
+ reason: :no_match,
283
+ data: data_dump
284
+ )
285
+ packet_in.to_binary # => Packet-In message in binary format.
286
+
251
287
  ## Installation
252
288
 
253
289
  The simplest way to install Pio is to use [Bundler](http://gembundler.com/).
@@ -0,0 +1,19 @@
1
+ require 'pio'
2
+
3
+ data_dump = [
4
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0x5d, 0x10, 0x31, 0x37,
5
+ 0x79, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
6
+ 0xac, 0x5d, 0x10, 0x31, 0x37, 0x79, 0xc0, 0xa8, 0x02, 0xfe, 0xff,
7
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa8, 0x02, 0x05, 0x00, 0x00,
8
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9
+ 0x00, 0x00, 0x00, 0x00, 0x00
10
+ ].pack('C*')
11
+
12
+ packet_in = Pio::PacketIn.new(
13
+ transaction_id: 0,
14
+ buffer_id: 0xffffff00,
15
+ in_port: 1,
16
+ reason: :no_match,
17
+ data: data_dump
18
+ )
19
+ packet_in.to_binary # => Packet-In message in binary format.
@@ -0,0 +1,5 @@
1
+ require 'pio'
2
+
3
+ packet_in = Pio::PacketIn.read(binary_data)
4
+ packet_in.in_port # => 1
5
+ packet_in.buffer_id # => 4294967040
@@ -0,0 +1,5 @@
1
+ Feature: Pio::PacketIn.read
2
+ Scenario: packet_in.raw
3
+ Given a packet data file "packet_in.raw"
4
+ When I try to parse the file with "PacketIn" class
5
+ Then it should finish successfully
data/lib/pio.rb CHANGED
@@ -8,3 +8,4 @@ require 'pio/hello'
8
8
  require 'pio/icmp'
9
9
  require 'pio/lldp'
10
10
  require 'pio/mac'
11
+ require 'pio/packet_in'
@@ -7,6 +7,7 @@ module Pio
7
7
  ECHO_REPLY = 3
8
8
  FEATURES_REQUEST = 5
9
9
  FEATURES_REPLY = 6
10
+ PACKET_IN = 10
10
11
  end
11
12
  end
12
13
  end
@@ -0,0 +1,28 @@
1
+ require 'pio/packet_in/format'
2
+ require 'pio/parse_error'
3
+
4
+ module Pio
5
+ # OpenFlow 1.0 Packet-In message
6
+ class PacketIn
7
+ def self.read(raw_data)
8
+ packet_in = allocate
9
+ packet_in.instance_variable_set :@format, Format.read(raw_data)
10
+ packet_in
11
+ rescue BinData::ValidityError
12
+ raise Pio::ParseError, 'Invalid Packet-In message.'
13
+ end
14
+
15
+ def_delegators :body, :buffer_id
16
+ def_delegators :body, :total_len
17
+ def_delegators :body, :in_port
18
+ def_delegators :body, :reason
19
+ def_delegators :body, :data
20
+
21
+ # @reek This method smells of :reek:FeatureEnvy
22
+ def initialize(user_options)
23
+ header_options = { transaction_id: user_options[:transaction_id] ||
24
+ user_options[:xid] || 0 }
25
+ @format = Format.new(open_flow_header: header_options, body: user_options)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,55 @@
1
+ require 'bindata'
2
+ require 'pio/open_flow'
3
+
4
+ module Pio
5
+ class PacketIn < Pio::OpenFlow::Message
6
+ # Why is this packet being sent to the controller?
7
+ # (enum ofp_packet_in_reason)
8
+ class Reason < BinData::Primitive
9
+ REASONS = { no_match: 0, action: 1 }
10
+
11
+ uint8 :reason
12
+
13
+ def get
14
+ REASONS.invert.fetch(reason)
15
+ end
16
+
17
+ def set(value)
18
+ self.reason = REASONS.fetch(value)
19
+ end
20
+ end
21
+
22
+ # Message body of Packet-In.
23
+ class Body < BinData::Record
24
+ endian :big
25
+
26
+ uint32 :buffer_id
27
+ uint16 :total_len, value: -> { data.length }
28
+ uint16 :in_port
29
+ reason :reason
30
+ uint8 :padding
31
+ hide :padding
32
+ string :data, read_length: :total_len
33
+
34
+ def empty?
35
+ false
36
+ end
37
+
38
+ def length
39
+ 10 + data.length
40
+ end
41
+ end
42
+
43
+ # OpenFlow 1.0 Packet-In message parser and generator.
44
+ class Format < BinData::Record
45
+ include Pio::OpenFlow::Type
46
+
47
+ endian :big
48
+
49
+ open_flow_header :open_flow_header, message_type_value: PACKET_IN
50
+ virtual assert: -> { open_flow_header.message_type == PACKET_IN }
51
+
52
+ body :body
53
+ end
54
+ end
55
+ end
@@ -1,5 +1,5 @@
1
1
  # Base module.
2
2
  module Pio
3
3
  # gem version.
4
- VERSION = '0.8.2'.freeze
4
+ VERSION = '0.9.0'.freeze
5
5
  end
@@ -37,14 +37,14 @@ Gem::Specification.new do |gem|
37
37
  gem.add_dependency 'bindata', '~> 2.1.0'
38
38
 
39
39
  gem.add_development_dependency 'rake'
40
- gem.add_development_dependency 'bundler', '~> 1.7.6'
40
+ gem.add_development_dependency 'bundler', '~> 1.7.9'
41
41
  gem.add_development_dependency 'pry', '~> 0.10.1'
42
42
 
43
43
  # Guard
44
- gem.add_development_dependency 'guard', '~> 2.8.2'
45
- gem.add_development_dependency 'guard-bundler', '~> 2.0.0'
46
- gem.add_development_dependency 'guard-cucumber', '~> 1.5.1'
47
- gem.add_development_dependency 'guard-rspec', '~> 4.3.1'
44
+ gem.add_development_dependency 'guard', '~> 2.10.4'
45
+ gem.add_development_dependency 'guard-bundler', '~> 2.1.0'
46
+ gem.add_development_dependency 'guard-cucumber', '~> 1.5.3'
47
+ gem.add_development_dependency 'guard-rspec', '~> 4.5.0'
48
48
  gem.add_development_dependency 'guard-rubocop', '~> 1.2.0'
49
49
  gem.add_development_dependency 'rb-fchange', '~> 0.0.6'
50
50
  gem.add_development_dependency 'rb-fsevent', '~> 0.9.4'
@@ -52,17 +52,17 @@ Gem::Specification.new do |gem|
52
52
  gem.add_development_dependency 'terminal-notifier-guard', '~> 1.6.4'
53
53
 
54
54
  # Docs
55
- gem.add_development_dependency 'inch', '~> 0.5.7'
55
+ gem.add_development_dependency 'inch', '~> 0.5.8'
56
56
  gem.add_development_dependency 'yard', '~> 0.8.7.6'
57
57
 
58
58
  # Test
59
- gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.1'
59
+ gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.3'
60
60
  gem.add_development_dependency 'coveralls', '~> 0.7.2'
61
61
  gem.add_development_dependency 'cucumber', '~> 1.3.17'
62
62
  gem.add_development_dependency 'flay', '~> 2.5.0'
63
63
  gem.add_development_dependency 'flog', '~> 4.3.0'
64
- gem.add_development_dependency 'reek', '~> 1.4.0'
64
+ gem.add_development_dependency 'reek', '~> 1.5.1'
65
65
  gem.add_development_dependency 'rspec', '~> 3.1.0'
66
66
  gem.add_development_dependency 'rspec-given', '~> 3.5.4'
67
- gem.add_development_dependency 'rubocop', '~> 0.27.1'
67
+ gem.add_development_dependency 'rubocop', '~> 0.28.0'
68
68
  end
@@ -0,0 +1,143 @@
1
+ require 'pio/packet_in'
2
+
3
+ describe Pio::PacketIn do
4
+ Given(:data_dump) do
5
+ [
6
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0x5d, 0x10, 0x31,
7
+ 0x37, 0x79, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
8
+ 0x00, 0x01, 0xac, 0x5d, 0x10, 0x31, 0x37, 0x79, 0xc0, 0xa8,
9
+ 0x02, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa8,
10
+ 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
12
+ ].pack('C*')
13
+ end
14
+
15
+ describe '.read' do
16
+ context 'with a packet_in message' do
17
+ Given(:header_dump) do
18
+ [
19
+ 0x01,
20
+ 0x0a,
21
+ 0x00, 0x4e,
22
+ 0x00, 0x00, 0x00, 0x00
23
+ ].pack('C*')
24
+ end
25
+ Given(:body_dump) do
26
+ [
27
+ 0xff, 0xff, 0xff, 0x00,
28
+ 0x00, 0x3c,
29
+ 0x00, 0x01,
30
+ 0x00,
31
+ 0x00
32
+ ].pack('C*') + data_dump
33
+ end
34
+
35
+ When(:packet_in) do
36
+ Pio::PacketIn.read(header_dump + body_dump)
37
+ end
38
+
39
+ Then { packet_in.class == Pio::PacketIn }
40
+ Then { packet_in.ofp_version == 0x1 }
41
+ Then { packet_in.message_type == 0xa }
42
+ Then { packet_in.message_length == 0x4e }
43
+ Then { packet_in.transaction_id == 0 }
44
+ Then { packet_in.xid == 0 }
45
+
46
+ Then { !packet_in.body.empty? }
47
+ Then { packet_in.buffer_id == 0xffffff00 }
48
+ Then { packet_in.total_len == 0x3c }
49
+ Then { packet_in.in_port == 1 }
50
+ Then { packet_in.reason == :no_match }
51
+ Then { packet_in.data == data_dump }
52
+ end
53
+
54
+ context 'with a packet_in message generated with PacketIn.new' do
55
+ Given(:packet_in_dump) do
56
+ Pio::PacketIn.new(
57
+ transaction_id: 0,
58
+ buffer_id: 0xffffff00,
59
+ in_port: 1,
60
+ reason: :no_match,
61
+ data: data_dump
62
+ ).to_binary
63
+ end
64
+ When(:packet_in) { Pio::PacketIn.read(packet_in_dump) }
65
+
66
+ Then { packet_in.class == Pio::PacketIn }
67
+ Then { packet_in.ofp_version == 0x1 }
68
+ Then { packet_in.message_type == 0xa }
69
+ Then { packet_in.message_length == 0x4e }
70
+ Then { packet_in.transaction_id == 0 }
71
+ Then { packet_in.xid == 0 }
72
+
73
+ Then { !packet_in.body.empty? }
74
+ Then { packet_in.buffer_id == 0xffffff00 }
75
+ Then { packet_in.total_len == 0x3c }
76
+ Then { packet_in.in_port == 1 }
77
+ Then { packet_in.reason == :no_match }
78
+ Then { packet_in.data == data_dump }
79
+ end
80
+
81
+ context 'with a Hello message' do
82
+ Given(:hello_dump) { [1, 0, 0, 8, 0, 0, 0, 0].pack('C*') }
83
+
84
+ When(:result) { Pio::PacketIn.read(hello_dump) }
85
+
86
+ Then do
87
+ result == Failure(Pio::ParseError, 'Invalid Packet-In message.')
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '.new' do
93
+ When(:packet_in) { Pio::PacketIn.new(user_options) }
94
+
95
+ context 'with transaction_id: option' do
96
+ When(:user_options) do
97
+ {
98
+ transaction_id: 0x123,
99
+ buffer_id: 0xffffff00,
100
+ in_port: 1,
101
+ reason: :no_match,
102
+ data: data_dump
103
+ }
104
+ end
105
+
106
+ Then { packet_in.ofp_version == 1 }
107
+ Then { packet_in.message_type == 10 }
108
+ Then { packet_in.message_length == 78 }
109
+ Then { packet_in.transaction_id == 0x123 }
110
+ Then { packet_in.xid == 0x123 }
111
+
112
+ Then { !packet_in.body.empty? }
113
+ Then { packet_in.buffer_id == 0xffffff00 }
114
+ Then { packet_in.in_port == 1 }
115
+ Then { packet_in.reason == :no_match }
116
+ Then { packet_in.data == data_dump }
117
+ end
118
+
119
+ context 'with xid: option' do
120
+ When(:user_options) do
121
+ {
122
+ xid: 0x123,
123
+ buffer_id: 0xffffff00,
124
+ in_port: 1,
125
+ reason: :no_match,
126
+ data: data_dump
127
+ }
128
+ end
129
+
130
+ Then { packet_in.ofp_version == 1 }
131
+ Then { packet_in.message_type == 10 }
132
+ Then { packet_in.message_length == 78 }
133
+ Then { packet_in.transaction_id == 0x123 }
134
+ Then { packet_in.xid == 0x123 }
135
+
136
+ Then { !packet_in.body.empty? }
137
+ Then { packet_in.buffer_id == 0xffffff00 }
138
+ Then { packet_in.in_port == 1 }
139
+ Then { packet_in.reason == :no_match }
140
+ Then { packet_in.data == data_dump }
141
+ end
142
+ end
143
+ 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.8.2
4
+ version: 0.9.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: 2014-12-17 00:00:00.000000000 Z
11
+ date: 2014-12-22 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.7.6
47
+ version: 1.7.9
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.7.6
54
+ version: 1.7.9
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,56 +72,56 @@ dependencies:
72
72
  requirements:
73
73
  - - ~>
74
74
  - !ruby/object:Gem::Version
75
- version: 2.8.2
75
+ version: 2.10.4
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ~>
81
81
  - !ruby/object:Gem::Version
82
- version: 2.8.2
82
+ version: 2.10.4
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: guard-bundler
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ~>
88
88
  - !ruby/object:Gem::Version
89
- version: 2.0.0
89
+ version: 2.1.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
- version: 2.0.0
96
+ version: 2.1.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: guard-cucumber
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ~>
102
102
  - !ruby/object:Gem::Version
103
- version: 1.5.1
103
+ version: 1.5.3
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ~>
109
109
  - !ruby/object:Gem::Version
110
- version: 1.5.1
110
+ version: 1.5.3
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: guard-rspec
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ~>
116
116
  - !ruby/object:Gem::Version
117
- version: 4.3.1
117
+ version: 4.5.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ~>
123
123
  - !ruby/object:Gem::Version
124
- version: 4.3.1
124
+ version: 4.5.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: guard-rubocop
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - ~>
200
200
  - !ruby/object:Gem::Version
201
- version: 0.5.7
201
+ version: 0.5.8
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.5.7
208
+ version: 0.5.8
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: yard
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -226,14 +226,14 @@ dependencies:
226
226
  requirements:
227
227
  - - ~>
228
228
  - !ruby/object:Gem::Version
229
- version: 0.4.1
229
+ version: 0.4.3
230
230
  type: :development
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
233
233
  requirements:
234
234
  - - ~>
235
235
  - !ruby/object:Gem::Version
236
- version: 0.4.1
236
+ version: 0.4.3
237
237
  - !ruby/object:Gem::Dependency
238
238
  name: coveralls
239
239
  requirement: !ruby/object:Gem::Requirement
@@ -296,14 +296,14 @@ dependencies:
296
296
  requirements:
297
297
  - - ~>
298
298
  - !ruby/object:Gem::Version
299
- version: 1.4.0
299
+ version: 1.5.1
300
300
  type: :development
301
301
  prerelease: false
302
302
  version_requirements: !ruby/object:Gem::Requirement
303
303
  requirements:
304
304
  - - ~>
305
305
  - !ruby/object:Gem::Version
306
- version: 1.4.0
306
+ version: 1.5.1
307
307
  - !ruby/object:Gem::Dependency
308
308
  name: rspec
309
309
  requirement: !ruby/object:Gem::Requirement
@@ -338,14 +338,14 @@ dependencies:
338
338
  requirements:
339
339
  - - ~>
340
340
  - !ruby/object:Gem::Version
341
- version: 0.27.1
341
+ version: 0.28.0
342
342
  type: :development
343
343
  prerelease: false
344
344
  version_requirements: !ruby/object:Gem::Requirement
345
345
  requirements:
346
346
  - - ~>
347
347
  - !ruby/object:Gem::Version
348
- version: 0.27.1
348
+ version: 0.28.0
349
349
  description: Pure ruby packet parser and generator.
350
350
  email:
351
351
  - yasuhito@gmail.com
@@ -376,6 +376,8 @@ files:
376
376
  - examples/icmp_read.rb
377
377
  - examples/lldp_new.rb
378
378
  - examples/lldp_read.rb
379
+ - examples/packet_in_new.rb
380
+ - examples/packet_in_read.rb
379
381
  - features/arp_read.feature
380
382
  - features/dhcp_read.feature
381
383
  - features/echo_read.feature
@@ -422,6 +424,7 @@ files:
422
424
  - features/packet_data/table_stats_request.raw
423
425
  - features/packet_data/vendor.raw
424
426
  - features/packet_data/vendor_stats_request.raw
427
+ - features/packet_in_read.feature
425
428
  - features/step_definitions/packet_data_steps.rb
426
429
  - features/step_definitions/pending_steps.rb
427
430
  - features/support/env.rb
@@ -490,6 +493,8 @@ files:
490
493
  - lib/pio/open_flow/phy_port.rb
491
494
  - lib/pio/open_flow/type.rb
492
495
  - lib/pio/options.rb
496
+ - lib/pio/packet_in.rb
497
+ - lib/pio/packet_in/format.rb
493
498
  - lib/pio/parse_error.rb
494
499
  - lib/pio/pcap.rb
495
500
  - lib/pio/type/ethernet_header.rb
@@ -525,6 +530,7 @@ files:
525
530
  - spec/pio/mac_spec.rb
526
531
  - spec/pio/open_flow/phy_port_spec.rb
527
532
  - spec/pio/open_flow/type_spec.rb
533
+ - spec/pio/packet_in_spec.rb
528
534
  - spec/spec_helper.rb
529
535
  homepage: http://github.com/trema/pio
530
536
  licenses:
@@ -577,6 +583,7 @@ test_files:
577
583
  - spec/pio/mac_spec.rb
578
584
  - spec/pio/open_flow/phy_port_spec.rb
579
585
  - spec/pio/open_flow/type_spec.rb
586
+ - spec/pio/packet_in_spec.rb
580
587
  - spec/spec_helper.rb
581
588
  - features/arp_read.feature
582
589
  - features/dhcp_read.feature
@@ -624,6 +631,7 @@ test_files:
624
631
  - features/packet_data/table_stats_request.raw
625
632
  - features/packet_data/vendor.raw
626
633
  - features/packet_data/vendor_stats_request.raw
634
+ - features/packet_in_read.feature
627
635
  - features/step_definitions/packet_data_steps.rb
628
636
  - features/step_definitions/pending_steps.rb
629
637
  - features/support/env.rb