packetgen 3.2.0 → 3.2.1
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/README.md +1 -1
- data/bin/pgconsole +3 -3
- data/lib/packetgen/header/arp.rb +24 -13
- data/lib/packetgen/header/asn1_base.rb +2 -2
- data/lib/packetgen/header/base.rb +1 -1
- data/lib/packetgen/header/dhcpv6/option.rb +11 -13
- data/lib/packetgen/header/dns/opt.rb +2 -2
- data/lib/packetgen/header/dns/rr.rb +61 -28
- data/lib/packetgen/header/dns.rb +13 -6
- data/lib/packetgen/header/dot11/management.rb +2 -5
- data/lib/packetgen/header/dot11.rb +1 -1
- data/lib/packetgen/header/eap.rb +1 -1
- data/lib/packetgen/header/eth.rb +1 -1
- data/lib/packetgen/header/http/response.rb +43 -23
- data/lib/packetgen/header/igmp.rb +1 -1
- data/lib/packetgen/header/ip/option.rb +2 -1
- data/lib/packetgen/header/ipv6/addr.rb +3 -0
- data/lib/packetgen/header/mdns.rb +19 -25
- data/lib/packetgen/header/mld.rb +1 -1
- data/lib/packetgen/header/ospfv2/lsa_header.rb +2 -4
- data/lib/packetgen/header/ospfv2.rb +1 -1
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +14 -5
- data/lib/packetgen/header/ospfv3/lsa.rb +1 -1
- data/lib/packetgen/header/ospfv3/lsa_header.rb +2 -4
- data/lib/packetgen/header/ospfv3.rb +1 -1
- data/lib/packetgen/header/snmp.rb +20 -14
- data/lib/packetgen/header/tcp/option.rb +1 -1
- data/lib/packetgen/header/tcp.rb +12 -5
- data/lib/packetgen/header/tftp.rb +15 -9
- data/lib/packetgen/inspect.rb +15 -9
- data/lib/packetgen/packet.rb +48 -2
- data/lib/packetgen/pcapng/file.rb +13 -13
- data/lib/packetgen/pcapng.rb +1 -0
- data/lib/packetgen/pcaprub_wrapper.rb +0 -4
- data/lib/packetgen/types/abstract_tlv.rb +1 -1
- data/lib/packetgen/types/array.rb +8 -1
- data/lib/packetgen/types/fields.rb +19 -19
- data/lib/packetgen/types/int.rb +7 -0
- data/lib/packetgen/types/oui.rb +1 -1
- data/lib/packetgen/types/tlv.rb +17 -9
- data/lib/packetgen/utils.rb +55 -21
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +3 -3
- metadata +3 -3
@@ -78,17 +78,15 @@ module PacketGen
|
|
78
78
|
# Compute and set Fletcher-16 checksum on LSA
|
79
79
|
# @return [Integer]
|
80
80
|
def calc_checksum
|
81
|
-
bytes = to_s[2..-1].unpack('C*')
|
82
|
-
|
83
81
|
c0 = c1 = 0
|
84
|
-
|
82
|
+
to_s[2..-1].unpack('C*').each do |byte|
|
85
83
|
c0 += byte
|
86
84
|
c1 += c0
|
87
85
|
end
|
88
86
|
c0 %= 255
|
89
87
|
c1 %= 255
|
90
88
|
|
91
|
-
x = ((sz -
|
89
|
+
x = ((sz - 17) * c0 - c1) % 255
|
92
90
|
x += 255 if x <= 0
|
93
91
|
y = 255 * 2 - c0 - x
|
94
92
|
y -= 255 if y > 255
|
@@ -145,7 +145,7 @@ module PacketGen
|
|
145
145
|
# directly called
|
146
146
|
def added_to_packet(packet)
|
147
147
|
ospf_idx = packet.headers.size
|
148
|
-
packet.instance_eval "def ospfize(**kwargs) @headers[#{ospf_idx}].ospfize(**kwargs); end"
|
148
|
+
packet.instance_eval "def ospfize(**kwargs) @headers[#{ospf_idx}].ospfize(**kwargs); end" # def ospfize(**kwargs) @headers[2].ospfize(**kwargs); end
|
149
149
|
end
|
150
150
|
|
151
151
|
# Compute checksum and set +checksum+ field
|
@@ -286,20 +286,11 @@ module PacketGen
|
|
286
286
|
def inspect
|
287
287
|
str = super
|
288
288
|
str << Inspect.shift_level
|
289
|
-
if self[:data].chosen.nil?
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
str << Inspect.dashed_line('ASN.1 content')
|
295
|
-
str << data.chosen_value.inspect(1)
|
296
|
-
begin
|
297
|
-
str << Inspect.inspect_body(self[:message].to_der, 'ASN.1 DER')
|
298
|
-
rescue StandardError => e
|
299
|
-
raise unless e.message.match?(/TAG.*not handled/)
|
300
|
-
end
|
301
|
-
str
|
302
|
-
end
|
289
|
+
str << if self[:data].chosen.nil?
|
290
|
+
Inspect::FMT_ATTR % [self[:data].type, :data, '']
|
291
|
+
else
|
292
|
+
inspect_data
|
293
|
+
end
|
303
294
|
end
|
304
295
|
|
305
296
|
# @api private
|
@@ -315,6 +306,21 @@ module PacketGen
|
|
315
306
|
|
316
307
|
packet.udp.sport = packet.udp.dport
|
317
308
|
end
|
309
|
+
|
310
|
+
private
|
311
|
+
|
312
|
+
def inspect_data
|
313
|
+
data = self[:data]
|
314
|
+
str = Inspect::FMT_ATTR % [data.type, :data, data.chosen_value.type]
|
315
|
+
str << Inspect.dashed_line('ASN.1 content')
|
316
|
+
str << data.chosen_value.inspect(1)
|
317
|
+
begin
|
318
|
+
str << Inspect.inspect_body(self[:message].to_der, 'ASN.1 DER')
|
319
|
+
rescue StandardError => e
|
320
|
+
raise unless e.message.match?(/TAG.*not handled/)
|
321
|
+
end
|
322
|
+
str
|
323
|
+
end
|
318
324
|
end
|
319
325
|
|
320
326
|
self.add_class SNMP
|
@@ -43,7 +43,7 @@ module PacketGen
|
|
43
43
|
# @!attribute value
|
44
44
|
# @return [Integer,String] option value
|
45
45
|
define_field :value, Types::String, optional: ->(h) { h.length? && h.length > 2 },
|
46
|
-
|
46
|
+
builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
|
47
47
|
|
48
48
|
# @param [hash] options
|
49
49
|
# @option options [Integer] :kind
|
data/lib/packetgen/header/tcp.rb
CHANGED
@@ -216,11 +216,7 @@ module PacketGen
|
|
216
216
|
doff = Inspect.int_dec_hex(data_offset, 1)
|
217
217
|
str << shift << Inspect::FMT_ATTR % ['', 'data_offset', doff]
|
218
218
|
str << shift << Inspect::FMT_ATTR % ['', 'reserved', reserved]
|
219
|
-
|
220
|
-
%w[ns cwr ece urg ack psh rst syn fin].each do |fl|
|
221
|
-
flags << (send("flag_#{fl}?") ? fl[0].upcase : '.')
|
222
|
-
end
|
223
|
-
str << shift << Inspect::FMT_ATTR % ['', 'flags', flags]
|
219
|
+
str << shift << Inspect::FMT_ATTR % ['', 'flags', flags2string]
|
224
220
|
end
|
225
221
|
end
|
226
222
|
|
@@ -231,6 +227,17 @@ module PacketGen
|
|
231
227
|
self[:sport], self[:dport] = self[:dport], self[:sport]
|
232
228
|
self
|
233
229
|
end
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
def flags2string
|
234
|
+
flags = +''
|
235
|
+
%w[ns cwr ece urg ack psh rst syn fin].each do |fl|
|
236
|
+
flags << (send("flag_#{fl}?") ? fl[0].upcase : '.')
|
237
|
+
end
|
238
|
+
|
239
|
+
flags
|
240
|
+
end
|
234
241
|
end
|
235
242
|
|
236
243
|
self.add_class TCP
|
@@ -102,22 +102,18 @@ module PacketGen
|
|
102
102
|
client_tid = packet.udp.sport
|
103
103
|
server_tid = nil
|
104
104
|
ary.each do |pkt|
|
105
|
+
next unless pkt.is?('UDP')
|
106
|
+
|
105
107
|
if server_tid.nil?
|
106
|
-
next unless pkt.
|
108
|
+
next unless pkt.udp.dport == client_tid
|
107
109
|
|
108
110
|
server_tid = pkt.udp.sport
|
109
111
|
else
|
110
|
-
next unless pkt.is?('UDP')
|
111
|
-
|
112
112
|
tids = [server_tid, client_tid]
|
113
113
|
ports = [pkt.udp.sport, pkt.udp.dport]
|
114
114
|
next unless (tids - ports).empty?
|
115
115
|
end
|
116
|
-
|
117
|
-
udp_dport = pkt.udp.dport
|
118
|
-
pkt.encapsulate tftp
|
119
|
-
# need to fix it as #encapsulate force it to 69
|
120
|
-
pkt.udp.dport = udp_dport
|
116
|
+
decode_tftp_packet(pkt)
|
121
117
|
end
|
122
118
|
end
|
123
119
|
|
@@ -135,7 +131,17 @@ module PacketGen
|
|
135
131
|
def added_to_packet(packet)
|
136
132
|
return if packet.respond_to? :tftp
|
137
133
|
|
138
|
-
packet.instance_eval("def tftp(arg=nil); header(#{self.class}, arg); end")
|
134
|
+
packet.instance_eval("def tftp(arg=nil); header(#{self.class}, arg); end") # def tftp(arg=nil); header(TFTP, arg); end
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def decode_tftp_packet(pkt)
|
140
|
+
tftp = Packet.parse(pkt.body, first_header: 'TFTP')
|
141
|
+
udp_dport = pkt.udp.dport
|
142
|
+
pkt.encapsulate tftp
|
143
|
+
# need to fix it as #encapsulate force it to 69
|
144
|
+
pkt.udp.dport = udp_dport
|
139
145
|
end
|
140
146
|
|
141
147
|
# TFTP Read Request header
|
data/lib/packetgen/inspect.rb
CHANGED
@@ -12,6 +12,8 @@ module PacketGen
|
|
12
12
|
module Inspect
|
13
13
|
# Maximum number of characters on a line for INSPECT
|
14
14
|
MAX_WIDTH = 70
|
15
|
+
# @private
|
16
|
+
SEPARATOR = ('-' * MAX_WIDTH << "\n").freeze
|
15
17
|
|
16
18
|
# Format to inspect attribute
|
17
19
|
FMT_ATTR = "%14s %16s: %s\n"
|
@@ -105,19 +107,23 @@ module PacketGen
|
|
105
107
|
return '' if body.nil? || body.empty?
|
106
108
|
|
107
109
|
str = dashed_line(name, 2)
|
108
|
-
|
109
|
-
str <<
|
110
|
+
0.upto(15) { |v| str << ' %02d' % v }
|
111
|
+
str << "\n" << SEPARATOR
|
110
112
|
unless body.empty?
|
111
113
|
(body.size / 16 + 1).times do |i|
|
112
|
-
|
113
|
-
o_str = octets.map { |v| ' %02x' % v }.join
|
114
|
-
str << o_str
|
115
|
-
str << ' ' * (3 * 16 - o_str.size) unless o_str.size >= 3 * 16
|
116
|
-
str << ' ' << octets.map { |v| v < 128 && v > 31 ? v.chr : '.' }.join
|
117
|
-
str << "\n"
|
114
|
+
str << self.convert_body_slice(body.to_s[i * 16, 16])
|
118
115
|
end
|
119
116
|
end
|
120
|
-
str <<
|
117
|
+
str << SEPARATOR
|
118
|
+
end
|
119
|
+
|
120
|
+
# @private
|
121
|
+
def self.convert_body_slice(bslice)
|
122
|
+
octets = bslice.unpack('C*')
|
123
|
+
str = octets.map { |v| ' %02x' % v }.join
|
124
|
+
str << ' ' * (48 - str.size) unless str.size >= 48
|
125
|
+
str << ' ' << octets.map { |v| (32..127).cover?(v) ? v.chr : '.' }.join
|
126
|
+
str << "\n"
|
121
127
|
end
|
122
128
|
end
|
123
129
|
end
|
data/lib/packetgen/packet.rb
CHANGED
@@ -51,6 +51,9 @@ module PacketGen
|
|
51
51
|
# Get packet headers, ordered as they appear in the packet.
|
52
52
|
# @return [Array<Header::Base>]
|
53
53
|
attr_reader :headers
|
54
|
+
# Activaye or deactivate header cache (activated by default)
|
55
|
+
# @return [Boolean]
|
56
|
+
attr_accessor :cache_headers
|
54
57
|
|
55
58
|
# Create a new Packet
|
56
59
|
# @param [String] protocol base protocol for packet
|
@@ -121,6 +124,8 @@ module PacketGen
|
|
121
124
|
# @private
|
122
125
|
def initialize
|
123
126
|
@headers = []
|
127
|
+
@header_cache = {}
|
128
|
+
@cache_headers = true
|
124
129
|
end
|
125
130
|
|
126
131
|
# Add a protocol header in packet.
|
@@ -166,7 +171,7 @@ module PacketGen
|
|
166
171
|
# @raise [ArgumentError] unknown protocol
|
167
172
|
def is?(protocol)
|
168
173
|
klass = check_protocol protocol
|
169
|
-
headers.any?
|
174
|
+
headers.any?(klass)
|
170
175
|
end
|
171
176
|
|
172
177
|
# Recalculate all packet checksums
|
@@ -271,6 +276,7 @@ module PacketGen
|
|
271
276
|
headers.delete(hdr)
|
272
277
|
add_header(next_hdr, previous_header: prev_hdr) if prev_hdr && next_hdr
|
273
278
|
end
|
279
|
+
invalidate_header_cache
|
274
280
|
rescue ArgumentError => e
|
275
281
|
raise FormatError, e.message
|
276
282
|
end
|
@@ -356,6 +362,7 @@ module PacketGen
|
|
356
362
|
headers.each do |header|
|
357
363
|
add_magic_header_method header
|
358
364
|
end
|
365
|
+
invalidate_header_cache
|
359
366
|
end
|
360
367
|
|
361
368
|
# Give first header of packet
|
@@ -409,7 +416,7 @@ module PacketGen
|
|
409
416
|
# @return [Header::Base]
|
410
417
|
def header(klass, arg)
|
411
418
|
layer = arg.is_a?(Integer) ? arg : 1
|
412
|
-
header =
|
419
|
+
header = find_header(klass, layer)
|
413
420
|
return header unless arg.is_a? Hash
|
414
421
|
|
415
422
|
arg.each do |key, value|
|
@@ -421,6 +428,19 @@ module PacketGen
|
|
421
428
|
header
|
422
429
|
end
|
423
430
|
|
431
|
+
# Get header from cache, or find it in packet
|
432
|
+
# @param [Class] klass
|
433
|
+
# @param [Integer] layer
|
434
|
+
# @return [Header::Base]
|
435
|
+
def find_header(klass, layer)
|
436
|
+
header = fetch_header_from_cache(klass, layer)
|
437
|
+
return header if header
|
438
|
+
|
439
|
+
header = headers.select { |h| h.is_a? klass }[layer - 1]
|
440
|
+
add_header_to_cache(header, klass, layer)
|
441
|
+
header
|
442
|
+
end
|
443
|
+
|
424
444
|
# check if protocol is known
|
425
445
|
# @param [String] protocol
|
426
446
|
# @raise [ArgumentError] unknown protocol
|
@@ -438,6 +458,7 @@ module PacketGen
|
|
438
458
|
# @return [void]
|
439
459
|
# @raise [BindingError]
|
440
460
|
def add_header(header, previous_header: nil, parsing: false)
|
461
|
+
invalidate_header_cache
|
441
462
|
prev_header = previous_header || last_header
|
442
463
|
add_to_previous_header(prev_header, header, parsing) if prev_header
|
443
464
|
|
@@ -521,6 +542,31 @@ module PacketGen
|
|
521
542
|
|
522
543
|
nil
|
523
544
|
end
|
545
|
+
|
546
|
+
def invalidate_header_cache
|
547
|
+
return unless cache_headers
|
548
|
+
|
549
|
+
@header_cache = {}
|
550
|
+
end
|
551
|
+
|
552
|
+
# Fetch header from cache if authorized
|
553
|
+
# @param [Class] klass
|
554
|
+
# @param [Integer] layer
|
555
|
+
# @return [Header::Base,nil]
|
556
|
+
def fetch_header_from_cache(klass, layer)
|
557
|
+
@header_cache.fetch(klass, []).fetch(layer - 1, nil) if cache_headers
|
558
|
+
end
|
559
|
+
|
560
|
+
# Add header to cache if authorized
|
561
|
+
# @param [Class] klass
|
562
|
+
# @param [Integer] layer
|
563
|
+
# @return [Header::Base,nil]
|
564
|
+
def add_header_to_cache(header, klass, layer)
|
565
|
+
return unless cache_headers
|
566
|
+
|
567
|
+
@header_cache[klass] ||= []
|
568
|
+
@header_cache[klass][layer - 1] = header
|
569
|
+
end
|
524
570
|
end
|
525
571
|
end
|
526
572
|
|
@@ -9,7 +9,7 @@ module PacketGen
|
|
9
9
|
module PcapNG
|
10
10
|
# PcapNG::File is a complete Pcap-NG file handler.
|
11
11
|
# @author Sylvain Daubert
|
12
|
-
class File
|
12
|
+
class File # rubocop:disable Metrics/ClassLength
|
13
13
|
# Known link types
|
14
14
|
KNOWN_LINK_TYPES = {
|
15
15
|
LINKTYPE_ETHERNET => 'Eth',
|
@@ -21,13 +21,11 @@ module PacketGen
|
|
21
21
|
}.freeze
|
22
22
|
|
23
23
|
# @private
|
24
|
-
BLOCK_TYPES =
|
25
|
-
PcapNG.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
].freeze
|
24
|
+
BLOCK_TYPES = PcapNG.constants(false).select { |c| c.to_s.include?('_TYPE') }.map do |c|
|
25
|
+
type_value = PcapNG.const_get(c).to_i
|
26
|
+
klass = PcapNG.const_get(c.to_s.delete_suffix('_TYPE'))
|
27
|
+
[type_value, klass]
|
28
|
+
end.to_h.freeze
|
31
29
|
|
32
30
|
# Get file sections
|
33
31
|
# @return [Array]
|
@@ -204,7 +202,7 @@ module PacketGen
|
|
204
202
|
# @return [Array] array of 2 elements: filename and size written
|
205
203
|
# @todo for 4.0, replace +options+ by +append+ kwarg
|
206
204
|
def to_file(filename, options={})
|
207
|
-
mode =
|
205
|
+
mode = options[:append] && ::File.exist?(filename) ? 'ab' : 'wb'
|
208
206
|
::File.open(filename, mode) { |f| f.write(self.to_s) }
|
209
207
|
[filename, self.to_s.size]
|
210
208
|
end
|
@@ -317,12 +315,12 @@ module PacketGen
|
|
317
315
|
shb = parse_shb(SHB.new, io)
|
318
316
|
raise InvalidFileError, 'no Section header found' unless shb.is_a?(SHB)
|
319
317
|
|
320
|
-
to_parse = if shb.section_len.to_i
|
321
|
-
# Section length is defined
|
322
|
-
StringIO.new(io.read(shb.section_len.to_i))
|
323
|
-
else
|
318
|
+
to_parse = if shb.section_len.to_i == 0xffffffffffffffff
|
324
319
|
# section length is undefined
|
325
320
|
io
|
321
|
+
else
|
322
|
+
# Section length is defined
|
323
|
+
StringIO.new(io.read(shb.section_len.to_i))
|
326
324
|
end
|
327
325
|
|
328
326
|
until to_parse.eof?
|
@@ -388,6 +386,7 @@ module PacketGen
|
|
388
386
|
end
|
389
387
|
end
|
390
388
|
|
389
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
391
390
|
# Extract and check options for #array_to_file
|
392
391
|
def array_to_file_options_from_hash(options)
|
393
392
|
%i[filename arr ts].each do |deprecated_opt|
|
@@ -404,6 +403,7 @@ module PacketGen
|
|
404
403
|
|
405
404
|
[filename, ary, ts, ts_inc, append]
|
406
405
|
end
|
406
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
407
407
|
|
408
408
|
def create_new_shb_section
|
409
409
|
section = SHB.new
|
data/lib/packetgen/pcapng.rb
CHANGED
@@ -38,8 +38,6 @@ module PacketGen
|
|
38
38
|
pcap.activate
|
39
39
|
end
|
40
40
|
|
41
|
-
# rubocop:disable Metrics/ParameterLists
|
42
|
-
|
43
41
|
# Capture packets from a network interface
|
44
42
|
# @param [String] iface interface name
|
45
43
|
# @param [Integer] snaplen
|
@@ -57,8 +55,6 @@ module PacketGen
|
|
57
55
|
pcap.each(&block)
|
58
56
|
end
|
59
57
|
|
60
|
-
# rubocop:enable Metrics/ParameterLists
|
61
|
-
|
62
58
|
# Inject given data onto wire
|
63
59
|
# @param [String] iface interface name
|
64
60
|
# @param [String] data to inject
|
@@ -62,7 +62,7 @@ module PacketGen
|
|
62
62
|
HUMAN_SEPARATOR = ','
|
63
63
|
|
64
64
|
# rubocop:disable Naming/AccessorMethodName
|
65
|
-
class <<self
|
65
|
+
class << self
|
66
66
|
# Get class set with {.set_of}.
|
67
67
|
# @return [Class]
|
68
68
|
# @since 3.0.0
|
@@ -154,6 +154,8 @@ module PacketGen
|
|
154
154
|
self
|
155
155
|
end
|
156
156
|
|
157
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
158
|
+
|
157
159
|
# Populate object from a string
|
158
160
|
# @param [String] str
|
159
161
|
# @return [self]
|
@@ -171,6 +173,7 @@ module PacketGen
|
|
171
173
|
end
|
172
174
|
self
|
173
175
|
end
|
176
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
174
177
|
|
175
178
|
# Get size in bytes
|
176
179
|
# @return [Integer]
|
@@ -228,18 +231,22 @@ module PacketGen
|
|
228
231
|
class ArrayOfInt8 < Array
|
229
232
|
set_of Int8
|
230
233
|
end
|
234
|
+
|
231
235
|
# Specialized array to handle serie of {Int16}.
|
232
236
|
class ArrayOfInt16 < Array
|
233
237
|
set_of Int16
|
234
238
|
end
|
239
|
+
|
235
240
|
# Specialized array to handle serie of {Int16le}.
|
236
241
|
class ArrayOfInt16le < Array
|
237
242
|
set_of Int16le
|
238
243
|
end
|
244
|
+
|
239
245
|
# Specialized array to handle serie of {Int32}.
|
240
246
|
class ArrayOfInt32 < Types::Array
|
241
247
|
set_of Types::Int32
|
242
248
|
end
|
249
|
+
|
243
250
|
# Specialized array to handle serie of {Int32le}.
|
244
251
|
class ArrayOfInt32le < Types::Array
|
245
252
|
set_of Types::Int32le
|
@@ -115,7 +115,7 @@ module PacketGen
|
|
115
115
|
# @private bit field definitions
|
116
116
|
@bit_fields = {}
|
117
117
|
|
118
|
-
class <<self
|
118
|
+
class << self
|
119
119
|
# Get field definitions for this class.
|
120
120
|
# @return [Hash]
|
121
121
|
# @since 3.1.0
|
@@ -282,7 +282,7 @@ module PacketGen
|
|
282
282
|
type = field_defs[attr].type
|
283
283
|
raise TypeError, "#{attr} is not a PacketGen::Types::Int" unless type < Types::Int
|
284
284
|
|
285
|
-
total_size = type.new.
|
285
|
+
total_size = type.new.nbits
|
286
286
|
idx = total_size - 1
|
287
287
|
|
288
288
|
until args.empty?
|
@@ -358,15 +358,15 @@ module PacketGen
|
|
358
358
|
clear_mask = compute_clear_mask(total_size, field_mask)
|
359
359
|
|
360
360
|
class_eval <<-METHODS
|
361
|
-
def #{name}?
|
362
|
-
val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift}
|
363
|
-
val != 0
|
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
|
361
|
+
def #{name}? # def bit?
|
362
|
+
val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift} # val = (self[:attr}].to_i & 1}) >> 1
|
363
|
+
val != 0 # val != 0
|
364
|
+
end # end
|
365
|
+
def #{name}=(v) # def bit=(v)
|
366
|
+
val = v ? 1 : 0 # val = v ? 1 : 0
|
367
|
+
self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask} # self[:attr].value = self[:attr].to_i & 0xfffd
|
368
|
+
self[:#{attr}].value |= val << #{shift} # self[:attr].value |= val << 1
|
369
|
+
end # end
|
370
370
|
METHODS
|
371
371
|
end
|
372
372
|
|
@@ -375,13 +375,13 @@ module PacketGen
|
|
375
375
|
clear_mask = compute_clear_mask(total_size, field_mask)
|
376
376
|
|
377
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
|
378
|
+
def #{name} # def multibit
|
379
|
+
(self[:#{attr}].to_i & #{field_mask}) >> #{shift} # (self[:attr].to_i & 6) >> 1
|
380
|
+
end # end
|
381
|
+
def #{name}=(v) # def multibit=(v)
|
382
|
+
self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask} # self[:attr].value = self[:attr].to_i & 0xfff9
|
383
|
+
self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift} # self[:attr].value |= (v & 3) << 1
|
384
|
+
end # end
|
385
385
|
METHODS
|
386
386
|
end
|
387
387
|
|
@@ -523,7 +523,7 @@ module PacketGen
|
|
523
523
|
# Return object as a hash
|
524
524
|
# @return [Hash] keys: attributes, values: attribute values
|
525
525
|
def to_h
|
526
|
-
|
526
|
+
fields.map { |f| [f, @fields[f].to_human] }.to_h
|
527
527
|
end
|
528
528
|
|
529
529
|
# Get offset of given field in {Fields} structure.
|
data/lib/packetgen/types/int.rb
CHANGED
data/lib/packetgen/types/oui.rb
CHANGED
data/lib/packetgen/types/tlv.rb
CHANGED
@@ -56,12 +56,8 @@ module PacketGen
|
|
56
56
|
def initialize(options={})
|
57
57
|
Deprecation.deprecated_class(self.class, AbstractTLV)
|
58
58
|
super
|
59
|
-
|
60
|
-
|
61
|
-
self[:value] = options[:v].new if options[:v]
|
62
|
-
self.type = options[:type] if options[:type]
|
63
|
-
self.value = options[:value] if options[:value]
|
64
|
-
self.length = options[:length] if options[:length]
|
59
|
+
initialize_types(options)
|
60
|
+
initialize_values(options)
|
65
61
|
end
|
66
62
|
|
67
63
|
# Populate object from a binary string
|
@@ -137,9 +133,9 @@ module PacketGen
|
|
137
133
|
else
|
138
134
|
'%s'
|
139
135
|
end
|
140
|
-
|
141
|
-
"#{name} type:#{@typestr} length:#{
|
142
|
-
|
136
|
+
lenstr = "%-#{(2**self[:length].nbits - 1).to_s.size}u"
|
137
|
+
"#{name} type:#{@typestr} length:#{lenstr} value:#{value.inspect}" % [human_type,
|
138
|
+
length]
|
143
139
|
end
|
144
140
|
|
145
141
|
private
|
@@ -147,6 +143,18 @@ module PacketGen
|
|
147
143
|
def human_types?
|
148
144
|
self.class.const_defined? :TYPES
|
149
145
|
end
|
146
|
+
|
147
|
+
def initialize_types(options)
|
148
|
+
self[:type] = options[:t].new(self.type) if options[:t]
|
149
|
+
self[:length] = options[:l].new(self.length) if options[:l]
|
150
|
+
self[:value] = options[:v].new if options[:v]
|
151
|
+
end
|
152
|
+
|
153
|
+
def initialize_values(options)
|
154
|
+
self.type = options[:type] if options[:type]
|
155
|
+
self.value = options[:value] if options[:value]
|
156
|
+
self.length = options[:length] if options[:length]
|
157
|
+
end
|
150
158
|
end
|
151
159
|
end
|
152
160
|
end
|