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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed11e05d37fb82187dbf1dc0a7dffd1e6c1931ebda0dea904da77f2731a523f8
|
4
|
+
data.tar.gz: e36705786a664ac257d1939a9c67d267a15c52f51e76b02069c923095c0d8852
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 151754f39d113f9dbeb65cda8f62f4e378440aa567c3e528b2d8e93920e70069a55bd26e737c03818a808463a9b3406805dcb8ed92e8b5582fbbfaae7f5d8fd4
|
7
|
+
data.tar.gz: 4f61a79f28f1fe8e5f4cac45b9b8fdc06eeca4ae4a07a567334535b3e8ac7ea5cb85cb6644215656e6c0e7e2d1ba0a58bae1fe66131805af7093742dc5098bdd
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
[](https://badge.fury.io/rb/packetgen)
|
3
|
-
[](https://github.com/lemontree55/packetgen/actions/workflows/ci.yml)
|
4
4
|
|
5
5
|
# PacketGen
|
6
6
|
|
@@ -29,7 +29,13 @@ module PacketGen
|
|
29
29
|
def self.deprecated(klass, deprecated_method, new_method=nil, klass_method: false, remove_version: REMOVE_VERSION)
|
30
30
|
base_name = "#{klass}#{klass_method ? '.' : '#'}"
|
31
31
|
complete_deprecated_method_name = "#{base_name}#{deprecated_method}"
|
32
|
-
|
32
|
+
unless new_method.nil?
|
33
|
+
complete_new_method_name = if %w[# .].any? { |punct| new_method.include?(punct) }
|
34
|
+
new_method
|
35
|
+
else
|
36
|
+
"#{base_name}#{new_method}"
|
37
|
+
end
|
38
|
+
end
|
33
39
|
|
34
40
|
file, line = caller(2..2).first.split(':')[0, 2]
|
35
41
|
message = "#{file}:#{line}: #{complete_deprecated_method_name} is deprecated"
|
data/lib/packetgen/header/arp.rb
CHANGED
@@ -9,9 +9,9 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
# An ARP header consists of:
|
12
|
-
# * a hardware type ({#hrd} or {#htype}) field (
|
12
|
+
# * a hardware type ({#hrd} or {#htype}) field (+BinStruct::Int16+),
|
13
13
|
# * a protocol type ({#pro} or {#ptype}) field (+Int16+),
|
14
|
-
# * a hardware address length ({#hln} or {#hlen}) field (
|
14
|
+
# * a hardware address length ({#hln} or {#hlen}) field (+BinStruct::Int8+),
|
15
15
|
# * a protocol address length ({#pln} or {#plen}) field (+Int8+),
|
16
16
|
# * a {#opcode} (or {#op}) field (+Int16+),
|
17
17
|
# * a source hardware address ({#sha} or {#src_mac}) field ({Eth::MacAddr}),
|
@@ -20,13 +20,13 @@ module PacketGen
|
|
20
20
|
# * a target protocol address ({#tpa} or {#dst_ip}) field (+IP::Addr+),
|
21
21
|
# * and a {#body}.
|
22
22
|
#
|
23
|
-
#
|
23
|
+
# @example Create a ARP header
|
24
24
|
# # standalone
|
25
25
|
# arp = PacketGen::Header::ARP.new
|
26
26
|
# # in a packet
|
27
27
|
# pkt = PacketGen.gen('Eth').add('ARP')
|
28
28
|
# # access to ARP header
|
29
|
-
# pkt.arp # =>
|
29
|
+
# pkt.arp.protocol_name # => "ARP"
|
30
30
|
#
|
31
31
|
# @author Sylvain Daubert
|
32
32
|
class ARP < Base
|
@@ -122,8 +122,7 @@ module PacketGen
|
|
122
122
|
|
123
123
|
private
|
124
124
|
|
125
|
-
|
126
|
-
def handle_options(options)
|
125
|
+
def handle_options(options)
|
127
126
|
options[:hrd] ||= options[:htype]
|
128
127
|
options[:pro] ||= options[:ptype]
|
129
128
|
options[:hln] ||= options[:hlen]
|
@@ -134,7 +133,7 @@ module PacketGen
|
|
134
133
|
options[:tha] ||= options[:dst_mac]
|
135
134
|
options[:tpa] ||= options[:dst_ip]
|
136
135
|
end
|
137
|
-
# rubocop:enable Metrics
|
136
|
+
# rubocop:enable Metrics
|
138
137
|
|
139
138
|
def invert_addresses
|
140
139
|
self.spa, self.tpa = self.tpa, self.spa
|
@@ -21,7 +21,7 @@ module PacketGen
|
|
21
21
|
include Headerable
|
22
22
|
|
23
23
|
class << self
|
24
|
-
# Define some methods from given ASN.1 attributes
|
24
|
+
# Define some methods from given ASN.1 attributes to mimic {Base} attributes
|
25
25
|
# @param [Array<Symbol>] attributes
|
26
26
|
# @return [void]
|
27
27
|
def define_attributes(*attributes)
|
@@ -32,6 +32,7 @@ module PacketGen
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
# @return [Hash]
|
35
36
|
def known_headers
|
36
37
|
@known_headers ||= {}.freeze
|
37
38
|
end
|
@@ -13,8 +13,10 @@ module PacketGen
|
|
13
13
|
# * +#calc_checksum+, which computes header checksum,
|
14
14
|
# * +#calc_length+, which computes header length,
|
15
15
|
# * {#parse?},
|
16
|
-
# * +#reply!+, which inverts needed attributes
|
16
|
+
# * +#reply!+, which inverts needed attributes to forge a response.
|
17
|
+
# {Base} class defines {.bind} method, to bind headers to outer ones.
|
17
18
|
# @author Sylvain Daubert
|
19
|
+
# @author LemonTree55
|
18
20
|
class Base < BinStruct::Struct
|
19
21
|
include Headerable
|
20
22
|
|
@@ -54,7 +56,7 @@ module PacketGen
|
|
54
56
|
# @api private
|
55
57
|
# Class to handle a header association from procs
|
56
58
|
class ProcBinding
|
57
|
-
# @param [Array
|
59
|
+
# @param [Array(Proc,Proc)] procs first proc is used to set fields, second proc is
|
58
60
|
# used to check binding
|
59
61
|
def initialize(procs)
|
60
62
|
@set = procs.shift
|
@@ -77,11 +79,11 @@ module PacketGen
|
|
77
79
|
end
|
78
80
|
|
79
81
|
# @api private
|
80
|
-
# Class to handle header associations
|
82
|
+
# Class to handle a set of header associations ({Binding} or/and {ProcBinding})
|
81
83
|
class Bindings
|
82
84
|
include Enumerable
|
83
85
|
|
84
|
-
# @return [Array<Binding>]
|
86
|
+
# @return [Array<Binding,ProcBinding>]
|
85
87
|
attr_accessor :bindings
|
86
88
|
|
87
89
|
def initialize
|
@@ -92,7 +94,7 @@ module PacketGen
|
|
92
94
|
@bindings << []
|
93
95
|
end
|
94
96
|
|
95
|
-
# @param [
|
97
|
+
# @param [Binding,ProcBinding] arg
|
96
98
|
# @return [Bindings] self
|
97
99
|
def <<(arg)
|
98
100
|
@bindings.last << arg
|
@@ -100,6 +102,7 @@ module PacketGen
|
|
100
102
|
|
101
103
|
# each iterator
|
102
104
|
# @return [void]
|
105
|
+
# @yieldparam [Binding,ProcBinding] binding
|
103
106
|
def each(&block)
|
104
107
|
@bindings.each(&block)
|
105
108
|
end
|
@@ -109,7 +112,7 @@ module PacketGen
|
|
109
112
|
@bindings.empty?
|
110
113
|
end
|
111
114
|
|
112
|
-
# Return
|
115
|
+
# Return bindings as a hash.
|
113
116
|
# @return [Hash]
|
114
117
|
def to_h
|
115
118
|
hsh = {}
|
@@ -146,12 +149,12 @@ module PacketGen
|
|
146
149
|
class << self
|
147
150
|
# @api private
|
148
151
|
# Get known headers
|
149
|
-
# @return [Hash
|
152
|
+
# @return [Hash{Headerable => Bindings}]
|
150
153
|
attr_reader :known_headers
|
151
154
|
|
152
155
|
# Bind a upper header to current one.
|
153
156
|
# @param [Class] header_klass header class to bind to current class
|
154
|
-
# @param [Hash] args current class attributes
|
157
|
+
# @param [Hash] args current class attributes and their value when +header_klass+
|
155
158
|
# is embedded in current class.
|
156
159
|
#
|
157
160
|
# Given value may be a lambda, whose alone argument is the value extracted
|
@@ -163,23 +166,23 @@ module PacketGen
|
|
163
166
|
# non-trivial checks should be made.
|
164
167
|
# @return [void]
|
165
168
|
# @example Basic examples
|
166
|
-
# # Bind
|
167
|
-
#
|
168
|
-
# # Bind
|
169
|
-
# # and
|
170
|
-
#
|
171
|
-
#
|
169
|
+
# # Bind TCP to IP when protocol attribute from IP has a value of 66
|
170
|
+
# PacketGen::Header::IP.bind PacketGen::Header::TCP, protocol: 66
|
171
|
+
# # Bind UDP to IP when protocol from IP has a value of 177
|
172
|
+
# # and tos has value 43 or 44
|
173
|
+
# PacketGen::Header::IP .bind PacketGen::Header::UDP, protocol: 177, tos: 43
|
174
|
+
# PacketGen::Header::IP .bind PacketGen::Header::UDP, protocol: 177, tos: 44
|
172
175
|
# @example Defining a binding on a field using a lambda.
|
173
|
-
# # Bind
|
174
|
-
# # greater or equal to 44. When adding a
|
176
|
+
# # Bind DHCP to Eth when ethertype from Eth has a value
|
177
|
+
# # greater or equal to 44. When adding a DHCP to a Eth
|
175
178
|
# # with Packet#add, force value to 44.
|
176
|
-
#
|
179
|
+
# PacketGen::Header::Eth.bind PacketGen::Header::DHCP, ethertype: ->(v) { v.nil? ? 44 : v >= 44 }
|
177
180
|
# @example Defining a binding using procs key
|
178
|
-
# # Bind
|
179
|
-
# # and first two bytes of
|
180
|
-
# # When adding a
|
181
|
-
#
|
182
|
-
#
|
181
|
+
# # Bind IPv6 to IP when protocol from IP has a value of 255
|
182
|
+
# # and first two bytes of IP's body are 0x6000.
|
183
|
+
# # When adding a IPv6 to a IP with Packet#add, force value to 255.
|
184
|
+
# PacketGen::Header::IP.bind PacketGen::Header::IPv6, procs: [->(hdr) { hdr.protocol = 255 },
|
185
|
+
# ->(hdr) { hdr.protocol == 255 && hdr.body[0..1] == "\x60\x00" }]
|
183
186
|
# @since 2.7.0
|
184
187
|
def bind(header_klass, args={})
|
185
188
|
bindings = @known_headers[header_klass]
|
@@ -221,7 +224,7 @@ module PacketGen
|
|
221
224
|
# @api private
|
222
225
|
# Get +header+ id in {Packet#headers} array
|
223
226
|
# @param [Header] header
|
224
|
-
# @return [Integer]
|
227
|
+
# @return [Integer] header id
|
225
228
|
# @raise [FormatError] +header+ not in a packet
|
226
229
|
def header_id(header)
|
227
230
|
raise FormatError, "header of type #{header.class} not in a packet" if packet.nil?
|
@@ -247,7 +250,7 @@ module PacketGen
|
|
247
250
|
end
|
248
251
|
|
249
252
|
# @api private
|
250
|
-
# Get link layer header from given header
|
253
|
+
# Get link layer ({Eth} or {Dot11}) header from given header
|
251
254
|
# @param [Header] header
|
252
255
|
# @return [Header]
|
253
256
|
# @raise [FormatError] no link layer header in packet
|
@@ -12,31 +12,31 @@ module PacketGen
|
|
12
12
|
# RFC 951}
|
13
13
|
#
|
14
14
|
# A BOOTP header consists of:
|
15
|
-
# * an operation code field ({#op} of type
|
16
|
-
# * a hardware address type ({#htype} of type
|
17
|
-
# * a hardware address length ({#hlen} of type
|
18
|
-
# * a {#hops} field (
|
19
|
-
# * a transaction ID ({#xid} of type
|
20
|
-
# * a {#secs} field (
|
21
|
-
# * a {#flags} field (
|
15
|
+
# * an operation code field ({#op} of type +BinStruct::Int8Enum+),
|
16
|
+
# * a hardware address type ({#htype} of type +BinStruct::Int8+),
|
17
|
+
# * a hardware address length ({#hlen} of type +BinStruct::Int8+),
|
18
|
+
# * a {#hops} field (+BinStruct::Int8+),
|
19
|
+
# * a transaction ID ({#xid} of type +BinStruct::Int32+),
|
20
|
+
# * a {#secs} field (+BinStruct::Int16+),
|
21
|
+
# * a {#flags} field (+BinStruct::Int16+):
|
22
22
|
# * a 1-bit broadcast flag ({#b}),
|
23
23
|
# * a 15-bit Must Be Zero field ({#mbz}),
|
24
24
|
# * a {#ciaddr} field ({IP::Addr}),
|
25
25
|
# * a {#yiaddr} field ({IP::Addr}),
|
26
26
|
# * a {#siaddr} field ({IP::Addr}),
|
27
27
|
# * a {#giaddr} field ({IP::Addr}),
|
28
|
-
# * a {#chaddr} field (16-byte
|
29
|
-
# * a {#sname} field (64-byte
|
30
|
-
# * a {#file} field (128-byte
|
31
|
-
# * and a body (
|
28
|
+
# * a {#chaddr} field (16-byte +BinStruct::String+),
|
29
|
+
# * a {#sname} field (64-byte +BinStruct::CString+),
|
30
|
+
# * a {#file} field (128-byte +BinStruct::CString+),
|
31
|
+
# * and a body (+BinStruct::String+).
|
32
32
|
#
|
33
|
-
#
|
33
|
+
# @example Create a BOOTP header
|
34
34
|
# # standalone
|
35
35
|
# bootp = PacketGen::Header::BOOTP.new
|
36
36
|
# # in a packet
|
37
|
-
# pkt = PacketGen.gen('IP').add('BOOTP')
|
37
|
+
# pkt = PacketGen.gen('IP').add('UDP').add('BOOTP')
|
38
38
|
# # access to BOOTP header
|
39
|
-
# pkt.bootp # =>
|
39
|
+
# pkt.bootp.protocol_name # => "BOOTP"
|
40
40
|
# @author Sylvain Daubert
|
41
41
|
# @since 2.2.0
|
42
42
|
class BOOTP < Base
|
@@ -58,12 +58,12 @@ module PacketGen
|
|
58
58
|
}.freeze
|
59
59
|
|
60
60
|
# @!parse
|
61
|
-
# # Option class with string value.
|
62
|
-
# #
|
61
|
+
# # Option class with string value. +#type+ and +#length+ are
|
62
|
+
# # +BinStruct::Int8+.
|
63
63
|
# #
|
64
|
-
# # See also {IPAddrOption}, {Int8Option}, {Int16Option} and {Int32Option}.
|
64
|
+
# # See also specialized {IPAddrOption}, {Int8Option}, {Int16Option} and {Int32Option}.
|
65
65
|
# # @since 2.2.0
|
66
|
-
# # @since 3.1.0 subclass of
|
66
|
+
# # @since 3.1.0 subclass of +BinStruct::AbstractTLV+
|
67
67
|
# class Option < BinStruct::AbstractTLV; end
|
68
68
|
# @private
|
69
69
|
Option = BinStruct::AbstractTLV.create
|
@@ -71,7 +71,7 @@ module PacketGen
|
|
71
71
|
# @!parse
|
72
72
|
# # {Option} class with IP address value
|
73
73
|
# # @since 2.2.0
|
74
|
-
# # @since 3.1.0 subclass of
|
74
|
+
# # @since 3.1.0 subclass of +BinStruct::AbstractTLV+
|
75
75
|
# class IPAddrOption < BinStruct::AbstractTLV; end
|
76
76
|
# @private
|
77
77
|
IPAddrOption = BinStruct::AbstractTLV.create(value_class: IP::Addr)
|
@@ -79,7 +79,7 @@ module PacketGen
|
|
79
79
|
# @!parse
|
80
80
|
# # {Option} class with int8 value
|
81
81
|
# # @since 2.2.0
|
82
|
-
# # @since 3.1.0 subclass of
|
82
|
+
# # @since 3.1.0 subclass of +BinStruct::AbstractTLV+
|
83
83
|
# class Int8Option < BinStruct::AbstractTLV; end
|
84
84
|
# @private
|
85
85
|
Int8Option = BinStruct::AbstractTLV.create(value_class: BinStruct::Int8)
|
@@ -87,7 +87,7 @@ module PacketGen
|
|
87
87
|
# @!parse
|
88
88
|
# # {Option} class with int16 value
|
89
89
|
# # @since 2.2.0
|
90
|
-
# # @since 3.1.0 subclass of {
|
90
|
+
# # @since 3.1.0 subclass of {+inStruct::AbstractTLV+
|
91
91
|
# class Int16Option < BinStruct::AbstractTLV; end
|
92
92
|
# @private
|
93
93
|
Int16Option = BinStruct::AbstractTLV.create(value_class: BinStruct::Int16)
|
@@ -95,7 +95,7 @@ module PacketGen
|
|
95
95
|
# @!parse
|
96
96
|
# # {Option} class with int32 value
|
97
97
|
# # @since 2.2.0
|
98
|
-
# # @since 3.1.0 subclass of
|
98
|
+
# # @since 3.1.0 subclass of +BinStruct::AbstractTLV+
|
99
99
|
# class Int32Option < BinStruct::AbstractTLV; end
|
100
100
|
# @private
|
101
101
|
Int32Option = BinStruct::AbstractTLV.create(value_class: BinStruct::Int32)
|
@@ -9,9 +9,9 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class DHCP
|
12
|
-
# Container class for {Option DHCP Options}.
|
12
|
+
# Container class for {Option DHCP Options}. Accepted options are listed on {DHCP::DHCP_OPTIONS}.
|
13
13
|
#
|
14
|
-
#
|
14
|
+
# @example Add DHCP options to an +Options+ instance
|
15
15
|
# options = PacketGen::Header::DHCP::Options.new
|
16
16
|
# # Add a lease_time option
|
17
17
|
# options << { type: 'lease_time', value: 3600 }
|
@@ -12,22 +12,21 @@ module PacketGen
|
|
12
12
|
# RFC 2131}
|
13
13
|
#
|
14
14
|
# A DHCP header is quite simple. It is composed of:
|
15
|
-
# * a {#magic} field (
|
16
|
-
# * a
|
15
|
+
# * a {#magic} field (+BinStruct::Int32+) to retrieve it in a BOOTP header,
|
16
|
+
# * a {#options} field ({Options} type, which is a collection of DHCP
|
17
17
|
# options).
|
18
18
|
#
|
19
19
|
# In PacketGen, a DHCP header is always a secondary header after {BOOTP} one.
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# @example Create a DHCP header
|
22
22
|
# # standalone
|
23
23
|
# dhcp = PacketGen::Header::DHCP.new
|
24
24
|
# # in a packet
|
25
|
-
# pkt = PacketGen.gen('IP').add('BOOTP').add('DHCP')
|
25
|
+
# pkt = PacketGen.gen('IP').add('UDP').add('BOOTP').add('DHCP')
|
26
26
|
# # access to DHCP header
|
27
|
-
# pkt.dhcp # => PacketGen::Header::DHCP
|
27
|
+
# pkt.dhcp.class # => PacketGen::Header::DHCP
|
28
28
|
#
|
29
|
-
#
|
30
|
-
# Options may be added these ways:
|
29
|
+
# @example Add options to a DHCP header
|
31
30
|
# dhcp = PacketGen::Header::DHCP.new
|
32
31
|
# # Add a lease_time option
|
33
32
|
# dhcp.options << { type: 'lease_time', value: 3600 }
|
@@ -25,7 +25,7 @@ module PacketGen
|
|
25
25
|
# @return [Integer]
|
26
26
|
define_attr :type, BinStruct::Int16Enum, enum: TYPES
|
27
27
|
# @!attribute body
|
28
|
-
# @abstract replaced by specific attributes
|
28
|
+
# @abstract replaced by specific attributes in subclasses
|
29
29
|
# DUID data.
|
30
30
|
# @return [String]
|
31
31
|
define_attr :body, BinStruct::String
|
@@ -9,10 +9,10 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class DHCPv6
|
12
|
-
# A DHCPv6 consists of:
|
13
|
-
# * a {#type} (
|
14
|
-
# * a {#length} (
|
15
|
-
# * and a {#data} (
|
12
|
+
# A DHCPv6 option consists of:
|
13
|
+
# * a {#type} (+BinStruct::Int16+),
|
14
|
+
# * a {#length} (+BinStruct::Int16+),
|
15
|
+
# * and a {#data} (+BinStruct::String+).
|
16
16
|
#
|
17
17
|
# Subclasses handles known options. These subclasses may remove {#data}
|
18
18
|
# field to replace it by specific option field(s).
|
@@ -25,9 +25,10 @@ module PacketGen
|
|
25
25
|
# @return [Integer]
|
26
26
|
define_attr :type, BinStruct::Int16
|
27
27
|
# @!attribute length
|
28
|
-
# 16-bit option length
|
28
|
+
# 16-bit option length. Length of data part.
|
29
29
|
# @return [Integer]
|
30
30
|
define_attr :length, BinStruct::Int16
|
31
|
+
# @!scope class
|
31
32
|
# @!attribute data
|
32
33
|
# variable length option data.
|
33
34
|
# @return [String]
|
@@ -216,13 +217,6 @@ module PacketGen
|
|
216
217
|
end
|
217
218
|
end
|
218
219
|
|
219
|
-
# List of requested options for {ORO} option.
|
220
|
-
# Set of {BinStruct::Int16}
|
221
|
-
# @author Sylvain Daubert
|
222
|
-
class RequestedOptions < BinStruct::Array
|
223
|
-
set_of BinStruct::Int16
|
224
|
-
end
|
225
|
-
|
226
220
|
# DHCPv6 Option Request Option
|
227
221
|
# @author Sylvain Daubert
|
228
222
|
class ORO < Option
|
@@ -230,8 +224,10 @@ module PacketGen
|
|
230
224
|
remove_attr :data
|
231
225
|
|
232
226
|
# @!attribute options
|
233
|
-
# @return [
|
234
|
-
|
227
|
+
# @return [BinStruct::ArrayOfInt16]
|
228
|
+
# @since 2.5.0
|
229
|
+
# @since 4.1.0 Type +BinStruct::ArrayOfInt16+ instead of custom +RequestedOptions+ (deleted)
|
230
|
+
define_attr :options, BinStruct::ArrayOfInt16, builder: ->(h, t) { t.new(length_from: h[:length]) }
|
235
231
|
|
236
232
|
# Get human-readable data
|
237
233
|
# @return [String]
|
@@ -280,6 +276,9 @@ module PacketGen
|
|
280
276
|
# @author Sylvain Daubert
|
281
277
|
class RelayMessage < Option
|
282
278
|
update_attr :type, default: 9
|
279
|
+
# @!attribute data
|
280
|
+
# variable length option data.
|
281
|
+
# @return [String]
|
283
282
|
end
|
284
283
|
|
285
284
|
# DHCPv6 Server Unicast option
|
@@ -302,8 +301,31 @@ module PacketGen
|
|
302
301
|
|
303
302
|
# DHCPv6 Status Code option
|
304
303
|
# @author Sylvain Daubert
|
305
|
-
class StatusCode <
|
304
|
+
class StatusCode < Option
|
306
305
|
update_attr :type, default: 13
|
306
|
+
remove_attr :data
|
307
|
+
|
308
|
+
# @!attribute status_code
|
309
|
+
# 16-bit status code
|
310
|
+
# @return [Integer]
|
311
|
+
define_attr :status_code, BinStruct::Int16
|
312
|
+
# @!attribute status_message
|
313
|
+
# UTF-8 encoded text string suitable for display to an end user
|
314
|
+
# @return [::String]
|
315
|
+
define_attr :status_message, BinStruct::String
|
316
|
+
|
317
|
+
# @param [Hash] options
|
318
|
+
def initialize(options={})
|
319
|
+
options[:length] = options[:status_message].to_s.size + 2 if options[:status_message]
|
320
|
+
super
|
321
|
+
self.length = self.sz - 4 if options[:status_message].nil?
|
322
|
+
end
|
323
|
+
|
324
|
+
# Get human-readable data (status code)
|
325
|
+
# @return [String]
|
326
|
+
def human_data
|
327
|
+
status_code.to_s
|
328
|
+
end
|
307
329
|
end
|
308
330
|
|
309
331
|
# DHCPv6 Rapid Commit option
|
@@ -11,8 +11,8 @@ module PacketGen
|
|
11
11
|
class DHCPv6
|
12
12
|
# Container class for DHCPv6 {Option options}.
|
13
13
|
#
|
14
|
-
#
|
15
|
-
# options = PacketGen::Header::
|
14
|
+
# @example Add DHCPv6 options to an +Options+ instance
|
15
|
+
# options = PacketGen::Header::DHCPv6::Options.new
|
16
16
|
# # Add an ElapsedTime option
|
17
17
|
# options << { type: 'ElapsedTime', value: 3600 }
|
18
18
|
# # Add a ClientID. Here, use integer type
|
@@ -22,7 +22,7 @@ module PacketGen
|
|
22
22
|
class Options < BinStruct::Array
|
23
23
|
set_of DHCPv6::Option
|
24
24
|
|
25
|
-
# Separator used in
|
25
|
+
# Separator used in +#to_human+.
|
26
26
|
HUMAN_SEPARATOR = ';'
|
27
27
|
|
28
28
|
private
|
@@ -22,22 +22,20 @@ module PacketGen
|
|
22
22
|
# | |
|
23
23
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
24
24
|
# A DHCPv6 header is made of:
|
25
|
-
# * a {#msg_type} field (
|
26
|
-
# * a {#transaction_id} field (
|
27
|
-
# * and an {#options} field ({DHCPv6::Options}).
|
25
|
+
# * a {#msg_type} field (+BinStruct::Int8Enum+),
|
26
|
+
# * a {#transaction_id} field (+BinStruct::Int24+),
|
27
|
+
# * and an {#options} field ({DHCPv6::Options}). This field is a container for {DHCPv6::Option} objects.
|
28
28
|
#
|
29
|
-
#
|
29
|
+
# @example Create a DHCPv6 header
|
30
30
|
# # standalone
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# == Add options
|
38
|
-
# DHCPv6 options are defined by subclasses of {DHCPv6::Option}.
|
31
|
+
# dhcpv6 = PacketGen::Header::DHCPv6.new(msg_type: 'SOLLICIT')
|
32
|
+
# # in a packet
|
33
|
+
# pkt = PacketGen.gen('IPv6').add('UDP').add('DHCPv6', msg_type: 'SOLLICIT')
|
34
|
+
# # access to DHCPv6 header from packet
|
35
|
+
# pkt.dhcpv6.class #=> PacketGen::Header::DHCPv6
|
39
36
|
#
|
40
|
-
#
|
37
|
+
# @example Add options
|
38
|
+
# # Options may be added by pushing a hash to #options:
|
41
39
|
# dhcpv6 = PacketGen::Header::DHCPv6.new(msg_type: 'SOLLICIT')
|
42
40
|
# dhcpv6.options << { type: 'Preference', value: 1 }
|
43
41
|
# @author Sylvain Daubert
|
@@ -75,9 +73,10 @@ module PacketGen
|
|
75
73
|
define_attr :msg_type, BinStruct::Int8Enum, enum: MESSAGE_TYPES
|
76
74
|
# @!attribute transaction_id
|
77
75
|
# 24-bit transaction ID
|
78
|
-
#
|
76
|
+
# @return [Integer]
|
79
77
|
define_attr :transaction_id, BinStruct::Int24
|
80
78
|
# @!attribute options
|
79
|
+
# Set of {Option}s
|
81
80
|
# @return [DHCPv6::Options]
|
82
81
|
define_attr :options, DHCPv6::Options
|
83
82
|
|
@@ -9,13 +9,14 @@
|
|
9
9
|
module PacketGen
|
10
10
|
module Header
|
11
11
|
class DNS
|
12
|
-
# DNS Name, defined as a suite of labels. A label is of type
|
12
|
+
# DNS Name, defined as a suite of labels. A label is of type +BinStruct::IntString+.
|
13
13
|
# @author Sylvain Daubert
|
14
14
|
# @author LemonTree55
|
15
15
|
class Name < BinStruct::Array
|
16
16
|
# Mask to decode a pointer on another label
|
17
17
|
POINTER_MASK = 0xc000
|
18
18
|
|
19
|
+
# DNS message to which this name is attached. Used to decode compressed names
|
19
20
|
# @return [DNS]
|
20
21
|
attr_accessor :dns
|
21
22
|
|
@@ -49,32 +50,32 @@ module PacketGen
|
|
49
50
|
end
|
50
51
|
|
51
52
|
# Clear name
|
52
|
-
#
|
53
|
+
# @return [void]
|
53
54
|
def clear
|
54
55
|
super
|
55
56
|
@pointer = nil
|
56
57
|
@pointer_name = nil
|
57
58
|
end
|
58
59
|
|
59
|
-
# Read a sequence of label from a string
|
60
|
+
# Read a sequence of label from a binary string
|
60
61
|
# @param [String] str binary string
|
61
62
|
# @return [Name] self
|
62
63
|
def read(str)
|
63
64
|
clear
|
64
65
|
return self if str.nil?
|
65
66
|
|
66
|
-
|
67
|
+
strb = str.to_s.b
|
67
68
|
start = 0
|
68
69
|
loop do
|
69
|
-
index =
|
70
|
+
index = strb[start, 2].unpack1('n')
|
70
71
|
if pointer?(index)
|
71
72
|
# Pointer on another label
|
72
|
-
@pointer =
|
73
|
+
@pointer = strb[start, 2]
|
73
74
|
break
|
74
75
|
else
|
75
|
-
label = add_label_from(
|
76
|
+
label = add_label_from(strb[start..])
|
76
77
|
start += label.sz
|
77
|
-
break if label.empty? ||
|
78
|
+
break if label.empty? || strb[start..].empty?
|
78
79
|
end
|
79
80
|
end
|
80
81
|
# force resolution of compressed names
|
@@ -15,6 +15,7 @@ module PacketGen
|
|
15
15
|
#
|
16
16
|
# a OPT record may contain zero or more {Option options} in its {#rdata}.
|
17
17
|
# @author Sylvain Daubert
|
18
|
+
# @author LemonTree55
|
18
19
|
# @since 1.3.0
|
19
20
|
# @since 3.1.1 {#options} is a {ArrayOfOptions}
|
20
21
|
class OPT < RR
|
@@ -118,11 +119,13 @@ module PacketGen
|
|
118
119
|
alias udp_size rrclass
|
119
120
|
alias udp_size= rrclass=
|
120
121
|
|
122
|
+
# Get human-readable string for flags
|
121
123
|
# @return [String]
|
122
124
|
def human_flags
|
123
125
|
do? ? 'do' : 'none'
|
124
126
|
end
|
125
127
|
|
128
|
+
# Get human-readable string for this OPT
|
126
129
|
# @return [String]
|
127
130
|
def to_human
|
128
131
|
"#{name} #{human_type} UDPsize:#{udp_size} " \
|