packetgen 3.1.4 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -1
- data/bin/pgconsole +1 -0
- data/lib/packetgen.rb +19 -3
- data/lib/packetgen/capture.rb +30 -9
- data/lib/packetgen/config.rb +15 -9
- data/lib/packetgen/deprecation.rb +1 -1
- data/lib/packetgen/header/asn1_base.rb +19 -9
- data/lib/packetgen/header/base.rb +68 -70
- data/lib/packetgen/header/dhcpv6/duid.rb +3 -1
- data/lib/packetgen/header/dhcpv6/option.rb +4 -12
- data/lib/packetgen/header/dns/name.rb +18 -7
- data/lib/packetgen/header/dns/qdsection.rb +1 -1
- data/lib/packetgen/header/dns/question.rb +2 -0
- data/lib/packetgen/header/dot11.rb +25 -38
- data/lib/packetgen/header/dot11/data.rb +28 -34
- data/lib/packetgen/header/dot1x.rb +1 -14
- data/lib/packetgen/header/eap.rb +14 -17
- data/lib/packetgen/header/eth.rb +5 -6
- data/lib/packetgen/header/http/headers.rb +4 -2
- data/lib/packetgen/header/http/request.rb +37 -18
- data/lib/packetgen/header/http/response.rb +11 -5
- 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 +3 -1
- data/lib/packetgen/header/ip/option.rb +4 -4
- data/lib/packetgen/header/ipv6/addr.rb +2 -0
- 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 +13 -3
- 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 +9 -3
- data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -1
- data/lib/packetgen/header/snmp.rb +3 -2
- data/lib/packetgen/header/tcp.rb +1 -20
- data/lib/packetgen/header/tcp/option.rb +8 -6
- data/lib/packetgen/inspect.rb +1 -17
- data/lib/packetgen/packet.rb +10 -6
- 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 +166 -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 +25 -11
- data/lib/packetgen/types.rb +1 -0
- data/lib/packetgen/types/abstract_tlv.rb +3 -1
- data/lib/packetgen/types/array.rb +17 -10
- data/lib/packetgen/types/cstring.rb +56 -19
- data/lib/packetgen/types/enum.rb +4 -0
- data/lib/packetgen/types/fieldable.rb +65 -0
- data/lib/packetgen/types/fields.rb +180 -113
- data/lib/packetgen/types/int.rb +15 -1
- data/lib/packetgen/types/int_string.rb +8 -0
- data/lib/packetgen/types/length_from.rb +18 -10
- data/lib/packetgen/types/oui.rb +2 -0
- data/lib/packetgen/types/string.rb +58 -7
- data/lib/packetgen/types/tlv.rb +2 -0
- data/lib/packetgen/unknown_packet.rb +84 -0
- data/lib/packetgen/utils.rb +6 -7
- data/lib/packetgen/version.rb +1 -1
- metadata +18 -15
data/lib/packetgen/pcapng/idb.rb
CHANGED
@@ -60,7 +60,7 @@ module PacketGen
|
|
60
60
|
# @option options [Integer] :block_len2 block total length
|
61
61
|
def initialize(options={})
|
62
62
|
super
|
63
|
-
|
63
|
+
endianness(options[:endian] || :little)
|
64
64
|
@packets = []
|
65
65
|
@options_decoded = false
|
66
66
|
recalc_block_len
|
@@ -74,15 +74,12 @@ module PacketGen
|
|
74
74
|
io = to_io(str_or_io)
|
75
75
|
return self if io.eof?
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
self[:reserved].read io.read(2)
|
81
|
-
self[:snaplen].read io.read(4)
|
77
|
+
%i[type block_len link_type reserved snaplen].each do |attr|
|
78
|
+
self[attr].read io.read(self[attr].sz)
|
79
|
+
end
|
82
80
|
self[:options].read io.read(self.block_len - MIN_SIZE)
|
83
|
-
|
81
|
+
read_blocklen2_and_check(io)
|
84
82
|
|
85
|
-
check_len_coherency
|
86
83
|
self
|
87
84
|
end
|
88
85
|
|
@@ -91,6 +88,7 @@ module PacketGen
|
|
91
88
|
# @return [self]
|
92
89
|
def <<(xpb)
|
93
90
|
@packets << xpb
|
91
|
+
xpb.interface = self
|
94
92
|
self
|
95
93
|
end
|
96
94
|
|
@@ -133,7 +131,7 @@ module PacketGen
|
|
133
131
|
|
134
132
|
while idx < options.length
|
135
133
|
opt_code, opt_len = options[idx, 4].unpack("#{packstr}2")
|
136
|
-
return options[idx + 4, 1].
|
134
|
+
return options[idx + 4, 1].unpack1('C') if opt_code == OPTION_IF_TSRESOL && opt_len == 1
|
137
135
|
|
138
136
|
idx += 4 + opt_len
|
139
137
|
end
|
data/lib/packetgen/pcapng/shb.rb
CHANGED
@@ -80,7 +80,7 @@ module PacketGen
|
|
80
80
|
super
|
81
81
|
@interfaces = []
|
82
82
|
@unknown_blocks = []
|
83
|
-
|
83
|
+
endianness(options[:endian] || :little)
|
84
84
|
recalc_block_len
|
85
85
|
self.type = options[:type] || PcapNG::SHB_TYPE.to_i
|
86
86
|
end
|
@@ -92,29 +92,15 @@ module PacketGen
|
|
92
92
|
io = to_io(str_or_io)
|
93
93
|
return self if io.eof?
|
94
94
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
case magic_str
|
100
|
-
when MAGIC_LITTLE
|
101
|
-
force_endianness :little if @endian == :big
|
102
|
-
when MAGIC_BIG
|
103
|
-
force_endianness :big if @endian == :little
|
104
|
-
else
|
105
|
-
raise InvalidFileError, 'Incorrect magic for Section Header Block'
|
95
|
+
self[:type].read check_shb(io)
|
96
|
+
%i[block_len magic ver_major ver_minor section_len].each do |attr|
|
97
|
+
self[attr].read io.read(self[attr].sz)
|
106
98
|
end
|
99
|
+
handle_magic_and_check(self[:magic].to_s)
|
107
100
|
|
108
|
-
|
109
|
-
|
110
|
-
self[:magic].read magic_str
|
111
|
-
self[:ver_major].read io.read(2)
|
112
|
-
self[:ver_minor].read io.read(2)
|
113
|
-
self[:section_len].read io.read(8)
|
114
|
-
self[:options].read io.read(self.block_len - MIN_SIZE)
|
115
|
-
self[:block_len2].read io.read(4)
|
101
|
+
read_options(io)
|
102
|
+
read_blocklen2_and_check(io)
|
116
103
|
|
117
|
-
check_len_coherency
|
118
104
|
self
|
119
105
|
end
|
120
106
|
|
@@ -123,6 +109,7 @@ module PacketGen
|
|
123
109
|
# @return [self]
|
124
110
|
def <<(idb)
|
125
111
|
@interfaces << idb
|
112
|
+
idb.section = self
|
126
113
|
self
|
127
114
|
end
|
128
115
|
|
@@ -137,17 +124,22 @@ module PacketGen
|
|
137
124
|
super + body
|
138
125
|
end
|
139
126
|
|
127
|
+
def add_unknown_block(block)
|
128
|
+
self.unknown_blocks << block
|
129
|
+
block.section = self
|
130
|
+
end
|
131
|
+
|
140
132
|
private
|
141
133
|
|
142
134
|
def force_endianness(endian)
|
143
135
|
@endian = endian
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
self[:
|
136
|
+
%i[type block_len magic block_len2].each do |attr|
|
137
|
+
self[attr] = Types::Int32.new(0, endian).read(self[attr].to_s)
|
138
|
+
end
|
139
|
+
%i[ver_major ver_minor].each do |attr|
|
140
|
+
self[attr] = Types::Int16.new(0, endian).read(self[attr].to_s)
|
141
|
+
end
|
142
|
+
self[:section_len] = Types::Int64.new(0, endian).read(self[:section_len].to_s)
|
151
143
|
end
|
152
144
|
|
153
145
|
# Check io contains a SHB
|
@@ -160,6 +152,21 @@ module PacketGen
|
|
160
152
|
type = type_str.unpack('H*').join
|
161
153
|
raise InvalidFileError, "Incorrect type (#{type})for Section Header Block"
|
162
154
|
end
|
155
|
+
|
156
|
+
def handle_magic_and_check(magic_str)
|
157
|
+
case magic_str
|
158
|
+
when MAGIC_LITTLE
|
159
|
+
force_endianness :little if endian == :big
|
160
|
+
when MAGIC_BIG
|
161
|
+
force_endianness :big if endian == :little
|
162
|
+
else
|
163
|
+
raise InvalidFileError, 'Incorrect magic for Section Header Block'
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def read_options(io)
|
168
|
+
self[:options].read io.read(self.block_len - MIN_SIZE)
|
169
|
+
end
|
163
170
|
end
|
164
171
|
end
|
165
172
|
end
|
data/lib/packetgen/pcapng/spb.rb
CHANGED
@@ -44,7 +44,7 @@ module PacketGen
|
|
44
44
|
# @option options [Integer] :block_len2 block total length
|
45
45
|
def initialize(options={})
|
46
46
|
super
|
47
|
-
|
47
|
+
endianness(options[:endian] || :little)
|
48
48
|
recalc_block_len
|
49
49
|
self.type = options[:type] || PcapNG::SPB_TYPE.to_i
|
50
50
|
end
|
@@ -66,19 +66,11 @@ module PacketGen
|
|
66
66
|
self[:type].read io.read(4)
|
67
67
|
self[:block_len].read io.read(4)
|
68
68
|
self[:orig_len].read io.read(4)
|
69
|
-
|
70
|
-
# CAUTION: snaplen == 0 -> no capture limit
|
71
|
-
data_len = if interface && interface.snaplen.to_i.positive?
|
72
|
-
[self[:orig_len].to_i, interface.snaplen.to_i].min
|
73
|
-
else
|
74
|
-
self[:orig_len].to_i
|
75
|
-
end
|
76
|
-
data_pad_len = (4 - (data_len % 4)) % 4
|
69
|
+
data_len = compute_data_len
|
77
70
|
self[:data].read io.read(data_len)
|
78
|
-
io
|
79
|
-
|
71
|
+
remove_padding(io, data_len)
|
72
|
+
read_blocklen2_and_check(io)
|
80
73
|
|
81
|
-
check_len_coherency
|
82
74
|
self.type ||= PcapNG::IDB_TYPE.to_i
|
83
75
|
self
|
84
76
|
end
|
@@ -90,6 +82,18 @@ module PacketGen
|
|
90
82
|
recalc_block_len
|
91
83
|
super
|
92
84
|
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# Take care of IDB snaplen
|
89
|
+
# CAUTION: snaplen == 0 -> no capture limit
|
90
|
+
def compute_data_len
|
91
|
+
if interface && interface.snaplen.to_i.positive?
|
92
|
+
[self[:orig_len].to_i, interface.snaplen.to_i].min
|
93
|
+
else
|
94
|
+
self[:orig_len].to_i
|
95
|
+
end
|
96
|
+
end
|
93
97
|
end
|
94
98
|
end
|
95
99
|
end
|
@@ -29,7 +29,7 @@ module PacketGen
|
|
29
29
|
# @option options [Integer] :block_len2 block total length
|
30
30
|
def initialize(options={})
|
31
31
|
super
|
32
|
-
|
32
|
+
endianness(options[:endian] || :little)
|
33
33
|
recalc_block_len
|
34
34
|
end
|
35
35
|
|
@@ -44,21 +44,13 @@ module PacketGen
|
|
44
44
|
# @param [::String,IO] str_or_io
|
45
45
|
# @return [self]
|
46
46
|
def read(str_or_io)
|
47
|
-
io =
|
48
|
-
str_or_io
|
49
|
-
else
|
50
|
-
StringIO.new(force_binary(str_or_io.to_s))
|
51
|
-
end
|
47
|
+
io = to_io(str_or_io)
|
52
48
|
return self if io.eof?
|
53
49
|
|
54
50
|
self[:type].read io.read(4)
|
55
51
|
self[:block_len].read io.read(4)
|
56
52
|
self[:body].read io.read(self[:block_len].to_i - MIN_SIZE)
|
57
|
-
|
58
|
-
|
59
|
-
unless self[:block_len].to_i == self[:block_len2].to_i
|
60
|
-
raise InvalidFileError, 'Incoherency in Header Block'
|
61
|
-
end
|
53
|
+
read_blocklen2_and_check(io)
|
62
54
|
|
63
55
|
self
|
64
56
|
end
|
@@ -23,26 +23,42 @@ module PacketGen
|
|
23
23
|
# @param [String] iface interface name
|
24
24
|
# @param [Integer] snaplen
|
25
25
|
# @param [Boolean] promisc
|
26
|
+
# @param [Boolean] monitor
|
26
27
|
# @return [PCAPRUB::Pcap]
|
27
|
-
|
28
|
-
|
28
|
+
# @author Sylvain Daubert
|
29
|
+
# @author optix2000 - add support for setting monitor mode
|
30
|
+
# @since 3.1.5 add monitor argument
|
31
|
+
def self.open_iface(iface:, snaplen: DEFAULT_SNAPLEN, promisc: DEFAULT_PROMISC, monitor: nil)
|
32
|
+
pcap = PCAPRUB::Pcap.create(iface)
|
33
|
+
pcap.setsnaplen(snaplen)
|
34
|
+
pcap.setpromisc(promisc)
|
35
|
+
pcap.settimeout(TIMEOUT)
|
36
|
+
# Monitor MUST be set before pcap is activated
|
37
|
+
pcap.setmonitor monitor unless monitor.nil?
|
38
|
+
pcap.activate
|
29
39
|
end
|
30
40
|
|
41
|
+
# rubocop:disable Metrics/ParameterLists
|
42
|
+
|
31
43
|
# Capture packets from a network interface
|
32
44
|
# @param [String] iface interface name
|
33
45
|
# @param [Integer] snaplen
|
34
46
|
# @param [Boolean] promisc
|
35
47
|
# @param [String] filter BPF filter
|
48
|
+
# @param [Boolean] monitor
|
36
49
|
# @yieldparam [String] packet_data binary packet data
|
37
50
|
# @return [void]
|
38
|
-
|
39
|
-
|
51
|
+
# @author Sylvain Daubert
|
52
|
+
# @author optix2000 - add support for setting monitor mode
|
53
|
+
# @since 3.1.5 add monitor argument
|
54
|
+
def self.capture(iface:, snaplen: DEFAULT_SNAPLEN, promisc: DEFAULT_PROMISC, filter: nil, monitor: nil, &block)
|
55
|
+
pcap = self.open_iface(iface: iface, snaplen: snaplen, promisc: promisc, monitor: monitor)
|
40
56
|
pcap.setfilter filter unless filter.nil?
|
41
|
-
pcap.each
|
42
|
-
yield packet_data
|
43
|
-
end
|
57
|
+
pcap.each(&block)
|
44
58
|
end
|
45
59
|
|
60
|
+
# rubocop:enable Metrics/ParameterLists
|
61
|
+
|
46
62
|
# Inject given data onto wire
|
47
63
|
# @param [String] iface interface name
|
48
64
|
# @param [String] data to inject
|
@@ -58,10 +74,8 @@ module PacketGen
|
|
58
74
|
# @yieldparam [String] data binary packet data
|
59
75
|
# @return [void]
|
60
76
|
# @author Kent Gruber
|
61
|
-
def self.read_pcap(filename
|
62
|
-
PCAPRUB::Pcap.open_offline(filename).each_packet
|
63
|
-
yield packet
|
64
|
-
end
|
77
|
+
def self.read_pcap(filename:, &block)
|
78
|
+
PCAPRUB::Pcap.open_offline(filename).each_packet(&block)
|
65
79
|
end
|
66
80
|
end
|
67
81
|
end
|
data/lib/packetgen/types.rb
CHANGED
@@ -58,6 +58,8 @@ module PacketGen
|
|
58
58
|
# @since 3.1.0
|
59
59
|
# @since 3.1.1 add +:aliases+ keyword to {#initialize}
|
60
60
|
class AbstractTLV < Types::Fields
|
61
|
+
include Fieldable
|
62
|
+
|
61
63
|
class <<self
|
62
64
|
# @return [Hash]
|
63
65
|
attr_accessor :aliases
|
@@ -169,7 +171,7 @@ module PacketGen
|
|
169
171
|
# @return [String]
|
170
172
|
def to_human
|
171
173
|
my_value = self[:value].is_a?(String) ? self[:value].inspect : self[:value].to_human
|
172
|
-
|
174
|
+
'type:%s,length:%u,value:%s' % [human_type, length, my_value]
|
173
175
|
end
|
174
176
|
|
175
177
|
private
|
@@ -27,6 +27,9 @@ module PacketGen
|
|
27
27
|
# @author Sylvain Daubert
|
28
28
|
class Array
|
29
29
|
extend Forwardable
|
30
|
+
include Enumerable
|
31
|
+
include Fieldable
|
32
|
+
include LengthFrom
|
30
33
|
|
31
34
|
# @!method [](index)
|
32
35
|
# Return the element at +index+.
|
@@ -54,9 +57,6 @@ module PacketGen
|
|
54
57
|
def_delegators :@array, :[], :clear, :each, :empty?, :first, :last, :size
|
55
58
|
alias length size
|
56
59
|
|
57
|
-
include Enumerable
|
58
|
-
include LengthFrom
|
59
|
-
|
60
60
|
# Separator used in {#to_human}.
|
61
61
|
# May be ovverriden by subclasses
|
62
62
|
HUMAN_SEPARATOR = ','
|
@@ -163,11 +163,8 @@ module PacketGen
|
|
163
163
|
return self if @counter&.to_i&.zero?
|
164
164
|
|
165
165
|
str = read_with_length_from(str)
|
166
|
-
klass = self.class.set_of_klass
|
167
166
|
until str.empty?
|
168
|
-
obj =
|
169
|
-
real_klass = real_type(obj)
|
170
|
-
obj = real_klass.new.read(str) unless real_klass == klass
|
167
|
+
obj = create_object_from_str(str)
|
171
168
|
@array << obj
|
172
169
|
str.slice!(0, obj.sz)
|
173
170
|
break if @counter && self.size == @counter.to_i
|
@@ -203,9 +200,7 @@ module PacketGen
|
|
203
200
|
|
204
201
|
def record_from_hash(hsh)
|
205
202
|
obj_klass = self.class.set_of_klass
|
206
|
-
unless obj_klass
|
207
|
-
raise NotImplementedError, 'class should define #record_from_hash or declare type of elements in set with .set_of'
|
208
|
-
end
|
203
|
+
raise NotImplementedError, 'class should define #record_from_hash or declare type of elements in set with .set_of' unless obj_klass
|
209
204
|
|
210
205
|
obj = obj_klass.new(hsh) if obj_klass
|
211
206
|
klass = real_type(obj)
|
@@ -215,6 +210,18 @@ module PacketGen
|
|
215
210
|
def real_type(obj)
|
216
211
|
obj.class
|
217
212
|
end
|
213
|
+
|
214
|
+
def create_object_from_str(str)
|
215
|
+
klass = self.class.set_of_klass
|
216
|
+
obj = klass.new.read(str)
|
217
|
+
real_klass = real_type(obj)
|
218
|
+
|
219
|
+
if real_klass == klass
|
220
|
+
obj
|
221
|
+
else
|
222
|
+
real_klass.new.read(str)
|
223
|
+
end
|
224
|
+
end
|
218
225
|
end
|
219
226
|
|
220
227
|
# Specialized array to handle serie of {Int8}.
|
@@ -6,15 +6,30 @@
|
|
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
13
|
# This class handles null-terminated strings (aka C strings).
|
12
14
|
# @author Sylvain Daubert
|
13
|
-
|
15
|
+
# @since 3.1.6 no more a subclass or regular String
|
16
|
+
class CString
|
17
|
+
extend Forwardable
|
18
|
+
include Fieldable
|
19
|
+
|
20
|
+
def_delegators :@string, :[], :length, :size, :inspect, :==,
|
21
|
+
:unpack, :force_encoding, :encoding, :index, :empty?,
|
22
|
+
:encode, :slice, :slice!
|
23
|
+
|
24
|
+
# @return [::String]
|
25
|
+
attr_reader :string
|
26
|
+
# @return [Integer]
|
27
|
+
attr_reader :static_length
|
28
|
+
|
14
29
|
# @param [Hash] options
|
15
30
|
# @option options [Integer] :static_length set a static length for this string
|
16
31
|
def initialize(options={})
|
17
|
-
|
32
|
+
register_internal_string(+'')
|
18
33
|
@static_length = options[:static_length]
|
19
34
|
end
|
20
35
|
|
@@ -22,38 +37,49 @@ module PacketGen
|
|
22
37
|
# @return [String] self
|
23
38
|
def read(str)
|
24
39
|
s = str.to_s
|
25
|
-
s = s[0,
|
26
|
-
|
27
|
-
|
28
|
-
self.replace s
|
40
|
+
s = s[0, static_length] if static_length?
|
41
|
+
register_internal_string s
|
42
|
+
remove_null_character
|
29
43
|
self
|
30
44
|
end
|
31
45
|
|
32
46
|
# get null-terminated string
|
33
47
|
# @return [String]
|
34
48
|
def to_s
|
35
|
-
if
|
36
|
-
|
37
|
-
|
38
|
-
s[-1] = "\x00".encode(s.encoding)
|
39
|
-
PacketGen.force_binary s
|
40
|
-
else
|
41
|
-
PacketGen.force_binary(self + "\0" * (@static_length - self.length))
|
42
|
-
end
|
49
|
+
if static_length?
|
50
|
+
s = string[0, static_length - 1]
|
51
|
+
s << "\x00" * (static_length - s.length)
|
43
52
|
else
|
44
|
-
|
53
|
+
s = "#{string}\x00"
|
45
54
|
end
|
55
|
+
PacketGen.force_binary(s)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Append the given string to CString
|
59
|
+
# @param [#to_s] str
|
60
|
+
# @return [self]
|
61
|
+
def <<(str)
|
62
|
+
@string << str.to_s
|
63
|
+
remove_null_character
|
64
|
+
self
|
46
65
|
end
|
47
66
|
|
48
67
|
# @return [Integer]
|
49
68
|
def sz
|
50
|
-
if
|
51
|
-
|
69
|
+
if static_length?
|
70
|
+
static_length
|
52
71
|
else
|
53
72
|
to_s.size
|
54
73
|
end
|
55
74
|
end
|
56
75
|
|
76
|
+
# Say if a static length is defined
|
77
|
+
# @return [Boolean]
|
78
|
+
# @since 3.1.6
|
79
|
+
def static_length?
|
80
|
+
!static_length.nil?
|
81
|
+
end
|
82
|
+
|
57
83
|
# Populate CString from a human readable string
|
58
84
|
# @param [String] str
|
59
85
|
# @return [self]
|
@@ -63,8 +89,19 @@ module PacketGen
|
|
63
89
|
|
64
90
|
# @return [String]
|
65
91
|
def to_human
|
66
|
-
|
67
|
-
|
92
|
+
string
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def register_internal_string(str)
|
98
|
+
@string = str
|
99
|
+
PacketGen.force_binary(@string)
|
100
|
+
end
|
101
|
+
|
102
|
+
def remove_null_character
|
103
|
+
idx = string.index(0.chr)
|
104
|
+
register_internal_string(string[0, idx]) unless idx.nil?
|
68
105
|
end
|
69
106
|
end
|
70
107
|
end
|