packetgen-plugin-ipsec 1.0.3 → 1.1.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
  SHA256:
3
- metadata.gz: 6000090bef8439281eed6482a399f0e05b188e7594d3de3e92d32a9088e32b88
4
- data.tar.gz: 0a753bf7266628b968ca9937f9d8f41c657c0bdd166b233b4c1e94eef4c71f89
3
+ metadata.gz: 63e6c93595c3d2f6361e87c0c5dd6cf60a792fadf6f15ecd52a8fe38be56bf29
4
+ data.tar.gz: 7759ddd4bdb74e1b510db940114c38e89ac6865d803c8966ebbc2b80c7379f97
5
5
  SHA512:
6
- metadata.gz: fdb0b0828199209621044b6c8a916018225cd025afd403a1f30d0137f5fad3f30bbcba0d58d924d1b2c6cef04690277d3b6de036c016ac20ced6d868b8576224
7
- data.tar.gz: 2b76622be17f0fdb03b9703bc25eceddd9cafbc968b5d99991d387926d886b4fea3c6fc2437528b9ab662584997a374387a053991dc896fe164cd7cdf6b47f2b
6
+ metadata.gz: dab304078f641492b8b6f431777ee1fc1a1a701d3351660ea276321cea9d6a3f00def177c6da41e30c76970f684a29a2e26558b90fa6e43527d41af7e9598235
7
+ data.tar.gz: 475aeb08d49dcbfd0c45c40181546c96c531f8d1772a253c64d3314337d65380b08d3c9a718e08c8c9aedc68396585e7e951c2e7a0013e2f503b3972367d38df
@@ -1,28 +1,32 @@
1
1
  name: Specs
2
+
2
3
  on:
3
4
  push:
4
5
  branches: [ master ]
5
6
  pull_request:
6
7
  branches: [ master ]
8
+
7
9
  jobs:
8
10
  test:
9
11
  strategy:
10
12
  fail-fast: false
11
13
  matrix:
12
14
  os: [ubuntu-latest]
13
- ruby: [2.4, 2.5, 2.6, 2.7]
15
+ ruby: ['3.0', '3.1', '3.2', '3.3', '3.4']
14
16
  runs-on: ${{ matrix.os }}
15
17
  steps:
16
- - uses: actions/checkout@v2
18
+ - uses: actions/checkout@v4
17
19
  - name: Install dependencies
18
20
  run: sudo apt-get update -qq && sudo apt-get install libpcap-dev -qq
19
21
  - name: Set up Ruby
20
22
  uses: ruby/setup-ruby@v1
21
23
  with:
22
24
  ruby-version: ${{ matrix.ruby }}
23
- - name: Run tests
25
+ - name: Install Gems
24
26
  run: |
25
27
  bundle config set path 'vendor/bundle'
26
28
  bundle config set --local without noci
27
29
  bundle install
30
+ - name: Run tests
31
+ run: |
28
32
  bundle exec rake
data/.rubocop.yml CHANGED
@@ -1,21 +1,39 @@
1
- require:
1
+ plugins:
2
2
  - rubocop-performance
3
3
  AllCops:
4
- TargetRubyVersion: 2.4
4
+ TargetRubyVersion: "3.0"
5
+ NewCops: enable
6
+ Exclude:
7
+ - .git/**/*
8
+ - spec/**/*
9
+ - vendor/**/*
5
10
  Layout/LineLength:
6
- Max: 150
11
+ Enabled: false
7
12
  Layout/SpaceAroundEqualsInParameterDefault:
8
13
  EnforcedStyle: no_space
9
14
  Lint/EmptyWhen:
10
15
  Enabled: false
11
16
  Lint/Void:
12
17
  Enabled: false
13
- Metrics:
18
+ Metrics/AbcSize:
19
+ Max: 20
20
+ Metrics/ClassLength:
21
+ Max: 200
22
+ Metrics/MethodLength:
23
+ Max: 20
24
+ Metrics/ParameterLists:
25
+ MaxOptionalParameters: 4
26
+ Naming/FileName:
27
+ Enabled: false
28
+ Style/AccessModifierDeclarations:
14
29
  Enabled: false
15
30
  Style/AsciiComments:
16
31
  Enabled: false
17
32
  Style/ClassAndModuleChildren:
18
- EnforcedStyle: compact
33
+ Enabled: false
34
+ Style/Documentation:
35
+ # Too many false positives!
36
+ Enabled: false
19
37
  Style/Encoding:
20
38
  Enabled: false
21
39
  Style/EvalWithLocation:
@@ -23,7 +41,7 @@ Style/EvalWithLocation:
23
41
  Style/FormatString:
24
42
  EnforcedStyle: percent
25
43
  Style/FormatStringToken:
26
- EnforcedStyle: unannotated
44
+ MaxUnannotatedPlaceholdersAllowed: 3
27
45
  Style/PerlBackrefs:
28
46
  Enabled: false
29
47
  Style/RedundantSelf:
data/Gemfile CHANGED
@@ -1,14 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
4
6
 
5
7
  gem 'bundler', '>= 1.17', '< 3'
6
- gem 'rake', '~> 12.3'
7
- gem 'rspec', '~> 3.10'
8
+
9
+ group :development do
10
+ gem 'rake', '~>13.0', require: false
11
+ gem 'rspec', '~>3.13'
12
+ end
8
13
 
9
14
  group :noci do
10
- gem 'rubocop', '~> 1.6'
11
- gem 'rubocop-performance', '~> 1.9'
12
- gem 'simplecov', '~> 0.18'
13
- gem 'yard', '~> 0.9'
15
+ gem 'rubocop', '~> 1.12', require: false
16
+ gem 'rubocop-performance', '~> 1.13', require: false
17
+ gem 'ruby-lsp', require: false
18
+ gem 'ruby-lsp-rspec', require: false
19
+ gem 'simplecov', '~> 0.21', require: false
20
+ gem 'yard', '~> 0.9', require: false
14
21
  end
data/README.md CHANGED
@@ -3,13 +3,15 @@
3
3
 
4
4
  # packetgen-plugin-ipsec
5
5
 
6
- **Warning:** this repository is a work-in-progress. It will be available with packetgen3.
7
-
8
6
  This is a plugin for [PacketGen gem](https://github.com/sdaubert/packetgen). It adds two protocols:
9
7
 
10
8
  * `PacketGen::Plugin::ESP`: IP Encapsulating Security Payload ([RFC 4303](https://tools.ietf.org/html/rfc4303)),
11
9
  * `PacketGen::Plugin::IKE`: Internet Key Exchange v2 ([RFC 7296](https://tools.ietf.org/html/rfc7296)).
12
10
 
11
+ Versions 1.0.x are compatible with PacketGen 3.x.
12
+
13
+ Versions 1.1.x are compatible with PacketGen 4.x.
14
+
13
15
  ## Installation
14
16
 
15
17
  Add this line to your application's Gemfile:
@@ -20,11 +22,15 @@ gem 'packetgen-plugin-ipsec'
20
22
 
21
23
  And then execute:
22
24
 
23
- $ bundle
25
+ ```bash
26
+ bundle
27
+ ```
24
28
 
25
29
  Or install it yourself as:
26
30
 
27
- $ gem install packetgen-plugin-ipsec
31
+ ```bash
32
+ gem install packetgen-plugin-ipsec
33
+ ```
28
34
 
29
35
  ## Usage
30
36
 
@@ -86,7 +92,7 @@ pkt.to_w
86
92
 
87
93
  ## See also
88
94
 
89
- API documentation: http://www.rubydoc.info/gems/packetgen-plugin-ipsec
95
+ API documentation: <http://www.rubydoc.info/gems/packetgen-plugin-ipsec>
90
96
 
91
97
  ## License
92
98
 
@@ -94,4 +100,4 @@ MIT License (see [LICENSE](https://github.com/sdaubert/packetgen-plugin-ipsec/bl
94
100
 
95
101
  ## Contributing
96
102
 
97
- Bug reports and pull requests are welcome on GitHub at https://github.com/sdaubert/packetgen-plugin-ipsec.
103
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/sdaubert/packetgen-plugin-ipsec>.
@@ -72,5 +72,37 @@ module PacketGen::Plugin
72
72
  @intg&.update(data)
73
73
  @conf.update(data)
74
74
  end
75
+
76
+ # Compute and set IV for deciphering mode
77
+ # @param [BinStruct::String] salt
78
+ # @param [String] msg ciphered message
79
+ # @return [String] iv
80
+ def compute_iv_for_decrypting(salt, msg)
81
+ case confidentiality_mode
82
+ when 'gcm'
83
+ iv = msg.slice!(0, 8)
84
+ real_iv = salt + iv
85
+ when 'cbc'
86
+ @conf.padding = 0
87
+ real_iv = iv = msg.slice!(0, 16)
88
+ when 'ctr'
89
+ iv = msg.slice!(0, 8)
90
+ real_iv = salt + iv + [1].pack('N')
91
+ else
92
+ real_iv = iv = msg.slice!(0, 16)
93
+ end
94
+ @conf.iv = real_iv
95
+ iv
96
+ end
97
+
98
+ # Compute and set real IV for ciphering mode
99
+ # @param [String] iv IV to use
100
+ # @param [String] salt salt to use
101
+ # @return [void]
102
+ def compute_iv_for_encrypting(iv, salt) # rubocop:disable Naming/MethodParameterName
103
+ real_iv = salt.b + iv.b
104
+ real_iv += [1].pack('N') if confidentiality_mode == 'ctr'
105
+ @conf.iv = real_iv
106
+ end
75
107
  end
76
108
  end
@@ -7,14 +7,16 @@
7
7
 
8
8
  require_relative 'crypto'
9
9
 
10
+ # rubocop:disable Metrics/ClassLength
11
+
10
12
  module PacketGen::Plugin
11
13
  # A ESP header consists of:
12
- # * a Security Parameters Index (#{spi}, {PacketGen::Types::Int32} type),
14
+ # * a Security Parameters Index (#{spi}, {BinStruct::Int32} type),
13
15
  # * a Sequence Number ({#sn}, +Int32+ type),
14
16
  # * a {#body} (variable length),
15
17
  # * an optional TFC padding ({#tfc}, variable length),
16
18
  # * an optional {#padding} (to align ESP on 32-bit boundary, variable length),
17
- # * a {#pad_length} ({PacketGen::Types::Int8}),
19
+ # * a {#pad_length} ({BinStruct::Int8}),
18
20
  # * a Next header field ({#next}, +Int8+),
19
21
  # * and an optional Integrity Check Value ({#icv}, variable length).
20
22
  #
@@ -78,34 +80,34 @@ module PacketGen::Plugin
78
80
  # @!attribute spi
79
81
  # 32-bit Security Parameter Index
80
82
  # @return [Integer]
81
- define_field :spi, PacketGen::Types::Int32
83
+ define_attr :spi, BinStruct::Int32
82
84
  # @!attribute sn
83
85
  # 32-bit Sequence Number
84
86
  # @return [Integer]
85
- define_field :sn, PacketGen::Types::Int32
87
+ define_attr :sn, BinStruct::Int32
86
88
  # @!attribute body
87
- # @return [PacketGen::Types::String,PacketGen::Header::Base]
88
- define_field :body, PacketGen::Types::String
89
+ # @return [BinStruct::String,PacketGen::Header::Base]
90
+ define_attr :body, BinStruct::String
89
91
  # @!attribute tfc
90
92
  # Traffic Flow Confidentiality padding
91
- # @return [PacketGen::Types::String,PacketGen::Header::Base]
92
- define_field :tfc, PacketGen::Types::String
93
+ # @return [BinStruct::String,PacketGen::Header::Base]
94
+ define_attr :tfc, BinStruct::String
93
95
  # @!attribute padding
94
96
  # ESP padding
95
- # @return [PacketGen::Types::String,PacketGen::Header::Base]
96
- define_field :padding, PacketGen::Types::String
97
+ # @return [BinStruct::String,PacketGen::Header::Base]
98
+ define_attr :padding, BinStruct::String
97
99
  # @!attribute pad_length
98
100
  # 8-bit padding length
99
101
  # @return [Integer]
100
- define_field :pad_length, PacketGen::Types::Int8
102
+ define_attr :pad_length, BinStruct::Int8
101
103
  # @!attribute next
102
104
  # 8-bit next protocol value
103
105
  # @return [Integer]
104
- define_field :next, PacketGen::Types::Int8
106
+ define_attr :next, BinStruct::Int8
105
107
  # @!attribute icv
106
108
  # Integrity Check Value
107
- # @return [PacketGen::Types::String,PacketGen::Header::Base]
108
- define_field :icv, PacketGen::Types::String
109
+ # @return [BinStruct::String,PacketGen::Header::Base]
110
+ define_attr :icv, BinStruct::String
109
111
 
110
112
  # ICV (Integrity Check Value) length
111
113
  # @return [Integer]
@@ -138,15 +140,14 @@ module PacketGen::Plugin
138
140
  def read(str)
139
141
  return self if str.nil?
140
142
 
141
- force_binary str
142
- self[:spi].read str[0, 4]
143
- self[:sn].read str[4, 4]
144
- self[:body].read str[8...-@icv_length - 2]
145
- self[:tfc].read ''
146
- self[:padding].read ''
147
- self[:pad_length].read str[-@icv_length - 2, 1]
148
- self[:next].read str[-@icv_length - 1, 1]
149
- self[:icv].read str[-@icv_length, @icv_length] if @icv_length
143
+ str = str.b
144
+ self[:spi].read(str[0, 4])
145
+ self[:sn].read(str[4, 4])
146
+ self[:tfc].read('')
147
+ self[:padding].read('')
148
+
149
+ read_icv_dependent_fields(str[8..])
150
+ read_icv(str)
150
151
  self
151
152
  end
152
153
 
@@ -177,72 +178,20 @@ module PacketGen::Plugin
177
178
  # @option options [OpenSSL::HMAC] :intmode integrity mode to use with a
178
179
  # confidentiality-only cipher. Only HMAC are supported.
179
180
  # @return [self]
180
- def encrypt!(cipher, iv, options={})
181
+ def encrypt!(cipher, iv, options={}) # rubocop:disable Naming/MethodParameterName
181
182
  opt = { salt: '', tfc_size: 1444 }.merge(options)
182
183
 
183
184
  set_crypto cipher, opt[:intmode]
184
-
185
- real_iv = force_binary(opt[:salt]) + force_binary(iv)
186
- real_iv += [1].pack('N') if confidentiality_mode == 'ctr'
187
- cipher.iv = real_iv
185
+ compute_iv_for_encrypting iv, opt[:salt]
188
186
 
189
187
  authenticate_esp_header_if_needed options, iv
190
188
 
191
- case confidentiality_mode
192
- when 'cbc'
193
- cipher_len = self[:body].sz + 2
194
- self.pad_length = (16 - (cipher_len % 16)) % 16
195
- else
196
- mod4 = to_s.size % 4
197
- self.pad_length = 4 - mod4 if mod4.positive?
198
- end
199
-
200
- if opt[:pad_length]
201
- self.pad_length = opt[:pad_length]
202
- padding = force_binary(opt[:padding] || (1..self.pad_length).to_a.pack('C*'))
203
- self[:padding].read padding
204
- else
205
- padding = force_binary(opt[:padding] || (1..self.pad_length).to_a.pack('C*'))
206
- self[:padding].read padding[0...self.pad_length]
207
- end
208
-
209
- tfc = ''
210
- if opt[:tfc]
211
- tfc_size = opt[:tfc_size] - self[:body].sz
212
- if tfc_size.positive?
213
- tfc_size = case confidentiality_mode
214
- when 'cbc'
215
- (tfc_size / 16) * 16
216
- else
217
- (tfc_size / 4) * 4
218
- end
219
- tfc = force_binary("\0" * tfc_size)
220
- end
221
- end
222
-
223
- msg = self[:body].to_s + tfc
224
- msg += self[:padding].to_s + self[:pad_length].to_s + self[:next].to_s
225
- enc_msg = encipher(msg)
226
- # as padding is used to pad for CBC mode, this is unused
227
- cipher.final
228
-
229
- self[:body] = PacketGen::Types::String.new.read(iv)
230
- self[:body] << enc_msg[0..-3]
231
- self[:pad_length].read enc_msg[-2]
232
- self[:next].read enc_msg[-1]
233
-
234
- # reset padding field as it has no sense in encrypted ESP
235
- self[:padding].read ''
189
+ encrypt_set_pad_length
190
+ encrypt_set_padding(opt)
191
+ encrypt_body(opt, iv)
236
192
 
237
193
  set_esp_icv_if_needed
238
-
239
- # Remove enciphered headers from packet
240
- id = header_id(self)
241
- if id < packet.headers.size - 1
242
- (packet.headers.size - 1).downto(id + 1) do |index|
243
- packet.headers.delete_at index
244
- end
245
- end
194
+ remove_enciphered_packets
246
195
 
247
196
  self
248
197
  end
@@ -265,51 +214,38 @@ module PacketGen::Plugin
265
214
  opt = { salt: '', parse: true }.merge(options)
266
215
 
267
216
  set_crypto cipher, opt[:intmode]
268
-
269
- case confidentiality_mode
270
- when 'gcm'
271
- iv = self[:body].slice!(0, 8)
272
- real_iv = opt[:salt] + iv
273
- when 'cbc'
274
- cipher.padding = 0
275
- real_iv = iv = self[:body].slice!(0, 16)
276
- when 'ctr'
277
- iv = self[:body].slice!(0, 8)
278
- real_iv = opt[:salt] + iv + [1].pack('N')
279
- else
280
- real_iv = iv = self[:body].slice!(0, 16)
281
- end
282
- cipher.iv = real_iv
283
-
217
+ iv = compute_iv_for_decrypting(opt[:salt], self[:body])
284
218
  if authenticated? && (@icv_length.zero? || opt[:icv_length])
285
- raise PacketGen::ParseError, 'unknown ICV size' unless opt[:icv_length]
286
-
287
- @icv_length = opt[:icv_length].to_i
288
- # reread ESP to handle new ICV size
289
- msg = self[:body].to_s + self[:pad_length].to_s
290
- msg += self[:next].to_s
291
- self[:icv].read msg.slice!(-@icv_length, @icv_length)
292
- self[:body].read msg[0..-3]
293
- self[:pad_length].read msg[-2]
294
- self[:next].read msg[-1]
219
+ check_icv_length(opt)
220
+ decrypt_format_packet
295
221
  end
296
-
297
222
  authenticate_esp_header_if_needed options, iv, icv
298
223
  private_decrypt opt
299
224
  end
300
225
 
301
226
  private
302
227
 
228
+ def read_icv_dependent_fields(str)
229
+ body_end = -@icv_length - 2
230
+ self[:body].read str[0...body_end]
231
+ self[:pad_length].read str[body_end, 1]
232
+ self[:next].read str[body_end + 1, 1]
233
+ end
234
+
235
+ def read_icv(str)
236
+ self[:icv].read str[-@icv_length, @icv_length] if @icv_length
237
+ end
238
+
303
239
  def get_auth_data(opt)
304
240
  ad = self[:spi].to_s
305
241
  if opt[:esn]
306
- @esn = PacketGen::Types::Int32.new(opt[:esn])
242
+ @esn = BinStruct::Int32.new(value: opt[:esn])
307
243
  ad << @esn.to_s if @conf.authenticated?
308
244
  end
309
245
  ad << self[:sn].to_s
310
246
  end
311
247
 
312
- def authenticate_esp_header_if_needed(opt, iv, icv=nil)
248
+ def authenticate_esp_header_if_needed(opt, iv, icv=nil) # rubocop:disable Naming/MethodParameterName
313
249
  if @conf.authenticated?
314
250
  @conf.auth_tag = icv if icv
315
251
  @conf.auth_data = get_auth_data(opt)
@@ -323,6 +259,65 @@ module PacketGen::Plugin
323
259
  end
324
260
  end
325
261
 
262
+ def encrypt_set_pad_length
263
+ case confidentiality_mode
264
+ when 'cbc'
265
+ cipher_len = self[:body].sz + 2
266
+ self.pad_length = (16 - (cipher_len % 16)) % 16
267
+ else
268
+ mod4 = to_s.size % 4
269
+ self.pad_length = 4 - mod4 if mod4.positive?
270
+ end
271
+ end
272
+
273
+ def encrypt_set_padding(opt)
274
+ if opt[:pad_length]
275
+ self.pad_length = opt[:pad_length]
276
+ padding = opt[:padding] || (1..self.pad_length).to_a.pack('C*')
277
+ else
278
+ padding = opt[:padding] || (1..self.pad_length).to_a.pack('C*')
279
+ padding = padding[0...self.pad_length]
280
+ end
281
+ self[:padding].read(padding)
282
+ end
283
+
284
+ def generate_tfc(opt)
285
+ tfc = ''
286
+ return tfc unless opt[:tfc]
287
+
288
+ tfc_size = opt[:tfc_size] - self[:body].sz
289
+ if tfc_size.positive?
290
+ tfc_size = case confidentiality_mode
291
+ when 'cbc'
292
+ (tfc_size / 16) * 16
293
+ else
294
+ (tfc_size / 4) * 4
295
+ end
296
+ tfc = "\0".b * tfc_size
297
+ end
298
+ tfc
299
+ end
300
+
301
+ def encrypt_body(opt, iv) # rubocop:disable Naming/MethodParameterName
302
+ msg = self[:body].to_s + generate_tfc(opt)
303
+ msg += self[:padding].to_s + self[:pad_length].to_s + self[:next].to_s
304
+ enc_msg = encipher(msg)
305
+ # as padding is used to pad for CBC mode, this is unused
306
+ @conf.final
307
+
308
+ encrypt_set_encrypted_fields(enc_msg, iv)
309
+ end
310
+
311
+ def encrypt_set_encrypted_fields(msg, iv) # rubocop:disable Naming/MethodParameterName
312
+ self[:body] = BinStruct::String.new.read(iv)
313
+ self[:body] << msg[0..-3]
314
+ self[:pad_length].read msg[-2]
315
+ self[:next].read msg[-1]
316
+
317
+ # reset padding field as it has no sense in encrypted ESP
318
+ self[:padding].read ''
319
+ end
320
+
326
321
  def set_esp_icv_if_needed
327
322
  return unless authenticated?
328
323
 
@@ -333,29 +328,62 @@ module PacketGen::Plugin
333
328
  end
334
329
  end
335
330
 
336
- def private_decrypt(options)
337
- # decrypt
338
- msg = self.body.to_s
339
- msg += self.padding + self[:pad_length].to_s + self[:next].to_s
340
- plain_msg = decipher(msg)
331
+ def remove_enciphered_packets
332
+ id = header_id(self)
333
+ return if id >= packet.headers.size - 1
334
+
335
+ (packet.headers.size - 1).downto(id + 1) do |index|
336
+ packet.headers.delete_at index
337
+ end
338
+ end
339
+
340
+ def check_icv_length(opt)
341
+ raise PacketGen::ParseError, 'unknown ICV size' unless opt[:icv_length]
342
+
343
+ @icv_length = opt[:icv_length].to_i
344
+ end
341
345
 
346
+ def decrypt_format_packet
347
+ # reread ESP to handle new ICV size
348
+ msg = self[:body].to_s + self[:pad_length].to_s
349
+ msg << self[:next].to_s
350
+ read_icv_dependent_fields(msg)
351
+ read_icv(msg)
352
+ end
353
+
354
+ def private_decrypt(options)
355
+ plain_msg = decrypt_body
342
356
  # check authentication tag
343
357
  return false if authenticated? && !authenticate!
344
358
 
345
- # Set ESP fields
359
+ new_pkt = fill_decrypted_fields_and_generate_plain_packet(plain_msg)
360
+ packet.encapsulate new_pkt if options[:parse] && !new_pkt.nil?
361
+ true
362
+ end
363
+
364
+ def decrypt_body
365
+ msg = self.body.to_s
366
+ msg += self.padding + self[:pad_length].to_s + self[:next].to_s
367
+ decipher(msg)
368
+ end
369
+
370
+ def fill_decrypted_fields_and_generate_plain_packet(plain_msg)
346
371
  self[:body].read plain_msg[0..-3]
347
372
  self[:pad_length].read plain_msg[-2]
348
373
  self[:next].read plain_msg[-1]
349
374
 
350
- # Set padding
351
- if self.pad_length.positive?
352
- len = self.pad_length
353
- self[:padding].read self[:body].slice!(-len, len)
354
- end
375
+ fill_padding_field
376
+ generate_plain_pkt
377
+ end
378
+
379
+ def fill_padding_field
380
+ return unless self.pad_length.positive?
355
381
 
356
- # Set TFC padding
357
- encap_length = 0
358
- pkt = nil
382
+ len = self.pad_length
383
+ self[:padding].read self[:body].slice!(-len, len)
384
+ end
385
+
386
+ def generate_plain_pkt # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
359
387
  case self.next
360
388
  when 4 # IPv4
361
389
  pkt = PacketGen::Packet.parse(body, first_header: 'IP')
@@ -381,19 +409,19 @@ module PacketGen::Plugin
381
409
  encap_length = self[:body].sz
382
410
  else
383
411
  # Unmanaged encapsulated protocol
412
+ pkt = nil
384
413
  encap_length = self[:body].sz
385
414
  end
386
415
 
387
- if encap_length < self[:body].sz
388
- tfc_len = self[:body].sz - encap_length
389
- self[:tfc].read self[:body].slice!(encap_length, tfc_len)
390
- end
416
+ remove_tfc_if_needed(encap_length)
417
+ pkt
418
+ end
391
419
 
392
- if options[:parse]
393
- packet.encapsulate pkt unless pkt.nil?
394
- end
420
+ def remove_tfc_if_needed(real_length)
421
+ return if real_length == self[:body].sz
395
422
 
396
- true
423
+ tfc_len = self[:body].sz - real_length
424
+ self[:tfc].read self[:body].slice!(real_length, tfc_len)
397
425
  end
398
426
  end
399
427
 
@@ -405,7 +433,7 @@ module PacketGen::Plugin
405
433
  lambda { |f|
406
434
  (f.dport == ESP::UDP_PORT ||
407
435
  f.sport == ESP::UDP_PORT) &&
408
- PacketGen::Types::Int32.new.read(f.body[0..3]).to_i.positive?
436
+ BinStruct::Int32.new.read(f.body[0..3]).to_i.positive?
409
437
  }]
410
438
  ESP.bind PacketGen::Header::IP, next: 4
411
439
  ESP.bind PacketGen::Header::IPv6, next: 41
@@ -414,3 +442,4 @@ module PacketGen::Plugin
414
442
  ESP.bind PacketGen::Header::ICMP, next: PacketGen::Header::ICMP::IP_PROTOCOL
415
443
  ESP.bind PacketGen::Header::ICMPv6, next: PacketGen::Header::ICMPv6::IP_PROTOCOL
416
444
  end
445
+ # rubocop:enable Metrics/ClassLength