packetgen 3.1.5 → 3.1.6
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 +4 -4
- data/bin/pgconsole +1 -0
- data/lib/packetgen.rb +2 -2
- data/lib/packetgen/capture.rb +9 -0
- data/lib/packetgen/header/base.rb +68 -70
- data/lib/packetgen/header/dhcpv6/duid.rb +3 -1
- data/lib/packetgen/header/dhcpv6/option.rb +3 -1
- data/lib/packetgen/header/dns/name.rb +18 -7
- data/lib/packetgen/header/dns/question.rb +2 -0
- data/lib/packetgen/header/dot11.rb +23 -6
- data/lib/packetgen/header/dot11/data.rb +9 -5
- data/lib/packetgen/header/eap.rb +3 -2
- data/lib/packetgen/header/eth.rb +4 -8
- data/lib/packetgen/header/http/headers.rb +3 -4
- data/lib/packetgen/header/http/request.rb +32 -17
- data/lib/packetgen/header/http/response.rb +1 -1
- data/lib/packetgen/header/http/verbs.rb +1 -1
- data/lib/packetgen/header/igmpv3/group_record.rb +2 -0
- data/lib/packetgen/header/ip.rb +27 -26
- data/lib/packetgen/header/ip/addr.rb +2 -3
- data/lib/packetgen/header/ip/option.rb +4 -4
- data/lib/packetgen/header/ipv6/addr.rb +1 -2
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +2 -0
- data/lib/packetgen/header/ospfv2/ls_request.rb +2 -0
- data/lib/packetgen/header/ospfv2/lsa.rb +6 -0
- data/lib/packetgen/header/ospfv2/lsa_header.rb +2 -1
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +2 -0
- data/lib/packetgen/header/ospfv3/ls_request.rb +2 -0
- data/lib/packetgen/header/ospfv3/lsa.rb +2 -0
- data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -1
- data/lib/packetgen/header/snmp.rb +3 -2
- data/lib/packetgen/header/tcp/option.rb +8 -6
- data/lib/packetgen/packet.rb +7 -3
- data/lib/packetgen/pcapng.rb +11 -11
- data/lib/packetgen/pcapng/block.rb +15 -2
- data/lib/packetgen/pcapng/epb.rb +22 -15
- data/lib/packetgen/pcapng/file.rb +164 -81
- data/lib/packetgen/pcapng/idb.rb +7 -9
- data/lib/packetgen/pcapng/shb.rb +35 -28
- data/lib/packetgen/pcapng/spb.rb +16 -12
- data/lib/packetgen/pcapng/unknown_block.rb +3 -11
- data/lib/packetgen/pcaprub_wrapper.rb +8 -8
- data/lib/packetgen/types.rb +1 -0
- data/lib/packetgen/types/abstract_tlv.rb +2 -3
- data/lib/packetgen/types/array.rb +15 -9
- data/lib/packetgen/types/cstring.rb +38 -17
- data/lib/packetgen/types/fieldable.rb +65 -0
- data/lib/packetgen/types/fields.rb +91 -56
- data/lib/packetgen/types/int.rb +2 -2
- data/lib/packetgen/types/int_string.rb +7 -2
- data/lib/packetgen/types/length_from.rb +18 -10
- data/lib/packetgen/types/oui.rb +1 -2
- data/lib/packetgen/types/string.rb +45 -8
- data/lib/packetgen/types/tlv.rb +1 -2
- data/lib/packetgen/utils.rb +2 -2
- data/lib/packetgen/version.rb +1 -1
- metadata +13 -12
- data/lib/packetgen/inspectable.rb +0 -20
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of PacketGen
|
4
|
+
# See https://github.com/sdaubert/packetgen for more informations
|
5
|
+
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
|
+
# This program is published under MIT license.
|
7
|
+
|
8
|
+
module PacketGen
|
9
|
+
module Types
|
10
|
+
# Mixin to define minimal API for a class to be embbeded as a field in
|
11
|
+
# {Fields} type.
|
12
|
+
#
|
13
|
+
# == Optional methods
|
14
|
+
# These methods may, optionally, be defined by fieldable types:
|
15
|
+
# * +from_human+ to load data from a human-readable string.
|
16
|
+
# @author Sylvain Daubert
|
17
|
+
# @since 3.1.6
|
18
|
+
module Fieldable
|
19
|
+
# Get type name
|
20
|
+
# @return [String]
|
21
|
+
def type_name
|
22
|
+
self.class.to_s.split('::').last
|
23
|
+
end
|
24
|
+
|
25
|
+
# rubocop:disable Lint/UselessMethodDefinition
|
26
|
+
# These methods are defined for documentation.
|
27
|
+
|
28
|
+
# Populate object from a binary string
|
29
|
+
# @param [String] str
|
30
|
+
# @return [Fields] self
|
31
|
+
# @abstract subclass should overload it.
|
32
|
+
def read(str)
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return object as a binary string
|
37
|
+
# @return [String]
|
38
|
+
# @abstract subclass should overload it.
|
39
|
+
def to_s
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
# Size of object as binary string
|
44
|
+
# @return [Integer]
|
45
|
+
def sz
|
46
|
+
to_s.size
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return a human-readbale string
|
50
|
+
# @return [String]
|
51
|
+
# @abstract subclass should overload it.
|
52
|
+
def to_human
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
# rubocop:enable Lint/UselessMethodDefinition
|
57
|
+
|
58
|
+
# Format object when inspecting a {Field} object
|
59
|
+
# @return [String]
|
60
|
+
def format_inspect
|
61
|
+
to_human
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -5,6 +5,8 @@
|
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# This program is published under MIT license.
|
7
7
|
|
8
|
+
# rubocop:disable Metrics/ClassLength
|
9
|
+
|
8
10
|
module PacketGen
|
9
11
|
module Types
|
10
12
|
# @abstract Set of fields
|
@@ -13,8 +15,7 @@ module PacketGen
|
|
13
15
|
#
|
14
16
|
# == Basics
|
15
17
|
# A {Fields} subclass is generaly composed of multiple binary fields. These fields
|
16
|
-
# have each a given type. All
|
17
|
-
# {Fields} subclasses may also be used as field type.
|
18
|
+
# have each a given type. All {Fieldable} types are supported.
|
18
19
|
#
|
19
20
|
# To define a new subclass, it has to inherit from {Fields}. And some class
|
20
21
|
# methods have to be used to declare attributes/fields:
|
@@ -128,6 +129,8 @@ module PacketGen
|
|
128
129
|
# @param [Class] klass
|
129
130
|
# @return [void]
|
130
131
|
def inherited(klass)
|
132
|
+
super
|
133
|
+
|
131
134
|
field_defs = {}
|
132
135
|
@field_defs.each do |k, v|
|
133
136
|
field_defs[k] = v.clone
|
@@ -162,7 +165,7 @@ module PacketGen
|
|
162
165
|
# bs[value1] # => Types::Int8
|
163
166
|
# bs.value1 # => Integer
|
164
167
|
# @param [Symbol] name field name
|
165
|
-
# @param [
|
168
|
+
# @param [Fieldable] type class or instance
|
166
169
|
# @param [Hash] options Unrecognized options are passed to object builder if
|
167
170
|
# +:builder+ option is not set.
|
168
171
|
# @option options [Object] :default default value. May be a proc. This lambda
|
@@ -191,7 +194,7 @@ module PacketGen
|
|
191
194
|
# @param [Symbol,nil] other field name to create a new one before. If +nil+,
|
192
195
|
# new field is appended.
|
193
196
|
# @param [Symbol] name field name to create
|
194
|
-
# @param [
|
197
|
+
# @param [Fieldable] type class or instance
|
195
198
|
# @param [Hash] options See {.define_field}.
|
196
199
|
# @return [void]
|
197
200
|
# @see .define_field
|
@@ -210,7 +213,7 @@ module PacketGen
|
|
210
213
|
# @param [Symbol,nil] other field name to create a new one after. If +nil+,
|
211
214
|
# new field is appended.
|
212
215
|
# @param [Symbol] name field name to create
|
213
|
-
# @param [
|
216
|
+
# @param [Fieldable] type class or instance
|
214
217
|
# @param [Hash] options See {.define_field}.
|
215
218
|
# @return [void]
|
216
219
|
# @see .define_field
|
@@ -244,12 +247,12 @@ module PacketGen
|
|
244
247
|
# @raise [ArgumentError] unknown +field+
|
245
248
|
# @since 2.8.4
|
246
249
|
def update_field(field, options)
|
247
|
-
|
250
|
+
check_existence_of field
|
251
|
+
|
252
|
+
%i[default builder optional enum].each do |property|
|
253
|
+
field_defs_property_from(field, property, options)
|
254
|
+
end
|
248
255
|
|
249
|
-
field_defs[field].default = options.delete(:default) if options.key?(:default)
|
250
|
-
field_defs[field].builder = options.delete(:builder) if options.key?(:builder)
|
251
|
-
field_defs[field].optional = options.delete(:optional) if options.key?(:optional)
|
252
|
-
field_defs[field].enum = options.delete(:enum) if options.key?(:enum)
|
253
256
|
field_defs[field].options.merge!(options)
|
254
257
|
end
|
255
258
|
|
@@ -271,12 +274,12 @@ module PacketGen
|
|
271
274
|
# subclass)
|
272
275
|
# @param [Array] args list of bitfield names. Name may be followed
|
273
276
|
# by bitfield size. If no size is given, 1 bit is assumed.
|
277
|
+
# @raise [ArgumentError] unknown +attr+
|
274
278
|
# @return [void]
|
275
279
|
def define_bit_fields_on(attr, *args)
|
276
|
-
|
277
|
-
raise ArgumentError, "unknown #{attr} field" if attr_def.nil?
|
280
|
+
check_existence_of attr
|
278
281
|
|
279
|
-
type =
|
282
|
+
type = field_defs[attr].type
|
280
283
|
raise TypeError, "#{attr} is not a PacketGen::Types::Int" unless type < Types::Int
|
281
284
|
|
282
285
|
total_size = type.new.width * 8
|
@@ -286,11 +289,7 @@ module PacketGen
|
|
286
289
|
field = args.shift
|
287
290
|
next unless field.is_a? Symbol
|
288
291
|
|
289
|
-
size =
|
290
|
-
args.shift
|
291
|
-
else
|
292
|
-
1
|
293
|
-
end
|
292
|
+
size = size_from(args)
|
294
293
|
|
295
294
|
unless field == :_
|
296
295
|
add_bit_methods(attr, field, size, total_size, idx)
|
@@ -338,38 +337,74 @@ module PacketGen
|
|
338
337
|
|
339
338
|
def add_bit_methods(attr, name, size, total_size, idx)
|
340
339
|
shift = idx - (size - 1)
|
341
|
-
field_mask = (2**size - 1) << shift
|
342
|
-
clear_mask = (2**total_size - 1) & (~field_mask & (2**total_size - 1))
|
343
340
|
|
344
341
|
if size == 1
|
345
|
-
|
346
|
-
def #{name}?
|
347
|
-
val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
|
348
|
-
val != 0
|
349
|
-
end
|
350
|
-
def #{name}=(v)
|
351
|
-
val = v ? 1 : 0
|
352
|
-
self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
|
353
|
-
self[:#{attr}].value |= val << #{shift}
|
354
|
-
end
|
355
|
-
METHODS
|
342
|
+
add_single_bit_methods(attr, name, size, total_size, shift)
|
356
343
|
else
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
344
|
+
add_multibit_methods(attr, name, size, total_size, shift)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def compute_field_mask(size, shift)
|
349
|
+
(2**size - 1) << shift
|
350
|
+
end
|
351
|
+
|
352
|
+
def compute_clear_mask(total_size, field_mask)
|
353
|
+
(2**total_size - 1) & (~field_mask & (2**total_size - 1))
|
354
|
+
end
|
355
|
+
|
356
|
+
def add_single_bit_methods(attr, name, size, total_size, shift)
|
357
|
+
field_mask = compute_field_mask(size, shift)
|
358
|
+
clear_mask = compute_clear_mask(total_size, field_mask)
|
359
|
+
|
360
|
+
class_eval <<-METHODS
|
361
|
+
def #{name}?
|
362
|
+
val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
|
363
|
+
val != 0
|
366
364
|
end
|
365
|
+
def #{name}=(v)
|
366
|
+
val = v ? 1 : 0
|
367
|
+
self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
|
368
|
+
self[:#{attr}].value |= val << #{shift}
|
369
|
+
end
|
370
|
+
METHODS
|
371
|
+
end
|
372
|
+
|
373
|
+
def add_multibit_methods(attr, name, size, total_size, shift)
|
374
|
+
field_mask = compute_field_mask(size, shift)
|
375
|
+
clear_mask = compute_clear_mask(total_size, field_mask)
|
376
|
+
|
377
|
+
class_eval <<-METHODS
|
378
|
+
def #{name}
|
379
|
+
(self[:#{attr}].to_i & #{field_mask}) >> #{shift}
|
380
|
+
end
|
381
|
+
def #{name}=(v)
|
382
|
+
self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask}
|
383
|
+
self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift}
|
384
|
+
end
|
385
|
+
METHODS
|
367
386
|
end
|
368
387
|
|
369
388
|
def register_bit_field_size(attr, field, size)
|
370
389
|
bit_fields[attr] = {} if bit_fields[attr].nil?
|
371
390
|
bit_fields[attr][field] = size
|
372
391
|
end
|
392
|
+
|
393
|
+
def field_defs_property_from(field, property, options)
|
394
|
+
field_defs[field].send("#{property}=", options.delete(property)) if options.key?(property)
|
395
|
+
end
|
396
|
+
|
397
|
+
def size_from(args)
|
398
|
+
if args.first.is_a? Integer
|
399
|
+
args.shift
|
400
|
+
else
|
401
|
+
1
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
def check_existence_of(field)
|
406
|
+
raise ArgumentError, "unknown #{field} field for #{self}" unless field_defs.key?(field)
|
407
|
+
end
|
373
408
|
end
|
374
409
|
|
375
410
|
# Create a new fields object
|
@@ -394,7 +429,7 @@ module PacketGen
|
|
394
429
|
|
395
430
|
# Get field object
|
396
431
|
# @param [Symbol] field
|
397
|
-
# @return [
|
432
|
+
# @return [Fieldable]
|
398
433
|
def [](field)
|
399
434
|
@fields[field]
|
400
435
|
end
|
@@ -414,6 +449,7 @@ module PacketGen
|
|
414
449
|
end
|
415
450
|
|
416
451
|
# Get all optional field name
|
452
|
+
# @return[Array<Symbol>,nil]
|
417
453
|
def optional_fields
|
418
454
|
@optional_fields.keys
|
419
455
|
end
|
@@ -444,11 +480,7 @@ module PacketGen
|
|
444
480
|
next unless present?(field)
|
445
481
|
|
446
482
|
obj = self[field].read str[start..-1]
|
447
|
-
|
448
|
-
start += self[field].sz
|
449
|
-
else
|
450
|
-
start = str.size
|
451
|
-
end
|
483
|
+
start += self[field].sz
|
452
484
|
self[field] = obj unless obj == self[field]
|
453
485
|
end
|
454
486
|
|
@@ -545,22 +577,21 @@ module PacketGen
|
|
545
577
|
self.class.field_defs
|
546
578
|
end
|
547
579
|
|
580
|
+
# rubocop:disable Metrics/AbcSize
|
548
581
|
def build_field(field)
|
549
582
|
type = field_defs[field].type
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
type.new(enum)
|
558
|
-
elsif !field_options.empty?
|
559
|
-
type.new(field_options)
|
583
|
+
|
584
|
+
@fields[field] = if field_defs[field].builder
|
585
|
+
field_defs[field].builder.call(self, type)
|
586
|
+
elsif field_defs[field].enum
|
587
|
+
type.new(field_defs[field].enum)
|
588
|
+
elsif !field_defs[field].options.empty?
|
589
|
+
type.new(field_defs[field].options)
|
560
590
|
else
|
561
591
|
type.new
|
562
592
|
end
|
563
593
|
end
|
594
|
+
# rubocop:enable Metrics/AbcSize
|
564
595
|
|
565
596
|
def initialize_value(field, val)
|
566
597
|
type = field_defs[field].type
|
@@ -572,6 +603,8 @@ module PacketGen
|
|
572
603
|
@fields[field] = value
|
573
604
|
elsif @fields[field].respond_to? :from_human
|
574
605
|
@fields[field].from_human(value)
|
606
|
+
else
|
607
|
+
@fields[field].read(value)
|
575
608
|
end
|
576
609
|
end
|
577
610
|
|
@@ -582,3 +615,5 @@ module PacketGen
|
|
582
615
|
end
|
583
616
|
end
|
584
617
|
end
|
618
|
+
|
619
|
+
# rubocop:enable Metrics/ClassLength
|
data/lib/packetgen/types/int.rb
CHANGED
@@ -12,7 +12,7 @@ module PacketGen
|
|
12
12
|
# @abstract
|
13
13
|
# @author Sylvain Daubert
|
14
14
|
class Int
|
15
|
-
include
|
15
|
+
include Fieldable
|
16
16
|
|
17
17
|
# Integer value
|
18
18
|
# @return [Integer]
|
@@ -47,7 +47,7 @@ module PacketGen
|
|
47
47
|
@value = if value.is_a?(Integer)
|
48
48
|
value.to_i
|
49
49
|
elsif defined? @packstr
|
50
|
-
value.to_s.
|
50
|
+
value.to_s.unpack1(@packstr[@endian])
|
51
51
|
else
|
52
52
|
raise ParseError, 'Int#read is abstract and cannot read'
|
53
53
|
end
|
@@ -12,7 +12,7 @@ module PacketGen
|
|
12
12
|
# By default, a null string will have one byte length (length byte set to 0).
|
13
13
|
# @author Sylvain Daubert
|
14
14
|
class IntString
|
15
|
-
include
|
15
|
+
include Fieldable
|
16
16
|
|
17
17
|
# internal string
|
18
18
|
# @return [String]
|
@@ -78,7 +78,6 @@ module PacketGen
|
|
78
78
|
def to_human
|
79
79
|
@string
|
80
80
|
end
|
81
|
-
alias format_inspect to_human
|
82
81
|
|
83
82
|
# Set length from internal string length
|
84
83
|
# @return [Integer]
|
@@ -91,6 +90,12 @@ module PacketGen
|
|
91
90
|
def sz
|
92
91
|
to_s.size
|
93
92
|
end
|
93
|
+
|
94
|
+
# Say if IntString is empty
|
95
|
+
# @return [Boolean]
|
96
|
+
def empty?
|
97
|
+
length.zero?
|
98
|
+
end
|
94
99
|
end
|
95
100
|
end
|
96
101
|
end
|
@@ -14,6 +14,9 @@ module PacketGen
|
|
14
14
|
# @author Sylvain Daubert
|
15
15
|
# @since 3.0.0
|
16
16
|
module LengthFrom
|
17
|
+
# Max value returned by {#sz_to_read}.
|
18
|
+
MAX_SZ_TO_READ = 65_535
|
19
|
+
|
17
20
|
# Initialize +length from+ capacity.
|
18
21
|
# Should be call by extensed object's initialize.
|
19
22
|
# @param [Hash] options
|
@@ -29,16 +32,21 @@ module PacketGen
|
|
29
32
|
# @return [String]
|
30
33
|
def read_with_length_from(str)
|
31
34
|
s = PacketGen.force_binary(str.to_s)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
s[0, sz_to_read]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Size to read, from length_from
|
39
|
+
# @return [Integer]
|
40
|
+
def sz_to_read
|
41
|
+
len = case @length_from
|
42
|
+
when Types::Int
|
43
|
+
@length_from.to_i
|
44
|
+
when Proc
|
45
|
+
@length_from.call
|
46
|
+
else
|
47
|
+
MAX_SZ_TO_READ
|
48
|
+
end
|
49
|
+
[0, len].max
|
42
50
|
end
|
43
51
|
end
|
44
52
|
end
|
data/lib/packetgen/types/oui.rb
CHANGED
@@ -14,7 +14,7 @@ module PacketGen
|
|
14
14
|
# oui.to_human # => "00:01:02"
|
15
15
|
# @author Sylvain Daubert
|
16
16
|
class OUI < Types::Fields
|
17
|
-
include
|
17
|
+
include Fieldable
|
18
18
|
|
19
19
|
# @attribute b2
|
20
20
|
# @return [Integer] left-most byte
|
@@ -46,7 +46,6 @@ module PacketGen
|
|
46
46
|
def to_human
|
47
47
|
fields.map { |m| '%02x' % self[m] }.join(':')
|
48
48
|
end
|
49
|
-
alias format_inspect to_human
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
@@ -6,16 +6,23 @@
|
|
6
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
7
7
|
# This program is published under MIT license.
|
8
8
|
|
9
|
+
require 'forwardable'
|
10
|
+
|
9
11
|
module PacketGen
|
10
12
|
module Types
|
11
|
-
# This class
|
12
|
-
# #{to_human} and {#from_human} methods
|
13
|
-
# to be compatible with others {Types}.
|
13
|
+
# This class mimics regular String, but it is {Fieldable}.
|
14
14
|
# @author Sylvain Daubert
|
15
|
-
|
15
|
+
# @since 3.1.6 no more a subclass or regular String
|
16
|
+
class String
|
17
|
+
extend Forwardable
|
18
|
+
include Fieldable
|
16
19
|
include LengthFrom
|
17
|
-
include Inspectable
|
18
20
|
|
21
|
+
def_delegators :@string, :[], :to_s, :length, :size, :inspect, :==, :<<,
|
22
|
+
:unpack, :force_encoding, :encoding, :index, :empty?
|
23
|
+
|
24
|
+
# @return [::String]
|
25
|
+
attr_reader :string
|
19
26
|
# @return [Integer]
|
20
27
|
attr_reader :static_length
|
21
28
|
|
@@ -24,7 +31,7 @@ module PacketGen
|
|
24
31
|
# takes length when reading
|
25
32
|
# @option options [Integer] :static_length set a static length for this string
|
26
33
|
def initialize(options={})
|
27
|
-
|
34
|
+
register_internal_string ''
|
28
35
|
initialize_length_from(options)
|
29
36
|
@static_length = options[:static_length]
|
30
37
|
end
|
@@ -33,14 +40,44 @@ module PacketGen
|
|
33
40
|
# @return [String] self
|
34
41
|
def read(str)
|
35
42
|
s = read_with_length_from(str)
|
36
|
-
|
37
|
-
self.replace(s)
|
43
|
+
register_internal_string s
|
38
44
|
self
|
39
45
|
end
|
40
46
|
|
47
|
+
alias old_sz_to_read sz_to_read
|
48
|
+
private :old_sz_to_read
|
49
|
+
|
50
|
+
# Size to read.
|
51
|
+
# Computed from static_length or length_from, if defined.
|
52
|
+
# @return [Integer]
|
53
|
+
# @since 3.1.6
|
54
|
+
def sz_to_read
|
55
|
+
return static_length if static_length?
|
56
|
+
|
57
|
+
old_sz_to_read
|
58
|
+
end
|
59
|
+
|
60
|
+
# Say if a static length is defined
|
61
|
+
# @return [Boolean]
|
62
|
+
# @since 3.1.6
|
63
|
+
def static_length?
|
64
|
+
!static_length.nil?
|
65
|
+
end
|
66
|
+
|
67
|
+
def format_inspect
|
68
|
+
inspect
|
69
|
+
end
|
70
|
+
|
41
71
|
alias sz length
|
42
72
|
alias to_human to_s
|
43
73
|
alias from_human read
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def register_internal_string(str)
|
78
|
+
@string = str
|
79
|
+
PacketGen.force_binary(@string)
|
80
|
+
end
|
44
81
|
end
|
45
82
|
end
|
46
83
|
end
|