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
@@ -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 Header
|
10
10
|
class OSPFv3
|
@@ -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 Header
|
10
10
|
class OSPFv3
|
@@ -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 Header
|
10
10
|
class OSPFv3
|
@@ -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 Header
|
10
10
|
class OSPFv3
|
@@ -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 Header
|
10
10
|
class OSPFv3
|
@@ -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 Header
|
10
10
|
class OSPFv3
|
@@ -197,9 +197,7 @@ module PacketGen
|
|
197
197
|
private
|
198
198
|
|
199
199
|
def record_from_hash(hsh)
|
200
|
-
unless hsh.key? :type
|
201
|
-
raise ArgumentError, 'hash should have :type key'
|
202
|
-
end
|
200
|
+
raise ArgumentError, 'hash should have :type key' unless hsh.key? :type
|
203
201
|
|
204
202
|
klass = if @only_headers
|
205
203
|
LSAHeader
|
@@ -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 Header
|
10
10
|
class OSPFv3
|
@@ -31,13 +31,13 @@ module PacketGen
|
|
31
31
|
class LSAHeader < Types::Fields
|
32
32
|
# LSA known types
|
33
33
|
TYPES = {
|
34
|
-
'Router'
|
35
|
-
'Network'
|
34
|
+
'Router' => 0x2001,
|
35
|
+
'Network' => 0x2002,
|
36
36
|
'Inter-Area-Prefix' => 0x2003,
|
37
37
|
'Inter-Area-Router' => 0x2004,
|
38
|
-
'AS-External'
|
39
|
-
'NSSA'
|
40
|
-
'Link'
|
38
|
+
'AS-External' => 0x4005,
|
39
|
+
'NSSA' => 0x2007,
|
40
|
+
'Link' => 0x0008,
|
41
41
|
'Intra-Area-Prefix' => 0x2009
|
42
42
|
}.freeze
|
43
43
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# This file is part of PacketGen
|
3
5
|
# See https://github.com/sdaubert/packetgen for more informations
|
4
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
7
|
# This program is published under MIT license.
|
6
8
|
|
7
|
-
# frozen_string_literal: true
|
8
|
-
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
# Dissect error
|
@@ -22,6 +22,8 @@ module PacketGen
|
|
22
22
|
# Configuration sinks listen to this port
|
23
23
|
UDP_PORT2 = 162
|
24
24
|
|
25
|
+
# rubocop:disable Naming/ConstantName
|
26
|
+
|
25
27
|
PDU_GET = 0
|
26
28
|
PDU_NEXT = 1
|
27
29
|
PDU_RESPONSE = 2
|
@@ -31,27 +33,28 @@ module PacketGen
|
|
31
33
|
PDU_INFORM = 6
|
32
34
|
PDU_TRAPv2 = 7
|
33
35
|
PDU_REPORT = 8
|
36
|
+
# rubocop:enable Naming/ConstantName
|
34
37
|
|
35
38
|
ERRORS = {
|
36
|
-
'no_error'
|
37
|
-
'too_big'
|
38
|
-
'no_such_name'
|
39
|
-
'bad_value'
|
40
|
-
'read_only'
|
41
|
-
'generic_error'
|
42
|
-
'no_access'
|
43
|
-
'wrong_type'
|
44
|
-
'wrong_length'
|
45
|
-
'wrong_encoding'
|
46
|
-
'wrong_value'
|
47
|
-
'no_creation'
|
48
|
-
'inconsistent_value'
|
39
|
+
'no_error' => 0,
|
40
|
+
'too_big' => 1,
|
41
|
+
'no_such_name' => 2,
|
42
|
+
'bad_value' => 3,
|
43
|
+
'read_only' => 4,
|
44
|
+
'generic_error' => 5,
|
45
|
+
'no_access' => 6,
|
46
|
+
'wrong_type' => 7,
|
47
|
+
'wrong_length' => 8,
|
48
|
+
'wrong_encoding' => 9,
|
49
|
+
'wrong_value' => 10,
|
50
|
+
'no_creation' => 11,
|
51
|
+
'inconsistent_value' => 12,
|
49
52
|
'ressource_unavailable' => 13,
|
50
|
-
'commit_failed'
|
51
|
-
'undo_failed'
|
52
|
-
'authorization_error'
|
53
|
-
'not_writable'
|
54
|
-
'inconsistent_name'
|
53
|
+
'commit_failed' => 14,
|
54
|
+
'undo_failed' => 15,
|
55
|
+
'authorization_error' => 16,
|
56
|
+
'not_writable' => 17,
|
57
|
+
'inconsistent_name' => 18
|
55
58
|
}.freeze
|
56
59
|
|
57
60
|
# Class to handle SNMP VarBind
|
@@ -162,13 +165,13 @@ module PacketGen
|
|
162
165
|
implicit: SNMP::PDU_TRAPv1, constructed: true,
|
163
166
|
content: [objectid(:enterprise),
|
164
167
|
octet_string(:agent_addr),
|
165
|
-
integer(:generic_trap, enum: { 'cold_start'
|
166
|
-
'warm_start'
|
167
|
-
'link_down'
|
168
|
-
'link_up'
|
169
|
-
'auth_failure'
|
168
|
+
integer(:generic_trap, enum: { 'cold_start' => 0,
|
169
|
+
'warm_start' => 1,
|
170
|
+
'link_down' => 2,
|
171
|
+
'link_up' => 3,
|
172
|
+
'auth_failure' => 4,
|
170
173
|
'egp_neighbor_loss' => 5,
|
171
|
-
'specific'
|
174
|
+
'specific' => 6 }),
|
172
175
|
integer(:specific_trap),
|
173
176
|
integer(:timestamp),
|
174
177
|
model(:varbindlist, VariableBindings)]
|
@@ -291,8 +294,8 @@ module PacketGen
|
|
291
294
|
str << data.chosen_value.inspect(1)
|
292
295
|
begin
|
293
296
|
str << Inspect.inspect_body(self[:message].to_der, 'ASN.1 DER')
|
294
|
-
rescue StandardError =>
|
295
|
-
raise unless
|
297
|
+
rescue StandardError => e
|
298
|
+
raise unless e.message =~ /TAG.*not handled/
|
296
299
|
end
|
297
300
|
str
|
298
301
|
end
|
data/lib/packetgen/header/tcp.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 Header
|
10
10
|
# TCP header ({https://tools.ietf.org/html/rfc793 RFC 793})
|
@@ -235,7 +235,7 @@ module PacketGen
|
|
235
235
|
doff = Inspect.int_dec_hex(data_offset, 1)
|
236
236
|
str << shift << Inspect::FMT_ATTR % ['', 'data_offset', doff]
|
237
237
|
str << shift << Inspect::FMT_ATTR % ['', 'reserved', reserved]
|
238
|
-
flags = ''
|
238
|
+
flags = +''
|
239
239
|
%w[ns cwr ece urg ack psh rst syn fin].each do |fl|
|
240
240
|
flags << (send("flag_#{fl}?") ? fl[0].upcase : '.')
|
241
241
|
end
|
@@ -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 Header
|
10
10
|
class TCP
|
@@ -113,9 +113,7 @@ module PacketGen
|
|
113
113
|
# @return [String]
|
114
114
|
def to_human
|
115
115
|
str = self.class == Option ? +"unk-#{kind}" : self.class.to_s.sub(/.*::/, '')
|
116
|
-
if (length > 2) && !self[:value].to_s.empty?
|
117
|
-
str << ":#{self[:value].to_s.inspect}"
|
118
|
-
end
|
116
|
+
str << ":#{self[:value].to_s.inspect}" if (length > 2) && !self[:value].to_s.empty?
|
119
117
|
str
|
120
118
|
end
|
121
119
|
|
@@ -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_relative 'option'
|
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 Header
|
10
10
|
# A TFTP (Trivial File Transfer Protocol,
|
@@ -49,10 +49,10 @@ module PacketGen
|
|
49
49
|
class TFTP < Base
|
50
50
|
# Known opcodes
|
51
51
|
OPCODES = {
|
52
|
-
'RRQ'
|
53
|
-
'WRQ'
|
54
|
-
'DATA'
|
55
|
-
'ACK'
|
52
|
+
'RRQ' => 1,
|
53
|
+
'WRQ' => 2,
|
54
|
+
'DATA' => 3,
|
55
|
+
'ACK' => 4,
|
56
56
|
'Error' => 5
|
57
57
|
}.freeze
|
58
58
|
|
data/lib/packetgen/header/udp.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 Header
|
10
10
|
# UDP header ({https://tools.ietf.org/html/rfc768 RFC 768})
|
@@ -71,7 +71,7 @@ module PacketGen
|
|
71
71
|
# option is set.
|
72
72
|
def initialize(options={})
|
73
73
|
super
|
74
|
-
self.length += self[:body].sz if self[:body].sz
|
74
|
+
self.length += self[:body].sz if self[:body].sz.positive?
|
75
75
|
end
|
76
76
|
|
77
77
|
# Compute checksum and set +checksum+ field
|
data/lib/packetgen/headerable.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
|
# This mixin module defines minimal API for a class to act as a header
|
10
10
|
# in {Packet}.
|
@@ -85,9 +85,10 @@ module PacketGen
|
|
85
85
|
# @return [self]
|
86
86
|
# @raise [NotImplementedError]
|
87
87
|
def read(str)
|
88
|
+
# Do not call super and rescue NoMethodError: too slow
|
89
|
+
raise NotImplementedError, "#{self.class} should implement #read" if method(:read).super_method.nil?
|
90
|
+
|
88
91
|
super
|
89
|
-
rescue NoMethodError
|
90
|
-
raise NotImplementedError, "#{self.class} should implement #read"
|
91
92
|
end
|
92
93
|
end
|
93
94
|
end
|
@@ -0,0 +1,23 @@
|
|
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 inject packets on wire
|
11
|
+
# @author Sylvain Daubert
|
12
|
+
# @api private
|
13
|
+
# @since 3.1.4
|
14
|
+
module Inject
|
15
|
+
# Inject given data onto wire
|
16
|
+
# @param [String] iface interface name
|
17
|
+
# @param [String,Packet,Header::Base] data to inject
|
18
|
+
# @return [void]
|
19
|
+
def self.inject(iface:, data:)
|
20
|
+
PCAPRUBWrapper.inject(iface: iface, data: data.to_s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/packetgen/inspect.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
|
# {Inspect} module provides methods to help writing +inspect+
|
10
10
|
# @api private
|
@@ -37,6 +37,25 @@ module PacketGen
|
|
37
37
|
"%-16s (0x%0#{hexsize}x)" % [value.to_i, value.to_i]
|
38
38
|
end
|
39
39
|
|
40
|
+
# @param [String] str
|
41
|
+
# @param [Integer] int
|
42
|
+
# @param [Integer] hexsize
|
43
|
+
# @return [String]
|
44
|
+
def self.enum_human_hex(str, int, hexsize)
|
45
|
+
"%-16s (0x%0#{hexsize}x)" % [str, int]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Simple formatter to inspect an attribute
|
49
|
+
# @param [String] type attribute type
|
50
|
+
# @param [String] attr attribute name
|
51
|
+
# @param [String] value
|
52
|
+
# @param [Integer] level
|
53
|
+
# @return [String]
|
54
|
+
def self.format(type, attr, value, level=1)
|
55
|
+
str = Inspect.shift_level(level)
|
56
|
+
str << Inspect::FMT_ATTR % [type, attr, value]
|
57
|
+
end
|
58
|
+
|
40
59
|
# Format an attribute for +#inspect+.
|
41
60
|
# 3 cases are handled:
|
42
61
|
# * attribute value is a {Types::Int}: show value as integer and in
|
@@ -48,10 +67,10 @@ module PacketGen
|
|
48
67
|
# @param [Integer] level
|
49
68
|
# @return [String]
|
50
69
|
def self.inspect_attribute(attr, value, level=1)
|
51
|
-
|
70
|
+
type = value.class.to_s.sub(/.*::/, '')
|
52
71
|
val = case value
|
53
72
|
when Types::Enum
|
54
|
-
|
73
|
+
enum_human_hex(value.to_human, value.to_i, value.sz * 2)
|
55
74
|
when Types::Int
|
56
75
|
int_dec_hex(value, value.sz * 2)
|
57
76
|
when Integer
|
@@ -65,7 +84,7 @@ module PacketGen
|
|
65
84
|
value.to_s.inspect
|
66
85
|
end
|
67
86
|
end
|
68
|
-
|
87
|
+
self.format(type, attr, val, level)
|
69
88
|
end
|
70
89
|
|
71
90
|
# Format a ASN.1 attribute for +#inspect+.
|
data/lib/packetgen/packet.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# This file is part of PacketGen
|
3
5
|
# See https://github.com/sdaubert/packetgen for more informations
|
4
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
5
7
|
# This program is published under MIT license.
|
6
8
|
|
7
|
-
# frozen_string_literal: true
|
8
|
-
|
9
|
-
require 'pcaprub'
|
10
|
-
|
11
9
|
module PacketGen
|
12
10
|
# An object of type {Packet} handles a network packet. This packet may contain
|
13
11
|
# multiple protocol headers, starting from MAC layer or from Network (OSI) layer.
|
@@ -89,26 +87,21 @@ module PacketGen
|
|
89
87
|
capture.packets
|
90
88
|
end
|
91
89
|
|
92
|
-
# Read packets from +filename+.
|
90
|
+
# Read packets from +filename+. May read Pcap and Pcap-NG formats.
|
93
91
|
#
|
94
|
-
# For more control, see {PcapNG::File}
|
92
|
+
# For more control (on Pcap-ng only), see {PcapNG::File}.
|
95
93
|
# @param [String] filename PcapNG or Pcap file.
|
96
94
|
# @return [Array<Packet>]
|
95
|
+
# @raise [ArgumentError] unknown file format
|
97
96
|
# @author Sylvain Daubert
|
98
97
|
# @author Kent Gruber - Pcap format
|
99
98
|
# @since 2.0.0 Also read Pcap format.
|
100
99
|
def self.read(filename)
|
101
|
-
PcapNG::File.new.read_packets
|
100
|
+
PcapNG::File.new.read_packets(filename)
|
102
101
|
rescue StandardError => e
|
103
102
|
raise ArgumentError, e unless File.extname(filename.downcase) == '.pcap'
|
104
103
|
|
105
|
-
|
106
|
-
PCAPRUB::Pcap.open_offline(filename).each_packet do |packet|
|
107
|
-
next unless (packet = PacketGen.parse(packet.to_s))
|
108
|
-
|
109
|
-
packets << packet
|
110
|
-
end
|
111
|
-
packets
|
104
|
+
Pcap.read(filename)
|
112
105
|
end
|
113
106
|
|
114
107
|
# Write packets to +filename+
|
@@ -132,11 +125,13 @@ module PacketGen
|
|
132
125
|
# @param [String] protocol
|
133
126
|
# @param [Hash] options protocol specific options
|
134
127
|
# @return [self]
|
135
|
-
# @raise [
|
128
|
+
# @raise [BindingError] unknown protocol
|
136
129
|
def add(protocol, options={})
|
137
130
|
klass = check_protocol(protocol)
|
138
131
|
|
139
|
-
|
132
|
+
# options[:packet]= self is speedier than options.merge(packet: self)
|
133
|
+
options[:packet] = self
|
134
|
+
header = klass.new(options)
|
140
135
|
add_header header
|
141
136
|
self
|
142
137
|
end
|
@@ -146,12 +141,14 @@ module PacketGen
|
|
146
141
|
# @param [String] protocol protocol to insert
|
147
142
|
# @param [Hash] options protocol specific options
|
148
143
|
# @return [self]
|
149
|
-
# @raise [
|
144
|
+
# @raise [BindingError] unknown protocol
|
150
145
|
def insert(prev, protocol, options={})
|
151
146
|
klass = check_protocol(protocol)
|
152
147
|
|
153
148
|
nxt = prev.body
|
154
|
-
|
149
|
+
# options[:packet]= self is speedier than options.merge(packet: self)
|
150
|
+
options[:packet] = self
|
151
|
+
header = klass.new(options)
|
155
152
|
add_header header, previous_header: prev
|
156
153
|
idx = headers.index(prev) + 1
|
157
154
|
headers[idx, 0] = header
|
@@ -217,7 +214,7 @@ module PacketGen
|
|
217
214
|
# @return [Array] see return from {PcapNG::File#to_file}
|
218
215
|
# @see File
|
219
216
|
def to_f(filename)
|
220
|
-
PcapNG::File.new.array_to_file(
|
217
|
+
PcapNG::File.new.array_to_file(file: filename, array: [self])
|
221
218
|
end
|
222
219
|
alias write to_f
|
223
220
|
|
@@ -251,10 +248,11 @@ module PacketGen
|
|
251
248
|
# from binding with first other's one. Use only when current header field
|
252
249
|
# has its value set accordingly.
|
253
250
|
# @return [self] +self+ with new headers from +other+
|
251
|
+
# @raise [BindingError] do not known how to encapsulate
|
254
252
|
# @since 1.1.0
|
255
253
|
def encapsulate(other, parsing: false)
|
256
254
|
other.headers.each_with_index do |h, i|
|
257
|
-
add_header h, parsing:
|
255
|
+
add_header h, parsing: i.positive? || parsing
|
258
256
|
end
|
259
257
|
end
|
260
258
|
|
@@ -262,36 +260,32 @@ module PacketGen
|
|
262
260
|
# @param [Array<Header>] hdrs
|
263
261
|
# @return [self] +self+ with some headers removed
|
264
262
|
# @raise [FormatError] any headers not in +self+
|
265
|
-
# @raise [
|
263
|
+
# @raise [BindingError] removed headers result in an unknown binding
|
266
264
|
# @since 1.1.0
|
267
265
|
def decapsulate(*hdrs)
|
268
266
|
hdrs.each do |hdr|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
prev_hdr = idx > 0 ? headers[idx - 1] : nil
|
273
|
-
next_hdr = (idx + 1) < headers.size ? headers[idx + 1] : nil
|
274
|
-
headers.delete_at(idx)
|
267
|
+
prev_hdr = previous_header(hdr)
|
268
|
+
next_hdr = next_header(hdr)
|
269
|
+
headers.delete(hdr)
|
275
270
|
add_header(next_hdr, previous_header: prev_hdr) if prev_hdr && next_hdr
|
276
271
|
end
|
277
|
-
rescue ArgumentError =>
|
278
|
-
raise FormatError,
|
272
|
+
rescue ArgumentError => e
|
273
|
+
raise FormatError, e.message
|
279
274
|
end
|
280
275
|
|
281
276
|
# Parse a binary string and populate Packet from it.
|
282
277
|
# @param [String] binary_str
|
283
278
|
# @param [String,nil] first_header First protocol header. +nil+ means discover it!
|
284
279
|
# @return [Packet] self
|
285
|
-
# @raise [
|
280
|
+
# @raise [ParseError] +first_header+ is an unknown header
|
281
|
+
# @raise [BindingError] unknwon binding between some headers
|
286
282
|
def parse(binary_str, first_header: nil)
|
287
283
|
headers.clear
|
288
284
|
|
289
285
|
if first_header.nil?
|
290
286
|
# No decoding forced for first header. Have to guess it!
|
291
287
|
first_header = guess_first_header(binary_str)
|
292
|
-
if first_header.nil?
|
293
|
-
raise ParseError, 'cannot identify first header in string'
|
294
|
-
end
|
288
|
+
raise ParseError, 'cannot identify first header in string' if first_header.nil?
|
295
289
|
end
|
296
290
|
|
297
291
|
add first_header
|
@@ -374,6 +368,35 @@ module PacketGen
|
|
374
368
|
headers.last
|
375
369
|
end
|
376
370
|
|
371
|
+
# Give header index in packet
|
372
|
+
# @param [Headerable] hdr
|
373
|
+
# @return [Integer]
|
374
|
+
# @raise [FormatError] +hdr+ not in packet
|
375
|
+
def header_index(hdr)
|
376
|
+
idx = headers.index(hdr)
|
377
|
+
raise FormatError, 'header not in packet!' if idx.nil?
|
378
|
+
|
379
|
+
idx
|
380
|
+
end
|
381
|
+
|
382
|
+
# Give header previous +hdr+ in packet
|
383
|
+
# @param [Headerable] hdr
|
384
|
+
# @return [Headerable,nil] May return +nil+ if +hdr+ is the first header in packet
|
385
|
+
# @raise [FormatError] +hdr+ not in packet
|
386
|
+
def previous_header(hdr)
|
387
|
+
idx = header_index(hdr)
|
388
|
+
idx.positive? ? headers[idx - 1] : nil
|
389
|
+
end
|
390
|
+
|
391
|
+
# Give header next +hdr+ in packet
|
392
|
+
# @param [Headerable] hdr
|
393
|
+
# @return [Headerable,nil] May return +nil+ if +hdr+ is the last header in packet
|
394
|
+
# @raise [FormatError] +hdr+ not in packet
|
395
|
+
def next_header(hdr)
|
396
|
+
idx = header_index(hdr)
|
397
|
+
(idx + 1) < headers.size ? headers[idx + 1] : nil
|
398
|
+
end
|
399
|
+
|
377
400
|
# @overload header(klass, layer=1)
|
378
401
|
# @param [Class] klass
|
379
402
|
# @param [Integer] layer
|
@@ -388,9 +411,8 @@ module PacketGen
|
|
388
411
|
return header unless arg.is_a? Hash
|
389
412
|
|
390
413
|
arg.each do |key, value|
|
391
|
-
unless header.respond_to? "#{key}="
|
392
|
-
|
393
|
-
end
|
414
|
+
raise ArgumentError, "unknown #{key} attribute for #{klass}" unless header.respond_to? "#{key}="
|
415
|
+
|
394
416
|
header.send "#{key}=", value
|
395
417
|
end
|
396
418
|
|
@@ -408,26 +430,15 @@ module PacketGen
|
|
408
430
|
end
|
409
431
|
|
410
432
|
# Add a header to packet
|
411
|
-
# @param [
|
412
|
-
# @param [
|
433
|
+
# @param [Headerable] header
|
434
|
+
# @param [Headerable] previous_header
|
413
435
|
# @param [Boolean] parsing
|
414
436
|
# @return [void]
|
437
|
+
# @raise [BindingError]
|
415
438
|
def add_header(header, previous_header: nil, parsing: false)
|
416
439
|
prev_header = previous_header || last_header
|
417
|
-
if prev_header
|
418
|
-
bindings = prev_header.class.known_headers[header.class]
|
419
|
-
bindings = prev_header.class.known_headers[header.class.superclass] if bindings.nil?
|
420
|
-
if bindings.nil?
|
421
|
-
msg = "#{prev_header.class} knowns no layer association with #{header.protocol_name}. ".dup
|
422
|
-
msg << "Try #{prev_header.class}.bind_layer(#{header.class}, "
|
423
|
-
msg << "#{prev_header.method_name}_proto_field: "
|
424
|
-
msg << "value_for_#{header.method_name})"
|
425
|
-
raise ArgumentError, msg
|
426
|
-
end
|
440
|
+
add_to_previous_header(prev_header, header, parsing) if prev_header
|
427
441
|
|
428
|
-
bindings.set(prev_header) if !bindings.empty? && !parsing
|
429
|
-
prev_header[:body] = header
|
430
|
-
end
|
431
442
|
header.packet = self
|
432
443
|
headers << header unless previous_header
|
433
444
|
|
@@ -436,6 +447,20 @@ module PacketGen
|
|
436
447
|
add_magic_header_method header
|
437
448
|
end
|
438
449
|
|
450
|
+
# Bind +header+ to +prev_header+.
|
451
|
+
# @param [Headerable] prev_header
|
452
|
+
# @param [Headerable] header
|
453
|
+
# @param [Boolean] parsing
|
454
|
+
# @return [void]
|
455
|
+
# @raise [BindingError]
|
456
|
+
def add_to_previous_header(prev_header, header, parsing)
|
457
|
+
bindings = prev_header.class.known_headers[header.class] || prev_header.class.known_headers[header.class.superclass]
|
458
|
+
raise BindingError.new(prev_header, header) if bindings.nil?
|
459
|
+
|
460
|
+
bindings.set(prev_header) if !bindings.empty? && !parsing
|
461
|
+
prev_header[:body] = header
|
462
|
+
end
|
463
|
+
|
439
464
|
# Add method to access +header+
|
440
465
|
# @param [Header::Base] header
|
441
466
|
# @return [void]
|