packetgen 4.0.0 → 4.1.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 +7 -9
- data/lib/packetgen/capture.rb +3 -6
- data/lib/packetgen/config.rb +1 -1
- data/lib/packetgen/deprecation.rb +7 -1
- data/lib/packetgen/header/arp.rb +7 -8
- data/lib/packetgen/header/asn1_base.rb +3 -2
- data/lib/packetgen/header/base.rb +39 -27
- data/lib/packetgen/header/bootp.rb +15 -15
- data/lib/packetgen/header/dhcp/option.rb +9 -9
- data/lib/packetgen/header/dhcp/options.rb +3 -3
- data/lib/packetgen/header/dhcp.rb +7 -8
- data/lib/packetgen/header/dhcpv6/duid.rb +3 -5
- data/lib/packetgen/header/dhcpv6/option.rb +38 -16
- data/lib/packetgen/header/dhcpv6/options.rb +4 -4
- data/lib/packetgen/header/dhcpv6/relay.rb +2 -1
- data/lib/packetgen/header/dhcpv6.rb +14 -15
- data/lib/packetgen/header/dns/name.rb +10 -9
- data/lib/packetgen/header/dns/opt.rb +4 -1
- data/lib/packetgen/header/dns/option.rb +8 -8
- data/lib/packetgen/header/dns/qdsection.rb +3 -3
- data/lib/packetgen/header/dns/question.rb +2 -1
- data/lib/packetgen/header/dns/rr.rb +2 -4
- data/lib/packetgen/header/dns/rrsection.rb +3 -3
- data/lib/packetgen/header/dns.rb +77 -61
- data/lib/packetgen/header/dot11/control.rb +6 -6
- data/lib/packetgen/header/dot11/data.rb +12 -11
- data/lib/packetgen/header/dot11/element.rb +2 -2
- data/lib/packetgen/header/dot11/management.rb +19 -16
- data/lib/packetgen/header/dot11/sub_mngt.rb +23 -22
- data/lib/packetgen/header/dot11.rb +39 -39
- data/lib/packetgen/header/dot1q.rb +6 -5
- data/lib/packetgen/header/dot1x.rb +9 -9
- data/lib/packetgen/header/eap/fast.rb +4 -4
- data/lib/packetgen/header/eap/md5.rb +12 -4
- data/lib/packetgen/header/eap/tls.rb +10 -9
- data/lib/packetgen/header/eap/ttls.rb +14 -11
- data/lib/packetgen/header/eap.rb +59 -34
- data/lib/packetgen/header/eth.rb +27 -13
- data/lib/packetgen/header/gre.rb +27 -3
- data/lib/packetgen/header/http/headers.rb +7 -6
- data/lib/packetgen/header/http/request.rb +25 -17
- data/lib/packetgen/header/http/response.rb +23 -16
- data/lib/packetgen/header/http/verbs.rb +1 -1
- data/lib/packetgen/header/http.rb +1 -1
- data/lib/packetgen/header/icmp.rb +11 -11
- data/lib/packetgen/header/icmpv6.rb +11 -10
- data/lib/packetgen/header/igmp.rb +22 -11
- data/lib/packetgen/header/igmpv3/group_record.rb +8 -3
- data/lib/packetgen/header/igmpv3/mq.rb +2 -2
- data/lib/packetgen/header/igmpv3/mr.rb +2 -2
- data/lib/packetgen/header/igmpv3.rb +12 -11
- data/lib/packetgen/header/ip/addr.rb +7 -3
- data/lib/packetgen/header/ip/option.rb +19 -6
- data/lib/packetgen/header/ip/options.rb +1 -1
- data/lib/packetgen/header/ip.rb +53 -36
- data/lib/packetgen/header/ipv6/addr.rb +15 -14
- data/lib/packetgen/header/ipv6/extension.rb +10 -8
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +27 -8
- data/lib/packetgen/header/ipv6.rb +32 -23
- data/lib/packetgen/header/llc.rb +21 -14
- data/lib/packetgen/header/mdns.rb +10 -3
- data/lib/packetgen/header/mld.rb +12 -10
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +7 -2
- data/lib/packetgen/header/mldv2/mlq.rb +9 -9
- data/lib/packetgen/header/mldv2/mlr.rb +5 -5
- data/lib/packetgen/header/mldv2.rb +2 -2
- data/lib/packetgen/header/ospfv2/db_description.rb +11 -11
- data/lib/packetgen/header/ospfv2/hello.rb +12 -11
- data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
- data/lib/packetgen/header/ospfv2/ls_request.rb +8 -7
- data/lib/packetgen/header/ospfv2/ls_update.rb +8 -8
- data/lib/packetgen/header/ospfv2/lsa.rb +34 -11
- data/lib/packetgen/header/ospfv2/lsa_header.rb +4 -3
- data/lib/packetgen/header/ospfv2.rb +32 -27
- data/lib/packetgen/header/ospfv3/db_description.rb +13 -14
- data/lib/packetgen/header/ospfv3/hello.rb +11 -10
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +7 -3
- data/lib/packetgen/header/ospfv3/ls_ack.rb +6 -7
- data/lib/packetgen/header/ospfv3/ls_request.rb +11 -11
- data/lib/packetgen/header/ospfv3/ls_update.rb +8 -8
- data/lib/packetgen/header/ospfv3/lsa.rb +24 -10
- data/lib/packetgen/header/ospfv3/lsa_header.rb +4 -3
- data/lib/packetgen/header/ospfv3.rb +39 -35
- data/lib/packetgen/header/sctp/chunk.rb +39 -18
- data/lib/packetgen/header/sctp/error.rb +170 -198
- data/lib/packetgen/header/sctp/padded32.rb +4 -4
- data/lib/packetgen/header/sctp/parameter.rb +86 -133
- data/lib/packetgen/header/sctp.rb +15 -4
- data/lib/packetgen/header/snmp.rb +111 -10
- data/lib/packetgen/header/tcp/option.rb +8 -1
- data/lib/packetgen/header/tcp/options.rb +12 -4
- data/lib/packetgen/header/tcp.rb +34 -27
- data/lib/packetgen/header/tftp.rb +17 -11
- data/lib/packetgen/header/udp.rb +16 -14
- data/lib/packetgen/header.rb +20 -14
- data/lib/packetgen/headerable.rb +10 -4
- data/lib/packetgen/inject.rb +1 -1
- data/lib/packetgen/inspect.rb +3 -8
- data/lib/packetgen/packet.rb +95 -37
- data/lib/packetgen/pcap.rb +1 -1
- data/lib/packetgen/pcapng/block.rb +3 -2
- data/lib/packetgen/pcapng/epb.rb +1 -1
- data/lib/packetgen/pcapng/file.rb +42 -15
- data/lib/packetgen/pcapng/idb.rb +3 -2
- data/lib/packetgen/pcapng/shb.rb +3 -2
- data/lib/packetgen/pcapng/spb.rb +2 -2
- data/lib/packetgen/pcapng/unknown_block.rb +1 -1
- data/lib/packetgen/pcapng.rb +3 -1
- data/lib/packetgen/pcaprub_wrapper.rb +1 -1
- data/lib/packetgen/proto.rb +5 -1
- data/lib/packetgen/unknown_packet.rb +4 -4
- data/lib/packetgen/utils/arp_spoofer.rb +1 -1
- data/lib/packetgen/utils.rb +4 -5
- data/lib/packetgen/version.rb +2 -2
- data/lib/packetgen.rb +9 -3
- metadata +8 -9
data/lib/packetgen/packet.rb
CHANGED
@@ -2,55 +2,63 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# This file is part of PacketGen
|
5
|
-
# See https://
|
5
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
8
8
|
# This program is published under MIT license.
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ClassLength
|
11
|
-
|
12
10
|
module PacketGen
|
13
11
|
# An object of type {Packet} handles a network packet. This packet may contain
|
14
12
|
# multiple protocol headers, starting from MAC layer or from Network (OSI) layer.
|
15
13
|
#
|
16
|
-
#
|
17
|
-
#
|
14
|
+
# A Packet is created using {.gen} method. Headers may be added to this packet using {#add}.
|
15
|
+
# It may also be created from parsing a binary string, using {.parse} method.
|
16
|
+
#
|
17
|
+
# @example Very simple packet
|
18
|
+
# # Create a packet with a single IP header. IP source and destination addresses are set.
|
19
|
+
# pkt = PacketGen::Packet.gen('IP', src: '192.168.1.1', dst: '192.168.1.2')
|
18
20
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# Packet.parse(binary_string)
|
21
|
+
# @example Parsing a binary string
|
22
|
+
# # a IP/ICMP packet, as binary string
|
23
|
+
# binary_string = "E\x00\x00\x1C\xAA`\x00\x00@\x01M-\xC0\xA8\x01\x01\xC0\xA8\x01\x02\x00\b;1abcd".b
|
24
|
+
# pkt = PacketGen::Packet.parse(binary_string)
|
25
|
+
# pkt.is?('IP') #=> true
|
26
|
+
# pkt.is?('ICMP') #=> true
|
23
27
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# # read information
|
27
|
-
# pkt.udp.sport
|
28
|
-
# pkt.ip.ttl
|
29
|
-
# # set information
|
30
|
-
# pkt.udp.dport = 2323
|
31
|
-
# pkt.ip.ttl = 1
|
32
|
-
# pkt.ip(ttl: 1, id: 1234)
|
28
|
+
# Information for each level is accessible through the associated header. Header is accessible through a
|
29
|
+
# method defined with its name at packet level (i.e. +#ip+ for a IP header).
|
33
30
|
#
|
34
|
-
#
|
35
|
-
#
|
31
|
+
# @example Accessing header information
|
32
|
+
# pkt = PacketGen::Packet.gen('IP').add('UDP')
|
33
|
+
# # read information
|
34
|
+
# pkt.udp.sport #=> 0
|
35
|
+
# pkt.ip.ttl #=> 64
|
36
|
+
# # set information
|
37
|
+
# pkt.udp.dport = 2323
|
38
|
+
# pkt.ip.ttl = 1
|
39
|
+
# # Set multiple attributes at once
|
40
|
+
# pkt.ip(ttl: 1, id: 1234)
|
36
41
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# do_some_stuffs
|
41
|
-
# end
|
42
|
-
# packets = Packet.capture(iface: 'eth0', max: 5) # get 5 packets from eth0
|
42
|
+
# Packets may be written to files using {#write}:
|
43
|
+
# pkt = PacketGen::Packet.gen('Eth')
|
44
|
+
# pkt.write('file.pcapng')
|
43
45
|
#
|
44
|
-
# Packets may
|
45
|
-
#
|
46
|
+
# Packets may be captured from network interfaces:
|
47
|
+
# # Capture all packets from default interface. Never end.
|
48
|
+
# PacketGen::Packet.capture do |packet|
|
49
|
+
# do_some_stuffs
|
50
|
+
# end
|
46
51
|
#
|
47
|
-
#
|
48
|
-
#
|
52
|
+
# # Get 5 packets from eth0 interface
|
53
|
+
# packets = Packet.capture(iface: 'eth0', max: 5)
|
49
54
|
#
|
55
|
+
# Finally, packets may also be read from a file:
|
56
|
+
# packets = Packet.read(file.pcapng)
|
50
57
|
# @author Sylvain Daubert
|
58
|
+
# @author LemonTree55
|
51
59
|
class Packet
|
52
60
|
# Get packet headers, ordered as they appear in the packet.
|
53
|
-
# @return [Array<
|
61
|
+
# @return [Array<Headerable>]
|
54
62
|
attr_reader :headers
|
55
63
|
# Activaye or deactivate header cache (activated by default)
|
56
64
|
# @return [Boolean]
|
@@ -142,7 +150,15 @@ module PacketGen
|
|
142
150
|
# @param [String] protocol
|
143
151
|
# @param [Hash] options protocol specific options
|
144
152
|
# @return [self]
|
145
|
-
# @raise [
|
153
|
+
# @raise [ArgumentError] unknown protocol
|
154
|
+
# @raise [BindingError] unknown binding
|
155
|
+
# @see #<<
|
156
|
+
# @example
|
157
|
+
# pkt = PacketGen::Packet.gen('Eth')
|
158
|
+
# # Add a IP header
|
159
|
+
# pkt.add('IP')
|
160
|
+
# # Add a TCP header, with some attributes and body set
|
161
|
+
# pkt.add('TCP', dport: 80, seqnum: 123456, body: "abcd".b)
|
146
162
|
def add(protocol, options={})
|
147
163
|
klass = check_protocol(protocol)
|
148
164
|
|
@@ -174,6 +190,7 @@ module PacketGen
|
|
174
190
|
end
|
175
191
|
|
176
192
|
# Check if a protocol header is embedded in packet.
|
193
|
+
# @example
|
177
194
|
# pkt = PacketGen.gen('IP').add('UDP')
|
178
195
|
# pkt.is?('IP') #=> true
|
179
196
|
# pkt.is?('TCP') #=> false
|
@@ -210,16 +227,22 @@ module PacketGen
|
|
210
227
|
end
|
211
228
|
end
|
212
229
|
|
213
|
-
# Get packet body
|
214
|
-
# @return [
|
230
|
+
# Get packet body. If packet (i.e. last header) has no +:body+ field, return +nil+.
|
231
|
+
# @return [Headerable,BinStruct::String,nil]
|
215
232
|
def body
|
216
233
|
last_header[:body] if last_header.respond_to?(:body)
|
217
234
|
end
|
218
235
|
|
219
236
|
# Set packet body
|
220
|
-
# @param [String] str
|
237
|
+
# @param [String] str Binary string
|
221
238
|
# @return [void]
|
239
|
+
# @raise [Error] Packet (i.e. last header) has no +:body+ field.
|
240
|
+
# @note To set a {Headerable} object, prefer #{<<}
|
241
|
+
# @see #<<
|
242
|
+
# @since 4.1.0 raise {Error} if no body on packet
|
222
243
|
def body=(str)
|
244
|
+
raise Error, 'no body in last headeré' unless last_header.respond_to?(:body)
|
245
|
+
|
223
246
|
last_header.body = str
|
224
247
|
end
|
225
248
|
|
@@ -270,6 +293,13 @@ module PacketGen
|
|
270
293
|
# @return [self] +self+ updated with new headers from +other+
|
271
294
|
# @raise [BindingError] do not known how to encapsulate
|
272
295
|
# @since 1.1.0
|
296
|
+
# @example
|
297
|
+
# # Create a first IP packet
|
298
|
+
# ip1 = PacketGen::Packet.gen('IP', id: 1)
|
299
|
+
# # Create second IP packet, to encapsulate in first
|
300
|
+
# ip2 = PacketGen.gen('IP', id: 2)
|
301
|
+
# ip1.encapsulate(ip2)
|
302
|
+
# ip1.ip(2) == ip2.ip
|
273
303
|
def encapsulate(other, parsing: false)
|
274
304
|
other.headers.each_with_index do |h, i|
|
275
305
|
add_header(h, parsing: i.positive? || parsing)
|
@@ -282,6 +312,12 @@ module PacketGen
|
|
282
312
|
# @raise [FormatError] any headers not in +self+
|
283
313
|
# @raise [BindingError] removed headers result in an unknown binding
|
284
314
|
# @since 1.1.0
|
315
|
+
# @example
|
316
|
+
# # IP/IP encapsulation
|
317
|
+
# pkt = PacketGen::Packet.gen('IP', id: 1).add('IP', id:2)
|
318
|
+
# # Remove outer IP header
|
319
|
+
# pkt.decapsulate(pkt.ip(1))
|
320
|
+
# pkt.ip.id #=> 2
|
285
321
|
def decapsulate(*hdrs)
|
286
322
|
hdrs.each do |hdr|
|
287
323
|
prev_hdr = previous_header(hdr)
|
@@ -290,6 +326,7 @@ module PacketGen
|
|
290
326
|
add_header(next_hdr, previous_header: prev_hdr) if prev_hdr && next_hdr
|
291
327
|
end
|
292
328
|
invalidate_header_cache
|
329
|
+
self
|
293
330
|
rescue ArgumentError => e
|
294
331
|
raise FormatError, e.message
|
295
332
|
end
|
@@ -334,7 +371,7 @@ module PacketGen
|
|
334
371
|
to_s == other.to_s
|
335
372
|
end
|
336
373
|
|
337
|
-
# +true+
|
374
|
+
# +true+ if {#==} is +true+ with another packet, or if +other+ is a protocol name String, whose protocol is in Packet.
|
338
375
|
# @param [Packet] other
|
339
376
|
# @return [Boolean]
|
340
377
|
# @since 3.1.2
|
@@ -349,8 +386,9 @@ module PacketGen
|
|
349
386
|
end
|
350
387
|
end
|
351
388
|
|
352
|
-
# Invert all possible attributes
|
389
|
+
# Invert all possible attributes in packet to create a reply.
|
353
390
|
# @return [self]
|
391
|
+
# @note Only modify headers responding to +#reply!+.
|
354
392
|
# @since 2.7.0
|
355
393
|
def reply!
|
356
394
|
headers.each do |header|
|
@@ -362,12 +400,32 @@ module PacketGen
|
|
362
400
|
# Forge a new packet from current one with all possible fields
|
363
401
|
# inverted. The new packet may be a reply to current one.
|
364
402
|
# @return [Packet]
|
403
|
+
# @note Only modify headers responding to +#reply!+.
|
365
404
|
# @since 2.7.0
|
366
405
|
def reply
|
367
406
|
pkt = dup
|
368
407
|
pkt.reply!
|
369
408
|
end
|
370
409
|
|
410
|
+
# Append an already defined header to packet
|
411
|
+
# @param [Headerable] header
|
412
|
+
# @return [self]
|
413
|
+
# @raise [ArgumentError] unknown protocol
|
414
|
+
# @raise [BindingError] unknown binding
|
415
|
+
# @example
|
416
|
+
# pkt = PacketGen.gen('Eth')
|
417
|
+
# # Add a new header from its type
|
418
|
+
# pkt.add('IP')
|
419
|
+
# # Add a new pre-generated header
|
420
|
+
# pkt << PacketGen::Header::TCP.new
|
421
|
+
# @see #add
|
422
|
+
# @since 4.1.0
|
423
|
+
# @author LemonTree55
|
424
|
+
def <<(header)
|
425
|
+
add_header(header)
|
426
|
+
self
|
427
|
+
end
|
428
|
+
|
371
429
|
private
|
372
430
|
|
373
431
|
# Dup +@headers+ instance variable. Internally used by +#dup+ and +#clone+
|
data/lib/packetgen/pcap.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -10,6 +10,7 @@ module PacketGen
|
|
10
10
|
module PcapNG
|
11
11
|
# @abstract Base class for all block types
|
12
12
|
# @author Sylvain Daubert
|
13
|
+
# @author LemonTree55
|
13
14
|
class Block < BinStruct::Struct
|
14
15
|
# @return [:little, :big]
|
15
16
|
attr_accessor :endian
|
@@ -78,7 +79,7 @@ module PacketGen
|
|
78
79
|
def to_io(str_or_io)
|
79
80
|
return str_or_io if str_or_io.respond_to?(:read)
|
80
81
|
|
81
|
-
StringIO.new(
|
82
|
+
StringIO.new(str_or_io.to_s.b)
|
82
83
|
end
|
83
84
|
|
84
85
|
def remove_padding(io, data_len)
|
data/lib/packetgen/pcapng/epb.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -1,16 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
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
|
|
@@ -168,13 +191,15 @@ module PacketGen
|
|
168
191
|
end
|
169
192
|
|
170
193
|
# Writes the {File} to a file.
|
171
|
-
# @param [
|
172
|
-
# @
|
194
|
+
# @param [String] filename file name to write
|
195
|
+
# @param [Boolean] append if set to +true+,
|
173
196
|
# the packets are appended to the file, rather than overwriting it
|
174
|
-
# @return [Array] array of 2 elements: filename and size written
|
175
|
-
# @
|
176
|
-
|
177
|
-
|
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'
|
178
203
|
::File.open(filename, mode) { |f| f.write(self.to_s) }
|
179
204
|
[filename, self.to_s.size]
|
180
205
|
end
|
@@ -182,14 +207,16 @@ module PacketGen
|
|
182
207
|
|
183
208
|
# Shorthand method for writing to a file.
|
184
209
|
# @param [#to_s] filename
|
185
|
-
# @return [Array]
|
210
|
+
# @return [Array(String, Integer)]
|
211
|
+
# @see #to_file
|
186
212
|
def write(filename='out.pcapng')
|
187
213
|
self.to_file(filename.to_s, append: false)
|
188
214
|
end
|
189
215
|
|
190
216
|
# Shorthand method for appending to a file.
|
191
217
|
# @param [#to_s] filename
|
192
|
-
# @return [Array]
|
218
|
+
# @return [Array(String, Integer)]
|
219
|
+
# @see #to_file
|
193
220
|
def append(filename='out.pcapng')
|
194
221
|
self.to_file(filename.to_s, append: true)
|
195
222
|
end
|
data/lib/packetgen/pcapng/idb.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
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
|
data/lib/packetgen/pcapng/shb.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
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
|
data/lib/packetgen/pcapng/spb.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
data/lib/packetgen/pcapng.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -11,6 +11,8 @@ 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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
data/lib/packetgen/proto.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# This file is part of PacketGen
|
5
|
-
# See https://
|
5
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
6
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
7
7
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
8
8
|
# This program is published under MIT license.
|
@@ -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
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# This file is part of PacketGen
|
5
|
-
# See https://
|
5
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
6
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
7
7
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
8
8
|
# This program is published under MIT license.
|
@@ -20,7 +20,7 @@ module PacketGen
|
|
20
20
|
|
21
21
|
def initialize
|
22
22
|
@headers = [].freeze
|
23
|
-
@binary_str =
|
23
|
+
@binary_str = ::String.new # Return empty string with encoding ASCII-8BIT, so BINARY
|
24
24
|
end
|
25
25
|
|
26
26
|
# Unknown packet, so unknown protocol.
|
@@ -40,7 +40,7 @@ module PacketGen
|
|
40
40
|
# @param [String] str
|
41
41
|
# @return [void]
|
42
42
|
def body=(str)
|
43
|
-
@binary_str =
|
43
|
+
@binary_str = str.b
|
44
44
|
end
|
45
45
|
|
46
46
|
# Write packet to a PCapNG file on disk.
|
@@ -56,7 +56,7 @@ module PacketGen
|
|
56
56
|
# @param [String] binary_str
|
57
57
|
# @return [self]
|
58
58
|
def parse(binary_str, _first_header: nil)
|
59
|
-
@binary_str =
|
59
|
+
@binary_str = binary_str.b
|
60
60
|
self
|
61
61
|
end
|
62
62
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
data/lib/packetgen/utils.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -71,9 +71,7 @@ module PacketGen
|
|
71
71
|
cache
|
72
72
|
end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
# Get MAC address from an IP address, or nil if this IP address is unknown
|
74
|
+
# Get MAC address from an IP address, or nil if this IP address is unknown
|
77
75
|
# on local network.
|
78
76
|
# @param [String] ipaddr dotted-octet IP address
|
79
77
|
# @param [Hash] options
|
@@ -168,7 +166,8 @@ module PacketGen
|
|
168
166
|
def self.mitm(target1, target2, options={}, &block)
|
169
167
|
options = { iface: PacketGen.default_iface }.merge(options)
|
170
168
|
|
171
|
-
|
169
|
+
spoofer_options = options.slice(:timeout, :interval, :iface)
|
170
|
+
spoofer = Utils::ARPSpoofer.new(**spoofer_options.compact)
|
172
171
|
spoofer.add target1, target2, options
|
173
172
|
spoofer.add target2, target1, options
|
174
173
|
|
data/lib/packetgen/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -11,5 +11,5 @@
|
|
11
11
|
# @author Sylvain Daubert
|
12
12
|
module PacketGen
|
13
13
|
# PacketGen version
|
14
|
-
VERSION = '4.
|
14
|
+
VERSION = '4.1.1'
|
15
15
|
end
|
data/lib/packetgen.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# This file is part of PacketGen
|
5
|
-
# See https://
|
5
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
6
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
7
7
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
8
8
|
# This program is published under MIT license.
|
@@ -13,6 +13,7 @@ require 'interfacez'
|
|
13
13
|
|
14
14
|
# PacketGen is a network packet generator and analyzor.
|
15
15
|
# @author Sylvain Daubert
|
16
|
+
# @author LemonTree
|
16
17
|
module PacketGen
|
17
18
|
# Base exception class for PacketGen exceptions
|
18
19
|
class Error < StandardError; end
|
@@ -33,12 +34,15 @@ module PacketGen
|
|
33
34
|
# @return [Headerable]
|
34
35
|
attr_reader :hdr
|
35
36
|
|
37
|
+
# @param [Headerable] prev_hdr
|
38
|
+
# @param [Headerable] hdr
|
36
39
|
def initialize(prev_hdr, hdr)
|
37
40
|
super()
|
38
41
|
@prev_hdr = prev_hdr
|
39
42
|
@hdr = hdr
|
40
43
|
end
|
41
44
|
|
45
|
+
# @return [String]
|
42
46
|
def message
|
43
47
|
"#{prev_hdr.class} knowns no layer association with #{hdr.protocol_name}. " \
|
44
48
|
"Try #{prev_hdr.class}.bind_layer(#{hdr.class}, " \
|
@@ -92,8 +96,10 @@ module PacketGen
|
|
92
96
|
# Force binary encoding for +str+
|
93
97
|
# @param [String] str
|
94
98
|
# @return [String] binary encoded string
|
99
|
+
# @deprecated Use +String#b+ instead.
|
95
100
|
def self.force_binary(str)
|
96
|
-
|
101
|
+
Deprecation.deprecated(self, :force_binary, 'String#b')
|
102
|
+
str.b
|
97
103
|
end
|
98
104
|
|
99
105
|
# Get default network interface (ie. first non-loopback declared interface)
|
@@ -120,7 +126,7 @@ module PacketGen
|
|
120
126
|
# Shortcut to get a header class
|
121
127
|
# @example builtin class
|
122
128
|
# # same as PacketGen::Header::Dot11:Data.new(id: 0xfedc)
|
123
|
-
# dot11 = PacketGen.header('Dot11::Data', id: 0xfedc)
|
129
|
+
# dot11 = PacketGen.header('Dot11::Data', id: 0xfedc)
|
124
130
|
# @example plugin class
|
125
131
|
# require 'packet-plugin-smb'
|
126
132
|
# # same as PacketGen::Plugin::SMB::CloseRequest.new(fid: 0x1234)
|