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
data/lib/packetgen/packet.rb
CHANGED
@@ -6,6 +6,8 @@
|
|
6
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
7
7
|
# This program is published under MIT license.
|
8
8
|
|
9
|
+
# rubocop:disable Metrics/ClassLength
|
10
|
+
|
9
11
|
module PacketGen
|
10
12
|
# An object of type {Packet} handles a network packet. This packet may contain
|
11
13
|
# multiple protocol headers, starting from MAC layer or from Network (OSI) layer.
|
@@ -77,10 +79,10 @@ module PacketGen
|
|
77
79
|
# @yieldparam [Packet,String] packet if a block is given, yield each
|
78
80
|
# captured packet (Packet or raw data String, depending on +:parse+ option)
|
79
81
|
# @return [Array<Packet>] captured packet
|
80
|
-
def self.capture(**kwargs)
|
81
|
-
capture = Capture.new(kwargs)
|
82
|
+
def self.capture(**kwargs, &block)
|
83
|
+
capture = Capture.new(**kwargs)
|
82
84
|
if block_given?
|
83
|
-
capture.start
|
85
|
+
capture.start(&block)
|
84
86
|
else
|
85
87
|
capture.start
|
86
88
|
end
|
@@ -522,5 +524,7 @@ module PacketGen
|
|
522
524
|
end
|
523
525
|
end
|
524
526
|
|
527
|
+
# rubocop:enable Metrics/ClassLength
|
528
|
+
|
525
529
|
require_relative 'headerable'
|
526
530
|
require_relative 'header'
|
data/lib/packetgen/pcapng.rb
CHANGED
@@ -13,13 +13,13 @@ module PacketGen
|
|
13
13
|
# @author Sylvain Daubert
|
14
14
|
module PcapNG
|
15
15
|
# Section Header Block type number
|
16
|
-
SHB_TYPE = Types::Int32.new(0x0A0D0D0A, :little)
|
16
|
+
SHB_TYPE = Types::Int32.new(0x0A0D0D0A, :little).freeze
|
17
17
|
# Interface Description Block type number
|
18
|
-
IDB_TYPE = Types::Int32.new(1, :little)
|
18
|
+
IDB_TYPE = Types::Int32.new(1, :little).freeze
|
19
19
|
# Simple Packet Block type number
|
20
|
-
SPB_TYPE = Types::Int32.new(3, :little)
|
20
|
+
SPB_TYPE = Types::Int32.new(3, :little).freeze
|
21
21
|
# Enhanced Packet Block type number
|
22
|
-
EPB_TYPE = Types::Int32.new(6, :little)
|
22
|
+
EPB_TYPE = Types::Int32.new(6, :little).freeze
|
23
23
|
|
24
24
|
# IEEE 802.3 Ethernet (10Mb, 100Mb, 1000Mb, and up)
|
25
25
|
LINKTYPE_ETHERNET = 1
|
@@ -46,10 +46,10 @@ module PacketGen
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
require_relative 'pcapng/block
|
50
|
-
require_relative 'pcapng/unknown_block
|
51
|
-
require_relative 'pcapng/shb
|
52
|
-
require_relative 'pcapng/idb
|
53
|
-
require_relative 'pcapng/epb
|
54
|
-
require_relative 'pcapng/spb
|
55
|
-
require_relative 'pcapng/file
|
49
|
+
require_relative 'pcapng/block'
|
50
|
+
require_relative 'pcapng/unknown_block'
|
51
|
+
require_relative 'pcapng/shb'
|
52
|
+
require_relative 'pcapng/idb'
|
53
|
+
require_relative 'pcapng/epb'
|
54
|
+
require_relative 'pcapng/spb'
|
55
|
+
require_relative 'pcapng/file'
|
@@ -49,7 +49,9 @@ module PacketGen
|
|
49
49
|
# @return [void]
|
50
50
|
def pad_field(*fields)
|
51
51
|
fields.each do |field|
|
52
|
-
|
52
|
+
obj = @fields[field]
|
53
|
+
pad_size = (obj.sz % 4).zero? ? 0 : (4 - (obj.sz % 4))
|
54
|
+
obj << "\x00" * pad_size
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
@@ -59,7 +61,7 @@ module PacketGen
|
|
59
61
|
# Must be called by all subclass #initialize method.
|
60
62
|
# @param [:little, :big] endian
|
61
63
|
# @return [:little, :big] returns endian
|
62
|
-
def
|
64
|
+
def endianness(endian)
|
63
65
|
raise ArgumentError, "unknown endianness for #{self.class}" unless %i[little big].include?(endian)
|
64
66
|
|
65
67
|
@endian = endian
|
@@ -76,6 +78,17 @@ module PacketGen
|
|
76
78
|
|
77
79
|
StringIO.new(force_binary(str_or_io.to_s))
|
78
80
|
end
|
81
|
+
|
82
|
+
def remove_padding(io, data_len)
|
83
|
+
data_pad_len = (4 - (data_len % 4)) % 4
|
84
|
+
io.read data_pad_len
|
85
|
+
data_pad_len
|
86
|
+
end
|
87
|
+
|
88
|
+
def read_blocklen2_and_check(io)
|
89
|
+
self[:block_len2].read io.read(4)
|
90
|
+
check_len_coherency
|
91
|
+
end
|
79
92
|
end
|
80
93
|
end
|
81
94
|
end
|
data/lib/packetgen/pcapng/epb.rb
CHANGED
@@ -73,7 +73,7 @@ module PacketGen
|
|
73
73
|
# @option options [Integer] :block_len2 block total length
|
74
74
|
def initialize(options={})
|
75
75
|
super
|
76
|
-
|
76
|
+
endianness(options[:endian] || :little)
|
77
77
|
recalc_block_len
|
78
78
|
self.type = options[:type] || PcapNG::EPB_TYPE.to_i
|
79
79
|
end
|
@@ -85,22 +85,13 @@ module PacketGen
|
|
85
85
|
io = to_io(str_or_io)
|
86
86
|
return self if io.eof?
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
self[:tsh].read io.read(4)
|
92
|
-
self[:tsl].read io.read(4)
|
93
|
-
self[:cap_len].read io.read(4)
|
94
|
-
self[:orig_len].read io.read(4)
|
88
|
+
%i[type block_len interface_id tsh tsl cap_len orig_len].each do |attr|
|
89
|
+
self[attr].read io.read(self[attr].sz)
|
90
|
+
end
|
95
91
|
self[:data].read io.read(self.cap_len)
|
96
|
-
|
97
|
-
io
|
98
|
-
options_len = self.block_len - self.cap_len - data_pad_len
|
99
|
-
options_len -= MIN_SIZE
|
100
|
-
self[:options].read io.read(options_len)
|
101
|
-
self[:block_len2].read io.read(4)
|
92
|
+
read_options(io)
|
93
|
+
read_blocklen2_and_check(io)
|
102
94
|
|
103
|
-
check_len_coherency
|
104
95
|
self
|
105
96
|
end
|
106
97
|
|
@@ -110,6 +101,16 @@ module PacketGen
|
|
110
101
|
Time.at((self.tsh << 32 | self.tsl) * ts_resol)
|
111
102
|
end
|
112
103
|
|
104
|
+
# Set timestamp from a Time object
|
105
|
+
# @param [Time] time
|
106
|
+
# @return [Time] time
|
107
|
+
def timestamp=(time)
|
108
|
+
tstamp = (time.to_r / ts_resol).to_i
|
109
|
+
self.tsh = (tstamp & 0xffffffff00000000) >> 32
|
110
|
+
self.tsl = tstamp & 0xffffffff
|
111
|
+
time
|
112
|
+
end
|
113
|
+
|
113
114
|
# Return the object as a String
|
114
115
|
# @return [String]
|
115
116
|
def to_s
|
@@ -127,6 +128,12 @@ module PacketGen
|
|
127
128
|
@interface.ts_resol
|
128
129
|
end
|
129
130
|
end
|
131
|
+
|
132
|
+
def read_options(io)
|
133
|
+
data_pad_len = remove_padding(io, self.cap_len)
|
134
|
+
options_len = self.block_len - self.cap_len - data_pad_len - MIN_SIZE
|
135
|
+
self[:options].read io.read(options_len)
|
136
|
+
end
|
130
137
|
end
|
131
138
|
end
|
132
139
|
end
|
@@ -22,9 +22,9 @@ module PacketGen
|
|
22
22
|
|
23
23
|
# @private
|
24
24
|
BLOCK_TYPES = Hash[
|
25
|
-
PcapNG.constants(false).select { |c| c.to_s
|
25
|
+
PcapNG.constants(false).select { |c| c.to_s.include?('_TYPE') }.map do |c|
|
26
26
|
type_value = PcapNG.const_get(c).to_i
|
27
|
-
klass = PcapNG.const_get(c.to_s[0..-6]) # use delete_suffix('_TYPE') when support for Ruby 2.4 will stop
|
27
|
+
klass = PcapNG.const_get(c.to_s[0..-6]) # @todo use delete_suffix('_TYPE') when support for Ruby 2.4 will stop
|
28
28
|
[type_value, klass]
|
29
29
|
end
|
30
30
|
].freeze
|
@@ -68,20 +68,13 @@ module PacketGen
|
|
68
68
|
def readfile(fname, &blk)
|
69
69
|
raise ArgumentError, "cannot read file #{fname}" unless ::File.readable?(fname)
|
70
70
|
|
71
|
-
::File.open(fname, 'rb')
|
72
|
-
parse_section(f) until f.eof?
|
73
|
-
end
|
74
|
-
|
71
|
+
::File.open(fname, 'rb') { |f| parse_section(f) until f.eof? }
|
75
72
|
return unless blk
|
76
73
|
|
77
74
|
count = 0
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
count += 1
|
82
|
-
yield pkt
|
83
|
-
end
|
84
|
-
end
|
75
|
+
each_packet_with_interface do |pkt, _itf|
|
76
|
+
count += 1
|
77
|
+
yield pkt
|
85
78
|
end
|
86
79
|
count
|
87
80
|
end
|
@@ -98,12 +91,10 @@ module PacketGen
|
|
98
91
|
# @return [Integer] number of packets
|
99
92
|
# @raise [ArgumentError] cannot read +fname+
|
100
93
|
def read_packet_bytes(fname, &blk)
|
101
|
-
count = 0
|
102
94
|
packets = [] unless blk
|
103
95
|
|
104
|
-
readfile(fname) do |packet|
|
96
|
+
count = readfile(fname) do |packet|
|
105
97
|
if blk
|
106
|
-
count += 1
|
107
98
|
yield packet.data.to_s, packet.interface.link_type
|
108
99
|
else
|
109
100
|
packets << packet.data.to_s
|
@@ -124,19 +115,11 @@ module PacketGen
|
|
124
115
|
# @return [Integer] number of packets
|
125
116
|
# @raise [ArgumentError] cannot read +fname+
|
126
117
|
def read_packets(fname, &blk)
|
127
|
-
count = 0
|
128
118
|
packets = [] unless blk
|
129
119
|
|
130
|
-
read_packet_bytes(fname) do |packet, link_type|
|
131
|
-
|
132
|
-
parsed_pkt = if first_header.nil?
|
133
|
-
# unknown link type, try to guess
|
134
|
-
Packet.parse(packet)
|
135
|
-
else
|
136
|
-
Packet.parse(packet, first_header: first_header)
|
137
|
-
end
|
120
|
+
count = read_packet_bytes(fname) do |packet, link_type|
|
121
|
+
parsed_pkt = parse_packet(packet, link_type)
|
138
122
|
if blk
|
139
|
-
count += 1
|
140
123
|
yield parsed_pkt
|
141
124
|
else
|
142
125
|
packets << parsed_pkt
|
@@ -158,6 +141,8 @@ module PacketGen
|
|
158
141
|
@sections.clear
|
159
142
|
end
|
160
143
|
|
144
|
+
# @deprecated
|
145
|
+
# Prefer use of {#to_a} or {#to_h}.
|
161
146
|
# Translates a {File} into an array of packets.
|
162
147
|
# @param [Hash] options
|
163
148
|
# @option options [String] :file if given, object is cleared and filename
|
@@ -167,37 +152,59 @@ module PacketGen
|
|
167
152
|
# as value. There is one hash per packet.
|
168
153
|
# @return [Array<Packet>,Array<Hash>]
|
169
154
|
def file_to_array(options={})
|
170
|
-
Deprecation.
|
171
|
-
Deprecation.deprecated_option(self.class, __method__, :keep_ts) if options[:keep_ts]
|
155
|
+
Deprecation.deprecated(self.class, __method__)
|
172
156
|
|
173
|
-
|
174
|
-
reread
|
157
|
+
file = options[:file] || options[:filename]
|
158
|
+
reread file
|
175
159
|
|
176
160
|
ary = []
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
161
|
+
blk = if options[:keep_timestamps] || options[:keep_ts]
|
162
|
+
proc { |pkt| { pkt.timestamp => pkt.data.to_s } }
|
163
|
+
else
|
164
|
+
proc { |pkt| pkt.data.to_s }
|
165
|
+
end
|
166
|
+
each_packet_with_interface do |pkt, _itf|
|
167
|
+
ary << blk.call(pkt)
|
168
|
+
end
|
169
|
+
|
170
|
+
ary
|
171
|
+
end
|
172
|
+
|
173
|
+
# Translates a {File} into an array of packets.
|
174
|
+
# @return [Array<Packet>]
|
175
|
+
# @since 3.1.6
|
176
|
+
def to_a
|
177
|
+
ary = []
|
178
|
+
each_packet_with_interface do |pkt, itf|
|
179
|
+
ary << parse_packet(pkt.data.to_s, itf.link_type)
|
186
180
|
end
|
181
|
+
|
187
182
|
ary
|
188
183
|
end
|
189
184
|
|
185
|
+
# Translates a {File} into a hash with timestamps as keys.
|
186
|
+
# @note Only packets from {EPB} sections are extracted, as {SPB} ones do not have timestamp.
|
187
|
+
# @return [Hash{Time => Packet}]
|
188
|
+
# @since 3.1.6
|
189
|
+
def to_h
|
190
|
+
hsh = {}
|
191
|
+
each_packet_with_interface do |pkt, itf|
|
192
|
+
next if pkt.is_a?(SPB)
|
193
|
+
|
194
|
+
hsh[pkt.timestamp] = parse_packet(pkt.data.to_s, itf.link_type)
|
195
|
+
end
|
196
|
+
|
197
|
+
hsh
|
198
|
+
end
|
199
|
+
|
190
200
|
# Writes the {File} to a file.
|
191
201
|
# @param [Hash] options
|
192
202
|
# @option options [Boolean] :append (default: +false+) if set to +true+,
|
193
203
|
# the packets are appended to the file, rather than overwriting it
|
194
204
|
# @return [Array] array of 2 elements: filename and size written
|
205
|
+
# @todo for 4.0, replace +options+ by +append+ kwarg
|
195
206
|
def to_file(filename, options={})
|
196
|
-
mode =
|
197
|
-
'ab'
|
198
|
-
else
|
199
|
-
'wb'
|
200
|
-
end
|
207
|
+
mode = (options[:append] && ::File.exist?(filename)) ? 'ab' : 'wb'
|
201
208
|
::File.open(filename, mode) { |f| f.write(self.to_s) }
|
202
209
|
[filename, self.to_s.size]
|
203
210
|
end
|
@@ -217,6 +224,7 @@ module PacketGen
|
|
217
224
|
self.to_file(filename.to_s, append: true)
|
218
225
|
end
|
219
226
|
|
227
|
+
# @deprecated Prefer use of {#read_array} or {#read_hash}.
|
220
228
|
# @overload array_to_file(ary)
|
221
229
|
# Update {File} object with packets.
|
222
230
|
# @param [Array] ary as generated by {#file_to_array} or Array of Packet objects.
|
@@ -238,12 +246,10 @@ module PacketGen
|
|
238
246
|
filename, ary, ts, ts_inc, append = array_to_file_options(options)
|
239
247
|
|
240
248
|
section = create_new_shb_section
|
241
|
-
ts_resol = section.interfaces.last.ts_resol
|
242
249
|
|
243
|
-
ts_add_val = 0 # value to add to ts in Array case
|
244
250
|
ary.each do |pkt|
|
245
|
-
classify_block(section, epb_from_pkt(pkt, section
|
246
|
-
|
251
|
+
classify_block(section, epb_from_pkt(pkt, section, ts))
|
252
|
+
ts += ts_inc
|
247
253
|
end
|
248
254
|
|
249
255
|
if filename
|
@@ -253,6 +259,52 @@ module PacketGen
|
|
253
259
|
end
|
254
260
|
end
|
255
261
|
|
262
|
+
# Update current object from an array of packets
|
263
|
+
# @param [Array<Packet>] packets
|
264
|
+
# @param [Time, nil] timestamp initial timestamp, used for first packet
|
265
|
+
# @param [Numeric, nil] ts_inc timestamp increment, in seconds, to increment
|
266
|
+
# initial timestamp for each packet
|
267
|
+
# @return [void]
|
268
|
+
# @note if +timestamp+ and/or +ts_inc+ are nil, {SPB} sections are created
|
269
|
+
# for each packet, else {EPB} ones are used
|
270
|
+
# @since 3.1.6
|
271
|
+
def read_array(packets, timestamp: nil, ts_inc: nil)
|
272
|
+
ts = timestamp
|
273
|
+
section = create_new_shb_section
|
274
|
+
packets.each do |pkt|
|
275
|
+
block = create_block_from_pkt(pkt, section, ts, ts_inc)
|
276
|
+
classify_block(section, block)
|
277
|
+
ts = update_ts(ts, ts_inc)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# Update current object from a hash of packets and timestamps
|
282
|
+
# @param [Hash{Time => Packet}] hsh
|
283
|
+
# @return [void]
|
284
|
+
# @since 3.1.6
|
285
|
+
def read_hash(hsh)
|
286
|
+
section = create_new_shb_section
|
287
|
+
hsh.each do |ts, pkt|
|
288
|
+
block = create_block_from_pkt(pkt, section, ts, 0)
|
289
|
+
classify_block(section, block)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# @return [String]
|
294
|
+
# @since 3.1.6
|
295
|
+
def inspect
|
296
|
+
str = +''
|
297
|
+
sections.each do |section|
|
298
|
+
str << section.inspect
|
299
|
+
section.interfaces.each do |itf|
|
300
|
+
str << itf.inspect
|
301
|
+
itf.packets.each { |block| str << block.inspect }
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
str
|
306
|
+
end
|
307
|
+
|
256
308
|
private
|
257
309
|
|
258
310
|
# Parse a section. A section is made of at least a SHB. It than may contain
|
@@ -260,8 +312,7 @@ module PacketGen
|
|
260
312
|
# @param [IO] io
|
261
313
|
# @return [void]
|
262
314
|
def parse_section(io)
|
263
|
-
shb = SHB.new
|
264
|
-
shb = parse_shb(shb, io)
|
315
|
+
shb = parse_shb(SHB.new, io)
|
265
316
|
raise InvalidFileError, 'no Section header found' unless shb.is_a?(SHB)
|
266
317
|
|
267
318
|
to_parse = if shb.section_len.to_i != 0xffffffffffffffff
|
@@ -294,17 +345,18 @@ module PacketGen
|
|
294
345
|
# @param [SHB] shb header of current section
|
295
346
|
# @return [Block]
|
296
347
|
def parse(type, io, shb)
|
297
|
-
|
298
|
-
BLOCK_TYPES[type.to_i]
|
299
|
-
else
|
300
|
-
UnknownBlock
|
301
|
-
end
|
302
|
-
|
303
|
-
block = klass.new(endian: shb.endian)
|
348
|
+
block = guess_block_type(type).new(endian: shb.endian)
|
304
349
|
classify_block shb, block
|
305
350
|
block.read(io)
|
306
351
|
end
|
307
352
|
|
353
|
+
# Guess class to use from type
|
354
|
+
# @param [Types::Int] type
|
355
|
+
# @return [Block]
|
356
|
+
def guess_block_type(type)
|
357
|
+
BLOCK_TYPES.key?(type.to_i) ? BLOCK_TYPES[type.to_i] : UnknownBlock
|
358
|
+
end
|
359
|
+
|
308
360
|
# Classify block from its type
|
309
361
|
# @param [SHB] shb header of current section
|
310
362
|
# @param [Block] block block to classify
|
@@ -315,16 +367,11 @@ module PacketGen
|
|
315
367
|
@sections << block
|
316
368
|
when IDB
|
317
369
|
shb << block
|
318
|
-
|
319
|
-
|
320
|
-
shb.interfaces[
|
321
|
-
block.interface = shb.interfaces[block.interface_id]
|
322
|
-
when SPB
|
323
|
-
shb.interfaces[0] << block
|
324
|
-
block.interface = shb.interfaces[0]
|
370
|
+
when SPB, EPB
|
371
|
+
ifid = block.is_a?(EPB) ? block.interface_id : 0
|
372
|
+
shb.interfaces[ifid] << block
|
325
373
|
else
|
326
|
-
shb.
|
327
|
-
block.section = shb
|
374
|
+
shb.add_unknown_block(block)
|
328
375
|
end
|
329
376
|
end
|
330
377
|
|
@@ -341,9 +388,9 @@ module PacketGen
|
|
341
388
|
|
342
389
|
# Extract and check options for #array_to_file
|
343
390
|
def array_to_file_options_from_hash(options)
|
344
|
-
|
345
|
-
|
346
|
-
|
391
|
+
%i[filename arr ts].each do |deprecated_opt|
|
392
|
+
Deprecation.deprecated_option(self.class, :array_to_file, deprecated_opt) if options[deprecated_opt]
|
393
|
+
end
|
347
394
|
|
348
395
|
filename = options[:filename] || options[:file]
|
349
396
|
ary = options[:array] || options[:arr]
|
@@ -368,10 +415,8 @@ module PacketGen
|
|
368
415
|
# Compute tsh and tsl from ts
|
369
416
|
def calc_ts(timeslot, ts_resol)
|
370
417
|
this_ts = (timeslot / ts_resol).to_i
|
371
|
-
this_tsh = this_ts >> 32
|
372
|
-
this_tsl = this_ts & 0xffffffff
|
373
418
|
|
374
|
-
[
|
419
|
+
[this_ts >> 32, this_ts & 0xffffffff]
|
375
420
|
end
|
376
421
|
|
377
422
|
def reread(filename)
|
@@ -381,18 +426,34 @@ module PacketGen
|
|
381
426
|
readfile filename
|
382
427
|
end
|
383
428
|
|
384
|
-
def
|
385
|
-
|
386
|
-
|
387
|
-
this_ts = pkt.keys.first.to_i
|
388
|
-
this_data = pkt.values.first.to_s
|
429
|
+
def create_block_from_pkt(pkt, section, timestamp, ts_inc)
|
430
|
+
if timestamp.nil? || ts_inc.nil?
|
431
|
+
spb_from_pkt(pkt, section)
|
389
432
|
else
|
390
|
-
|
391
|
-
this_data = pkt.to_s
|
433
|
+
epb_from_pkt(pkt, section, timestamp)
|
392
434
|
end
|
435
|
+
end
|
436
|
+
|
437
|
+
def spb_from_pkt(pkt, section)
|
438
|
+
pkt_s = pkt.to_s
|
439
|
+
size = pkt_s.size
|
440
|
+
SPB.new(endian: section.endian,
|
441
|
+
block_len: size,
|
442
|
+
orig_len: size,
|
443
|
+
data: pkt_s)
|
444
|
+
end
|
445
|
+
|
446
|
+
# @todo remove hash case when #array_to_file will be removed
|
447
|
+
def epb_from_pkt(pkt, section, timestamp)
|
448
|
+
this_ts, this_data = case pkt
|
449
|
+
when Hash
|
450
|
+
[pkt.keys.first.to_i, pkt.values.first.to_s]
|
451
|
+
else
|
452
|
+
[timestamp.to_r, pkt.to_s]
|
453
|
+
end
|
393
454
|
this_cap_len = this_data.size
|
394
|
-
this_tsh, this_tsl = calc_ts(this_ts, ts_resol)
|
395
|
-
EPB.new(endian: endian,
|
455
|
+
this_tsh, this_tsl = calc_ts(this_ts, section.interfaces.last.ts_resol)
|
456
|
+
EPB.new(endian: section.endian,
|
396
457
|
interface_id: 0,
|
397
458
|
tsh: this_tsh,
|
398
459
|
tsl: this_tsl,
|
@@ -400,6 +461,28 @@ module PacketGen
|
|
400
461
|
orig_len: this_cap_len,
|
401
462
|
data: this_data)
|
402
463
|
end
|
464
|
+
|
465
|
+
def update_ts(timestamp, ts_inc)
|
466
|
+
return nil if timestamp.nil? || ts_inc.nil?
|
467
|
+
|
468
|
+
timestamp + ts_inc
|
469
|
+
end
|
470
|
+
|
471
|
+
# Iterate over each xPB with its associated interface
|
472
|
+
# @return [void]
|
473
|
+
# @yieldparam [String] xpb
|
474
|
+
# @yieldparam [IDB] itf
|
475
|
+
def each_packet_with_interface
|
476
|
+
sections.each do |section|
|
477
|
+
section.interfaces.each do |itf|
|
478
|
+
itf.packets.each { |xpb| yield xpb, itf }
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
def parse_packet(data, link_type)
|
484
|
+
Packet.parse(data, first_header: KNOWN_LINK_TYPES[link_type])
|
485
|
+
end
|
403
486
|
end
|
404
487
|
end
|
405
488
|
end
|