packetgen 2.6.0 → 2.7.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/.gitignore +1 -0
- data/.rubocop.yml +28 -0
- data/Rakefile +6 -6
- data/bin/pgconsole +6 -6
- data/lib/packetgen.rb +4 -3
- data/lib/packetgen/capture.rb +5 -7
- data/lib/packetgen/config.rb +3 -3
- data/lib/packetgen/deprecation.rb +17 -0
- data/lib/packetgen/header.rb +40 -38
- data/lib/packetgen/header/arp.rb +46 -31
- data/lib/packetgen/header/asn1_base.rb +8 -8
- data/lib/packetgen/header/base.rb +108 -36
- data/lib/packetgen/header/bootp.rb +28 -19
- data/lib/packetgen/header/crypto.rb +6 -8
- data/lib/packetgen/header/dhcp.rb +4 -5
- data/lib/packetgen/header/dhcp/option.rb +46 -34
- data/lib/packetgen/header/dhcp/options.rb +0 -1
- data/lib/packetgen/header/dhcpv6.rb +10 -10
- data/lib/packetgen/header/dhcpv6/duid.rb +2 -3
- data/lib/packetgen/header/dhcpv6/option.rb +16 -21
- data/lib/packetgen/header/dhcpv6/relay.rb +6 -4
- data/lib/packetgen/header/dns.rb +13 -11
- data/lib/packetgen/header/dns/name.rb +4 -6
- data/lib/packetgen/header/dns/opt.rb +31 -31
- data/lib/packetgen/header/dns/option.rb +0 -2
- data/lib/packetgen/header/dns/qdsection.rb +1 -2
- data/lib/packetgen/header/dns/question.rb +19 -13
- data/lib/packetgen/header/dns/rr.rb +11 -14
- data/lib/packetgen/header/dns/rrsection.rb +5 -7
- data/lib/packetgen/header/dot11.rb +45 -29
- data/lib/packetgen/header/dot11/control.rb +3 -5
- data/lib/packetgen/header/dot11/data.rb +34 -6
- data/lib/packetgen/header/dot11/element.rb +0 -1
- data/lib/packetgen/header/dot11/management.rb +9 -5
- data/lib/packetgen/header/dot11/sub_mngt.rb +13 -14
- data/lib/packetgen/header/dot1q.rb +2 -2
- data/lib/packetgen/header/dot1x.rb +3 -4
- data/lib/packetgen/header/eap.rb +62 -53
- data/lib/packetgen/header/eap/fast.rb +0 -1
- data/lib/packetgen/header/eap/md5.rb +1 -2
- data/lib/packetgen/header/eap/tls.rb +9 -10
- data/lib/packetgen/header/eap/ttls.rb +9 -10
- data/lib/packetgen/header/esp.rb +33 -33
- data/lib/packetgen/header/eth.rb +11 -8
- data/lib/packetgen/header/gre.rb +5 -6
- data/lib/packetgen/header/http/headers.rb +11 -14
- data/lib/packetgen/header/http/request.rb +20 -20
- data/lib/packetgen/header/http/response.rb +16 -18
- data/lib/packetgen/header/http/verbs.rb +5 -5
- data/lib/packetgen/header/icmp.rb +1 -3
- data/lib/packetgen/header/icmpv6.rb +1 -3
- data/lib/packetgen/header/igmp.rb +5 -6
- data/lib/packetgen/header/igmpv3.rb +5 -9
- data/lib/packetgen/header/igmpv3/group_record.rb +4 -5
- data/lib/packetgen/header/igmpv3/mq.rb +2 -2
- data/lib/packetgen/header/igmpv3/mr.rb +4 -3
- data/lib/packetgen/header/ike.rb +33 -8
- data/lib/packetgen/header/ike/auth.rb +4 -6
- data/lib/packetgen/header/ike/cert.rb +0 -2
- data/lib/packetgen/header/ike/certreq.rb +1 -3
- data/lib/packetgen/header/ike/id.rb +1 -3
- data/lib/packetgen/header/ike/ke.rb +0 -2
- data/lib/packetgen/header/ike/nonce.rb +0 -2
- data/lib/packetgen/header/ike/notify.rb +22 -24
- data/lib/packetgen/header/ike/payload.rb +198 -199
- data/lib/packetgen/header/ike/sa.rb +21 -30
- data/lib/packetgen/header/ike/sk.rb +16 -17
- data/lib/packetgen/header/ike/ts.rb +22 -24
- data/lib/packetgen/header/ike/vendor_id.rb +0 -2
- data/lib/packetgen/header/ip.rb +30 -23
- data/lib/packetgen/header/ip/addr.rb +5 -6
- data/lib/packetgen/header/ip/option.rb +11 -15
- data/lib/packetgen/header/ip/options.rb +1 -2
- data/lib/packetgen/header/ipv6.rb +27 -12
- data/lib/packetgen/header/ipv6/addr.rb +2 -2
- data/lib/packetgen/header/ipv6/extension.rb +1 -1
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +11 -11
- data/lib/packetgen/header/llc.rb +4 -3
- data/lib/packetgen/header/mdns.rb +11 -5
- data/lib/packetgen/header/mld.rb +4 -4
- data/lib/packetgen/header/mldv2.rb +4 -3
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +3 -4
- data/lib/packetgen/header/mldv2/mlq.rb +3 -4
- data/lib/packetgen/header/mldv2/mlr.rb +4 -3
- data/lib/packetgen/header/netbios.rb +18 -5
- data/lib/packetgen/header/ospfv2.rb +6 -7
- data/lib/packetgen/header/ospfv2/db_description.rb +3 -4
- data/lib/packetgen/header/ospfv2/hello.rb +2 -3
- data/lib/packetgen/header/ospfv2/ls_ack.rb +2 -3
- data/lib/packetgen/header/ospfv2/ls_request.rb +2 -3
- data/lib/packetgen/header/ospfv2/ls_update.rb +5 -6
- data/lib/packetgen/header/ospfv2/lsa.rb +13 -14
- data/lib/packetgen/header/ospfv2/lsa_header.rb +4 -5
- data/lib/packetgen/header/ospfv3.rb +3 -4
- data/lib/packetgen/header/ospfv3/db_description.rb +3 -5
- data/lib/packetgen/header/ospfv3/hello.rb +2 -3
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +7 -8
- data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -3
- data/lib/packetgen/header/ospfv3/ls_request.rb +2 -3
- data/lib/packetgen/header/ospfv3/ls_update.rb +5 -6
- data/lib/packetgen/header/ospfv3/lsa.rb +10 -11
- data/lib/packetgen/header/ospfv3/lsa_header.rb +3 -4
- data/lib/packetgen/header/snmp.rb +45 -32
- data/lib/packetgen/header/tcp.rb +13 -9
- data/lib/packetgen/header/tcp/option.rb +16 -11
- data/lib/packetgen/header/tcp/options.rb +3 -4
- data/lib/packetgen/header/tftp.rb +15 -17
- data/lib/packetgen/header/udp.rb +10 -4
- data/lib/packetgen/inspect.rb +7 -9
- data/lib/packetgen/packet.rb +44 -22
- data/lib/packetgen/pcapng.rb +1 -5
- data/lib/packetgen/pcapng/block.rb +17 -11
- data/lib/packetgen/pcapng/epb.rb +6 -11
- data/lib/packetgen/pcapng/file.rb +37 -44
- data/lib/packetgen/pcapng/idb.rb +17 -22
- data/lib/packetgen/pcapng/shb.rb +7 -10
- data/lib/packetgen/pcapng/spb.rb +21 -17
- data/lib/packetgen/pcapng/unknown_block.rb +17 -13
- data/lib/packetgen/proto.rb +1 -2
- data/lib/packetgen/types/array.rb +119 -34
- data/lib/packetgen/types/cstring.rb +1 -5
- data/lib/packetgen/types/enum.rb +8 -10
- data/lib/packetgen/types/fields.rb +34 -28
- data/lib/packetgen/types/int.rb +11 -13
- data/lib/packetgen/types/int_string.rb +6 -8
- data/lib/packetgen/types/oui.rb +3 -6
- data/lib/packetgen/types/string.rb +4 -6
- data/lib/packetgen/types/tlv.rb +11 -14
- data/lib/packetgen/utils.rb +15 -23
- data/lib/packetgen/utils/arp_spoofer.rb +12 -18
- data/lib/packetgen/version.rb +1 -1
- data/packetgen.gemspec +9 -8
- metadata +19 -17
@@ -8,7 +8,6 @@
|
|
8
8
|
module PacketGen
|
9
9
|
module Header
|
10
10
|
class DNS
|
11
|
-
|
12
11
|
# Define a DNS Question Section
|
13
12
|
# @author Sylvain Daubert
|
14
13
|
class QDSection < RRSection
|
@@ -32,7 +31,7 @@ module PacketGen
|
|
32
31
|
clear
|
33
32
|
return self if str.nil?
|
34
33
|
force_binary str
|
35
|
-
while str.
|
34
|
+
while !str.empty? && (self.size < @counter.to_i)
|
36
35
|
question = Question.new(@dns).read(str)
|
37
36
|
str.slice!(0, question.sz)
|
38
37
|
self.push question
|
@@ -8,11 +8,9 @@
|
|
8
8
|
module PacketGen
|
9
9
|
module Header
|
10
10
|
class DNS
|
11
|
-
|
12
11
|
# DNS Question
|
13
12
|
# @author Sylvain Daubert
|
14
13
|
class Question < Base
|
15
|
-
|
16
14
|
# Ressource Record types
|
17
15
|
TYPES = {
|
18
16
|
'A' => 1,
|
@@ -84,12 +82,12 @@ module PacketGen
|
|
84
82
|
# @param [Integer] val
|
85
83
|
# @return [Integer,String]
|
86
84
|
def rrclass=(val)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
85
|
+
v = case val
|
86
|
+
when String
|
87
|
+
self.class::CLASSES[val.upcase]
|
88
|
+
else
|
89
|
+
val
|
90
|
+
end
|
93
91
|
raise ArgumentError, "unknown class #{val.inspect}" unless v
|
94
92
|
self[:rrclass].read v
|
95
93
|
end
|
@@ -97,30 +95,38 @@ module PacketGen
|
|
97
95
|
# Check type
|
98
96
|
# @param [String] type name
|
99
97
|
# @return [Boolean]
|
100
|
-
|
98
|
+
# @since 2.7.0
|
99
|
+
def type?(type)
|
101
100
|
self.class::TYPES[type] == self.type
|
102
101
|
end
|
103
102
|
|
103
|
+
# @deprecated Use {#type?} instead
|
104
|
+
# @return [Boolean]
|
105
|
+
def has_type?(type)
|
106
|
+
Deprecation.deprecated(self.class, __method__, 'type?')
|
107
|
+
type?(type)
|
108
|
+
end
|
109
|
+
|
104
110
|
# Get human readable type
|
105
111
|
# @return [String]
|
106
112
|
def human_type
|
107
|
-
self.class::TYPES.key(type) ||
|
113
|
+
self.class::TYPES.key(type) || '0x%04x' % type
|
108
114
|
end
|
109
115
|
|
110
116
|
# Get human readable class
|
111
117
|
# @return [String]
|
112
118
|
def human_rrclass
|
113
119
|
if self[:name].dns.is_a? MDNS
|
114
|
-
self.class::CLASSES.key(self.rrclass & 0x7fff) ||
|
120
|
+
self.class::CLASSES.key(self.rrclass & 0x7fff) || '0x%04x' % (self.rrclass & 0x7fff)
|
115
121
|
else
|
116
|
-
self.class::CLASSES.key(self.rrclass) ||
|
122
|
+
self.class::CLASSES.key(self.rrclass) || '0x%04x' % self.rrclass
|
117
123
|
end
|
118
124
|
end
|
119
125
|
|
120
126
|
# @return [String]
|
121
127
|
def to_human
|
122
128
|
if self[:name].dns.is_a? MDNS
|
123
|
-
unicast_bit =
|
129
|
+
unicast_bit = self.rrclass & 0x8000 == 0x8000 ? 'QU' : 'QM'
|
124
130
|
"#{human_type} #{human_rrclass} #{unicast_bit} #{name}"
|
125
131
|
else
|
126
132
|
"#{human_type} #{human_rrclass} #{name}"
|
@@ -8,11 +8,9 @@
|
|
8
8
|
module PacketGen
|
9
9
|
module Header
|
10
10
|
class DNS
|
11
|
-
|
12
11
|
# DNS Ressource Record
|
13
12
|
# @author Sylvain Daubert
|
14
13
|
class RR < Question
|
15
|
-
|
16
14
|
# @!attribute ttl
|
17
15
|
# 32-bit time to live
|
18
16
|
# @return [Integer]
|
@@ -37,9 +35,8 @@ module PacketGen
|
|
37
35
|
# @option options [String] :rdata
|
38
36
|
def initialize(dns, options={})
|
39
37
|
super
|
40
|
-
|
41
|
-
|
42
|
-
end
|
38
|
+
return unless options[:rdata] && options[:rdlength].nil?
|
39
|
+
self.rdata = options[:rdata]
|
43
40
|
end
|
44
41
|
|
45
42
|
# Set rdata and rdlength from +data+
|
@@ -49,7 +46,7 @@ module PacketGen
|
|
49
46
|
self[:rdlength].read data.size
|
50
47
|
self[:rdata].read data
|
51
48
|
end
|
52
|
-
|
49
|
+
|
53
50
|
# Get human readable rdata
|
54
51
|
# @return [String]
|
55
52
|
def human_rdata
|
@@ -71,11 +68,11 @@ module PacketGen
|
|
71
68
|
when TYPES['SOA']
|
72
69
|
mname = name.read(self[:rdata]).dup
|
73
70
|
rname = name.read(self[:rdata][mname.sz..-1])
|
74
|
-
serial = Types::Int32.new.read(self[:rdata][mname.sz+rname.sz, 4])
|
75
|
-
refresh = Types::Int32.new.read(self[:rdata][mname.sz+rname.sz+4, 4])
|
76
|
-
retryi = Types::Int32.new.read(self[:rdata][mname.sz+rname.sz+8, 4])
|
77
|
-
expire = Types::Int32.new.read(self[:rdata][mname.sz+rname.sz+12, 4])
|
78
|
-
minimum = Types::Int32.new.read(self[:rdata][mname.sz+rname.sz+16, 4])
|
71
|
+
serial = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz, 4])
|
72
|
+
refresh = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 4, 4])
|
73
|
+
retryi = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 8, 4])
|
74
|
+
expire = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 12, 4])
|
75
|
+
minimum = Types::Int32.new.read(self[:rdata][mname.sz + rname.sz + 16, 4])
|
79
76
|
str = "#{mname.to_human} #{rname.to_human} #{serial.to_i} #{refresh.to_i} " \
|
80
77
|
"#{retryi.to_i} #{expire.to_i} #{minimum.to_i}"
|
81
78
|
when TYPES['MX']
|
@@ -93,15 +90,15 @@ module PacketGen
|
|
93
90
|
str
|
94
91
|
end
|
95
92
|
|
96
|
-
def human_rrclass
|
97
93
|
# Get human readable class
|
98
94
|
# @return [String]
|
95
|
+
def human_rrclass
|
99
96
|
if self[:name].dns.is_a? MDNS
|
100
|
-
str = self.class::CLASSES.key(self.rrclass & 0x7fff) ||
|
97
|
+
str = self.class::CLASSES.key(self.rrclass & 0x7fff) || '0x%04x' % (self.rrclass & 0x7fff)
|
101
98
|
str += ' CACHE-FLUSH' if self.rrclass & 0x8000 > 0
|
102
99
|
str
|
103
100
|
else
|
104
|
-
self.class::CLASSES.key(self.rrclass) ||
|
101
|
+
self.class::CLASSES.key(self.rrclass) || '0x%04x' % self.rrclass
|
105
102
|
end
|
106
103
|
end
|
107
104
|
|
@@ -8,17 +8,15 @@
|
|
8
8
|
module PacketGen
|
9
9
|
module Header
|
10
10
|
class DNS
|
11
|
-
|
12
11
|
# Define a DNS Ressource Record Section
|
13
12
|
# @author Sylvain Daubert
|
14
13
|
class RRSection < Types::Array
|
15
|
-
|
16
14
|
# @api private
|
17
15
|
# @param [DNS] dns
|
18
16
|
# @param [Types::Int] counter
|
19
17
|
def initialize(dns, counter)
|
18
|
+
super(counter: counter)
|
20
19
|
@dns = dns
|
21
|
-
@counter = counter
|
22
20
|
end
|
23
21
|
|
24
22
|
# Read RR section from a string
|
@@ -28,11 +26,11 @@ module PacketGen
|
|
28
26
|
clear
|
29
27
|
return self if str.nil?
|
30
28
|
force_binary str
|
31
|
-
while str.
|
29
|
+
while !str.empty? && (self.size < @counter.to_i)
|
32
30
|
rr = RR.new(@dns).read(str)
|
33
|
-
rr = OPT.new(@dns).read(str) if rr.
|
31
|
+
rr = OPT.new(@dns).read(str) if rr.type?('OPT')
|
34
32
|
str.slice!(0, rr.sz)
|
35
|
-
|
33
|
+
push rr
|
36
34
|
end
|
37
35
|
self
|
38
36
|
end
|
@@ -40,7 +38,7 @@ module PacketGen
|
|
40
38
|
private
|
41
39
|
|
42
40
|
def record_from_hash(hsh)
|
43
|
-
if hsh.
|
41
|
+
if hsh.key? :rtype
|
44
42
|
case hsh.delete(:rtype)
|
45
43
|
when 'Question'
|
46
44
|
Question.new(@dns, hsh)
|
@@ -5,13 +5,14 @@
|
|
5
5
|
# This program is published under MIT license.
|
6
6
|
|
7
7
|
# frozen_string_literal: true
|
8
|
+
|
8
9
|
require 'zlib'
|
9
10
|
|
10
11
|
module PacketGen
|
11
12
|
module Header
|
12
|
-
|
13
13
|
# PPI (Per-Packet Information) packet
|
14
|
-
|
14
|
+
# @author Sylvain Daubert
|
15
|
+
# @since 1.4.0
|
15
16
|
class PPI < Base
|
16
17
|
# @!attribute version
|
17
18
|
# @return [Integer] 8-bit PPI version
|
@@ -52,7 +53,7 @@ module PacketGen
|
|
52
53
|
# Check version field
|
53
54
|
# @see [Base#parse?]
|
54
55
|
def parse?
|
55
|
-
version
|
56
|
+
version.zero? && (length >= 8)
|
56
57
|
end
|
57
58
|
|
58
59
|
# Calculate header length
|
@@ -76,6 +77,7 @@ module PacketGen
|
|
76
77
|
|
77
78
|
# Radiotap header (see http://www.radiotap.org/)
|
78
79
|
# @author Sylvain Daubert
|
80
|
+
# @since 1.4.0
|
79
81
|
class RadioTap < Base
|
80
82
|
# @!attribute version
|
81
83
|
# @return [Integer] 8-bit version
|
@@ -113,9 +115,9 @@ module PacketGen
|
|
113
115
|
# Check version field
|
114
116
|
# @see [Base#parse?]
|
115
117
|
def parse?
|
116
|
-
version
|
118
|
+
version.zero? && (length >= 8)
|
117
119
|
end
|
118
|
-
|
120
|
+
|
119
121
|
# Calculate header length
|
120
122
|
# @return [Integer] calculated length
|
121
123
|
# @since 2.1.3
|
@@ -204,18 +206,34 @@ module PacketGen
|
|
204
206
|
# pkt.calc
|
205
207
|
# pkt.to_w('wlan0')
|
206
208
|
# @author Sylvain Daubert
|
209
|
+
# @since 1.4.0
|
207
210
|
class Dot11 < Base
|
208
|
-
|
209
211
|
# Frame types
|
210
|
-
TYPES = %w
|
212
|
+
TYPES = %w[Management Control Data Reserved].freeze
|
211
213
|
|
212
214
|
class << self
|
213
215
|
# Set a flag for parsing Dot11 packets. If set to +true+, parse FCS field,
|
214
216
|
# else don't. Default is +true+.
|
215
217
|
# @return [Boolean]
|
216
|
-
attr_accessor :
|
218
|
+
attr_accessor :fcs
|
219
|
+
alias fcs? fcs
|
220
|
+
|
221
|
+
# rubocop:disable Naming/PredicateName
|
222
|
+
|
223
|
+
# @deprecated Use {#fcs?} instead.
|
224
|
+
def has_fcs
|
225
|
+
Deprecation.deprecated(self, __method__, 'fcs?', klass_method: true)
|
226
|
+
fcs?
|
227
|
+
end
|
228
|
+
|
229
|
+
# @deprecated Use {#fcs=} instead.
|
230
|
+
def has_fcs=(fcs)
|
231
|
+
Deprecation.deprecated(self, __method__, 'fcs=', klass_method: true)
|
232
|
+
self.fcs = fcs
|
233
|
+
end
|
234
|
+
# rubocop:enable Naming/PredicateName
|
217
235
|
end
|
218
|
-
Dot11.
|
236
|
+
Dot11.fcs = true
|
219
237
|
|
220
238
|
# @!attribute frame_ctrl
|
221
239
|
# @return [Integer] 16-bit frame control word
|
@@ -273,9 +291,8 @@ module PacketGen
|
|
273
291
|
# @return [Boolean] from_ds flag from {#frame_ctrl}
|
274
292
|
# @!attribute to_ds
|
275
293
|
# @return [Boolean] to_ds flag from {#frame_ctrl}
|
276
|
-
define_bit_fields_on :frame_ctrl,
|
277
|
-
|
278
|
-
|
294
|
+
define_bit_fields_on :frame_ctrl, :subtype, 4, :type, 2, :proto_version, 2,
|
295
|
+
:order, :wep, :md, :pwmngt, :retry, :mf, :from_ds, :to_ds
|
279
296
|
|
280
297
|
# @!attribute sequence_number (12-bit field from {#sequence_ctrl})
|
281
298
|
# @return [Integer]
|
@@ -310,7 +327,7 @@ module PacketGen
|
|
310
327
|
# @return [Dot11] may return a subclass object if a more specific class
|
311
328
|
# may be determined
|
312
329
|
def read(str)
|
313
|
-
|
330
|
+
fcs = Dot11.fcs?
|
314
331
|
|
315
332
|
if self.class == Dot11
|
316
333
|
return self if str.nil?
|
@@ -325,10 +342,10 @@ module PacketGen
|
|
325
342
|
when 2
|
326
343
|
Dot11::Data.new.read str
|
327
344
|
else
|
328
|
-
private_read str,
|
345
|
+
private_read str, fcs
|
329
346
|
end
|
330
347
|
else
|
331
|
-
private_read str,
|
348
|
+
private_read str, fcs
|
332
349
|
end
|
333
350
|
end
|
334
351
|
|
@@ -359,7 +376,7 @@ module PacketGen
|
|
359
376
|
elsif self.respond_to? :human_subtype
|
360
377
|
Inspect.dashed_line("#{self.class} #{human_subtype}", 2)
|
361
378
|
else
|
362
|
-
Inspect.dashed_line(
|
379
|
+
Inspect.dashed_line(self.class.to_s, 2)
|
363
380
|
end
|
364
381
|
define_applicable_fields
|
365
382
|
@applicable_fields.each do |attr|
|
@@ -378,25 +395,24 @@ module PacketGen
|
|
378
395
|
pcap.inject self.to_s
|
379
396
|
pcap.close
|
380
397
|
end
|
381
|
-
|
398
|
+
|
382
399
|
# Callback called when a Dot11 header is added to a packet
|
383
400
|
# Here, add +#dot11+ method as a shortcut to existing
|
384
401
|
# +#dot11_(control|management|data)+.
|
385
402
|
# @param [Packet] packet
|
386
403
|
# @return [void]
|
387
404
|
def added_to_packet(packet)
|
388
|
-
|
389
|
-
|
390
|
-
end
|
405
|
+
return if packet.respond_to? :dot11
|
406
|
+
packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end")
|
391
407
|
end
|
392
408
|
|
393
409
|
private
|
394
410
|
|
395
411
|
def define_applicable_fields
|
396
|
-
if to_ds?
|
412
|
+
if to_ds? && from_ds?
|
397
413
|
@applicable_fields[6, 0] = :mac4 unless @applicable_fields.include? :mac4
|
398
414
|
else
|
399
|
-
@applicable_fields -= %i
|
415
|
+
@applicable_fields -= %i[mac4]
|
400
416
|
end
|
401
417
|
if order?
|
402
418
|
unless @applicable_fields.include? :ht_ctrl
|
@@ -404,19 +420,19 @@ module PacketGen
|
|
404
420
|
@applicable_fields[idx, 0] = :ht_ctrl
|
405
421
|
end
|
406
422
|
else
|
407
|
-
@applicable_fields -= %i
|
423
|
+
@applicable_fields -= %i[ht_ctrl]
|
408
424
|
end
|
409
|
-
if Dot11.
|
425
|
+
if Dot11.fcs?
|
410
426
|
@applicable_fields << :fcs unless @applicable_fields.include? :fcs
|
411
427
|
else
|
412
|
-
@applicable_fields -= %i
|
428
|
+
@applicable_fields -= %i[fcs]
|
413
429
|
end
|
414
430
|
end
|
415
431
|
|
416
|
-
def private_read(str,
|
432
|
+
def private_read(str, fcs)
|
417
433
|
self[:frame_ctrl].read str[0, 2]
|
418
434
|
define_applicable_fields
|
419
|
-
if
|
435
|
+
if fcs
|
420
436
|
old_read str[0...-4]
|
421
437
|
self[:fcs].read str[-4..-1]
|
422
438
|
else
|
@@ -427,8 +443,8 @@ module PacketGen
|
|
427
443
|
end
|
428
444
|
|
429
445
|
self.add_class Dot11
|
430
|
-
PPI.
|
431
|
-
RadioTap.
|
446
|
+
PPI.bind Dot11, dlt: PcapNG::LINKTYPE_IEEE802_11
|
447
|
+
RadioTap.bind Dot11
|
432
448
|
end
|
433
449
|
end
|
434
450
|
|
@@ -9,7 +9,6 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class Dot11
|
12
|
-
|
13
12
|
# IEEE 802.11 control frame header
|
14
13
|
#
|
15
14
|
# This class make a {Dot11} header with {#type} set to +1+
|
@@ -24,7 +23,6 @@ module PacketGen
|
|
24
23
|
# * and a Frame check sequence ({#fcs}, of type {Types::Int32le}).
|
25
24
|
# @author Sylvain Daubert
|
26
25
|
class Control < Dot11
|
27
|
-
|
28
26
|
# Control subtypes
|
29
27
|
SUBTYPES = {
|
30
28
|
7 => 'Wrapper',
|
@@ -44,8 +42,8 @@ module PacketGen
|
|
44
42
|
# @param [Hash] options
|
45
43
|
# @see Base#initialize
|
46
44
|
def initialize(options={})
|
47
|
-
super({type: 1}.merge!(options))
|
48
|
-
@applicable_fields -= %i
|
45
|
+
super({ type: 1 }.merge!(options))
|
46
|
+
@applicable_fields -= %i[mac3 sequence_ctrl mac4 qos_ctrl ht_ctrl]
|
49
47
|
define_applicable_fields
|
50
48
|
end
|
51
49
|
|
@@ -60,7 +58,7 @@ module PacketGen
|
|
60
58
|
def define_applicable_fields
|
61
59
|
super
|
62
60
|
if @applicable_fields.include? :mac2
|
63
|
-
@applicable_fields -= %i
|
61
|
+
@applicable_fields -= %i[mac2] unless SUBTYPES_WITH_MAC2.include? self.subtype
|
64
62
|
elsif SUBTYPES_WITH_MAC2.include? self.subtype
|
65
63
|
@applicable_fields[3, 0] = :mac2
|
66
64
|
end
|
@@ -9,7 +9,6 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class Dot11
|
12
|
-
|
13
12
|
# IEEE 802.11 data frame header
|
14
13
|
#
|
15
14
|
# This class make a {Dot11} header with {#type} set to +2+
|
@@ -27,20 +26,49 @@ module PacketGen
|
|
27
26
|
# * and a Frame check sequence ({#fcs}, of type {Types::Int32le}).
|
28
27
|
# @author Sylvain Daubert
|
29
28
|
class Data < Dot11
|
30
|
-
|
31
29
|
# @param [Hash] options
|
32
30
|
# @see Base#initialize
|
33
31
|
def initialize(options={})
|
34
|
-
super({type: 2}.merge!(options))
|
35
|
-
@applicable_fields -= %i
|
32
|
+
super({ type: 2 }.merge!(options))
|
33
|
+
@applicable_fields -= %i[mac4 qos_ctrl ht_ctrl]
|
36
34
|
define_applicable_fields
|
37
35
|
end
|
38
36
|
|
37
|
+
# Invert source and destination addresses (see Table 8-19 from
|
38
|
+
# IEEE 802.11-2012 document to known which MAC is SA, and which
|
39
|
+
# one is DA).
|
40
|
+
# Also invert Receiver and Transmitter address in case ToDS and
|
41
|
+
# FromDS are true.
|
42
|
+
def reply!
|
43
|
+
ds = frame_ctrl & 3
|
44
|
+
case ds
|
45
|
+
when 0
|
46
|
+
# MAC1: RA/DA, MAC2: TA/SA
|
47
|
+
self[:mac1], self[:mac2] = self[:mac2], self[:mac1]
|
48
|
+
when 1
|
49
|
+
# MAC1: RA/BSSID, MAC2: TA/SA, MAC3: DA
|
50
|
+
self[:mac2], self[:mac1] = self[:mac1], self[:mac2]
|
51
|
+
self.to_ds = false
|
52
|
+
self.from_ds = true
|
53
|
+
when 2
|
54
|
+
# MAC1: RA/DA, MAC2: BSSID, MAC3: SA or BSSID
|
55
|
+
self[:mac1], self[:mac2] = self[:mac2], self[:mac1]
|
56
|
+
self.to_ds = true
|
57
|
+
self.from_ds = false
|
58
|
+
when 3
|
59
|
+
# MAC1: RA, MAC2: TA
|
60
|
+
self[:mac1], self[:mac2] = self[:mac2], self[:mac1]
|
61
|
+
# MAC3: DA, MAC4: SA
|
62
|
+
self[:mac4], self[:mac3] = self[:mac3], self[:mac4]
|
63
|
+
end
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
39
67
|
private
|
40
68
|
|
41
69
|
def define_applicable_fields
|
42
70
|
super
|
43
|
-
if subtype >= 8
|
71
|
+
if (subtype >= 8) && !@applicable_fields.include?(:qos_ctrl)
|
44
72
|
# Insert after mac4, if present
|
45
73
|
# else insert after sequence_ctrl
|
46
74
|
if @applicable_fields.include? :mac4
|
@@ -50,7 +78,7 @@ module PacketGen
|
|
50
78
|
@applicable_fields[6, 0] = :qos_ctrl
|
51
79
|
end
|
52
80
|
elsif subtype < 8
|
53
|
-
@applicable_fields -= %i
|
81
|
+
@applicable_fields -= %i[qos_ctrl]
|
54
82
|
end
|
55
83
|
end
|
56
84
|
end
|