packetgen 3.1.3 → 3.1.4
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/lib/packetgen.rb +24 -2
- data/lib/packetgen/capture.rb +30 -24
- data/lib/packetgen/config.rb +2 -2
- data/lib/packetgen/deprecation.rb +33 -7
- data/lib/packetgen/header.rb +2 -9
- data/lib/packetgen/header/arp.rb +2 -2
- data/lib/packetgen/header/asn1_base.rb +2 -2
- data/lib/packetgen/header/base.rb +2 -4
- data/lib/packetgen/header/bootp.rb +3 -3
- data/lib/packetgen/header/dhcp.rb +2 -2
- data/lib/packetgen/header/dhcp/option.rb +2 -2
- data/lib/packetgen/header/dhcp/options.rb +2 -2
- data/lib/packetgen/header/dhcpv6.rb +12 -12
- data/lib/packetgen/header/dhcpv6/duid.rb +8 -4
- data/lib/packetgen/header/dhcpv6/option.rb +4 -4
- data/lib/packetgen/header/dhcpv6/options.rb +2 -2
- data/lib/packetgen/header/dhcpv6/relay.rb +2 -2
- data/lib/packetgen/header/dns.rb +9 -9
- data/lib/packetgen/header/dns/name.rb +2 -2
- data/lib/packetgen/header/dns/opt.rb +2 -2
- data/lib/packetgen/header/dns/option.rb +2 -2
- data/lib/packetgen/header/dns/qdsection.rb +2 -2
- data/lib/packetgen/header/dns/question.rb +35 -35
- data/lib/packetgen/header/dns/rr.rb +3 -3
- data/lib/packetgen/header/dns/rrsection.rb +2 -2
- data/lib/packetgen/header/dot11.rb +5 -13
- data/lib/packetgen/header/dot11/control.rb +5 -5
- data/lib/packetgen/header/dot11/data.rb +2 -2
- data/lib/packetgen/header/dot11/element.rb +16 -16
- data/lib/packetgen/header/dot11/management.rb +2 -2
- data/lib/packetgen/header/dot11/sub_mngt.rb +2 -12
- data/lib/packetgen/header/dot1q.rb +2 -2
- data/lib/packetgen/header/dot1x.rb +6 -6
- data/lib/packetgen/header/eap.rb +16 -16
- data/lib/packetgen/header/eap/fast.rb +2 -2
- data/lib/packetgen/header/eap/md5.rb +2 -2
- data/lib/packetgen/header/eap/tls.rb +2 -2
- data/lib/packetgen/header/eap/ttls.rb +2 -2
- data/lib/packetgen/header/eth.rb +8 -5
- data/lib/packetgen/header/gre.rb +2 -2
- data/lib/packetgen/header/http.rb +2 -0
- data/lib/packetgen/header/http/headers.rb +2 -2
- data/lib/packetgen/header/http/request.rb +5 -5
- data/lib/packetgen/header/http/response.rb +6 -6
- data/lib/packetgen/header/http/verbs.rb +2 -2
- data/lib/packetgen/header/icmp.rb +2 -2
- data/lib/packetgen/header/icmpv6.rb +2 -2
- data/lib/packetgen/header/igmp.rb +4 -4
- data/lib/packetgen/header/igmpv3.rb +3 -3
- data/lib/packetgen/header/igmpv3/group_record.rb +6 -6
- data/lib/packetgen/header/igmpv3/mq.rb +2 -2
- data/lib/packetgen/header/igmpv3/mr.rb +2 -2
- data/lib/packetgen/header/ip.rb +3 -5
- data/lib/packetgen/header/ip/addr.rb +7 -2
- data/lib/packetgen/header/ip/option.rb +4 -6
- data/lib/packetgen/header/ip/options.rb +3 -5
- data/lib/packetgen/header/ipv6.rb +2 -2
- data/lib/packetgen/header/ipv6/addr.rb +7 -2
- data/lib/packetgen/header/ipv6/extension.rb +2 -2
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +3 -3
- data/lib/packetgen/header/llc.rb +2 -2
- data/lib/packetgen/header/mdns.rb +2 -2
- data/lib/packetgen/header/mld.rb +2 -2
- data/lib/packetgen/header/mldv2.rb +2 -2
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +2 -2
- data/lib/packetgen/header/mldv2/mlq.rb +2 -2
- data/lib/packetgen/header/mldv2/mlr.rb +2 -2
- data/lib/packetgen/header/ospfv2.rb +9 -9
- data/lib/packetgen/header/ospfv2/db_description.rb +2 -2
- data/lib/packetgen/header/ospfv2/hello.rb +2 -2
- data/lib/packetgen/header/ospfv2/ls_ack.rb +2 -2
- data/lib/packetgen/header/ospfv2/ls_request.rb +2 -2
- data/lib/packetgen/header/ospfv2/ls_update.rb +2 -2
- data/lib/packetgen/header/ospfv2/lsa.rb +3 -5
- data/lib/packetgen/header/ospfv2/lsa_header.rb +6 -6
- data/lib/packetgen/header/ospfv3.rb +2 -2
- data/lib/packetgen/header/ospfv3/db_description.rb +2 -2
- data/lib/packetgen/header/ospfv3/hello.rb +2 -2
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +2 -2
- data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -2
- data/lib/packetgen/header/ospfv3/ls_request.rb +2 -2
- data/lib/packetgen/header/ospfv3/ls_update.rb +2 -2
- data/lib/packetgen/header/ospfv3/lsa.rb +3 -5
- data/lib/packetgen/header/ospfv3/lsa_header.rb +7 -7
- data/lib/packetgen/header/snmp.rb +31 -28
- data/lib/packetgen/header/tcp.rb +3 -3
- data/lib/packetgen/header/tcp/option.rb +3 -5
- data/lib/packetgen/header/tcp/options.rb +2 -2
- data/lib/packetgen/header/tftp.rb +6 -6
- data/lib/packetgen/header/udp.rb +3 -3
- data/lib/packetgen/headerable.rb +5 -4
- data/lib/packetgen/inject.rb +23 -0
- data/lib/packetgen/inspect.rb +24 -5
- data/lib/packetgen/packet.rb +76 -51
- data/lib/packetgen/pcap.rb +29 -0
- data/lib/packetgen/pcapng.rb +2 -2
- data/lib/packetgen/pcapng/block.rb +12 -12
- data/lib/packetgen/pcapng/epb.rb +3 -7
- data/lib/packetgen/pcapng/file.rb +134 -95
- data/lib/packetgen/pcapng/idb.rb +30 -30
- data/lib/packetgen/pcapng/shb.rb +25 -34
- data/lib/packetgen/pcapng/spb.rb +4 -8
- data/lib/packetgen/pcapng/unknown_block.rb +2 -2
- data/lib/packetgen/pcaprub_wrapper.rb +67 -0
- data/lib/packetgen/proto.rb +2 -2
- data/lib/packetgen/types.rb +2 -0
- data/lib/packetgen/types/abstract_tlv.rb +24 -6
- data/lib/packetgen/types/array.rb +5 -5
- data/lib/packetgen/types/cstring.rb +2 -2
- data/lib/packetgen/types/enum.rb +3 -2
- data/lib/packetgen/types/fields.rb +5 -7
- data/lib/packetgen/types/int.rb +3 -5
- data/lib/packetgen/types/int_string.rb +2 -2
- data/lib/packetgen/types/length_from.rb +3 -3
- data/lib/packetgen/types/oui.rb +2 -2
- data/lib/packetgen/types/string.rb +2 -2
- data/lib/packetgen/types/tlv.rb +2 -2
- data/lib/packetgen/utils.rb +2 -2
- data/lib/packetgen/utils/arp_spoofer.rb +2 -2
- data/lib/packetgen/version.rb +3 -3
- metadata +26 -50
- data/.gitignore +0 -13
- data/.rubocop.yml +0 -30
- data/.travis.yml +0 -19
- data/Gemfile +0 -4
- data/Rakefile +0 -21
- data/packetgen.gemspec +0 -36
@@ -0,0 +1,29 @@
|
|
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
|
+
require_relative 'pcaprub_wrapper'
|
8
|
+
|
9
|
+
module PacketGen
|
10
|
+
# Module to read PCAP files
|
11
|
+
# @author Sylvain Daubert
|
12
|
+
# @api private
|
13
|
+
# @since 3.1.4
|
14
|
+
module Pcap
|
15
|
+
# Read a PCAP file
|
16
|
+
# @param [String] filename
|
17
|
+
# @return [Array<Packet>]
|
18
|
+
# @author Kent Gruber
|
19
|
+
def self.read(filename)
|
20
|
+
packets = []
|
21
|
+
PCAPRUBWrapper.read_pcap(filename: filename) do |packet|
|
22
|
+
next unless (packet = PacketGen.parse(packet.to_s))
|
23
|
+
|
24
|
+
packets << packet
|
25
|
+
end
|
26
|
+
packets
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/packetgen/pcapng.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of PacketGen
|
2
4
|
# See https://github.com/sdaubert/packetgen for more informations
|
3
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
require 'stringio'
|
9
9
|
|
10
10
|
module PacketGen
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of PacketGen
|
2
4
|
# See https://github.com/sdaubert/packetgen for more informations
|
3
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen
|
9
9
|
module PcapNG
|
10
10
|
# @abstract Base class for all block types
|
@@ -34,7 +34,7 @@ module PacketGen
|
|
34
34
|
# @return [Boolean]
|
35
35
|
# @since 2.7.0
|
36
36
|
def options?
|
37
|
-
@fields.key?(:options) && @fields[:options].sz
|
37
|
+
@fields.key?(:options) && @fields[:options].sz.positive?
|
38
38
|
end
|
39
39
|
|
40
40
|
# Calculate block length and update :block_len and block_len2 fields
|
@@ -49,9 +49,7 @@ module PacketGen
|
|
49
49
|
# @return [void]
|
50
50
|
def pad_field(*fields)
|
51
51
|
fields.each do |field|
|
52
|
-
unless (@fields[field].sz % 4).zero?
|
53
|
-
@fields[field] << "\x00" * (4 - (@fields[field].sz % 4))
|
54
|
-
end
|
52
|
+
@fields[field] << "\x00" * (4 - (@fields[field].sz % 4)) unless (@fields[field].sz % 4).zero?
|
55
53
|
end
|
56
54
|
end
|
57
55
|
|
@@ -62,9 +60,7 @@ module PacketGen
|
|
62
60
|
# @param [:little, :big] endian
|
63
61
|
# @return [:little, :big] returns endian
|
64
62
|
def set_endianness(endian)
|
65
|
-
unless %i[little big].include?
|
66
|
-
raise ArgumentError, "unknown endianness for #{self.class}"
|
67
|
-
end
|
63
|
+
raise ArgumentError, "unknown endianness for #{self.class}" unless %i[little big].include?(endian)
|
68
64
|
|
69
65
|
@endian = endian
|
70
66
|
@fields.each { |_f, v| v.endian = endian if v.is_a?(Types::Int) }
|
@@ -72,9 +68,13 @@ module PacketGen
|
|
72
68
|
end
|
73
69
|
|
74
70
|
def check_len_coherency
|
75
|
-
unless self.block_len == self.block_len2
|
76
|
-
|
77
|
-
|
71
|
+
raise InvalidFileError, 'Incoherency in Block length' unless self.block_len == self.block_len2
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_io(str_or_io)
|
75
|
+
return str_or_io if str_or_io.respond_to? :read
|
76
|
+
|
77
|
+
StringIO.new(force_binary(str_or_io.to_s))
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
data/lib/packetgen/pcapng/epb.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of PacketGen
|
2
4
|
# See https://github.com/sdaubert/packetgen for more informations
|
3
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen
|
9
9
|
module PcapNG
|
10
10
|
# {EPB} represents a Enhanced Packet Block (EPB) of a pcapng file.
|
@@ -82,11 +82,7 @@ module PacketGen
|
|
82
82
|
# @param [::String,IO] str_or_io
|
83
83
|
# @return [self]
|
84
84
|
def read(str_or_io)
|
85
|
-
io =
|
86
|
-
str_or_io
|
87
|
-
else
|
88
|
-
StringIO.new(force_binary(str_or_io.to_s))
|
89
|
-
end
|
85
|
+
io = to_io(str_or_io)
|
90
86
|
return self if io.eof?
|
91
87
|
|
92
88
|
self[:type].read io.read(4)
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of PacketGen
|
2
4
|
# See https://github.com/sdaubert/packetgen for more informations
|
3
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen
|
9
9
|
module PcapNG
|
10
10
|
# PcapNG::File is a complete Pcap-NG file handler.
|
@@ -20,6 +20,15 @@ module PacketGen
|
|
20
20
|
LINKTYPE_IPV6 => 'IPv6'
|
21
21
|
}.freeze
|
22
22
|
|
23
|
+
# @private
|
24
|
+
BLOCK_TYPES = Hash[
|
25
|
+
PcapNG.constants(false).select { |c| c.to_s =~ /_TYPE/ }.map do |c|
|
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
|
28
|
+
[type_value, klass]
|
29
|
+
end
|
30
|
+
].freeze
|
31
|
+
|
23
32
|
# Get file sections
|
24
33
|
# @return [Array]
|
25
34
|
attr_accessor :sections
|
@@ -57,9 +66,7 @@ module PacketGen
|
|
57
66
|
# @return [Integer] return number of yielded blocks (only if a block is given)
|
58
67
|
# @raise [ArgumentError] cannot read +fname+
|
59
68
|
def readfile(fname, &blk)
|
60
|
-
unless ::File.readable?(fname)
|
61
|
-
raise ArgumentError, "cannot read file #{fname}"
|
62
|
-
end
|
69
|
+
raise ArgumentError, "cannot read file #{fname}" unless ::File.readable?(fname)
|
63
70
|
|
64
71
|
::File.open(fname, 'rb') do |f|
|
65
72
|
parse_section(f) until f.eof?
|
@@ -153,29 +160,28 @@ module PacketGen
|
|
153
160
|
|
154
161
|
# Translates a {File} into an array of packets.
|
155
162
|
# @param [Hash] options
|
156
|
-
# @option options [String] :
|
163
|
+
# @option options [String] :file if given, object is cleared and filename
|
157
164
|
# is analyzed before generating array. Else, array is generated from +self+
|
158
|
-
# @option options [String] :file same as +:filename+
|
159
165
|
# @option options [Boolean] :keep_timestamps if +true+ (default value: +false+),
|
160
166
|
# generates an array of hashes, each one with timestamp as key and packet
|
161
167
|
# as value. There is one hash per packet.
|
162
|
-
# @option options [Boolean] :keep_ts same as +:keep_timestamp+
|
163
168
|
# @return [Array<Packet>,Array<Hash>]
|
164
169
|
def file_to_array(options={})
|
170
|
+
Deprecation.deprecated_option(self.class, __method__, :filename) if options[:filename]
|
171
|
+
Deprecation.deprecated_option(self.class, __method__, :keep_ts) if options[:keep_ts]
|
172
|
+
|
165
173
|
filename = options[:filename] || options[:file]
|
166
|
-
|
167
|
-
clear
|
168
|
-
readfile filename
|
169
|
-
end
|
174
|
+
reread filename
|
170
175
|
|
171
176
|
ary = []
|
172
177
|
@sections.each do |section|
|
173
178
|
section.interfaces.each do |itf|
|
174
|
-
if options[:keep_timestamps] || options[:keep_ts]
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
+
blk = if options[:keep_timestamps] || options[:keep_ts]
|
180
|
+
proc { |pkt| { pkt.timestamp => pkt.data.to_s } }
|
181
|
+
else
|
182
|
+
proc { |pkt| pkt.data.to_s }
|
183
|
+
end
|
184
|
+
ary.concat(itf.packets.map(&blk))
|
179
185
|
end
|
180
186
|
end
|
181
187
|
ary
|
@@ -219,7 +225,7 @@ module PacketGen
|
|
219
225
|
# @overload array_to_file(options={})
|
220
226
|
# Update {File} and/or write it to a file
|
221
227
|
# @param [Hash] options
|
222
|
-
# @option options [String] :
|
228
|
+
# @option options [String] :file file written on disk only if given
|
223
229
|
# @option options [Array] :array can either be an array of packet data,
|
224
230
|
# or a hash-value pair of timestamp => data.
|
225
231
|
# @option options [Time] :timestamp set an initial timestamp
|
@@ -229,53 +235,15 @@ module PacketGen
|
|
229
235
|
# the file
|
230
236
|
# @return [Array] see return value from {#to_file}
|
231
237
|
def array_to_file(options={})
|
232
|
-
|
233
|
-
when Hash
|
234
|
-
filename = options[:filename] || options[:file]
|
235
|
-
ary = options[:array] || options[:arr]
|
236
|
-
unless ary.is_a? Array
|
237
|
-
raise ArgumentError, ':array parameter needs to be an array'
|
238
|
-
end
|
239
|
-
ts = options[:timestamp] || options[:ts] || Time.now
|
240
|
-
ts_inc = options[:ts_inc] || 1
|
241
|
-
append = !options[:append].nil?
|
242
|
-
when Array
|
243
|
-
ary = options
|
244
|
-
ts = Time.now
|
245
|
-
ts_inc = 1
|
246
|
-
filename = nil
|
247
|
-
append = false
|
248
|
-
else
|
249
|
-
raise ArgumentError, 'unknown argument. Need either a Hash or Array'
|
250
|
-
end
|
238
|
+
filename, ary, ts, ts_inc, append = array_to_file_options(options)
|
251
239
|
|
252
|
-
section =
|
253
|
-
|
254
|
-
itf = IDB.new(endian: section.endian)
|
255
|
-
classify_block section, itf
|
240
|
+
section = create_new_shb_section
|
241
|
+
ts_resol = section.interfaces.last.ts_resol
|
256
242
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
this_cap_len = pkt.values.first.to_s.size
|
262
|
-
this_data = pkt.values.first.to_s
|
263
|
-
else
|
264
|
-
this_ts = (ts + ts_inc * i).to_i
|
265
|
-
this_cap_len = pkt.to_s.size
|
266
|
-
this_data = pkt.to_s
|
267
|
-
end
|
268
|
-
this_ts = (this_ts / itf.ts_resol).to_i
|
269
|
-
this_tsh = this_ts >> 32
|
270
|
-
this_tsl = this_ts & 0xffffffff
|
271
|
-
this_pkt = EPB.new(endian: section.endian,
|
272
|
-
interface_id: 0,
|
273
|
-
tsh: this_tsh,
|
274
|
-
tsl: this_tsl,
|
275
|
-
cap_len: this_cap_len,
|
276
|
-
orig_len: this_cap_len,
|
277
|
-
data: this_data)
|
278
|
-
classify_block section, this_pkt
|
243
|
+
ts_add_val = 0 # value to add to ts in Array case
|
244
|
+
ary.each do |pkt|
|
245
|
+
classify_block(section, epb_from_pkt(pkt, section.endian, ts, ts_resol, ts_add_val))
|
246
|
+
ts_add_val += ts_inc
|
279
247
|
end
|
280
248
|
|
281
249
|
if filename
|
@@ -288,53 +256,51 @@ module PacketGen
|
|
288
256
|
private
|
289
257
|
|
290
258
|
# Parse a section. A section is made of at least a SHB. It than may contain
|
291
|
-
# others blocks, such as
|
259
|
+
# others blocks, such as IDB, SPB or EPB.
|
292
260
|
# @param [IO] io
|
293
261
|
# @return [void]
|
294
262
|
def parse_section(io)
|
295
263
|
shb = SHB.new
|
296
|
-
|
297
|
-
io.seek(-4, IO::SEEK_CUR)
|
298
|
-
shb = parse(type, io, shb)
|
264
|
+
shb = parse_shb(shb, io)
|
299
265
|
raise InvalidFileError, 'no Section header found' unless shb.is_a?(SHB)
|
300
266
|
|
301
|
-
if shb.section_len.to_i != 0xffffffffffffffff
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
until io.eof?
|
313
|
-
shb = @sections.last
|
314
|
-
type = Types::Int32.new(0, shb.endian).read(io.read(4))
|
315
|
-
io.seek(-4, IO::SEEK_CUR)
|
316
|
-
parse(type, io, shb)
|
317
|
-
end
|
267
|
+
to_parse = if shb.section_len.to_i != 0xffffffffffffffff
|
268
|
+
# Section length is defined
|
269
|
+
StringIO.new(io.read(shb.section_len.to_i))
|
270
|
+
else
|
271
|
+
# section length is undefined
|
272
|
+
io
|
273
|
+
end
|
274
|
+
|
275
|
+
until to_parse.eof?
|
276
|
+
shb = @sections.last
|
277
|
+
parse_shb shb, to_parse
|
318
278
|
end
|
319
279
|
end
|
320
280
|
|
281
|
+
# Parse a SHB
|
282
|
+
# @param [SHB] shb SHB to parse
|
283
|
+
# @param [IO] io stream from which parse SHB
|
284
|
+
# @return [SHB]
|
285
|
+
def parse_shb(shb, io)
|
286
|
+
type = Types::Int32.new(0, shb.endian).read(io.read(4))
|
287
|
+
io.seek(-4, IO::SEEK_CUR)
|
288
|
+
parse(type, io, shb)
|
289
|
+
end
|
290
|
+
|
321
291
|
# Parse a block from its type
|
322
292
|
# @param [Types::Int32] type
|
323
293
|
# @param [IO] io stream from which parse block
|
324
294
|
# @param [SHB] shb header of current section
|
325
|
-
# @return [
|
295
|
+
# @return [Block]
|
326
296
|
def parse(type, io, shb)
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
klass = PcapNG.const_get(types[type.to_i].to_s.gsub(/_TYPE/, '').to_sym)
|
333
|
-
block = klass.new(endian: shb.endian)
|
334
|
-
else
|
335
|
-
block = UnknownBlock.new(endian: shb.endian)
|
336
|
-
end
|
297
|
+
klass = if BLOCK_TYPES.key?(type.to_i)
|
298
|
+
BLOCK_TYPES[type.to_i]
|
299
|
+
else
|
300
|
+
UnknownBlock
|
301
|
+
end
|
337
302
|
|
303
|
+
block = klass.new(endian: shb.endian)
|
338
304
|
classify_block shb, block
|
339
305
|
block.read(io)
|
340
306
|
end
|
@@ -361,6 +327,79 @@ module PacketGen
|
|
361
327
|
block.section = shb
|
362
328
|
end
|
363
329
|
end
|
330
|
+
|
331
|
+
def array_to_file_options(options)
|
332
|
+
case options
|
333
|
+
when Hash
|
334
|
+
array_to_file_options_from_hash(options)
|
335
|
+
when Array
|
336
|
+
[nil, options, Time.now, 1, false]
|
337
|
+
else
|
338
|
+
raise ArgumentError, 'unknown argument. Need either a Hash or Array'
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# Extract and check options for #array_to_file
|
343
|
+
def array_to_file_options_from_hash(options)
|
344
|
+
Deprecation.deprecated_option(self.class, :array_to_file, :filename) if options[:filename]
|
345
|
+
Deprecation.deprecated_option(self.class, :array_to_file, :arr) if options[:arr]
|
346
|
+
Deprecation.deprecated_option(self.class, :array_to_file, :ts) if options[:ts]
|
347
|
+
|
348
|
+
filename = options[:filename] || options[:file]
|
349
|
+
ary = options[:array] || options[:arr]
|
350
|
+
raise ArgumentError, ':array parameter needs to be an array' unless ary.is_a? Array
|
351
|
+
|
352
|
+
ts = options[:timestamp] || options[:ts] || Time.now
|
353
|
+
ts_inc = options[:ts_inc] || 1
|
354
|
+
append = !options[:append].nil?
|
355
|
+
|
356
|
+
[filename, ary, ts, ts_inc, append]
|
357
|
+
end
|
358
|
+
|
359
|
+
def create_new_shb_section
|
360
|
+
section = SHB.new
|
361
|
+
@sections << section
|
362
|
+
itf = IDB.new(endian: section.endian)
|
363
|
+
classify_block section, itf
|
364
|
+
|
365
|
+
section
|
366
|
+
end
|
367
|
+
|
368
|
+
# Compute tsh and tsl from ts
|
369
|
+
def calc_ts(timeslot, ts_resol)
|
370
|
+
this_ts = (timeslot / ts_resol).to_i
|
371
|
+
this_tsh = this_ts >> 32
|
372
|
+
this_tsl = this_ts & 0xffffffff
|
373
|
+
|
374
|
+
[this_tsh, this_tsl]
|
375
|
+
end
|
376
|
+
|
377
|
+
def reread(filename)
|
378
|
+
return if filename.nil?
|
379
|
+
|
380
|
+
clear
|
381
|
+
readfile filename
|
382
|
+
end
|
383
|
+
|
384
|
+
def epb_from_pkt(pkt, endian, ts, ts_resol, ts_add_val)
|
385
|
+
case pkt
|
386
|
+
when Hash
|
387
|
+
this_ts = pkt.keys.first.to_i
|
388
|
+
this_data = pkt.values.first.to_s
|
389
|
+
else
|
390
|
+
this_ts = (ts + ts_add_val).to_i
|
391
|
+
this_data = pkt.to_s
|
392
|
+
end
|
393
|
+
this_cap_len = this_data.size
|
394
|
+
this_tsh, this_tsl = calc_ts(this_ts, ts_resol)
|
395
|
+
EPB.new(endian: endian,
|
396
|
+
interface_id: 0,
|
397
|
+
tsh: this_tsh,
|
398
|
+
tsl: this_tsl,
|
399
|
+
cap_len: this_cap_len,
|
400
|
+
orig_len: this_cap_len,
|
401
|
+
data: this_data)
|
402
|
+
end
|
364
403
|
end
|
365
404
|
end
|
366
405
|
end
|
data/lib/packetgen/pcapng/idb.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of PacketGen
|
2
4
|
# See https://github.com/sdaubert/packetgen for more informations
|
3
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen
|
9
9
|
module PcapNG
|
10
10
|
# {IDB} represents a Interface Description Block (IDB) of a pcapng file.
|
@@ -71,11 +71,7 @@ module PacketGen
|
|
71
71
|
# @param [::String,IO] str_or_io
|
72
72
|
# @return [self]
|
73
73
|
def read(str_or_io)
|
74
|
-
io =
|
75
|
-
str_or_io
|
76
|
-
else
|
77
|
-
StringIO.new(force_binary(str_or_io.to_s))
|
78
|
-
end
|
74
|
+
io = to_io(str_or_io)
|
79
75
|
return self if io.eof?
|
80
76
|
|
81
77
|
self[:type].read io.read(4)
|
@@ -105,29 +101,7 @@ module PacketGen
|
|
105
101
|
if @options_decoded && !force
|
106
102
|
@ts_resol
|
107
103
|
else
|
108
|
-
|
109
|
-
idx = 0
|
110
|
-
options = self[:options]
|
111
|
-
|
112
|
-
while idx < options.length
|
113
|
-
opt_code, opt_len = options[idx, 4].unpack("#{packstr}2")
|
114
|
-
if opt_code == OPTION_IF_TSRESOL && opt_len == 1
|
115
|
-
tsresol = options[idx + 4, 1].unpack('C').first
|
116
|
-
@ts_resol = if (tsresol & 0x80).zero?
|
117
|
-
10**-tsresol
|
118
|
-
else
|
119
|
-
2**-(tsresol & 0x7f)
|
120
|
-
end
|
121
|
-
|
122
|
-
@options_decoded = true
|
123
|
-
return @ts_resol
|
124
|
-
else
|
125
|
-
idx += 4 + opt_len
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
@options_decoded = true
|
130
|
-
@ts_resol = 1E-6 # default value
|
104
|
+
decode_ts_resol
|
131
105
|
end
|
132
106
|
end
|
133
107
|
|
@@ -138,6 +112,32 @@ module PacketGen
|
|
138
112
|
recalc_block_len
|
139
113
|
super << @packets.map(&:to_s).join
|
140
114
|
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def decode_ts_resol
|
119
|
+
tsresol = search_for_ts_resol_opt(self[:options])
|
120
|
+
@options_decoded = true
|
121
|
+
return @ts_resol = 1E-6 if tsresol.nil?
|
122
|
+
|
123
|
+
@ts_resol = if (tsresol & 0x80).zero?
|
124
|
+
10**-tsresol
|
125
|
+
else
|
126
|
+
2**-(tsresol & 0x7f)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def search_for_ts_resol_opt(options)
|
131
|
+
packstr = endian == :little ? 'v' : 'n'
|
132
|
+
idx = 0
|
133
|
+
|
134
|
+
while idx < options.length
|
135
|
+
opt_code, opt_len = options[idx, 4].unpack("#{packstr}2")
|
136
|
+
return options[idx + 4, 1].unpack('C').first if opt_code == OPTION_IF_TSRESOL && opt_len == 1
|
137
|
+
|
138
|
+
idx += 4 + opt_len
|
139
|
+
end
|
140
|
+
end
|
141
141
|
end
|
142
142
|
end
|
143
143
|
end
|