packetgen 3.1.0 → 3.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 877d57dd457d4cde03fca6e13c0042168c8630b08073533b7b7fb95da49632a0
4
- data.tar.gz: 5c18abe50abcb423edf22571e88241cddb6095a0c626fb6018bfbafac49278b1
3
+ metadata.gz: 36578b725eb28ace342c6468423d781158b376c16bcc8b949e1df62262aba11a
4
+ data.tar.gz: 6e3bbdfc313f54611b05a19a31336438fa781cce24bc19867a2e72d91bbc8f9e
5
5
  SHA512:
6
- metadata.gz: '09c0197e3f3d1bf72dffbaf97abc4007902ade04b94a6893d1a79e97944e6560eb16aad024726497a064b9fdc59fed5efd8e456cffcaa3f7bf64b7b0c7a2604c'
7
- data.tar.gz: 575402b40e5be3c8bf6d68e8dfd01fa3b4a9d3e917fda6cefa17b0759f99193bb69a5e3b5734cfa839e149856d7d98ea88e13bb8fa273c9ac295a94a79e7502b
6
+ metadata.gz: 64cfe76137b2f4f2ea1b75806019a28d63d32cb904fe3a22982d8cf5b090e3df74befd527606d250d49a2541842b2dba2c0e1060b61128ecd538b2c6c7e6d544
7
+ data.tar.gz: 9700b4a0f455d5b6918d8a0eac2309100e29db650eb2f88469a54241b8b5888d2605571883aaebe187d69db97c0e0e380ba35c4325a6bd420c492ec7dc619c55
data/README.md CHANGED
@@ -164,7 +164,7 @@ PacketGen provides a plugin system (see [wiki](https://github.com/sdaubert/packe
164
164
  Available plugins (available as gem) are:
165
165
 
166
166
  * [packetgen-plugin-ipsec](https://github.com/sdaubert/packetgen-plugin-ipsec): add support for ESP and IKEv2 protocols. Before PacketGen3, these protocols were included in packetgen.
167
- * [packetgen-plugin-smb](https://github.com/sdaubert/packetgen-plugin-smb): add (limited) support for SMB protocol suite.
167
+ * [packetgen-plugin-smb](https://github.com/sdaubert/packetgen-plugin-smb): add support for SMB protocol suite.
168
168
 
169
169
  ## See also
170
170
 
@@ -56,19 +56,47 @@ module PacketGen
56
56
  'end' => 255
57
57
  }.freeze
58
58
 
59
- # Option class with string value
59
+ # @!parse
60
+ # # Option class with string value. {#type #type} and {#length #length} are
61
+ # # {Types::Int8}.
62
+ # #
63
+ # # See also {IPAddrOption}, {Int8Option}, {Int16Option} and {Int32Option}.
64
+ # # @since 2.2.0
65
+ # # @since 3.1.0 subclass of {Types::AbstractTLV}
66
+ # class Option < Types::AbstractTLV; end
67
+ # @private
60
68
  Option = Types::AbstractTLV.create
61
69
  Option.define_type_enum DHCP_OPTIONS
62
- # Option class with IP address value
70
+ # @!parse
71
+ # # {Option} class with IP address value
72
+ # # @since 2.2.0
73
+ # # @since 3.1.0 subclass of {Types::AbstractTLV}
74
+ # class IPAddrOption < Types::AbstractTLV; end
75
+ # @private
63
76
  IPAddrOption = Types::AbstractTLV.create(value_class: IP::Addr)
64
77
  IPAddrOption.define_type_enum DHCP_OPTIONS
65
- # Option class with int8 value
78
+ # @!parse
79
+ # # {Option} class with int8 value
80
+ # # @since 2.2.0
81
+ # # @since 3.1.0 subclass of {Types::AbstractTLV}
82
+ # class Int8Option < Types::AbstractTLV; end
83
+ # @private
66
84
  Int8Option = Types::AbstractTLV.create(value_class: Types::Int8)
67
85
  Int8Option.define_type_enum DHCP_OPTIONS
68
- # Option class with int16 value
86
+ # @!parse
87
+ # # {Option} class with int16 value
88
+ # # @since 2.2.0
89
+ # # @since 3.1.0 subclass of {Types::AbstractTLV}
90
+ # class Int16Option < Types::AbstractTLV; end
91
+ # @private
69
92
  Int16Option = Types::AbstractTLV.create(value_class: Types::Int16)
70
93
  Int16Option.define_type_enum DHCP_OPTIONS
71
- # Option class with int32 value
94
+ # @!parse
95
+ # # {Option} class with int32 value
96
+ # # @since 2.2.0
97
+ # # @since 3.1.0 subclass of {Types::AbstractTLV}
98
+ # class Int32Option < Types::AbstractTLV; end
99
+ # @private
72
100
  Int32Option = Types::AbstractTLV.create(value_class: Types::Int32)
73
101
  Int32Option.define_type_enum DHCP_OPTIONS
74
102
 
@@ -8,7 +8,7 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class DHCP
11
- # Container class for DHCP Options
11
+ # Container class for {Option DHCP Options}.
12
12
  #
13
13
  # == Add DHCP options to an +Options+ instance
14
14
  # options = PacketGen::Header::DHCP::Options.new
@@ -43,10 +43,14 @@ module PacketGen
43
43
  # == DNS attributes
44
44
  # dns.id = 0x1234
45
45
  # dns.qr = false
46
- # dns.opcode = 0xe
47
- # dns.opcode = 'query'
46
+ # # opcode may be set as an Integer (all values are possible)
47
+ # # or as a String (only keys from PacketGen::Header::DNS::OPCODES)
48
+ # dns.opcode = 0xe # set as integer, value not defined in standard
49
+ # dns.opcode = 'query' # set as string
48
50
  # dns.aa = dns.tc = dns.rd = dns.ra = false
49
- # dns.rcode = 0xa
51
+ # # rcode may be set as an Integer (all values are possible)
52
+ # # or as a String (only keys from PacketGen::Header::DNS::RCODES)
53
+ # dns.rcode = 11
50
54
  # dns.rcode = 'refused'
51
55
  # dns.qdcount = 123
52
56
  # dns.ancount = 0x1234
@@ -71,8 +75,8 @@ module PacketGen
71
75
  # dns.qd.push({ rtype: 'Question', name: 'example.net', type: 'AAAA' })
72
76
  #
73
77
  # == Add a ressource record to a DNS section
74
- # Adding a {RR} with {RRSection#<<} automagically increments section counter.
75
- # To not modify it, use {RRSection#push}
78
+ # Adding a {RR} with {RRSection#<< RRSection#<<} automagically increments section counter.
79
+ # To not modify it, use {RRSection#push RRSection#push}
76
80
  # # add a RR to answer section. Increment ancount
77
81
  # dns.an << PacketGen::Header::DNS::RR.new(dns, name: 'example.net', rdata: IPAddr.new('1.2.3.4').hton)
78
82
  # # or
@@ -89,7 +93,9 @@ module PacketGen
89
93
  # # or
90
94
  # dns.ar << { rtype: 'OPT', udp_size: 4096, ext_rcode: 43 }
91
95
  # # add an option to OPT record
92
- # dns.ar.last.options << PacketGen::Header::DNS::Option.new(code: 48, length: 2, data: "12")
96
+ # dns.ar.last.options << PacketGen::Header::DNS::Option.new(code: 48, data: '12')
97
+ # # or
98
+ # dns.ar.last.options << { code: 48, data: '12' }
93
99
  # @author Sylvain Daubert
94
100
  # @since 1.3.0
95
101
  class DNS < Base
@@ -14,9 +14,12 @@ module PacketGen
14
14
  #
15
15
  # a OPT record may contain zero or more {Option options} in its {#rdata}.
16
16
  # @author Sylvain Daubert
17
+ # @since 1.3.0
18
+ # @since 3.1.1 {#options} is a {ArrayOfOptions}
17
19
  class OPT < RR
18
- # @return [Array<Option>]
19
- attr_reader :options
20
+ # @!attribute options
21
+ # @return [ArrayOfOptions]
22
+ define_field_after :rdata, :options, ArrayOfOptions
20
23
 
21
24
  # @param [DNS] dns
22
25
  # @param [Hash] options
@@ -35,7 +38,6 @@ module PacketGen
35
38
  def initialize(dns, options={})
36
39
  opts = { name: '.', rrclass: 512, type: 41 }.merge!(options)
37
40
  super dns, opts
38
- @options = []
39
41
 
40
42
  self.udp_size = options[:udp_size] if options[:udp_size]
41
43
  self.ext_rcode = options[:ext_rcode] if options[:ext_rcode]
@@ -120,22 +122,11 @@ module PacketGen
120
122
  do? ? 'do' : 'none'
121
123
  end
122
124
 
123
- # @return [String]
124
- def human_options
125
- str = @options.map(&:to_human).join(';')
126
- str.empty? ? 'none' : str
127
- end
128
-
129
125
  # @return [String]
130
126
  def to_human
131
127
  "#{name} #{human_type} UDPsize:#{udp_size} " \
132
128
  "extRCODE:#{ext_rcode} EDNSversion:#{version} flags:#{human_flags} " \
133
- "options:#{human_options}"
134
- end
135
-
136
- # @return [String]
137
- def to_s
138
- super + @options.map(&:to_s).join
129
+ "options:#{options.empty? ? 'none' : options.to_human}"
139
130
  end
140
131
  end
141
132
  end
@@ -8,9 +8,32 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class DNS
11
- # DNS option
11
+ # @!parse
12
+ # # DNS option is a TLV object:
13
+ # # * {#code} is a {Types::Int16},
14
+ # # * {#length #length} is a {Types::Int16},
15
+ # # * {#data} is a {Types::String}.
16
+ # #
17
+ # # @since 1.3.0
18
+ # # @since 3.1.0 defined with {Types::AbstractTLV}
19
+ # # @!parse class Option < Types::AbstractTLV; end
20
+ # # @!attribute code
21
+ # # Alias for {#type}
22
+ # # @return [Integer]
23
+ # # @!attribute data
24
+ # # Alias for {#value}
25
+ # # @return [Types::String]
26
+ # class Option < Types::AbstractTLV; end
27
+ # @private
12
28
  Option = Types::AbstractTLV.create(type_class: Types::Int16,
13
- length_class: Types::Int16)
29
+ length_class: Types::Int16,
30
+ aliases: { code: :type, data: :value })
31
+
32
+ # Array of {Option}.
33
+ # @since 3.1.1
34
+ class ArrayOfOptions < Types::Array
35
+ set_of Option
36
+ end
14
37
  end
15
38
  end
16
39
  end
@@ -9,9 +9,14 @@
9
9
  module PacketGen
10
10
  module Header
11
11
  class Dot11
12
- # IEEE 802.11 information element
13
- #
14
- # An {Element} is a piece of data contained in a Dot11 management frame.
12
+ # @!parse
13
+ # # IEEE 802.11 information element
14
+ # #
15
+ # # An {Element} is a piece of data contained in a Dot11 management frame.
16
+ # # @since 1.4.0
17
+ # # @since 3.1.0 subclass of {Types::AbstractTLV}
18
+ # class Element < Types::AbstractTLV; end
19
+ # @private
15
20
  Element = Types::AbstractTLV.create
16
21
 
17
22
  class Element
@@ -35,6 +40,12 @@ module PacketGen
35
40
  }.freeze
36
41
  end
37
42
  Element.define_type_enum Element::TYPES.invert
43
+
44
+ # Array of {Element}.
45
+ # @since 3.1.1
46
+ class ArrayOfElements < Types::Array
47
+ set_of Element
48
+ end
38
49
  end
39
50
  end
40
51
  end
@@ -54,8 +54,7 @@ module PacketGen
54
54
  # @since 2.1.3
55
55
  def add_element(type:, value:)
56
56
  if self[:body].is_a? SubMngt
57
- element = Element.new(type: type, value: value)
58
- self[:body].elements << element
57
+ self[:body].elements << { type: type, value: value }
59
58
  else
60
59
  raise FormatError, 'Before adding an Element, you have to add a Dot11::SubMngt subclass instance'
61
60
  end
@@ -19,61 +19,31 @@ module PacketGen
19
19
  # @author Sylvain Daubert
20
20
  class SubMngt < Base
21
21
  # @return [Array<Element>]
22
- attr_accessor :elements
23
-
24
- # @param [Hash] options
25
- # @see Base#initialize
26
- def initialize(options={})
27
- super
28
- @elements = []
29
- end
30
-
31
- # Populate object from binary string
32
- # @param [String] str
33
- # @return [SubMngt] self
34
- def read(str)
35
- super
36
- read_elements str[sz, str.size] || ''
37
- self
38
- end
39
-
40
- # @return [String]
41
- def to_s
42
- super + @elements.map(&:to_s).join
43
- end
22
+ define_field :elements, ArrayOfElements
44
23
 
45
24
  # @return [String]
46
- def inspect
47
- str = super
48
- str << Inspect.dashed_line('Dot11 Elements', 2)
49
- @elements.each do |el|
50
- str << Inspect.shift_level(2) << el.to_human << "\n"
51
- end
52
- str
53
- end
25
+ #def inspect
26
+ # str = super
27
+ # str << Inspect.dashed_line('Dot11 Elements', 2)
28
+ # @elements.each do |el|
29
+ # str << Inspect.shift_level(2) << el.to_human << "\n"
30
+ # end
31
+ # str
32
+ #end
54
33
 
55
34
  # Add an {Element} to header
56
35
  # @param [Integer,String] type element type
57
36
  # @param [Object] value element value
58
37
  # @return [self]
59
38
  # @since 2.1.3
39
+ # @since 3.1.1 #elements in no more an Array but an {ArrayOfElements}
40
+ # @deprecated Prefer use of +submngt.element << {type: type, value: value}+
60
41
  def add_element(type:, value:)
42
+ Deprecation.deprecated(self.class, __method__, 'elements')
61
43
  element = Element.new(type: type, value: value)
62
- @elements << element
44
+ self.elements << element
63
45
  self
64
46
  end
65
-
66
- private
67
-
68
- def read_elements(str)
69
- start = 0
70
- elsz = Element.new.sz
71
- while str.size - start >= elsz
72
- el = Element.new.read(str[start, str.size])
73
- @elements << el
74
- start += el.sz
75
- end
76
- end
77
47
  end
78
48
 
79
49
  # IEEE 802.11 Association Request frame
@@ -87,10 +57,10 @@ module PacketGen
87
57
  class AssoReq < SubMngt
88
58
  # @!attribute cap
89
59
  # @return [Integer] 16-bit capabillities word
90
- define_field :cap, Types::Int16le
60
+ define_field_before :elements, :cap, Types::Int16le
91
61
  # @!attribute listen_interval
92
62
  # @return [Integer] 16-bit listen interval value
93
- define_field :listen_interval, Types::Int16le, default: 0x00c8
63
+ define_field_before :elements, :listen_interval, Types::Int16le, default: 0x00c8
94
64
  end
95
65
  Header.add_class AssoReq
96
66
  Management.bind AssoReq, type: 0, subtype: 0
@@ -107,13 +77,13 @@ module PacketGen
107
77
  class AssoResp < SubMngt
108
78
  # @!attribute cap
109
79
  # @return [Integer] 16-bit capabillities word
110
- define_field :cap, Types::Int16le
80
+ define_field_before :elements, :cap, Types::Int16le
111
81
  # @!attribute status
112
82
  # @return [Integer] 16-bit status word
113
- define_field :status, Types::Int16le
83
+ define_field_before :elements, :status, Types::Int16le
114
84
  # @!attribute aid
115
85
  # @return [Integer] 16-bit AID word
116
- define_field :aid, Types::Int16le
86
+ define_field_before :elements, :aid, Types::Int16le
117
87
  end
118
88
  Header.add_class AssoResp
119
89
  Management.bind AssoResp, type: 0, subtype: 1
@@ -130,7 +100,7 @@ module PacketGen
130
100
  class ReAssoReq < AssoReq
131
101
  # @!attribute current_ap
132
102
  # @return [Eth::MAcAddr]
133
- define_field :current_ap, Eth::MacAddr
103
+ define_field_before :elements, :current_ap, Eth::MacAddr
134
104
  end
135
105
  Header.add_class ReAssoReq
136
106
  Management.bind ReAssoReq, type: 0, subtype: 2
@@ -172,13 +142,13 @@ module PacketGen
172
142
  class ProbeResp < SubMngt
173
143
  # @!attribute timestamp
174
144
  # @return [Integer] 64-bit timestamp
175
- define_field :timestamp, Types::Int64le
145
+ define_field_before :elements, :timestamp, Types::Int64le
176
146
  # @!attribute beacon_interval
177
147
  # @return [Integer] 16-bit beacon interval value
178
- define_field :beacon_interval, Types::Int16le, default: 0x0064
148
+ define_field_before :elements, :beacon_interval, Types::Int16le, default: 0x0064
179
149
  # @!attribute cap
180
150
  # @return [Integer] 16-bit capabillities word
181
- define_field :cap, Types::Int16le
151
+ define_field_before :elements, :cap, Types::Int16le
182
152
  end
183
153
  Header.add_class ProbeResp
184
154
  Management.bind ProbeResp, type: 0, subtype: 5
@@ -195,13 +165,13 @@ module PacketGen
195
165
  class Beacon < SubMngt
196
166
  # @!attribute timestamp
197
167
  # @return [Integer] 64-bit timestamp
198
- define_field :timestamp, Types::Int64le
168
+ define_field_before :elements, :timestamp, Types::Int64le
199
169
  # @!attribute interval
200
170
  # @return [Integer] 16-bit interval value
201
- define_field :interval, Types::Int16le, default: 0x64
171
+ define_field_before :elements, :interval, Types::Int16le, default: 0x64
202
172
  # @!attribute cap
203
173
  # @return [Integer] 16-bit capabillities word
204
- define_field :cap, Types::Int16le
174
+ define_field_before :elements, :cap, Types::Int16le
205
175
  end
206
176
  Header.add_class Beacon
207
177
  Management.bind Beacon, type: 0, subtype: 8
@@ -226,7 +196,7 @@ module PacketGen
226
196
  class Disas < SubMngt
227
197
  # @!attribute reason
228
198
  # @return [Integer] 16-bit reason value
229
- define_field :reason, Types::Int16le
199
+ define_field_before :elements, :reason, Types::Int16le
230
200
  end
231
201
  Header.add_class Disas
232
202
  Management.bind Disas, type: 0, subtype: 10
@@ -243,13 +213,13 @@ module PacketGen
243
213
  class Auth < SubMngt
244
214
  # @!attribute algo
245
215
  # @return [Integer] 16-bit algo value
246
- define_field :algo, Types::Int16le
216
+ define_field_before :elements, :algo, Types::Int16le
247
217
  # @!attribute seqnum
248
218
  # @return [Integer] 16-bit seqnum value
249
- define_field :seqnum, Types::Int16le
219
+ define_field_before :elements, :seqnum, Types::Int16le
250
220
  # @!attribute status
251
221
  # @return [Integer] 16-bit status word
252
- define_field :status, Types::Int16le
222
+ define_field_before :elements, :status, Types::Int16le
253
223
  end
254
224
  Header.add_class Auth
255
225
  Management.bind Auth, type: 0, subtype: 11
@@ -264,7 +234,7 @@ module PacketGen
264
234
  class DeAuth < SubMngt
265
235
  # @!attribute reason
266
236
  # @return [Integer] 16-bit reason value
267
- define_field :reason, Types::Int16le
237
+ define_field_before :elements, :reason, Types::Int16le
268
238
  end
269
239
  Header.add_class DeAuth
270
240
  Management.bind DeAuth, type: 0, subtype: 12
@@ -8,7 +8,11 @@
8
8
  module PacketGen
9
9
  module Header
10
10
  class IPv6
11
- # Option for {HopByHop} IPv6 extension header.
11
+ # @!parse
12
+ # # Option for {HopByHop} IPv6 extension header.
13
+ # # @since 3.1.0 subclass of {Types::AbstractTLV}
14
+ # class Option <AbstractTLV; end
15
+ # @private
12
16
  Option = Types::AbstractTLV.create
13
17
 
14
18
  class Option
@@ -40,20 +40,40 @@ module PacketGen
40
40
  # tlv = MyTLV.new(type: 1, value: '1.2.3.4')
41
41
  # tlv.type #=> 1
42
42
  # tlv.length #=> 4
43
- # tlv.value #=> 42
43
+ # tlv.value #=> '1.2.3.4'
44
44
  # tlv.to_s #=> "\x00\x01\x00\x04\x01\x02\x03\x04"
45
+ #
46
+ # Some aliases may also be defined. For example, to create a TLV type
47
+ # whose +type+ field should be named +code+:
48
+ # MyTLV = PacketGen::Types::AbstractTLV.create(type_class: PacketGen::Types::Int16,
49
+ # length_class: PacketGen::Types::Int16,
50
+ # aliases: { code: :type })
51
+ # tlv = MyTLV.new(code: 1, value: 'abcd')
52
+ # tlv.code #=> 1
53
+ # tlv.type #=> 1
54
+ # tlv.length #=> 4
55
+ # tlv.value #=> 'abcd'
56
+ #
45
57
  # @author Sylvain Daubert
46
58
  # @since 3.1.0
59
+ # @since 3.1.1 add +:aliases+ keyword to {#initialize}
47
60
  class AbstractTLV < Types::Fields
61
+ class <<self
62
+ # @return [Hash]
63
+ attr_accessor :aliases
64
+ end
65
+ self.aliases = {}
66
+
48
67
  # Generate a TLV class
49
68
  # @param [Class] type_class Class to use for +type+
50
69
  # @param [Class] length_class Class to use for +length+
51
70
  # @param [Class] value_class Class to use for +value+
52
71
  # @return [Class]
53
- def self.create(type_class: Int8Enum, length_class: Int8, value_class: String)
72
+ def self.create(type_class: Int8Enum, length_class: Int8, value_class: String, aliases: {})
54
73
  raise Error, '.create cannot be called on a subclass of PacketGen::Types::AbstractTLV' unless self.equal? AbstractTLV
55
74
 
56
75
  klass = Class.new(self)
76
+ klass.aliases = aliases
57
77
 
58
78
  if type_class < Enum
59
79
  klass.define_field :type, type_class, enum: {}
@@ -63,6 +83,13 @@ module PacketGen
63
83
  klass.define_field :length, length_class
64
84
  klass.define_field :value, value_class
65
85
 
86
+ aliases.each do |al, orig|
87
+ klass.instance_eval do
88
+ alias_method al, orig if klass.method_defined?(orig)
89
+ alias_method :"#{al}=", :"#{orig}=" if klass.method_defined?(:"#{orig}=")
90
+ end
91
+ end
92
+
66
93
  klass
67
94
  end
68
95
  # @!attribute type
@@ -90,6 +117,10 @@ module PacketGen
90
117
  # @option options [Integer] :length
91
118
  # @option options [Object] :value
92
119
  def initialize(options={})
120
+ self.class.aliases.each do |al, orig|
121
+ options[orig] = options[al] if options.key?(al)
122
+ end
123
+
93
124
  super
94
125
  # used #value= defined below, which set length if needed
95
126
  self.value = options[:value] if options[:value]
@@ -10,5 +10,5 @@
10
10
  # @author Sylvain Daubert
11
11
  module PacketGen
12
12
  # PacketGen version
13
- VERSION = '3.1.0'
13
+ VERSION = '3.1.1'
14
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: packetgen
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-28 00:00:00.000000000 Z
11
+ date: 2018-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interfacez