packetgen 4.0.0 → 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 +1 -1
- data/lib/packetgen/deprecation.rb +7 -1
- data/lib/packetgen/header/arp.rb +6 -7
- data/lib/packetgen/header/asn1_base.rb +2 -1
- data/lib/packetgen/header/base.rb +27 -24
- data/lib/packetgen/header/bootp.rb +14 -14
- data/lib/packetgen/header/dhcp/option.rb +8 -8
- data/lib/packetgen/header/dhcp/options.rb +2 -2
- data/lib/packetgen/header/dhcp.rb +6 -7
- data/lib/packetgen/header/dhcpv6/duid.rb +1 -1
- data/lib/packetgen/header/dhcpv6/option.rb +37 -15
- data/lib/packetgen/header/dhcpv6/options.rb +3 -3
- data/lib/packetgen/header/dhcpv6/relay.rb +1 -0
- data/lib/packetgen/header/dhcpv6.rb +13 -14
- data/lib/packetgen/header/dns/name.rb +9 -8
- data/lib/packetgen/header/dns/opt.rb +3 -0
- data/lib/packetgen/header/dns/option.rb +7 -7
- data/lib/packetgen/header/dns/qdsection.rb +2 -2
- data/lib/packetgen/header/dns/question.rb +1 -0
- data/lib/packetgen/header/dns/rrsection.rb +2 -2
- data/lib/packetgen/header/dns.rb +76 -60
- data/lib/packetgen/header/dot11/control.rb +5 -5
- data/lib/packetgen/header/dot11/data.rb +11 -10
- data/lib/packetgen/header/dot11/element.rb +1 -1
- data/lib/packetgen/header/dot11/management.rb +18 -15
- data/lib/packetgen/header/dot11/sub_mngt.rb +22 -21
- data/lib/packetgen/header/dot11.rb +38 -38
- data/lib/packetgen/header/dot1q.rb +5 -4
- data/lib/packetgen/header/dot1x.rb +8 -8
- data/lib/packetgen/header/eap/fast.rb +3 -3
- data/lib/packetgen/header/eap/md5.rb +11 -3
- data/lib/packetgen/header/eap/tls.rb +9 -8
- data/lib/packetgen/header/eap/ttls.rb +13 -10
- data/lib/packetgen/header/eap.rb +58 -33
- data/lib/packetgen/header/eth.rb +26 -12
- data/lib/packetgen/header/gre.rb +26 -2
- data/lib/packetgen/header/http/headers.rb +6 -5
- data/lib/packetgen/header/http/request.rb +24 -16
- data/lib/packetgen/header/http/response.rb +22 -15
- data/lib/packetgen/header/icmp.rb +10 -10
- data/lib/packetgen/header/icmpv6.rb +10 -9
- data/lib/packetgen/header/igmp.rb +21 -10
- data/lib/packetgen/header/igmpv3/group_record.rb +7 -2
- data/lib/packetgen/header/igmpv3/mq.rb +1 -1
- data/lib/packetgen/header/igmpv3/mr.rb +1 -1
- data/lib/packetgen/header/igmpv3.rb +11 -10
- data/lib/packetgen/header/ip/addr.rb +6 -2
- data/lib/packetgen/header/ip/option.rb +18 -5
- data/lib/packetgen/header/ip.rb +52 -35
- data/lib/packetgen/header/ipv6/addr.rb +14 -13
- data/lib/packetgen/header/ipv6/extension.rb +9 -7
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +26 -7
- data/lib/packetgen/header/ipv6.rb +31 -22
- data/lib/packetgen/header/llc.rb +20 -13
- data/lib/packetgen/header/mdns.rb +9 -2
- data/lib/packetgen/header/mld.rb +11 -9
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +6 -1
- data/lib/packetgen/header/mldv2/mlq.rb +8 -8
- data/lib/packetgen/header/mldv2/mlr.rb +4 -4
- data/lib/packetgen/header/mldv2.rb +1 -1
- data/lib/packetgen/header/ospfv2/db_description.rb +10 -10
- data/lib/packetgen/header/ospfv2/hello.rb +11 -10
- data/lib/packetgen/header/ospfv2/ls_ack.rb +5 -6
- data/lib/packetgen/header/ospfv2/ls_request.rb +7 -6
- data/lib/packetgen/header/ospfv2/ls_update.rb +7 -7
- data/lib/packetgen/header/ospfv2/lsa.rb +33 -10
- data/lib/packetgen/header/ospfv2/lsa_header.rb +3 -2
- data/lib/packetgen/header/ospfv2.rb +31 -26
- data/lib/packetgen/header/ospfv3/db_description.rb +12 -13
- data/lib/packetgen/header/ospfv3/hello.rb +10 -9
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +6 -2
- data/lib/packetgen/header/ospfv3/ls_ack.rb +5 -6
- data/lib/packetgen/header/ospfv3/ls_request.rb +10 -10
- data/lib/packetgen/header/ospfv3/ls_update.rb +7 -7
- data/lib/packetgen/header/ospfv3/lsa.rb +23 -9
- data/lib/packetgen/header/ospfv3/lsa_header.rb +3 -2
- data/lib/packetgen/header/ospfv3.rb +38 -34
- data/lib/packetgen/header/sctp/chunk.rb +38 -17
- data/lib/packetgen/header/sctp/error.rb +169 -197
- data/lib/packetgen/header/sctp/padded32.rb +3 -3
- data/lib/packetgen/header/sctp/parameter.rb +85 -132
- data/lib/packetgen/header/sctp.rb +14 -3
- data/lib/packetgen/header/snmp.rb +108 -7
- data/lib/packetgen/header/tcp/option.rb +7 -0
- data/lib/packetgen/header/tcp/options.rb +11 -3
- data/lib/packetgen/header/tcp.rb +33 -26
- data/lib/packetgen/header/tftp.rb +16 -10
- data/lib/packetgen/header/udp.rb +15 -13
- data/lib/packetgen/header.rb +19 -13
- data/lib/packetgen/headerable.rb +9 -3
- data/lib/packetgen/inspect.rb +2 -7
- data/lib/packetgen/packet.rb +94 -36
- data/lib/packetgen/pcapng/block.rb +2 -1
- data/lib/packetgen/pcapng/file.rb +41 -14
- data/lib/packetgen/pcapng/idb.rb +2 -1
- data/lib/packetgen/pcapng/shb.rb +2 -1
- data/lib/packetgen/pcapng/spb.rb +1 -1
- data/lib/packetgen/pcapng.rb +2 -0
- data/lib/packetgen/proto.rb +4 -0
- data/lib/packetgen/unknown_packet.rb +3 -3
- data/lib/packetgen/utils.rb +2 -1
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +8 -2
- metadata +4 -4
@@ -103,58 +103,54 @@ module PacketGen
|
|
103
103
|
end
|
104
104
|
self.add_class RadioTap
|
105
105
|
|
106
|
-
# IEEE 802.11 header
|
107
106
|
# @abstract This is a base class to demultiplex different IEEE 802.11 frames when
|
108
107
|
# parsing.
|
109
108
|
# A IEEE 802.11 header may consist of at least:
|
110
|
-
# * a {#frame_ctrl} (
|
111
|
-
# * a {#id}/duration (
|
109
|
+
# * a {#frame_ctrl} (+BinStruct::Int16+),
|
110
|
+
# * a {#id}/duration (+BinStruct::Int16le+),
|
112
111
|
# * and a {#mac1} ({Eth::MacAddr}).
|
113
112
|
# Depending on frame type and subtype, it may also contains:
|
114
113
|
# * a {#mac2} ({Eth::MacAddr}),
|
115
114
|
# * a {#mac3} ({Eth::MacAddr}),
|
116
|
-
# * a {#sequence_ctrl} (
|
115
|
+
# * a {#sequence_ctrl} (+BinStruct::Int16+),
|
117
116
|
# * a {#mac4} ({Eth::MacAddr}),
|
118
|
-
# * a {#qos_ctrl} (
|
119
|
-
# * a {#ht_ctrl} (
|
120
|
-
# * a {#body} (a
|
121
|
-
# * a Frame check sequence ({#fcs}, of type
|
117
|
+
# * a {#qos_ctrl} (+BinStruct::Int16+),
|
118
|
+
# * a {#ht_ctrl} (+BinStruct::Int32+),
|
119
|
+
# * a {#body} (a +BinStruct::String+ or another {Headerable} class),
|
120
|
+
# * a Frame check sequence ({#fcs}, of type +BinStruct::Int32le+)
|
122
121
|
#
|
123
122
|
# == Header accessors
|
124
123
|
# As Dot11 header types are defined under Dot11 namespace, Dot11 header accessors
|
125
|
-
# have a specific name.
|
124
|
+
# have a specific name. For example, to access to a {Dot11::Beacon} header,
|
126
125
|
# accessor is +#dot11_beacon+.
|
127
126
|
#
|
128
127
|
# == Create Dot11 packets
|
129
128
|
# As {Dot11} is an abstract class, you have to use one of its subclasses to
|
130
|
-
# instanciate a IEEE802.11 header.
|
129
|
+
# instanciate a IEEE802.11 header (see examples below).
|
131
130
|
#
|
132
|
-
#
|
133
|
-
# Control frames may be created this way:
|
131
|
+
# @example Create IEEE802.11 control frames
|
134
132
|
# pkt = PacketGen.gen('Dot11::Control', subtype: 13) # Ack control frame
|
135
|
-
# pkt.dot11_control
|
133
|
+
# pkt.dot11_control.class # => PacketGen::Header::Dot11::Control
|
136
134
|
# # #dot11 is a shortcut for #dot11_control
|
137
|
-
# pkt.dot11
|
135
|
+
# pkt.dot11.class # => PacketGen::Header::Dot11::Control
|
138
136
|
#
|
139
|
-
#
|
140
|
-
# Management frames may be created this way:
|
137
|
+
# @example Create IEEE802.11 management frames
|
141
138
|
# pkt = PacketGen.gen('Dot11::Management')
|
142
|
-
# pkt.dot11_management
|
139
|
+
# pkt.dot11_management.class # => PacketGen::Header::Dot11::Management
|
143
140
|
# # #dot11 is a shortcut for #dot11_management
|
144
|
-
# pkt.dot11
|
145
|
-
# Management frames are usually specialized, AssociationRequest by example
|
141
|
+
# pkt.dot11.class # => PacketGen::Header::Dot11::Management
|
142
|
+
# # Management frames are usually specialized, AssociationRequest by example
|
146
143
|
# pkt.add('Dot11::AssoReq')
|
147
|
-
# pkt.dot11_assoreq
|
148
|
-
# Management frames also may contain some elements (see IEEE 802.11 standard)
|
149
|
-
# pkt.dot11_assoreq.
|
150
|
-
# pkt.dot11_assoreq.
|
144
|
+
# pkt.dot11_assoreq .class # => PacketGen::Header::Dot11::AssoReq
|
145
|
+
# # Management frames also may contain some elements (see IEEE 802.11 standard)
|
146
|
+
# pkt.dot11_assoreq.elements << { type: 'SSID', value: "My SSID" }
|
147
|
+
# pkt.dot11_assoreq.elements << { type: 'Rates', value: "\x8c\x12\x98\x24\xb0" }
|
151
148
|
#
|
152
|
-
#
|
153
|
-
# Data frames may be created this way:
|
149
|
+
# @example Create IEEE802.11 data frames
|
154
150
|
# pkt = PacketGen.gen('Dot11::Data')
|
155
|
-
# pkt.dot11_data
|
151
|
+
# pkt.dot11_data.class # => PacketGen::Header::Dot11::Data
|
156
152
|
# # #dot11 is a shortcut for #dot11_data
|
157
|
-
# pkt.dot11
|
153
|
+
# pkt.dot11.class # => PacketGen::Header::Dot11::Data
|
158
154
|
#
|
159
155
|
# == Parse Dot11 packets
|
160
156
|
# When parsing a Dot11 packet, Dot11 subclass is created from +type+ value.
|
@@ -163,13 +159,12 @@ module PacketGen
|
|
163
159
|
# for a control frame, +Packet#dot11_control+ may also be used.
|
164
160
|
#
|
165
161
|
# == Send Dot11 packets
|
166
|
-
# To send a Dot11 packet, a RadioTap header is needed:
|
162
|
+
# To send a Dot11 packet, a RadioTap or PPI header is needed (depending on your hardware):
|
167
163
|
# pkt = PacketGen.gen('RadioTap')
|
168
164
|
# pkt.add('Dot11::Management', mac1: client, mac2: bssid, mac3: bssid)
|
169
165
|
# pkt.add('Dot11::Beacon')
|
170
|
-
# pkt.
|
171
|
-
# pkt.
|
172
|
-
# pkt.calc
|
166
|
+
# pkt.dot11_management.add_element(type: 'SSID', value: 'My SSID')
|
167
|
+
# pkt.dot11_management.add_element(type: 'Rates', value: "\x85\x0c")
|
173
168
|
# pkt.to_w('wlan0')
|
174
169
|
# @author Sylvain Daubert
|
175
170
|
# @since 1.4.0
|
@@ -226,10 +221,12 @@ module PacketGen
|
|
226
221
|
define_attr :mac3, Eth::MacAddr
|
227
222
|
# @!attribute sequence_ctrl
|
228
223
|
# @return [Integer] 16-bit sequence control word
|
229
|
-
# @!attribute sequence_number
|
224
|
+
# @!attribute sequence_number
|
225
|
+
# 12-bit field from {#sequence_ctrl}
|
230
226
|
# @return [Integer]
|
231
227
|
# @since 2.1.3
|
232
|
-
# @!attribute fragment_number
|
228
|
+
# @!attribute fragment_number
|
229
|
+
# 4-bit attribute from {#sequence_ctrl}
|
233
230
|
# @return [Integer]
|
234
231
|
# @since 2.1.3
|
235
232
|
define_bit_attr :sequence_ctrl, sequence_number: 12, fragment_number: 4
|
@@ -243,9 +240,11 @@ module PacketGen
|
|
243
240
|
# @return [Integer] 16-bit HT control word
|
244
241
|
define_attr :ht_ctrl, BinStruct::Int32
|
245
242
|
# @!attribute body
|
243
|
+
# Dot11 body, if any
|
246
244
|
# @return [BinStruct::String]
|
247
245
|
define_attr :body, BinStruct::String
|
248
246
|
# @!attribute fcs
|
247
|
+
# Checksum of the Dot11 frame.
|
249
248
|
# @return [BinStruct::Int32le]
|
250
249
|
define_attr :fcs, BinStruct::Int32le
|
251
250
|
|
@@ -260,7 +259,7 @@ module PacketGen
|
|
260
259
|
@applicable_attributes = old_attributes
|
261
260
|
end
|
262
261
|
|
263
|
-
# Get all used
|
262
|
+
# Get all used attribute names
|
264
263
|
# @return [Array<Symbol>]
|
265
264
|
def attributes
|
266
265
|
@applicable_attributes
|
@@ -279,7 +278,7 @@ module PacketGen
|
|
279
278
|
if self.instance_of?(Dot11)
|
280
279
|
return self if str.nil?
|
281
280
|
|
282
|
-
|
281
|
+
str = str.b unless str.encoding == Encoding::BINARY
|
283
282
|
self[:frame_ctrl].read(str[0, 2])
|
284
283
|
|
285
284
|
case type
|
@@ -305,10 +304,11 @@ module PacketGen
|
|
305
304
|
fcs
|
306
305
|
end
|
307
306
|
|
307
|
+
# Generate binary string
|
308
308
|
# @return [String]
|
309
309
|
def to_s
|
310
310
|
define_applicable_attributes
|
311
|
-
@applicable_attributes.map { |f|
|
311
|
+
@applicable_attributes.map { |f| @attributes[f].to_s.b }.join
|
312
312
|
end
|
313
313
|
|
314
314
|
# Get human readable type
|
@@ -343,7 +343,7 @@ module PacketGen
|
|
343
343
|
Inject.inject(iface: iface, data: self)
|
344
344
|
end
|
345
345
|
|
346
|
-
# Callback called when a Dot11 header is added to a packet
|
346
|
+
# Callback called when a Dot11 header is added to a packet.
|
347
347
|
# Here, add +#dot11+ method as a shortcut to existing
|
348
348
|
# +#dot11_(control|management|data)+.
|
349
349
|
# @param [Packet] packet
|
@@ -357,7 +357,7 @@ module PacketGen
|
|
357
357
|
private
|
358
358
|
|
359
359
|
def remove_from_applicable_attributes(attributes)
|
360
|
-
attributes = [attributes] unless attributes.is_a?
|
360
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
361
361
|
@applicable_attributes -= attributes
|
362
362
|
end
|
363
363
|
|
@@ -11,13 +11,14 @@ module PacketGen
|
|
11
11
|
# IEEE 802.1Q VLAN tagging
|
12
12
|
#
|
13
13
|
# A VLAN tag consists of:
|
14
|
-
# * a {#tci Tag Control Information} (
|
15
|
-
# * a {#ethertype} (
|
16
|
-
# * and a body (a
|
14
|
+
# * a {#tci Tag Control Information} (+BinStruct::Int16+),
|
15
|
+
# * a {#ethertype} (+BinStruct::Int16+),
|
16
|
+
# * and a body (a +BinStruct::String+ or another {Headerable} class).
|
17
17
|
#
|
18
|
-
#
|
18
|
+
# @example Create a Dot1q header
|
19
19
|
# # Create a IP packet in VLAN #43
|
20
20
|
# pkt = PacketGen.gen('Eth').add('Dot1q', vid: 43).add('IP')
|
21
|
+
# pkt.is?('Dot1q') #=> true
|
21
22
|
# @author Sylvain Daubert
|
22
23
|
# @since 1.4.0
|
23
24
|
class Dot1q < Base
|
@@ -11,15 +11,15 @@ module PacketGen
|
|
11
11
|
# IEEE 802.1X / EAPOL
|
12
12
|
#
|
13
13
|
# A IEEE 802.1X header consists of:
|
14
|
-
# * a {#version} (
|
15
|
-
# * a packet {#type} (
|
16
|
-
# * a {#length} (
|
17
|
-
# * and a body (a
|
18
|
-
#
|
14
|
+
# * a {#version} (+BinStruct::Int8+),
|
15
|
+
# * a packet {#type} (+BinStruct::Int8+),
|
16
|
+
# * a {#length} (+BinStruct::Int16+),
|
17
|
+
# * and a body (a +BinStruct::String+ or another {Headerable} class).
|
18
|
+
# @example Create a Dot1x header
|
19
|
+
# # Create with integer type
|
19
20
|
# pkt1 = PacketGen.gen('Eth').add('Dot1x', type: 1)
|
20
|
-
#
|
21
|
-
# pkt2.
|
22
|
-
# pkt2.dot1x.body.read 'body'
|
21
|
+
# # Create with human-readable type
|
22
|
+
# pkt2 = PacketGen.gen('Eth').add('Dot1x', type: 'EAP Packet')
|
23
23
|
# @author Sylvain Daubert
|
24
24
|
# @since 1.4.0
|
25
25
|
class Dot1x < Base
|
@@ -13,9 +13,9 @@ module PacketGen
|
|
13
13
|
# Secure Tunneling, {https://tools.ietf.org/html/rfc4851 RFC 4851}
|
14
14
|
#
|
15
15
|
# {EAP::FAST} has following fields:
|
16
|
-
# * {#flags} (
|
17
|
-
# * optionally {#message_length} (
|
18
|
-
# * {#body} (
|
16
|
+
# * {#flags} (+BinStruct::Int8+),
|
17
|
+
# * optionally {#message_length} (+BinStruct::Int32+), if +#l?+ is +true+,
|
18
|
+
# * {#body} (+BinStruct::String+).
|
19
19
|
# @author Sylvain Daubert
|
20
20
|
# @since 2.1.4
|
21
21
|
class FAST < TTLS
|
@@ -18,15 +18,23 @@ module PacketGen
|
|
18
18
|
remove_attr :body
|
19
19
|
|
20
20
|
# @!attribute value_size
|
21
|
-
#
|
21
|
+
# 8-bit size of the {#value} attribute.
|
22
|
+
# @return [Integer]
|
22
23
|
define_attr :value_size, BinStruct::Int8
|
23
24
|
# @!attribute value
|
25
|
+
# MD5 challenge value, as an octet stream, as per {https://datatracker.ietf.org/doc/html/rfc1994#section-4 RFC1994}
|
24
26
|
# @return [::String]
|
25
27
|
define_attr :value, BinStruct::String,
|
26
28
|
builder: ->(h, t) { t.new(length_from: h[:value_size]) }
|
27
|
-
# @!attribute
|
29
|
+
# @!attribute name
|
30
|
+
# Name identifying the system sending the packet. It is or or more octets. Its size is
|
31
|
+
# determined from the {#length} attribute.
|
28
32
|
# @return [::String]
|
29
|
-
|
33
|
+
# @since 4.1.0 Attribute renamed from +optioanl_name+ to +name+
|
34
|
+
define_attr :name, BinStruct::String
|
35
|
+
|
36
|
+
# @deprecated
|
37
|
+
alias optional_name name
|
30
38
|
end
|
31
39
|
end
|
32
40
|
end
|
@@ -13,22 +13,23 @@ module PacketGen
|
|
13
13
|
# {https://tools.ietf.org/html/rfc5216 RFC 5216}
|
14
14
|
#
|
15
15
|
# {EAP::TLS} has following fields:
|
16
|
-
# * {#flags} (
|
17
|
-
# * optionally {#tls_length} (
|
18
|
-
# * {#body} (
|
16
|
+
# * {#flags} (+BinStruct::Int8+),
|
17
|
+
# * optionally {#tls_length} (+BinStruct::Int32+), if +#l?+ is +true+,
|
18
|
+
# * {#body} (+BinStruct::String+).
|
19
19
|
# @author Sylvain Daubert
|
20
20
|
# @since 2.1.4
|
21
21
|
class TLS < EAP
|
22
22
|
update_attr :type, default: 13
|
23
23
|
# @!attribute flags
|
24
|
-
#
|
25
|
-
# @!attribute l
|
26
|
-
# Say if length field is included
|
24
|
+
# 8-bit flags
|
27
25
|
# @return [Integer]
|
28
|
-
# @!attribute
|
26
|
+
# @!attribute l?
|
27
|
+
# Say if {#tls_length 32-bit TLS length attribute} is included.
|
28
|
+
# @return [Integer]
|
29
|
+
# @!attribute m?
|
29
30
|
# Say if there are more fragments
|
30
31
|
# @return [Integer]
|
31
|
-
# @!attribute s
|
32
|
+
# @!attribute s?
|
32
33
|
# If set, this message is a TLS-Start
|
33
34
|
# @return [Integer]
|
34
35
|
define_bit_attr_before :body, :flags, l: 1, m: 1, s: 1, reserved: 5
|
@@ -13,28 +13,31 @@ module PacketGen
|
|
13
13
|
# {https://tools.ietf.org/html/rfc5281 RFC 5281}
|
14
14
|
#
|
15
15
|
# {EAP::TTLS} has following fields:
|
16
|
-
# * {#flags} (
|
17
|
-
# * optionally {#message_length} (
|
18
|
-
# * {#body} (
|
16
|
+
# * {#flags} (+BinStruct::Int8+),
|
17
|
+
# * optionally {#message_length} (+BinStruct::Int32+), if +#l?+ is +true+,
|
18
|
+
# * {#body} (+BinStruct::String+).
|
19
19
|
# @author Sylvain Daubert
|
20
20
|
# @since 2.1.4
|
21
21
|
class TTLS < EAP
|
22
22
|
update_attr :type, default: 21
|
23
23
|
# @!attribute flags
|
24
|
-
#
|
25
|
-
# @!attribute l
|
26
|
-
# Say if length field is included
|
24
|
+
# 8-bit flags
|
27
25
|
# @return [Integer]
|
28
|
-
# @!attribute
|
26
|
+
# @!attribute l?
|
27
|
+
# Say if {#message_length} field is included
|
28
|
+
# @return [Integer]
|
29
|
+
# @!attribute m?
|
29
30
|
# Say if there are more fragments
|
30
31
|
# @return [Integer]
|
31
|
-
# @!attribute s
|
32
|
+
# @!attribute s?
|
32
33
|
# If set, this message is a TLS-Start
|
33
34
|
# @return [Integer]
|
34
35
|
# @!attribute reserved
|
35
|
-
#
|
36
|
+
# 2-bit reserved integer
|
37
|
+
# @return [Integer]
|
36
38
|
# @!attribute version
|
37
|
-
#
|
39
|
+
# 3-bit version
|
40
|
+
# @return [Integer]
|
38
41
|
define_bit_attr_before :body, :flags, l: 1, m: 1, s: 1, reserved: 2, version: 3
|
39
42
|
alias length_present? l?
|
40
43
|
alias more_fragments? m?
|
data/lib/packetgen/header/eap.rb
CHANGED
@@ -12,34 +12,22 @@ module PacketGen
|
|
12
12
|
# {https://tools.ietf.org/html/rfc3748 RFC 3748}
|
13
13
|
#
|
14
14
|
# A EAP header has:
|
15
|
-
# * a {#code} field (
|
16
|
-
# * a {#id} field (
|
17
|
-
# * a {#length} field (
|
15
|
+
# * a {#code} field (+BinStruct::Int8Enum+),
|
16
|
+
# * a {#id} field (+BinStruct::Int8+),
|
17
|
+
# * a {#length} field (+BinStruct::Int16+).
|
18
18
|
# Request (code 1) and Response (code 2) packets also have:
|
19
19
|
# * a {#type} field (+BinStruct::Int8Enum+).
|
20
20
|
# And Expanded Types (type 254) packets also have:
|
21
|
-
# * a {#vendor_id} field (
|
22
|
-
# * a {#vendor_type} field (
|
23
|
-
# Finally, all packets have a {#body} (
|
24
|
-
#
|
25
|
-
# == Create EAP headers
|
26
|
-
# An EAP header may be created this way:
|
27
|
-
# # create a request header with default type (1)
|
28
|
-
# eap = EAP.new(code: 1) # => PacketGen::Header::EAP
|
29
|
-
# # the same
|
30
|
-
# eap = EAP.new(code: 'Request') # => PacketGen::Header::EAP
|
31
|
-
# # create a Response header of type Nak
|
32
|
-
# nak = EAP.new(code: 'Response', type: 'Nak')
|
21
|
+
# * a {#vendor_id} field (+BinStruct::Int24+),
|
22
|
+
# * a {#vendor_type} field (+BinStruct::Int32+).
|
23
|
+
# Finally, all packets have a {#body} (+BinStruct::String+).
|
33
24
|
#
|
34
25
|
# === Specialized headers
|
35
26
|
# Some EAP has a specialized class:
|
36
|
-
# * EAP-MD5,
|
37
|
-
# * EAP-TLS,
|
38
|
-
# * EAP-TTLS,
|
39
|
-
# * EAP-FAST.
|
40
|
-
# Creating such a header is fairly simple:
|
41
|
-
# # Generate a EAP-TLS Response (type is forced to 13)
|
42
|
-
# eap = EAP::TLS.new(code: 2) # => PacketGen::Header::EAP::TLS
|
27
|
+
# * EAP-MD5 ({EAP::MD5}),
|
28
|
+
# * EAP-TLS ({EAP::TLS}),
|
29
|
+
# * EAP-TTLS ({EAP::TTLS}),
|
30
|
+
# * EAP-FAST ({EAP::FAST}).
|
43
31
|
#
|
44
32
|
# == Header accessors
|
45
33
|
# EAP headers may be accessed through +Packet#eap+ accessor.
|
@@ -54,7 +42,29 @@ module PacketGen
|
|
54
42
|
# So result of parsing a EAP header may be a {EAP}, {EAP::MD5}, {EAP::TLS},
|
55
43
|
# {EAP::TTLS} or {EAP::FAST} instance. But this instance is still accessible
|
56
44
|
# through +Packet#eap+.
|
45
|
+
#
|
46
|
+
# @example Create EAP headers
|
47
|
+
# # create a request header with default type (1)
|
48
|
+
# eap = PacketGen::Header::EAP.new(code: 1)
|
49
|
+
# eap.human_code #=> 'Request'
|
50
|
+
# # the same
|
51
|
+
# eap = PacketGen::Header::EAP.new(code: 'Request')
|
52
|
+
# eap.code #=> 1
|
53
|
+
# # create a Response header of type Nak
|
54
|
+
# nak = PacketGen::Header::EAP.new(code: 'Response', type: 'Nak')
|
55
|
+
# nak.code #=> 2
|
56
|
+
# nak.type #=> 3
|
57
|
+
#
|
58
|
+
# @example Create a specialized EAP header
|
59
|
+
# eap = PacketGen::Header::EAP::TLS.new(code: 2)
|
60
|
+
# eap.class #=> PacketGen::Header::EAP::TLS
|
61
|
+
#
|
62
|
+
# @example Parse a specialized class from a binary string
|
63
|
+
# pkt = PacketGen.parse("\x01\x00\x00\x0e\x04\x04\x00\x01\x02\x03name", first_header: 'EAP')
|
64
|
+
# pkt.eap.class # => PacketGen::Header::EAP::MD5
|
65
|
+
#
|
57
66
|
# @author Sylvain Daubert
|
67
|
+
# @author LemonTree55
|
58
68
|
# @since 2.1.4
|
59
69
|
class EAP < Base
|
60
70
|
# EAP known codes
|
@@ -81,41 +91,48 @@ module PacketGen
|
|
81
91
|
}.freeze
|
82
92
|
|
83
93
|
# @!attribute code
|
84
|
-
#
|
94
|
+
# 8-bit EAP code. See {CODES known EAP codes}
|
95
|
+
# @return [Integer]
|
85
96
|
define_attr :code, BinStruct::Int8Enum, enum: CODES
|
86
97
|
|
87
98
|
# @!attribute id
|
88
|
-
#
|
99
|
+
# 8-bit identifier
|
100
|
+
# @return [Integer]
|
89
101
|
define_attr :id, BinStruct::Int8
|
90
102
|
|
91
103
|
# @!attribute length
|
92
|
-
#
|
104
|
+
# 16-bit length of EAP packet
|
105
|
+
# @return [Integer]
|
93
106
|
define_attr :length, BinStruct::Int16, default: 4
|
94
107
|
|
95
108
|
# @!attribute type
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
109
|
+
# 8-bit request or response type.
|
110
|
+
# This field is present only for Request or Response packets.
|
111
|
+
# See {TYPES known EAP types}.
|
112
|
+
# @return [Integer]
|
99
113
|
define_attr :type, BinStruct::Int8Enum,
|
100
114
|
enum: TYPES,
|
101
115
|
optional: lambda(&:type?)
|
102
116
|
|
103
117
|
# @!attribute vendor_id
|
118
|
+
# 24-bit vendor ID.
|
104
119
|
# This field is present only for Request or Response packets,
|
105
120
|
# with type equal to +Expanded Types+ (254).
|
106
|
-
# @return [Integer]
|
121
|
+
# @return [Integer]
|
107
122
|
define_attr :vendor_id, BinStruct::Int24,
|
108
123
|
optional: ->(eap) { eap.type? && (eap.type == 254) }
|
109
124
|
|
110
125
|
# @!attribute vendor_type
|
126
|
+
# 32-bit vendor type.
|
111
127
|
# This field is present only for Request or Response packets,
|
112
128
|
# with type equal to +Expanded Types+ (254).
|
113
|
-
# @return [Integer]
|
129
|
+
# @return [Integer]
|
114
130
|
define_attr :vendor_type, BinStruct::Int32,
|
115
131
|
optional: ->(eap) { eap.type? && (eap.type == 254) }
|
116
132
|
|
117
133
|
# @!attribute body
|
118
|
-
#
|
134
|
+
# EAP packet body
|
135
|
+
# @return [BinStruct::String, Headerable]
|
119
136
|
define_attr :body, BinStruct::String
|
120
137
|
|
121
138
|
# @return [EAP]
|
@@ -129,7 +146,7 @@ module PacketGen
|
|
129
146
|
|
130
147
|
# Populate object from a binary string
|
131
148
|
# @param [String] str
|
132
|
-
# @return [
|
149
|
+
# @return [EAP] may return a subclass object if a more specific class
|
133
150
|
# may be determined
|
134
151
|
def read(str)
|
135
152
|
super
|
@@ -189,11 +206,19 @@ module PacketGen
|
|
189
206
|
code == CODES['Failure']
|
190
207
|
end
|
191
208
|
|
209
|
+
# Is packet a NAK?
|
210
|
+
# @return [Boolean]
|
211
|
+
# @since 4.1.0
|
212
|
+
# @author LemonTree55
|
213
|
+
def nak?
|
214
|
+
(code == 2) && (type == 3)
|
215
|
+
end
|
216
|
+
|
192
217
|
# Return an array of desired authentication types from a Nak packet
|
193
218
|
# @return [Array<Integer>]
|
194
219
|
# @raise [ParseError] not a Nak packet
|
195
220
|
def desired_auth_type
|
196
|
-
raise ParseError, 'not a Nak response'
|
221
|
+
raise ParseError, 'not a Nak response' unless nak?
|
197
222
|
|
198
223
|
body.to_s.unpack('C*')
|
199
224
|
end
|
data/lib/packetgen/header/eth.rb
CHANGED
@@ -10,26 +10,32 @@ module PacketGen
|
|
10
10
|
module Header
|
11
11
|
# An Ethernet header consists of:
|
12
12
|
# * a destination MAC address ({MacAddr}),
|
13
|
-
# * a source MAC address (MacAddr),
|
14
|
-
# * a {#ethertype} (
|
15
|
-
# * and a body (a
|
13
|
+
# * a source MAC address ({MacAddr}),
|
14
|
+
# * a {#ethertype} (+BinStruct::Int16+),
|
15
|
+
# * and a body (a +BinStruct::String+ or another {Headerable} class).
|
16
16
|
#
|
17
|
-
#
|
17
|
+
# @example Create a Ethernet header
|
18
18
|
# # standalone
|
19
19
|
# eth = PacketGen::Header::Eth.new
|
20
20
|
# # in a packet
|
21
21
|
# pkt = PacketGen.gen('Eth')
|
22
22
|
# # access to Ethernet header
|
23
|
-
# pkt.eth # => PacketGen::Header::Eth
|
23
|
+
# pkt.eth.class # => PacketGen::Header::Eth
|
24
24
|
#
|
25
|
-
#
|
25
|
+
# @example Access to Ethernet attributes
|
26
|
+
# eth = PacketGen::Header::Eth.new(src: '00:01:01:01:01:01', ethertype: 0x1234)
|
27
|
+
# # Set destination MAC address
|
26
28
|
# eth.dst = "00:01:02:03:04:05"
|
27
|
-
#
|
28
|
-
# eth
|
29
|
-
#
|
29
|
+
# # Access source MAC address, human-redable
|
30
|
+
# eth.src # => "00:01:01:01:01:01"
|
31
|
+
# # Access to MacAddr object
|
32
|
+
# eth[:src].class # => PacketGen::Header::Eth::MacAddr
|
33
|
+
# eth.ethertype # => 0x1234
|
34
|
+
# # Set Ethernet body
|
30
35
|
# eth.body = "This is a body"
|
31
36
|
#
|
32
37
|
# @author Sylvain Daubert
|
38
|
+
# @author LemonTree55
|
33
39
|
class Eth < Base
|
34
40
|
# Ethernet MAC address, as a group of 6 bytes
|
35
41
|
# @author Sylvain Daubert
|
@@ -58,6 +64,10 @@ module PacketGen
|
|
58
64
|
# Read a human-readable string to populate +MacAddr+
|
59
65
|
# @param [String] str
|
60
66
|
# @return [self]
|
67
|
+
# @example
|
68
|
+
# mac = PacketGen::Header::Eth::MacAddr.new
|
69
|
+
# mac.from_human('01:02:03:04:05:06')
|
70
|
+
# mac.a5 # => 6
|
61
71
|
def from_human(str)
|
62
72
|
return self if str.nil?
|
63
73
|
|
@@ -76,6 +86,8 @@ module PacketGen
|
|
76
86
|
attributes.map { |m| '%02x' % self[m] }.join(':')
|
77
87
|
end
|
78
88
|
|
89
|
+
# Equality check. +true+ only if +other+ is a MacAddr, and each address byte is the same.
|
90
|
+
# @return [Boolean]
|
79
91
|
def ==(other)
|
80
92
|
other.is_a?(self.class) &&
|
81
93
|
attributes.all? { |attr| self[attr].value == other[attr].value }
|
@@ -83,16 +95,18 @@ module PacketGen
|
|
83
95
|
end
|
84
96
|
|
85
97
|
# @!attribute dst
|
86
|
-
#
|
98
|
+
# Destination MAC address
|
99
|
+
# @return [::String]
|
87
100
|
define_attr :dst, MacAddr, default: '00:00:00:00:00:00'
|
88
101
|
# @!attribute src
|
89
|
-
#
|
102
|
+
# Source MAC address
|
103
|
+
# @return [::String]
|
90
104
|
define_attr :src, MacAddr, default: '00:00:00:00:00:00'
|
91
105
|
# @!attribute ethertype
|
92
106
|
# @return [Integer] 16-bit integer to determine payload type
|
93
107
|
define_attr :ethertype, BinStruct::Int16, default: 0
|
94
108
|
# @!attribute body
|
95
|
-
# @return [BinStruct::String,
|
109
|
+
# @return [BinStruct::String,Headerable]
|
96
110
|
define_attr :body, BinStruct::String
|
97
111
|
|
98
112
|
# send Eth packet on wire.
|
data/lib/packetgen/header/gre.rb
CHANGED
@@ -20,21 +20,40 @@ module PacketGen
|
|
20
20
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
21
21
|
# | Sequence Number (Optional) |
|
22
22
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
23
|
+
#
|
24
|
+
# A GRE header is composed of:
|
25
|
+
# * A first 16-bit attribute containing given flags:
|
26
|
+
# * {#c} indicates if {#checksum} and {#reserved1} attributes are present.
|
27
|
+
# * {#k} indicates if {#key} attribute is present.
|
28
|
+
# * {#s} indicatesid {#sequence_number} attribute is present.
|
29
|
+
# * {#ver} 3-bit version number.
|
30
|
+
# * {#protocol_type} (+BinStruct::Int16+).
|
31
|
+
# * optional {#checksum} and {#reserved1} attribute (both +BinStruct::Int16+).
|
32
|
+
# * optional {#key} attribute (+BinStruct::Int32+).
|
33
|
+
# * optional {#sequence_number} attribute (+BinStruct::Int32+).
|
34
|
+
# * and a {#body} (+BinStruct::String or {Headerable}).
|
35
|
+
#
|
36
|
+
# Current implementation supports tunneling {IP} and {IPv6} packets in GRE.
|
23
37
|
# @author Sylvain Daubert
|
38
|
+
# @author LemonTree55
|
24
39
|
# @since 2.1.0
|
25
40
|
class GRE < Base
|
26
41
|
# IP protocol number for GRE
|
27
42
|
IP_PROTOCOL = 47
|
28
43
|
|
29
44
|
# @!attribute c
|
45
|
+
# Say if {#checksum} and {#reserved1} attributes are present
|
30
46
|
# @return [Boolean]
|
31
47
|
# @!attribute k
|
48
|
+
# Say if {#key} attribute is present
|
32
49
|
# @return [Boolean]
|
33
50
|
# @!attribute s
|
51
|
+
# Say if {#sequence_number} attribute is present
|
34
52
|
# @return [Boolean]
|
35
53
|
# @!attribute reserved0
|
36
54
|
# @return [Integer]
|
37
55
|
# @!attribute ver
|
56
|
+
# 3-bit GRE protocol version.
|
38
57
|
# @return [Integer]
|
39
58
|
define_bit_attr :u16, c: 1, r: 1, k: 1, s: 1, reserved0: 9, ver: 3
|
40
59
|
|
@@ -42,19 +61,24 @@ module PacketGen
|
|
42
61
|
# @return [Integer]
|
43
62
|
define_attr :protocol_type, BinStruct::Int16
|
44
63
|
# @!attribute checksum
|
64
|
+
# IP checksum over all 16-bit words in GRE header and its body. Present only if {#c} is set.
|
45
65
|
# @return [Integer]
|
46
66
|
define_attr :checksum, BinStruct::Int16, default: 0, optional: lambda(&:c?)
|
47
67
|
# @!attribute reserved1
|
68
|
+
# Reserved field, present only if {#c} is set.
|
48
69
|
# @return [Integer]
|
49
70
|
define_attr :reserved1, BinStruct::Int16, default: 0, optional: lambda(&:c?)
|
50
71
|
# @!attribute key
|
72
|
+
# 32-bit integer used to identify an individual traffic flow within a tunnel.
|
73
|
+
# Present only if {#k} is set.
|
51
74
|
# @return [Integer]
|
52
75
|
define_attr :key, BinStruct::Int32, optional: lambda(&:k?)
|
53
76
|
# @!attribute sequence_number
|
77
|
+
# 32-bit integer. Present only if {#s} is set.
|
54
78
|
# @return [Integer]
|
55
79
|
define_attr :sequence_number, BinStruct::Int32, optional: lambda(&:s?)
|
56
80
|
# @!attribute body
|
57
|
-
#
|
81
|
+
# @return [BinStruct::String,Headerable]
|
58
82
|
define_attr :body, BinStruct::String
|
59
83
|
|
60
84
|
alias seqnum sequence_number
|
@@ -65,7 +89,7 @@ module PacketGen
|
|
65
89
|
super(opts)
|
66
90
|
end
|
67
91
|
|
68
|
-
# Compute checksum and set +checksum+
|
92
|
+
# Compute checksum and set +checksum+ attribute.
|
69
93
|
# @return [Integer]
|
70
94
|
def calc_checksum
|
71
95
|
sum = IP.sum16(self)
|