packetgen 3.3.3 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +38 -22
- data/lib/packetgen/capture.rb +2 -2
- data/lib/packetgen/config.rb +0 -1
- data/lib/packetgen/deprecation.rb +14 -8
- data/lib/packetgen/header/arp.rb +17 -18
- data/lib/packetgen/header/asn1_base.rb +2 -1
- data/lib/packetgen/header/base.rb +42 -40
- data/lib/packetgen/header/bootp.rb +35 -37
- data/lib/packetgen/header/dhcp/option.rb +21 -21
- data/lib/packetgen/header/dhcp/options.rb +3 -3
- data/lib/packetgen/header/dhcp.rb +8 -9
- data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
- data/lib/packetgen/header/dhcpv6/option.rb +83 -61
- data/lib/packetgen/header/dhcpv6/options.rb +4 -4
- data/lib/packetgen/header/dhcpv6/relay.rb +6 -5
- data/lib/packetgen/header/dhcpv6.rb +17 -18
- data/lib/packetgen/header/dns/name.rb +21 -16
- data/lib/packetgen/header/dns/opt.rb +5 -2
- data/lib/packetgen/header/dns/option.rb +14 -14
- data/lib/packetgen/header/dns/qdsection.rb +3 -3
- data/lib/packetgen/header/dns/question.rb +7 -8
- data/lib/packetgen/header/dns/rr.rb +56 -43
- data/lib/packetgen/header/dns/rrsection.rb +6 -6
- data/lib/packetgen/header/dns.rb +103 -90
- data/lib/packetgen/header/dot11/control.rb +12 -12
- data/lib/packetgen/header/dot11/data.rb +25 -24
- data/lib/packetgen/header/dot11/element.rb +4 -4
- data/lib/packetgen/header/dot11/management.rb +21 -18
- data/lib/packetgen/header/dot11/sub_mngt.rb +40 -53
- data/lib/packetgen/header/dot11.rb +117 -122
- data/lib/packetgen/header/dot1q.rb +12 -13
- data/lib/packetgen/header/dot1x.rb +13 -13
- data/lib/packetgen/header/eap/fast.rb +4 -4
- data/lib/packetgen/header/eap/md5.rb +16 -8
- data/lib/packetgen/header/eap/tls.rb +18 -19
- data/lib/packetgen/header/eap/ttls.rb +22 -21
- data/lib/packetgen/header/eap.rb +73 -48
- data/lib/packetgen/header/eth.rb +41 -27
- data/lib/packetgen/header/gre.rb +33 -11
- data/lib/packetgen/header/http/headers.rb +7 -6
- data/lib/packetgen/header/http/request.rb +38 -29
- data/lib/packetgen/header/http/response.rb +35 -27
- data/lib/packetgen/header/http/verbs.rb +1 -3
- data/lib/packetgen/header/icmp.rb +14 -14
- data/lib/packetgen/header/icmpv6.rb +10 -9
- data/lib/packetgen/header/igmp.rb +26 -15
- data/lib/packetgen/header/igmpv3/group_record.rb +18 -13
- data/lib/packetgen/header/igmpv3/mq.rb +16 -18
- data/lib/packetgen/header/igmpv3/mr.rb +5 -5
- data/lib/packetgen/header/igmpv3.rb +12 -11
- data/lib/packetgen/header/ip/addr.rb +19 -15
- data/lib/packetgen/header/ip/option.rb +47 -36
- data/lib/packetgen/header/ip/options.rb +1 -1
- data/lib/packetgen/header/ip.rb +77 -95
- data/lib/packetgen/header/ipv6/addr.rb +28 -27
- data/lib/packetgen/header/ipv6/extension.rb +13 -11
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +32 -13
- data/lib/packetgen/header/ipv6.rb +42 -35
- data/lib/packetgen/header/llc.rb +28 -21
- data/lib/packetgen/header/mdns.rb +10 -3
- data/lib/packetgen/header/mld.rb +15 -13
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +17 -12
- data/lib/packetgen/header/mldv2/mlq.rb +22 -24
- data/lib/packetgen/header/mldv2/mlr.rb +8 -8
- data/lib/packetgen/header/mldv2.rb +1 -1
- data/lib/packetgen/header/ospfv2/db_description.rb +17 -18
- data/lib/packetgen/header/ospfv2/hello.rb +18 -17
- data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
- data/lib/packetgen/header/ospfv2/ls_request.rb +14 -13
- data/lib/packetgen/header/ospfv2/ls_update.rb +9 -9
- data/lib/packetgen/header/ospfv2/lsa.rb +79 -60
- data/lib/packetgen/header/ospfv2/lsa_header.rb +12 -11
- data/lib/packetgen/header/ospfv2.rb +49 -46
- data/lib/packetgen/header/ospfv3/db_description.rb +20 -22
- data/lib/packetgen/header/ospfv3/hello.rb +17 -16
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +22 -20
- data/lib/packetgen/header/ospfv3/ls_ack.rb +7 -8
- data/lib/packetgen/header/ospfv3/ls_request.rb +18 -18
- data/lib/packetgen/header/ospfv3/ls_update.rb +10 -10
- data/lib/packetgen/header/ospfv3/lsa.rb +62 -51
- data/lib/packetgen/header/ospfv3/lsa_header.rb +12 -11
- data/lib/packetgen/header/ospfv3.rb +54 -52
- data/lib/packetgen/header/sctp/chunk.rb +80 -56
- data/lib/packetgen/header/sctp/error.rb +174 -202
- data/lib/packetgen/header/sctp/padded32.rb +3 -3
- data/lib/packetgen/header/sctp/parameter.rb +89 -136
- data/lib/packetgen/header/sctp.rb +19 -8
- data/lib/packetgen/header/snmp.rb +108 -7
- data/lib/packetgen/header/tcp/option.rb +52 -39
- data/lib/packetgen/header/tcp/options.rb +13 -5
- data/lib/packetgen/header/tcp.rb +83 -65
- data/lib/packetgen/header/tftp.rb +31 -25
- data/lib/packetgen/header/udp.rb +21 -19
- data/lib/packetgen/header.rb +23 -18
- data/lib/packetgen/headerable.rb +21 -5
- data/lib/packetgen/inspect.rb +3 -8
- data/lib/packetgen/packet.rb +146 -71
- data/lib/packetgen/pcap.rb +15 -4
- data/lib/packetgen/pcapng/block.rb +20 -18
- data/lib/packetgen/pcapng/epb.rb +13 -15
- data/lib/packetgen/pcapng/file.rb +44 -111
- data/lib/packetgen/pcapng/idb.rb +11 -12
- data/lib/packetgen/pcapng/shb.rb +15 -16
- data/lib/packetgen/pcapng/spb.rb +9 -11
- data/lib/packetgen/pcapng/unknown_block.rb +6 -17
- data/lib/packetgen/pcapng.rb +6 -4
- data/lib/packetgen/pcaprub_wrapper.rb +17 -1
- data/lib/packetgen/proto.rb +5 -1
- data/lib/packetgen/unknown_packet.rb +5 -5
- data/lib/packetgen/utils/arp_spoofer.rb +18 -19
- data/lib/packetgen/utils.rb +4 -3
- data/lib/packetgen/version.rb +1 -1
- data/lib/packetgen.rb +12 -5
- metadata +29 -38
- data/lib/packetgen/types/abstract_tlv.rb +0 -278
- data/lib/packetgen/types/array.rb +0 -287
- data/lib/packetgen/types/cstring.rb +0 -109
- data/lib/packetgen/types/enum.rb +0 -171
- data/lib/packetgen/types/fieldable.rb +0 -66
- data/lib/packetgen/types/fields.rb +0 -622
- data/lib/packetgen/types/int.rb +0 -473
- data/lib/packetgen/types/int_string.rb +0 -102
- data/lib/packetgen/types/length_from.rb +0 -54
- data/lib/packetgen/types/oui.rb +0 -52
- data/lib/packetgen/types/string.rb +0 -97
- data/lib/packetgen/types/tlv.rb +0 -161
- data/lib/packetgen/types.rb +0 -26
@@ -13,31 +13,32 @@ 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
|
-
|
26
|
-
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# @return [Boolean]
|
24
|
+
# 8-bit flags
|
25
|
+
# @return [Integer]
|
26
|
+
# @!attribute l?
|
27
|
+
# Say if {#message_length} field is included
|
28
|
+
# @return [Integer]
|
29
|
+
# @!attribute m?
|
30
|
+
# Say if there are more fragments
|
31
|
+
# @return [Integer]
|
32
|
+
# @!attribute s?
|
33
|
+
# If set, this message is a TLS-Start
|
34
|
+
# @return [Integer]
|
36
35
|
# @!attribute reserved
|
37
|
-
#
|
36
|
+
# 2-bit reserved integer
|
37
|
+
# @return [Integer]
|
38
38
|
# @!attribute version
|
39
|
-
#
|
40
|
-
|
39
|
+
# 3-bit version
|
40
|
+
# @return [Integer]
|
41
|
+
define_bit_attr_before :body, :flags, l: 1, m: 1, s: 1, reserved: 2, version: 3
|
41
42
|
alias length_present? l?
|
42
43
|
alias more_fragments? m?
|
43
44
|
alias tls_start? s?
|
@@ -47,8 +48,8 @@ module PacketGen
|
|
47
48
|
# raw data message sequence prior to fragmentation. So, it
|
48
49
|
# cannot be automatically calculated (no +#calc_length+ method).
|
49
50
|
# @return [Integer] 32-bit message length
|
50
|
-
|
51
|
-
|
51
|
+
define_attr_before :body, :message_length, BinStruct::Int32,
|
52
|
+
optional: lambda(&:l?)
|
52
53
|
|
53
54
|
# @return [String]
|
54
55
|
def inspect
|
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
|
-
# * a {#type} field (+
|
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,42 +91,49 @@ module PacketGen
|
|
81
91
|
}.freeze
|
82
92
|
|
83
93
|
# @!attribute code
|
84
|
-
#
|
85
|
-
|
94
|
+
# 8-bit EAP code. See {CODES known EAP codes}
|
95
|
+
# @return [Integer]
|
96
|
+
define_attr :code, BinStruct::Int8Enum, enum: CODES
|
86
97
|
|
87
98
|
# @!attribute id
|
88
|
-
#
|
89
|
-
|
99
|
+
# 8-bit identifier
|
100
|
+
# @return [Integer]
|
101
|
+
define_attr :id, BinStruct::Int8
|
90
102
|
|
91
103
|
# @!attribute length
|
92
|
-
#
|
93
|
-
|
104
|
+
# 16-bit length of EAP packet
|
105
|
+
# @return [Integer]
|
106
|
+
define_attr :length, BinStruct::Int16, default: 4
|
94
107
|
|
95
108
|
# @!attribute type
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
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]
|
113
|
+
define_attr :type, BinStruct::Int8Enum,
|
114
|
+
enum: TYPES,
|
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]
|
107
|
-
|
108
|
-
|
121
|
+
# @return [Integer]
|
122
|
+
define_attr :vendor_id, BinStruct::Int24,
|
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]
|
114
|
-
|
115
|
-
|
129
|
+
# @return [Integer]
|
130
|
+
define_attr :vendor_type, BinStruct::Int32,
|
131
|
+
optional: ->(eap) { eap.type? && (eap.type == 254) }
|
116
132
|
|
117
133
|
# @!attribute body
|
118
|
-
#
|
119
|
-
|
134
|
+
# EAP packet body
|
135
|
+
# @return [BinStruct::String, Headerable]
|
136
|
+
define_attr :body, BinStruct::String
|
120
137
|
|
121
138
|
# @return [EAP]
|
122
139
|
def initialize(options={})
|
@@ -129,10 +146,10 @@ 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
|
-
super
|
152
|
+
super
|
136
153
|
return self unless self.instance_of?(EAP)
|
137
154
|
return self unless type?
|
138
155
|
|
@@ -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
|
@@ -201,7 +226,7 @@ module PacketGen
|
|
201
226
|
# Calculate length field from content
|
202
227
|
# @return [Integer]
|
203
228
|
def calc_length
|
204
|
-
Base.calculate_and_set_length
|
229
|
+
Base.calculate_and_set_length(self)
|
205
230
|
end
|
206
231
|
|
207
232
|
# Say is this EAP header has {#type} field
|
@@ -217,7 +242,7 @@ module PacketGen
|
|
217
242
|
# @param [Packet] packet
|
218
243
|
# @return [void]
|
219
244
|
def added_to_packet(packet)
|
220
|
-
return if packet.respond_to?
|
245
|
+
return if packet.respond_to?(:eap)
|
221
246
|
|
222
247
|
packet.instance_eval("def eap(arg=nil); header(#{self.class}, arg); end") # def eap(arg=nil); header(EAP, arg); end
|
223
248
|
end
|
data/lib/packetgen/header/eth.rb
CHANGED
@@ -10,54 +10,64 @@ 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
|
36
|
-
class MacAddr <
|
37
|
-
include
|
42
|
+
class MacAddr < BinStruct::Struct
|
43
|
+
include BinStruct::Structable
|
38
44
|
|
39
45
|
# @!attribute a0
|
40
46
|
# @return [Integer] first byte from MacAddr
|
41
|
-
|
47
|
+
define_attr :a0, BinStruct::Int8
|
42
48
|
# @!attribute a1
|
43
49
|
# @return [Integer] second byte from MacAddr
|
44
|
-
|
50
|
+
define_attr :a1, BinStruct::Int8
|
45
51
|
# @!attribute a2
|
46
52
|
# @return [Integer] third byte from MacAddr
|
47
|
-
|
53
|
+
define_attr :a2, BinStruct::Int8
|
48
54
|
# @!attribute a3
|
49
55
|
# @return [Integer] fourth byte from MacAddr
|
50
|
-
|
56
|
+
define_attr :a3, BinStruct::Int8
|
51
57
|
# @!attribute a4
|
52
58
|
# @return [Integer] fifth byte from MacAddr
|
53
|
-
|
59
|
+
define_attr :a4, BinStruct::Int8
|
54
60
|
# @!attribute a5
|
55
61
|
# @return [Integer] sixth byte from MacAddr
|
56
|
-
|
62
|
+
define_attr :a5, BinStruct::Int8
|
57
63
|
|
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
|
|
@@ -65,7 +75,7 @@ module PacketGen
|
|
65
75
|
raise ArgumentError, 'not a MAC address' unless bytes.size == 6
|
66
76
|
|
67
77
|
6.times do |i|
|
68
|
-
self[:"a#{i}"].
|
78
|
+
self[:"a#{i}"].from_human(bytes[i].to_i(16))
|
69
79
|
end
|
70
80
|
self
|
71
81
|
end
|
@@ -73,27 +83,31 @@ module PacketGen
|
|
73
83
|
# +MacAddr+ in human readable form (colon format)
|
74
84
|
# @return [String]
|
75
85
|
def to_human
|
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 }
|
82
94
|
end
|
83
95
|
end
|
84
96
|
|
85
97
|
# @!attribute dst
|
86
|
-
#
|
87
|
-
|
98
|
+
# Destination MAC address
|
99
|
+
# @return [::String]
|
100
|
+
define_attr :dst, MacAddr, default: '00:00:00:00:00:00'
|
88
101
|
# @!attribute src
|
89
|
-
#
|
90
|
-
|
102
|
+
# Source MAC address
|
103
|
+
# @return [::String]
|
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 [
|
96
|
-
|
109
|
+
# @return [BinStruct::String,Headerable]
|
110
|
+
define_attr :body, BinStruct::String
|
97
111
|
|
98
112
|
# send Eth packet on wire.
|
99
113
|
# @param [String] iface interface name
|
data/lib/packetgen/header/gre.rb
CHANGED
@@ -20,44 +20,66 @@ 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
|
-
define_field :u16, Types::Int16
|
30
|
-
|
31
44
|
# @!attribute c
|
45
|
+
# Say if {#checksum} and {#reserved1} attributes are present
|
32
46
|
# @return [Boolean]
|
33
47
|
# @!attribute k
|
48
|
+
# Say if {#key} attribute is present
|
34
49
|
# @return [Boolean]
|
35
50
|
# @!attribute s
|
51
|
+
# Say if {#sequence_number} attribute is present
|
36
52
|
# @return [Boolean]
|
37
53
|
# @!attribute reserved0
|
38
54
|
# @return [Integer]
|
39
55
|
# @!attribute ver
|
56
|
+
# 3-bit GRE protocol version.
|
40
57
|
# @return [Integer]
|
41
|
-
|
58
|
+
define_bit_attr :u16, c: 1, r: 1, k: 1, s: 1, reserved0: 9, ver: 3
|
42
59
|
|
43
60
|
# @!attribute protocol_type
|
44
61
|
# @return [Integer]
|
45
|
-
|
62
|
+
define_attr :protocol_type, BinStruct::Int16
|
46
63
|
# @!attribute checksum
|
64
|
+
# IP checksum over all 16-bit words in GRE header and its body. Present only if {#c} is set.
|
47
65
|
# @return [Integer]
|
48
|
-
|
66
|
+
define_attr :checksum, BinStruct::Int16, default: 0, optional: lambda(&:c?)
|
49
67
|
# @!attribute reserved1
|
68
|
+
# Reserved field, present only if {#c} is set.
|
50
69
|
# @return [Integer]
|
51
|
-
|
70
|
+
define_attr :reserved1, BinStruct::Int16, default: 0, optional: lambda(&:c?)
|
52
71
|
# @!attribute key
|
72
|
+
# 32-bit integer used to identify an individual traffic flow within a tunnel.
|
73
|
+
# Present only if {#k} is set.
|
53
74
|
# @return [Integer]
|
54
|
-
|
75
|
+
define_attr :key, BinStruct::Int32, optional: lambda(&:k?)
|
55
76
|
# @!attribute sequence_number
|
77
|
+
# 32-bit integer. Present only if {#s} is set.
|
56
78
|
# @return [Integer]
|
57
|
-
|
79
|
+
define_attr :sequence_number, BinStruct::Int32, optional: lambda(&:s?)
|
58
80
|
# @!attribute body
|
59
|
-
#
|
60
|
-
|
81
|
+
# @return [BinStruct::String,Headerable]
|
82
|
+
define_attr :body, BinStruct::String
|
61
83
|
|
62
84
|
alias seqnum sequence_number
|
63
85
|
alias seqnum= sequence_number=
|
@@ -67,7 +89,7 @@ module PacketGen
|
|
67
89
|
super(opts)
|
68
90
|
end
|
69
91
|
|
70
|
-
# Compute checksum and set +checksum+
|
92
|
+
# Compute checksum and set +checksum+ attribute.
|
71
93
|
# @return [Integer]
|
72
94
|
def calc_checksum
|
73
95
|
sum = IP.sum16(self)
|
@@ -9,14 +9,15 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
# @since 2.2.0
|
12
|
+
# @author Kent 'picat' Gruber
|
12
13
|
module HTTP
|
13
14
|
# @abstract Base class for HTTP headers.
|
14
15
|
# @author Kent 'picat' Gruber
|
15
16
|
class Headers
|
16
|
-
include
|
17
|
+
include BinStruct::Structable
|
17
18
|
|
18
|
-
# Underlying Headers data
|
19
|
-
# @return [Hash, nil]
|
19
|
+
# Underlying Headers data.
|
20
|
+
# @return [Hash{String => String}, nil]
|
20
21
|
attr_reader :data
|
21
22
|
alias to_h data
|
22
23
|
|
@@ -25,7 +26,7 @@ module PacketGen
|
|
25
26
|
end
|
26
27
|
|
27
28
|
# Populate object from a string or directly from a hash.
|
28
|
-
# @param [String, Hash] s_or_h
|
29
|
+
# @param [String, Hash{String=>String}] s_or_h
|
29
30
|
# @return [self]
|
30
31
|
def read(s_or_h)
|
31
32
|
case s_or_h
|
@@ -69,14 +70,14 @@ module PacketGen
|
|
69
70
|
d.join("\r\n") << "\r\n\r\n"
|
70
71
|
end
|
71
72
|
|
72
|
-
# Get a human readable
|
73
|
+
# Get a human readable hash.
|
73
74
|
# @return [Hash]
|
74
75
|
def to_human
|
75
76
|
@data
|
76
77
|
end
|
77
78
|
|
78
79
|
# Read human-readable data to populate header data.
|
79
|
-
# @param [String
|
80
|
+
# @param [Hash{String=>String}] data
|
80
81
|
# @return [self]
|
81
82
|
def from_human(data)
|
82
83
|
read(data)
|
@@ -10,50 +10,57 @@ module PacketGen
|
|
10
10
|
module Header
|
11
11
|
module HTTP
|
12
12
|
# An HTTP/1.1 Request packet consists of:
|
13
|
-
# * the http verb (
|
14
|
-
# * the path (
|
15
|
-
# * the version (
|
13
|
+
# * the http verb (+BinStruct::String+).
|
14
|
+
# * the path (+BinStruct::String+).
|
15
|
+
# * the version (+BinStruct::String+).
|
16
16
|
# * associated http headers ({HTTP::Headers}).
|
17
|
+
# * and a {#body} (+BinStruct::String+).
|
17
18
|
#
|
18
|
-
#
|
19
|
+
# Note: When creating a HTTP Request packet, {TCP#sport} and {TCP#dport}
|
20
|
+
# attributes are not set.
|
21
|
+
#
|
22
|
+
# @example Create a HTTP Request header
|
19
23
|
# # standalone
|
20
|
-
#
|
24
|
+
# http_request = PacketGen::Header::HTTP::Request.new
|
21
25
|
# # in a packet
|
22
26
|
# pkt = PacketGen.gen("IP").add("TCP").add("HTTP::Request")
|
23
27
|
# # access to HTTP Request header
|
24
|
-
# pkt.http_request # => PacketGen::Header::HTTP::Request
|
25
|
-
#
|
26
|
-
# Note: When creating a HTTP Request packet, +sport+ and +dport+
|
27
|
-
# attributes of TCP header are not set.
|
28
|
+
# pkt.http_request.class # => PacketGen::Header::HTTP::Request
|
28
29
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
30
|
+
# @example HTTP Request attributes
|
31
|
+
# http_request = PacketGen::Header::HTTP::Request.new
|
32
|
+
# http_request.version #=> "HTTP/1.1"
|
33
|
+
# http_request.verb = "GET"
|
34
|
+
# http_request.path = "/meow.html"
|
35
|
+
# http_request.headers = "Host: tcpdump.org" # string or
|
36
|
+
# http_request.headers = { "Host": "tcpdump.org" } # even a hash
|
35
37
|
#
|
36
38
|
# @author Kent 'picat' Gruber
|
37
39
|
# @author Sylvain Daubert
|
40
|
+
# @author LemonTree55
|
38
41
|
# @since 3.1.0 Rename +#method+ into {#verb} to not mask +Object#method+.
|
39
42
|
class Request < Base
|
40
43
|
# @!attribute verb
|
41
|
-
#
|
44
|
+
# HTTP verb (method)
|
45
|
+
# @return [BinStruct::String]
|
42
46
|
# @since 3.1.0
|
43
|
-
|
47
|
+
define_attr :verb, BinStruct::String
|
44
48
|
# @!attribute path
|
45
|
-
#
|
46
|
-
|
49
|
+
# Requested path
|
50
|
+
# @return [BinStruct::String]
|
51
|
+
define_attr :path, BinStruct::String
|
47
52
|
# @!attribute version
|
48
|
-
#
|
49
|
-
|
53
|
+
# HTTP version
|
54
|
+
# @return [BinStruct::String]
|
55
|
+
define_attr :version, BinStruct::String, default: 'HTTP/1.1'
|
50
56
|
# @!attribute headers
|
51
57
|
# associated http/1.1 headers
|
52
58
|
# @return [HTTP::Headers]
|
53
|
-
|
59
|
+
define_attr :headers, HTTP::Headers
|
54
60
|
# @!attribute body
|
55
|
-
#
|
56
|
-
|
61
|
+
# HTTP request body, if any
|
62
|
+
# @return [BinStruct::String]
|
63
|
+
define_attr :body, BinStruct::String
|
57
64
|
|
58
65
|
# @param [Hash] options
|
59
66
|
# @option options [String] :verb
|
@@ -61,18 +68,18 @@ module PacketGen
|
|
61
68
|
# @option options [String] :version
|
62
69
|
# @option options [Hash] :headers
|
63
70
|
def initialize(options={})
|
64
|
-
super
|
71
|
+
super
|
65
72
|
self.headers ||= options[:headers]
|
66
73
|
end
|
67
74
|
|
68
75
|
# Read in the HTTP portion of the packet, and parse it.
|
69
|
-
# @return [
|
76
|
+
# @return [self]
|
70
77
|
def read(str)
|
71
78
|
lines = lines(str)
|
72
79
|
first_line_words = lines.shift.split
|
73
|
-
self[:verb].read
|
74
|
-
self[:path].read
|
75
|
-
self[:version].read
|
80
|
+
self[:verb].read(first_line_words[0])
|
81
|
+
self[:path].read(first_line_words[1])
|
82
|
+
self[:version].read(first_line_words[2])
|
76
83
|
|
77
84
|
# requests can sometimes have a payload
|
78
85
|
headers, data = headers_and_payload_from_lines(lines)
|
@@ -82,6 +89,8 @@ module PacketGen
|
|
82
89
|
self
|
83
90
|
end
|
84
91
|
|
92
|
+
# May be parsed as a HTTP request if verb is known, and if version is +HTTP/1.x+.
|
93
|
+
# @return [Boolean]
|
85
94
|
def parse?
|
86
95
|
VERBS.include?(self.verb) && self.version.start_with?('HTTP/1.')
|
87
96
|
end
|