packetgen 3.3.3 → 4.1.0
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 +38 -22
- data/lib/packetgen/capture.rb +2 -2
- data/lib/packetgen/config.rb +0 -1
- data/lib/packetgen/deprecation.rb +14 -8
- data/lib/packetgen/header/arp.rb +17 -18
- data/lib/packetgen/header/asn1_base.rb +2 -1
- data/lib/packetgen/header/base.rb +42 -40
- data/lib/packetgen/header/bootp.rb +35 -37
- data/lib/packetgen/header/dhcp/option.rb +21 -21
- data/lib/packetgen/header/dhcp/options.rb +3 -3
- data/lib/packetgen/header/dhcp.rb +8 -9
- data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
- data/lib/packetgen/header/dhcpv6/option.rb +83 -61
- data/lib/packetgen/header/dhcpv6/options.rb +4 -4
- data/lib/packetgen/header/dhcpv6/relay.rb +6 -5
- data/lib/packetgen/header/dhcpv6.rb +17 -18
- data/lib/packetgen/header/dns/name.rb +21 -16
- data/lib/packetgen/header/dns/opt.rb +5 -2
- data/lib/packetgen/header/dns/option.rb +14 -14
- data/lib/packetgen/header/dns/qdsection.rb +3 -3
- data/lib/packetgen/header/dns/question.rb +7 -8
- data/lib/packetgen/header/dns/rr.rb +56 -43
- data/lib/packetgen/header/dns/rrsection.rb +6 -6
- data/lib/packetgen/header/dns.rb +103 -90
- data/lib/packetgen/header/dot11/control.rb +12 -12
- data/lib/packetgen/header/dot11/data.rb +25 -24
- data/lib/packetgen/header/dot11/element.rb +4 -4
- data/lib/packetgen/header/dot11/management.rb +21 -18
- data/lib/packetgen/header/dot11/sub_mngt.rb +40 -53
- data/lib/packetgen/header/dot11.rb +117 -122
- data/lib/packetgen/header/dot1q.rb +12 -13
- data/lib/packetgen/header/dot1x.rb +13 -13
- data/lib/packetgen/header/eap/fast.rb +4 -4
- data/lib/packetgen/header/eap/md5.rb +16 -8
- data/lib/packetgen/header/eap/tls.rb +18 -19
- data/lib/packetgen/header/eap/ttls.rb +22 -21
- data/lib/packetgen/header/eap.rb +73 -48
- data/lib/packetgen/header/eth.rb +41 -27
- data/lib/packetgen/header/gre.rb +33 -11
- data/lib/packetgen/header/http/headers.rb +7 -6
- data/lib/packetgen/header/http/request.rb +38 -29
- data/lib/packetgen/header/http/response.rb +35 -27
- data/lib/packetgen/header/http/verbs.rb +1 -3
- data/lib/packetgen/header/icmp.rb +14 -14
- data/lib/packetgen/header/icmpv6.rb +10 -9
- data/lib/packetgen/header/igmp.rb +26 -15
- data/lib/packetgen/header/igmpv3/group_record.rb +18 -13
- data/lib/packetgen/header/igmpv3/mq.rb +16 -18
- data/lib/packetgen/header/igmpv3/mr.rb +5 -5
- data/lib/packetgen/header/igmpv3.rb +12 -11
- data/lib/packetgen/header/ip/addr.rb +19 -15
- data/lib/packetgen/header/ip/option.rb +47 -36
- data/lib/packetgen/header/ip/options.rb +1 -1
- data/lib/packetgen/header/ip.rb +77 -95
- data/lib/packetgen/header/ipv6/addr.rb +28 -27
- data/lib/packetgen/header/ipv6/extension.rb +13 -11
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +32 -13
- data/lib/packetgen/header/ipv6.rb +42 -35
- data/lib/packetgen/header/llc.rb +28 -21
- data/lib/packetgen/header/mdns.rb +10 -3
- data/lib/packetgen/header/mld.rb +15 -13
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +17 -12
- data/lib/packetgen/header/mldv2/mlq.rb +22 -24
- data/lib/packetgen/header/mldv2/mlr.rb +8 -8
- data/lib/packetgen/header/mldv2.rb +1 -1
- data/lib/packetgen/header/ospfv2/db_description.rb +17 -18
- data/lib/packetgen/header/ospfv2/hello.rb +18 -17
- data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
- data/lib/packetgen/header/ospfv2/ls_request.rb +14 -13
- data/lib/packetgen/header/ospfv2/ls_update.rb +9 -9
- data/lib/packetgen/header/ospfv2/lsa.rb +79 -60
- data/lib/packetgen/header/ospfv2/lsa_header.rb +12 -11
- data/lib/packetgen/header/ospfv2.rb +49 -46
- data/lib/packetgen/header/ospfv3/db_description.rb +20 -22
- data/lib/packetgen/header/ospfv3/hello.rb +17 -16
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +22 -20
- data/lib/packetgen/header/ospfv3/ls_ack.rb +7 -8
- data/lib/packetgen/header/ospfv3/ls_request.rb +18 -18
- data/lib/packetgen/header/ospfv3/ls_update.rb +10 -10
- data/lib/packetgen/header/ospfv3/lsa.rb +62 -51
- data/lib/packetgen/header/ospfv3/lsa_header.rb +12 -11
- data/lib/packetgen/header/ospfv3.rb +54 -52
- data/lib/packetgen/header/sctp/chunk.rb +80 -56
- data/lib/packetgen/header/sctp/error.rb +174 -202
- data/lib/packetgen/header/sctp/padded32.rb +3 -3
- data/lib/packetgen/header/sctp/parameter.rb +89 -136
- data/lib/packetgen/header/sctp.rb +19 -8
- data/lib/packetgen/header/snmp.rb +108 -7
- data/lib/packetgen/header/tcp/option.rb +52 -39
- data/lib/packetgen/header/tcp/options.rb +13 -5
- data/lib/packetgen/header/tcp.rb +83 -65
- data/lib/packetgen/header/tftp.rb +31 -25
- data/lib/packetgen/header/udp.rb +21 -19
- data/lib/packetgen/header.rb +23 -18
- data/lib/packetgen/headerable.rb +21 -5
- data/lib/packetgen/inspect.rb +3 -8
- data/lib/packetgen/packet.rb +146 -71
- data/lib/packetgen/pcap.rb +15 -4
- data/lib/packetgen/pcapng/block.rb +20 -18
- data/lib/packetgen/pcapng/epb.rb +13 -15
- data/lib/packetgen/pcapng/file.rb +44 -111
- data/lib/packetgen/pcapng/idb.rb +11 -12
- data/lib/packetgen/pcapng/shb.rb +15 -16
- data/lib/packetgen/pcapng/spb.rb +9 -11
- data/lib/packetgen/pcapng/unknown_block.rb +6 -17
- data/lib/packetgen/pcapng.rb +6 -4
- data/lib/packetgen/pcaprub_wrapper.rb +17 -1
- data/lib/packetgen/proto.rb +5 -1
- data/lib/packetgen/unknown_packet.rb +5 -5
- data/lib/packetgen/utils/arp_spoofer.rb +18 -19
- data/lib/packetgen/utils.rb +4 -3
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +12 -5
- metadata +29 -38
- data/lib/packetgen/types/abstract_tlv.rb +0 -278
- data/lib/packetgen/types/array.rb +0 -287
- data/lib/packetgen/types/cstring.rb +0 -109
- data/lib/packetgen/types/enum.rb +0 -171
- data/lib/packetgen/types/fieldable.rb +0 -66
- data/lib/packetgen/types/fields.rb +0 -622
- data/lib/packetgen/types/int.rb +0 -473
- data/lib/packetgen/types/int_string.rb +0 -102
- data/lib/packetgen/types/length_from.rb +0 -54
- data/lib/packetgen/types/oui.rb +0 -52
- data/lib/packetgen/types/string.rb +0 -97
- data/lib/packetgen/types/tlv.rb +0 -161
- data/lib/packetgen/types.rb +0 -26
data/lib/packetgen/pcapng/epb.rb
CHANGED
@@ -34,29 +34,29 @@ module PacketGen
|
|
34
34
|
# @!attribute interface_id
|
35
35
|
# 32-bit interface ID
|
36
36
|
# @return [Integer]
|
37
|
-
|
37
|
+
define_attr_before :block_len2, :interface_id, BinStruct::Int32, default: 0
|
38
38
|
# @!attribute tsh
|
39
39
|
# high 32-bit timestamp value
|
40
40
|
# @return [Integer]
|
41
|
-
|
41
|
+
define_attr_before :block_len2, :tsh, BinStruct::Int32, default: 0
|
42
42
|
# @!attribute tsl
|
43
43
|
# low 32-bit imestamp value
|
44
44
|
# @return [Integer]
|
45
|
-
|
45
|
+
define_attr_before :block_len2, :tsl, BinStruct::Int32, default: 0
|
46
46
|
# @!attribute cap_len
|
47
47
|
# 32-bit capture length
|
48
48
|
# @return [Integer]
|
49
|
-
|
49
|
+
define_attr_before :block_len2, :cap_len, BinStruct::Int32, default: 0
|
50
50
|
# @!attribute orig_len
|
51
51
|
# 32-bit original length
|
52
52
|
# @return [Integer]
|
53
|
-
|
53
|
+
define_attr_before :block_len2, :orig_len, BinStruct::Int32, default: 0
|
54
54
|
# @!attribute data
|
55
|
-
# @return [
|
56
|
-
|
55
|
+
# @return [BinStruct::String]
|
56
|
+
define_attr_before :block_len2, :data, BinStruct::String
|
57
57
|
# @!attribute options
|
58
|
-
# @return [
|
59
|
-
|
58
|
+
# @return [BinStruct::String]
|
59
|
+
define_attr_before :block_len2, :options, BinStruct::String
|
60
60
|
|
61
61
|
# @param [Hash] options
|
62
62
|
# @option options [:little, :big] :endian set block endianness
|
@@ -74,8 +74,6 @@ module PacketGen
|
|
74
74
|
# @option options [Integer] :block_len2 block total length
|
75
75
|
def initialize(options={})
|
76
76
|
super
|
77
|
-
endianness(options[:endian] || :little)
|
78
|
-
recalc_block_len
|
79
77
|
self.type = options[:type] || PcapNG::EPB_TYPE.to_i
|
80
78
|
end
|
81
79
|
|
@@ -87,9 +85,9 @@ module PacketGen
|
|
87
85
|
return self if io.eof?
|
88
86
|
|
89
87
|
%i[type block_len interface_id tsh tsl cap_len orig_len].each do |attr|
|
90
|
-
self[attr].read
|
88
|
+
self[attr].read(io.read(self[attr].sz))
|
91
89
|
end
|
92
|
-
self[:data].read
|
90
|
+
self[:data].read(io.read(self.cap_len))
|
93
91
|
read_options(io)
|
94
92
|
read_blocklen2_and_check(io)
|
95
93
|
|
@@ -115,7 +113,7 @@ module PacketGen
|
|
115
113
|
# Return the object as a String
|
116
114
|
# @return [String]
|
117
115
|
def to_s
|
118
|
-
pad_field
|
116
|
+
pad_field(:data, :options)
|
119
117
|
recalc_block_len
|
120
118
|
super
|
121
119
|
end
|
@@ -133,7 +131,7 @@ module PacketGen
|
|
133
131
|
def read_options(io)
|
134
132
|
data_pad_len = remove_padding(io, self.cap_len)
|
135
133
|
options_len = self.block_len - self.cap_len - data_pad_len - MIN_SIZE
|
136
|
-
self[:options].read
|
134
|
+
self[:options].read(io.read(options_len))
|
137
135
|
end
|
138
136
|
end
|
139
137
|
end
|
@@ -8,9 +8,24 @@
|
|
8
8
|
|
9
9
|
module PacketGen
|
10
10
|
module PcapNG
|
11
|
-
# PcapNG::File is a complete Pcap-NG file handler.
|
11
|
+
# PcapNG::File is a complete Pcap-NG file handler. It provides methods to:
|
12
|
+
# * read and write PcapNG files,
|
13
|
+
# * process packets from such files.
|
14
|
+
#
|
15
|
+
# @example Writing a file
|
16
|
+
# pkt1 = PacketGen.gen('IP', id: 1).add('TCP')
|
17
|
+
# pkt2 = PacketGen.gen('IP', id: 2).add('UDP')
|
18
|
+
# file = PacketGen::PcapNG::File.new
|
19
|
+
# file.read_array([pkt1, pkt2])
|
20
|
+
# file.write('/tmp/file.pcapng')
|
21
|
+
#
|
22
|
+
# @example Reading a file
|
23
|
+
# file = PacketGen::PcapNG::File.new
|
24
|
+
# pkts = file.read_packets('/tmp/file.pcapng')
|
25
|
+
#
|
12
26
|
# @author Sylvain Daubert
|
13
|
-
|
27
|
+
# @author LemonTree55
|
28
|
+
class File
|
14
29
|
# Known link types
|
15
30
|
KNOWN_LINK_TYPES = {
|
16
31
|
LINKTYPE_ETHERNET => 'Eth',
|
@@ -29,19 +44,19 @@ module PacketGen
|
|
29
44
|
end.freeze
|
30
45
|
|
31
46
|
# Get file sections
|
32
|
-
# @return [Array]
|
47
|
+
# @return [Array<SHB>]
|
33
48
|
attr_accessor :sections
|
34
49
|
|
35
50
|
def initialize
|
36
51
|
@sections = []
|
37
52
|
end
|
38
53
|
|
39
|
-
# Read a string to populate the object. Note that this appends new blocks to
|
54
|
+
# Read a binary string to populate the object. Note that this appends new blocks to
|
40
55
|
# the Pcapng::File object.
|
41
56
|
# @param [String] str
|
42
57
|
# @return [self]
|
43
58
|
def read(str)
|
44
|
-
|
59
|
+
str = str.b unless str.encoding == Encoding::BINARY
|
45
60
|
io = StringIO.new(str)
|
46
61
|
parse_section(io)
|
47
62
|
self
|
@@ -59,11 +74,19 @@ module PacketGen
|
|
59
74
|
|
60
75
|
# Read a given file and analyze it.
|
61
76
|
# If given a block, it will yield PcapNG::EPB or PcapNG::SPB objects.
|
62
|
-
# This is the only way to get packet timestamps.
|
77
|
+
# This is the only way to get packet timestamps (via {EPB#timestamp}).
|
63
78
|
# @param [String] fname pcapng file name
|
64
79
|
# @yieldparam [EPB,SPB] block
|
65
80
|
# @return [Integer] return number of yielded blocks (only if a block is given)
|
66
81
|
# @raise [ArgumentError] cannot read +fname+
|
82
|
+
# @example Parse packets and get their timestamp
|
83
|
+
# hsh = {}
|
84
|
+
# file = PacketGen::PcapNG::File.new
|
85
|
+
# file.readfile('/tmp/file.pcapng') do |xpb|
|
86
|
+
# ts = xpb.is_a?(PacketGen::PcapNG::EPB) ? xpb.timestamp : nil
|
87
|
+
# pkt = PacketGen.parse(xpb.data)
|
88
|
+
# hsh[pkt] = ts
|
89
|
+
# end
|
67
90
|
def readfile(fname, &blk)
|
68
91
|
raise ArgumentError, "cannot read file #{fname}" unless ::File.readable?(fname)
|
69
92
|
|
@@ -140,35 +163,6 @@ module PacketGen
|
|
140
163
|
@sections.clear
|
141
164
|
end
|
142
165
|
|
143
|
-
# @deprecated
|
144
|
-
# Prefer use of {#to_a} or {#to_h}.
|
145
|
-
# Translates a {File} into an array of packets.
|
146
|
-
# @param [Hash] options
|
147
|
-
# @option options [String] :file if given, object is cleared and filename
|
148
|
-
# is analyzed before generating array. Else, array is generated from +self+
|
149
|
-
# @option options [Boolean] :keep_timestamps if +true+ (default value: +false+),
|
150
|
-
# generates an array of hashes, each one with timestamp as key and packet
|
151
|
-
# as value. There is one hash per packet.
|
152
|
-
# @return [Array<Packet>,Array<Hash>]
|
153
|
-
def file_to_array(options={})
|
154
|
-
Deprecation.deprecated(self.class, __method__)
|
155
|
-
|
156
|
-
file = options[:file] || options[:filename]
|
157
|
-
reread file
|
158
|
-
|
159
|
-
ary = []
|
160
|
-
blk = if options[:keep_timestamps] || options[:keep_ts]
|
161
|
-
proc { |pkt| { pkt.timestamp => pkt.data.to_s } }
|
162
|
-
else
|
163
|
-
proc { |pkt| pkt.data.to_s }
|
164
|
-
end
|
165
|
-
each_packet_with_interface do |pkt, _itf|
|
166
|
-
ary << blk.call(pkt)
|
167
|
-
end
|
168
|
-
|
169
|
-
ary
|
170
|
-
end
|
171
|
-
|
172
166
|
# Translates a {File} into an array of packets.
|
173
167
|
# @return [Array<Packet>]
|
174
168
|
# @since 3.1.6
|
@@ -197,13 +191,15 @@ module PacketGen
|
|
197
191
|
end
|
198
192
|
|
199
193
|
# Writes the {File} to a file.
|
200
|
-
# @param [
|
201
|
-
# @
|
194
|
+
# @param [String] filename file name to write
|
195
|
+
# @param [Boolean] append if set to +true+,
|
202
196
|
# the packets are appended to the file, rather than overwriting it
|
203
|
-
# @return [Array] array of 2 elements: filename and size written
|
204
|
-
# @
|
205
|
-
|
206
|
-
|
197
|
+
# @return [Array(String, Integer)] array of 2 elements: filename and size written
|
198
|
+
# @since 4.1.0 Options hash with single +:append+ option is replaced by +append+ keyword argument.
|
199
|
+
# @see #append
|
200
|
+
# @see #write
|
201
|
+
def to_file(filename, append: false)
|
202
|
+
mode = append && ::File.exist?(filename) ? 'ab' : 'wb'
|
207
203
|
::File.open(filename, mode) { |f| f.write(self.to_s) }
|
208
204
|
[filename, self.to_s.size]
|
209
205
|
end
|
@@ -211,53 +207,20 @@ module PacketGen
|
|
211
207
|
|
212
208
|
# Shorthand method for writing to a file.
|
213
209
|
# @param [#to_s] filename
|
214
|
-
# @return [Array]
|
210
|
+
# @return [Array(String, Integer)]
|
211
|
+
# @see #to_file
|
215
212
|
def write(filename='out.pcapng')
|
216
213
|
self.to_file(filename.to_s, append: false)
|
217
214
|
end
|
218
215
|
|
219
216
|
# Shorthand method for appending to a file.
|
220
217
|
# @param [#to_s] filename
|
221
|
-
# @return [Array]
|
218
|
+
# @return [Array(String, Integer)]
|
219
|
+
# @see #to_file
|
222
220
|
def append(filename='out.pcapng')
|
223
221
|
self.to_file(filename.to_s, append: true)
|
224
222
|
end
|
225
223
|
|
226
|
-
# @deprecated Prefer use of {#read_array} or {#read_hash}.
|
227
|
-
# @overload array_to_file(ary)
|
228
|
-
# Update {File} object with packets.
|
229
|
-
# @param [Array] ary as generated by {#file_to_array} or Array of Packet objects.
|
230
|
-
# Update {File} object without writing file on disk
|
231
|
-
# @return [self]
|
232
|
-
# @overload array_to_file(options={})
|
233
|
-
# Update {File} and/or write it to a file
|
234
|
-
# @param [Hash] options
|
235
|
-
# @option options [String] :file file written on disk only if given
|
236
|
-
# @option options [Array] :array can either be an array of packet data,
|
237
|
-
# or a hash-value pair of timestamp => data.
|
238
|
-
# @option options [Time] :timestamp set an initial timestamp
|
239
|
-
# @option options [Integer] :ts_inc set the increment between timestamps.
|
240
|
-
# Defaults to 1
|
241
|
-
# @option options [Boolean] :append if +true+, append packets to the end of
|
242
|
-
# the file
|
243
|
-
# @return [Array] see return value from {#to_file}
|
244
|
-
def array_to_file(options={})
|
245
|
-
filename, ary, ts, ts_inc, append = array_to_file_options(options)
|
246
|
-
|
247
|
-
section = create_new_shb_section
|
248
|
-
|
249
|
-
ary.each do |pkt|
|
250
|
-
classify_block(section, epb_from_pkt(pkt, section, ts))
|
251
|
-
ts += ts_inc
|
252
|
-
end
|
253
|
-
|
254
|
-
if filename
|
255
|
-
self.to_f(filename, append: append)
|
256
|
-
else
|
257
|
-
self
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
224
|
# Update current object from an array of packets
|
262
225
|
# @param [Array<Packet>] packets
|
263
226
|
# @param [Time, nil] timestamp initial timestamp, used for first packet
|
@@ -335,13 +298,13 @@ module PacketGen
|
|
335
298
|
# @param [IO] io stream from which parse SHB
|
336
299
|
# @return [SHB]
|
337
300
|
def parse_shb(shb, io)
|
338
|
-
type =
|
301
|
+
type = BinStruct::Int32.new(value: 0, endian: shb.endian).read(io.read(4))
|
339
302
|
io.seek(-4, IO::SEEK_CUR)
|
340
303
|
parse(type, io, shb)
|
341
304
|
end
|
342
305
|
|
343
306
|
# Parse a block from its type
|
344
|
-
# @param [
|
307
|
+
# @param [BinStruct::Int32] type
|
345
308
|
# @param [IO] io stream from which parse block
|
346
309
|
# @param [SHB] shb header of current section
|
347
310
|
# @return [Block]
|
@@ -352,7 +315,7 @@ module PacketGen
|
|
352
315
|
end
|
353
316
|
|
354
317
|
# Guess class to use from type
|
355
|
-
# @param [
|
318
|
+
# @param [BinStruct::Int] type
|
356
319
|
# @return [Block]
|
357
320
|
def guess_block_type(type)
|
358
321
|
BLOCK_TYPES.key?(type.to_i) ? BLOCK_TYPES[type.to_i] : UnknownBlock
|
@@ -376,36 +339,6 @@ module PacketGen
|
|
376
339
|
end
|
377
340
|
end
|
378
341
|
|
379
|
-
def array_to_file_options(options)
|
380
|
-
case options
|
381
|
-
when Hash
|
382
|
-
array_to_file_options_from_hash(options)
|
383
|
-
when Array
|
384
|
-
[nil, options, Time.now, 1, false]
|
385
|
-
else
|
386
|
-
raise ArgumentError, 'unknown argument. Need either a Hash or Array'
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
391
|
-
# Extract and check options for #array_to_file
|
392
|
-
def array_to_file_options_from_hash(options)
|
393
|
-
%i[filename arr ts].each do |deprecated_opt|
|
394
|
-
Deprecation.deprecated_option(self.class, :array_to_file, deprecated_opt) if options[deprecated_opt]
|
395
|
-
end
|
396
|
-
|
397
|
-
filename = options[:filename] || options[:file]
|
398
|
-
ary = options[:array] || options[:arr]
|
399
|
-
raise ArgumentError, ':array parameter needs to be an array' unless ary.is_a? Array
|
400
|
-
|
401
|
-
ts = options[:timestamp] || options[:ts] || Time.now
|
402
|
-
ts_inc = options[:ts_inc] || 1
|
403
|
-
append = !options[:append].nil?
|
404
|
-
|
405
|
-
[filename, ary, ts, ts_inc, append]
|
406
|
-
end
|
407
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
408
|
-
|
409
342
|
def create_new_shb_section
|
410
343
|
section = SHB.new
|
411
344
|
@sections << section
|
data/lib/packetgen/pcapng/idb.rb
CHANGED
@@ -8,7 +8,8 @@
|
|
8
8
|
|
9
9
|
module PacketGen
|
10
10
|
module PcapNG
|
11
|
-
# {IDB} represents
|
11
|
+
# {IDB} represents an Interface Description Block (IDB) of a pcapng file. It is associated to a network interfaces.
|
12
|
+
# It contains packet data as {EPB} and/or {SPB}.
|
12
13
|
#
|
13
14
|
# == IDB Definition
|
14
15
|
# Int32 :type Default: 0x00000001
|
@@ -36,18 +37,18 @@ module PacketGen
|
|
36
37
|
# @!attribute link_type
|
37
38
|
# 16-bit link type
|
38
39
|
# @return [Integer]
|
39
|
-
|
40
|
+
define_attr_before :block_len2, :link_type, BinStruct::Int16, default: 1
|
40
41
|
# @!attribute reserved
|
41
42
|
# 16-bit reserved field
|
42
43
|
# @return [Integer]
|
43
|
-
|
44
|
+
define_attr_before :block_len2, :reserved, BinStruct::Int16, default: 0
|
44
45
|
# @!attribute snaplen
|
45
46
|
# 32-bit snap length
|
46
47
|
# @return [Integer]
|
47
|
-
|
48
|
+
define_attr_before :block_len2, :snaplen, BinStruct::Int32, default: 0
|
48
49
|
# @!attribute options
|
49
|
-
# @return [
|
50
|
-
|
50
|
+
# @return [BinStruct::String]
|
51
|
+
define_attr_before :block_len2, :options, BinStruct::String
|
51
52
|
|
52
53
|
# @param [Hash] options
|
53
54
|
# @option options [:little, :big] :endian set block endianness
|
@@ -61,10 +62,8 @@ module PacketGen
|
|
61
62
|
# @option options [Integer] :block_len2 block total length
|
62
63
|
def initialize(options={})
|
63
64
|
super
|
64
|
-
endianness(options[:endian] || :little)
|
65
65
|
@packets = []
|
66
66
|
@options_decoded = false
|
67
|
-
recalc_block_len
|
68
67
|
self.type = options[:type] || PcapNG::IDB_TYPE.to_i
|
69
68
|
end
|
70
69
|
|
@@ -76,9 +75,9 @@ module PacketGen
|
|
76
75
|
return self if io.eof?
|
77
76
|
|
78
77
|
%i[type block_len link_type reserved snaplen].each do |attr|
|
79
|
-
self[attr].read
|
78
|
+
self[attr].read(io.read(self[attr].sz))
|
80
79
|
end
|
81
|
-
self[:options].read
|
80
|
+
self[:options].read(io.read(self.block_len - MIN_SIZE))
|
82
81
|
read_blocklen2_and_check(io)
|
83
82
|
|
84
83
|
self
|
@@ -107,7 +106,7 @@ module PacketGen
|
|
107
106
|
# Return the object as a String
|
108
107
|
# @return [String]
|
109
108
|
def to_s
|
110
|
-
pad_field
|
109
|
+
pad_field(:options)
|
111
110
|
recalc_block_len
|
112
111
|
super << @packets.map(&:to_s).join
|
113
112
|
end
|
@@ -119,7 +118,7 @@ module PacketGen
|
|
119
118
|
@options_decoded = true
|
120
119
|
return @ts_resol = 1E-6 if tsresol.nil?
|
121
120
|
|
122
|
-
@ts_resol = if (
|
121
|
+
@ts_resol = if tsresol.nobits?(0x80)
|
123
122
|
10**-tsresol
|
124
123
|
else
|
125
124
|
2**-(tsresol & 0x7f)
|
data/lib/packetgen/pcapng/shb.rb
CHANGED
@@ -8,7 +8,8 @@
|
|
8
8
|
|
9
9
|
module PacketGen
|
10
10
|
module PcapNG
|
11
|
-
# {SHB} represents a Section Header Block (SHB) of a pcapng file.
|
11
|
+
# {SHB} represents a Section Header Block (SHB) of a pcapng file. A SHB contains {IDB}, which contain
|
12
|
+
# {EPB} and/or {SPB}.
|
12
13
|
#
|
13
14
|
# == SHB Definition
|
14
15
|
# Int32 :type Default: 0x0A0D0D0A
|
@@ -45,23 +46,23 @@ module PacketGen
|
|
45
46
|
# @!attribute magic
|
46
47
|
# 32-bit magic number
|
47
48
|
# @return [Integer]
|
48
|
-
|
49
|
+
define_attr_before :block_len2, :magic, BinStruct::Int32, default: MAGIC_INT32
|
49
50
|
# @!attribute ver_major
|
50
51
|
# 16-bit major version number
|
51
52
|
# @return [Integer]
|
52
|
-
|
53
|
+
define_attr_before :block_len2, :ver_major, BinStruct::Int16, default: 1
|
53
54
|
# @!attribute ver_major
|
54
55
|
# 16-bit minor version number
|
55
56
|
# @return [Integer]
|
56
|
-
|
57
|
+
define_attr_before :block_len2, :ver_minor, BinStruct::Int16, default: 0
|
57
58
|
# @!attribute section_len
|
58
59
|
# 64-bit section length
|
59
60
|
# @return [Integer]
|
60
|
-
|
61
|
-
|
61
|
+
define_attr_before :block_len2, :section_len, BinStruct::Int64,
|
62
|
+
default: SECTION_LEN_UNDEFINED
|
62
63
|
# @!attribute options
|
63
|
-
# @return [
|
64
|
-
|
64
|
+
# @return [BinStruct::String]
|
65
|
+
define_attr_before :block_len2, :options, BinStruct::String
|
65
66
|
|
66
67
|
# @param [Hash] options
|
67
68
|
# @option options [:little, :big] :endian set block endianness
|
@@ -81,8 +82,6 @@ module PacketGen
|
|
81
82
|
super
|
82
83
|
@interfaces = []
|
83
84
|
@unknown_blocks = []
|
84
|
-
endianness(options[:endian] || :little)
|
85
|
-
recalc_block_len
|
86
85
|
self.type = options[:type] || PcapNG::SHB_TYPE.to_i
|
87
86
|
end
|
88
87
|
|
@@ -93,9 +92,9 @@ module PacketGen
|
|
93
92
|
io = to_io(str_or_io)
|
94
93
|
return self if io.eof?
|
95
94
|
|
96
|
-
self[:type].read
|
95
|
+
self[:type].read(check_shb(io))
|
97
96
|
%i[block_len magic ver_major ver_minor section_len].each do |attr|
|
98
|
-
self[attr].read
|
97
|
+
self[attr].read(io.read(self[attr].sz))
|
99
98
|
end
|
100
99
|
handle_magic_and_check(self[:magic].to_s)
|
101
100
|
|
@@ -120,7 +119,7 @@ module PacketGen
|
|
120
119
|
body = @interfaces.map(&:to_s).join
|
121
120
|
self.section_len = body.size unless self.section_len == SECTION_LEN_UNDEFINED
|
122
121
|
|
123
|
-
pad_field
|
122
|
+
pad_field(:options)
|
124
123
|
recalc_block_len
|
125
124
|
super + body
|
126
125
|
end
|
@@ -135,12 +134,12 @@ module PacketGen
|
|
135
134
|
def force_endianness(endian)
|
136
135
|
@endian = endian
|
137
136
|
%i[type block_len magic block_len2].each do |attr|
|
138
|
-
self[attr] =
|
137
|
+
self[attr] = BinStruct::Int32.new(value: 0, endian: endian).read(self[attr].to_s)
|
139
138
|
end
|
140
139
|
%i[ver_major ver_minor].each do |attr|
|
141
|
-
self[attr] =
|
140
|
+
self[attr] = BinStruct::Int16.new(value: 0, endian: endian).read(self[attr].to_s)
|
142
141
|
end
|
143
|
-
self[:section_len] =
|
142
|
+
self[:section_len] = BinStruct::Int64.new(value: 0, endian: endian).read(self[:section_len].to_s)
|
144
143
|
end
|
145
144
|
|
146
145
|
# Check io contains a SHB
|
data/lib/packetgen/pcapng/spb.rb
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
module PacketGen
|
10
10
|
module PcapNG
|
11
|
-
# {SPB} represents a
|
11
|
+
# {SPB} represents a Simple Packet Block (SPB) of a pcapng file.
|
12
12
|
#
|
13
13
|
# == Pcapng::SPB Definition
|
14
14
|
# Int32 :type Default: 0x00000003
|
@@ -29,10 +29,10 @@ module PacketGen
|
|
29
29
|
# @!attribute orig_len
|
30
30
|
# 32-bit original length
|
31
31
|
# @return [Integer]
|
32
|
-
|
32
|
+
define_attr_before :block_len2, :orig_len, BinStruct::Int32, default: 0
|
33
33
|
# @!attribute data
|
34
|
-
# @return [
|
35
|
-
|
34
|
+
# @return [BinStruct::String]
|
35
|
+
define_attr_before :block_len2, :data, BinStruct::String
|
36
36
|
|
37
37
|
# @param [Hash] options
|
38
38
|
# @option options [:little, :big] :endian set block endianness
|
@@ -45,8 +45,6 @@ module PacketGen
|
|
45
45
|
# @option options [Integer] :block_len2 block total length
|
46
46
|
def initialize(options={})
|
47
47
|
super
|
48
|
-
endianness(options[:endian] || :little)
|
49
|
-
recalc_block_len
|
50
48
|
self.type = options[:type] || PcapNG::SPB_TYPE.to_i
|
51
49
|
end
|
52
50
|
|
@@ -64,11 +62,11 @@ module PacketGen
|
|
64
62
|
io = to_io(str_or_io)
|
65
63
|
return self if io.eof?
|
66
64
|
|
67
|
-
self[:type].read
|
68
|
-
self[:block_len].read
|
69
|
-
self[:orig_len].read
|
65
|
+
self[:type].read(io.read(4))
|
66
|
+
self[:block_len].read(io.read(4))
|
67
|
+
self[:orig_len].read(io.read(4))
|
70
68
|
data_len = compute_data_len
|
71
|
-
self[:data].read
|
69
|
+
self[:data].read(io.read(data_len))
|
72
70
|
remove_padding(io, data_len)
|
73
71
|
read_blocklen2_and_check(io)
|
74
72
|
|
@@ -79,7 +77,7 @@ module PacketGen
|
|
79
77
|
# Return the object as a String
|
80
78
|
# @return [String]
|
81
79
|
def to_s
|
82
|
-
pad_field
|
80
|
+
pad_field(:data)
|
83
81
|
recalc_block_len
|
84
82
|
super
|
85
83
|
end
|
@@ -20,19 +20,8 @@ module PacketGen
|
|
20
20
|
attr_accessor :section
|
21
21
|
|
22
22
|
# @!attribute body
|
23
|
-
# @return [
|
24
|
-
|
25
|
-
|
26
|
-
# @option options [:little, :big] :endian set block endianness
|
27
|
-
# @option options [Integer] :type
|
28
|
-
# @option options [Integer] :block_len block total length
|
29
|
-
# @option options [::String] :body
|
30
|
-
# @option options [Integer] :block_len2 block total length
|
31
|
-
def initialize(options={})
|
32
|
-
super
|
33
|
-
endianness(options[:endian] || :little)
|
34
|
-
recalc_block_len
|
35
|
-
end
|
23
|
+
# @return [BinStruct::String]
|
24
|
+
define_attr_before :block_len2, :body, BinStruct::String
|
36
25
|
|
37
26
|
# Has this block options?
|
38
27
|
# @return [false]
|
@@ -48,9 +37,9 @@ module PacketGen
|
|
48
37
|
io = to_io(str_or_io)
|
49
38
|
return self if io.eof?
|
50
39
|
|
51
|
-
self[:type].read
|
52
|
-
self[:block_len].read
|
53
|
-
self[:body].read
|
40
|
+
self[:type].read(io.read(4))
|
41
|
+
self[:block_len].read(io.read(4))
|
42
|
+
self[:body].read(io.read(self[:block_len].to_i - MIN_SIZE))
|
54
43
|
read_blocklen2_and_check(io)
|
55
44
|
|
56
45
|
self
|
@@ -59,7 +48,7 @@ module PacketGen
|
|
59
48
|
# Return the object as a String
|
60
49
|
# @return [String]
|
61
50
|
def to_s
|
62
|
-
pad_field
|
51
|
+
pad_field(:body)
|
63
52
|
recalc_block_len
|
64
53
|
super
|
65
54
|
end
|
data/lib/packetgen/pcapng.rb
CHANGED
@@ -11,16 +11,18 @@ require 'stringio'
|
|
11
11
|
module PacketGen
|
12
12
|
# Module to handle PCAP-NG file format.
|
13
13
|
# See http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii
|
14
|
+
#
|
15
|
+
# See {PcapNG::File} to handle Pcap-NG files.
|
14
16
|
# @author Sylvain Daubert
|
15
17
|
module PcapNG
|
16
18
|
# Section Header Block type number
|
17
|
-
SHB_TYPE =
|
19
|
+
SHB_TYPE = BinStruct::Int32.new(value: 0x0A0D0D0A, endian: :little).freeze
|
18
20
|
# Interface Description Block type number
|
19
|
-
IDB_TYPE =
|
21
|
+
IDB_TYPE = BinStruct::Int32.new(value: 1, endian: :little).freeze
|
20
22
|
# Simple Packet Block type number
|
21
|
-
SPB_TYPE =
|
23
|
+
SPB_TYPE = BinStruct::Int32.new(value: 3, endian: :little).freeze
|
22
24
|
# Enhanced Packet Block type number
|
23
|
-
EPB_TYPE =
|
25
|
+
EPB_TYPE = BinStruct::Int32.new(value: 6, endian: :little).freeze
|
24
26
|
|
25
27
|
# IEEE 802.3 Ethernet (10Mb, 100Mb, 1000Mb, and up)
|
26
28
|
LINKTYPE_ETHERNET = 1
|
@@ -10,6 +10,7 @@ require 'pcaprub'
|
|
10
10
|
module PacketGen
|
11
11
|
# Wrapper around PCAPRUB
|
12
12
|
# @author Sylvain Daubert
|
13
|
+
# @author LemonTree55
|
13
14
|
# @api private
|
14
15
|
# @since 3.1.4
|
15
16
|
module PCAPRUBWrapper
|
@@ -35,8 +36,9 @@ module PacketGen
|
|
35
36
|
pcap.setpromisc(promisc)
|
36
37
|
pcap.settimeout(TIMEOUT)
|
37
38
|
# Monitor MUST be set before pcap is activated
|
38
|
-
pcap.setmonitor
|
39
|
+
pcap.setmonitor(monitor) unless monitor.nil?
|
39
40
|
pcap.activate
|
41
|
+
pcap
|
40
42
|
end
|
41
43
|
|
42
44
|
# Capture packets from a network interface
|
@@ -74,5 +76,19 @@ module PacketGen
|
|
74
76
|
def self.read_pcap(filename:, &block)
|
75
77
|
PCAPRUB::Pcap.open_offline(filename).each_packet(&block)
|
76
78
|
end
|
79
|
+
|
80
|
+
# Write binary packets to a PCAP file
|
81
|
+
# @param [String] filename
|
82
|
+
# @param [Array<String>] packets
|
83
|
+
# @return [void]
|
84
|
+
# @since 4.0.0
|
85
|
+
# @author LemonTree55
|
86
|
+
def self.write_pcap(filename:, packets:)
|
87
|
+
PCAPRUB::Pcap.dump_open(filename) do |pcap|
|
88
|
+
packets.each do |packet|
|
89
|
+
pcap.dump(packet)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
77
93
|
end
|
78
94
|
end
|
data/lib/packetgen/proto.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
require 'socket'
|
11
11
|
|
12
12
|
module PacketGen
|
13
|
-
# Module handling some helper methods for protocols
|
13
|
+
# Module handling some helper methods for well_known protocols
|
14
14
|
# @author Sylvain Daubert
|
15
15
|
# @since 2.1.2
|
16
16
|
module Proto
|
@@ -30,6 +30,8 @@ module PacketGen
|
|
30
30
|
# Get protocol number from its name
|
31
31
|
# @param [String] name
|
32
32
|
# @return [Integer,nil] return nil for unknown protocol names
|
33
|
+
# @example
|
34
|
+
# PacketGen::Proto.getprotobyname('tcp') #=> 6
|
33
35
|
def self.getprotobyname(name)
|
34
36
|
@cache[name]
|
35
37
|
end
|
@@ -37,6 +39,8 @@ module PacketGen
|
|
37
39
|
# Get protocol name from its number
|
38
40
|
# @param [Integer] num
|
39
41
|
# @return [String,nil] return nil for unknown protocol numbers
|
42
|
+
# @example
|
43
|
+
# PacketGen::Proto.getprotobynumber(6) #=> 'tcp'
|
40
44
|
def self.getprotobynumber(num)
|
41
45
|
@cache.key(num)
|
42
46
|
end
|