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