packetgen 2.8.1 → 2.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37df498d94945f9c9f6388bdbdddb9e0358b28bf554605205dd9411635710325
4
- data.tar.gz: 5c175ea4e4ce48c912f184375b1dfc78c86733356c0fb1207b35de53e1d757a5
3
+ metadata.gz: 8ed1bb8d789bf32ec06fefdb337c59a0bc798c681b109414e3c84e29d7668890
4
+ data.tar.gz: 938c883c20a2a5452aa4ade8d55cec86971eafc4c561c8980260c509b57312fb
5
5
  SHA512:
6
- metadata.gz: fbb0342a14a3ef2add45c1957839827aad610dda2d5bda9ed3c1141a5da011ca5695615087cbe917b11397cad0df342966d912c14dee56b4f968df1c9a1855d2
7
- data.tar.gz: 39998bac4ecd5d8be0e09f639159dfc257ca5fad34f546a5c7fe180607f899b1005877ed0a52ea30da916fe99c8db8ae0533c959adb7c964eb9ed8ac24f8ddc4
6
+ metadata.gz: 8cccb84679cdf8934e2e26b267cb4d00576201ff309311d70d7907dd3ea1ddb6ea3f61a11b2a081b4648a8e3263083ba7484961448ea60f944b6f0541e145d58
7
+ data.tar.gz: dfda8ea794e137b501bcbf1810f35ed637113ee33c548132d8f0f0db2cb24b6ca8603222eaf8185d02f37ca8ba2a0bd7ff60701cedd28fbaf8ccedd1c3985d35
data/README.md CHANGED
@@ -157,20 +157,27 @@ classes. A special `config` object gives local network configuration:
157
157
 
158
158
  If `pry` gem is installed, it is used as backend for `pgconsole`, else IRB is used.
159
159
 
160
+ ## Plugins
161
+
162
+ PacketGen provides a plugin system (see [wiki](https://github.com/sdaubert/packetgen/wiki/Create-Custom-Protocol)).
163
+
164
+ For now, there is only one plugin available as a gem:
165
+
166
+ * [packetgen-plugin-smb](https://github.com/sdaubert/packetgen-plugin-smb): add (limited) support for SMB protocol suite.
167
+
160
168
  ## See also
161
169
 
162
170
  Wiki: https://github.com/sdaubert/packetgen/wiki
163
171
 
164
172
  API documentation: http://www.rubydoc.info/gems/packetgen
165
173
 
166
- ## Pull requests?
174
+ ## Contributing
167
175
 
168
- yes
176
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sdaubert/packetgen-plugin-smb.
169
177
 
170
178
  ## License
171
- MIT License (see [LICENSE](https://github.com/sdaubert/packetgen/blob/master/LICENSE))
172
179
 
173
- Copyright © 2016 Sylvain Daubert
180
+ MIT License (see [LICENSE](https://github.com/sdaubert/packetgen/blob/master/LICENSE))
174
181
 
175
182
  ### Other sources
176
183
  All original code maintains its copyright from its original authors and licensing.
@@ -10,7 +10,8 @@ module PacketGen
10
10
  complete_deprecated_method_name = base_name + deprecated_method.to_s
11
11
  complete_new_method_name = base_name + new_method.to_s
12
12
 
13
- warn "#{complete_deprecated_method_name} is deprecated in favor of #{complete_new_method_name}. " \
13
+ file, line = caller(2).first.split(':')[0, 2]
14
+ warn "#{file}:#{line}: #{complete_deprecated_method_name} is deprecated in favor of #{complete_new_method_name}. " \
14
15
  "It will be remove in PacketGen #{remove_version}."
15
16
  end
16
17
  end
@@ -100,9 +100,9 @@ module PacketGen
100
100
  # Common inspect method for ASN.1 headers
101
101
  # @return [String]
102
102
  def inspect
103
- str = Inspect.dashed_line(self.class, 2)
103
+ str = Inspect.dashed_line(self.class, 1)
104
104
  self.class.class_eval { @attributes }.each do |attr|
105
- str << Inspect.inspect_asn1_attribute(attr, self[attr], 2)
105
+ str << Inspect.inspect_asn1_attribute(attr, self[attr], 1)
106
106
  end
107
107
  str
108
108
  end
@@ -17,7 +17,6 @@ module PacketGen
17
17
  class Base < Types::Fields
18
18
  # @api private
19
19
  # Simple class to handle a header association
20
- # @deprecated Will be remove with {Base.bind_header}
21
20
  class Binding < Struct.new(:key, :value)
22
21
  # Check +fields+ responds to binding
23
22
  # @param [Types::Fields] fields
@@ -51,7 +50,6 @@ module PacketGen
51
50
 
52
51
  # @api private
53
52
  # Class to handle a header association from procs
54
- # @deprecated Will be remove with {Base.bind_header}
55
53
  class ProcBinding
56
54
  # @param [Array<Proc>] procs first proc is used to set fields, second proc is
57
55
  # used to check binding
@@ -163,7 +161,7 @@ module PacketGen
163
161
  # @return [Packet,nil]
164
162
  attr_reader :packet
165
163
 
166
- # On inheritage, create +@old_known_header+ class variable
164
+ # On inheritage, create +@known_header+ class variable
167
165
  # @param [Class] klass
168
166
  # @return [void]
169
167
  def self.inherited(klass)
@@ -286,6 +284,12 @@ module PacketGen
286
284
  @known_headers
287
285
  end
288
286
 
287
+ # @see Types::Fields#initialize
288
+ def initialize(options={})
289
+ @packet = options.delete(:packet) if options.key?(:packet)
290
+ super
291
+ end
292
+
289
293
  # Return header protocol name
290
294
  # @return [String]
291
295
  def protocol_name
@@ -132,14 +132,15 @@ module PacketGen
132
132
 
133
133
  # @return [String]
134
134
  def inspect
135
- str = Inspect.dashed_line(self.class, 2)
135
+ str = Inspect.dashed_line(self.class, 1)
136
136
  fields.each do |attr|
137
137
  next if attr == :body
138
138
  next unless is_present?(attr)
139
+
139
140
  str << if (attr == :chaddr) && (self.hlen == 6)
140
- Inspect.inspect_attribute(attr, Eth::MacAddr.new.read(self[:chaddr][0, 6]), 2)
141
+ Inspect.inspect_attribute(attr, Eth::MacAddr.new.read(self[:chaddr][0, 6]), 1)
141
142
  else
142
- Inspect.inspect_attribute(attr, self[attr], 2)
143
+ Inspect.inspect_attribute(attr, self[attr], 1)
143
144
  end
144
145
  end
145
146
  str
@@ -62,8 +62,6 @@ module PacketGen
62
62
  # @author Sylvain Daubert
63
63
  class DUID_LLT < DUID
64
64
  delete_field :body
65
- undef body
66
- undef body=
67
65
 
68
66
  # Base time for time computation
69
67
  BASE_TIME = Time.utc(2000, 1, 1)
@@ -102,8 +100,6 @@ module PacketGen
102
100
  # @author Sylvain Daubert
103
101
  class DUID_EN < DUID
104
102
  delete_field :body
105
- undef body
106
- undef body=
107
103
 
108
104
  # @!attribute en
109
105
  # 32-bit entreprise number
@@ -124,8 +120,6 @@ module PacketGen
124
120
  # @author Sylvain Daubert
125
121
  class DUID_LL < DUID
126
122
  delete_field :body
127
- undef body
128
- undef body=
129
123
 
130
124
  # @!attribute htype
131
125
  # 16-bit hardware protocol type
@@ -135,8 +135,6 @@ module PacketGen
135
135
  TYPE = 1
136
136
 
137
137
  delete_field :data
138
- undef data
139
- undef data=
140
138
 
141
139
  # @!attribute duid
142
140
  # @return [DUID]
@@ -163,8 +161,6 @@ module PacketGen
163
161
  TYPE = 3
164
162
 
165
163
  delete_field :data
166
- undef data
167
- undef data=
168
164
 
169
165
  # @!attribute iaid
170
166
  # 32-bit IAID field
@@ -198,8 +194,6 @@ module PacketGen
198
194
  TYPE = 4
199
195
 
200
196
  delete_field :data
201
- undef data
202
- undef data=
203
197
 
204
198
  # @!attribute iaid
205
199
  # 32-bit IAID field
@@ -225,8 +219,6 @@ module PacketGen
225
219
  TYPE = 5
226
220
 
227
221
  delete_field :data
228
- undef data
229
- undef data=
230
222
 
231
223
  # @attribute ipv6
232
224
  # IPv6 address
@@ -267,8 +259,6 @@ module PacketGen
267
259
  TYPE = 6
268
260
 
269
261
  delete_field :data
270
- undef data
271
- undef data=
272
262
 
273
263
  # @!attribute options
274
264
  # @return [RequestedOptions]
@@ -298,8 +288,6 @@ module PacketGen
298
288
  TYPE = 7
299
289
 
300
290
  delete_field :data
301
- undef data
302
- undef data=
303
291
 
304
292
  # @!attribute value
305
293
  # 8-bit value
@@ -320,8 +308,6 @@ module PacketGen
320
308
  TYPE = 8
321
309
 
322
310
  delete_field :data
323
- undef data
324
- undef data=
325
311
 
326
312
  # @!attribute value
327
313
  # 16-bit value
@@ -349,8 +335,6 @@ module PacketGen
349
335
  TYPE = 12
350
336
 
351
337
  delete_field :data
352
- undef data
353
- undef data=
354
338
 
355
339
  # @!attribute addr
356
340
  # IPv6 server address
@@ -378,8 +362,6 @@ module PacketGen
378
362
  TYPE = 14
379
363
 
380
364
  delete_field :data
381
- undef data
382
- undef data=
383
365
  end
384
366
  end
385
367
  end
@@ -250,21 +250,21 @@ module PacketGen
250
250
 
251
251
  # @return [String]
252
252
  def inspect
253
- str = Inspect.dashed_line(self.class, 2)
253
+ str = Inspect.dashed_line(self.class, 1)
254
254
  fields.each do |attr|
255
255
  if attr == :u16
256
256
  flags = %i[qr aa tc rd ra].select! { |flag| send "#{flag}?" }
257
257
  .map(&:to_s).join(',')
258
- str << Inspect.shift_level(2)
258
+ str << Inspect.shift_level(1)
259
259
  str << Inspect::FMT_ATTR % ['Flags', 'flags', flags]
260
- opcode = '%-10s (%u)' % [OPCODES.key(self.opcode), self.opcode]
261
- str << Inspect.shift_level(2)
260
+ opcode = '%-16s (%u)' % [OPCODES.key(self.opcode), self.opcode]
261
+ str << Inspect.shift_level(1)
262
262
  str << Inspect::FMT_ATTR % ['Integer', 'opcode', opcode]
263
- rcode = '%-10s (%u)' % [RCODES.key(self.rcode), self.rcode]
264
- str << Inspect.shift_level(2)
263
+ rcode = '%-16s (%u)' % [RCODES.key(self.rcode), self.rcode]
264
+ str << Inspect.shift_level(1)
265
265
  str << Inspect::FMT_ATTR % ['Integer', 'rcode', rcode]
266
266
  else
267
- str << Inspect.inspect_attribute(attr, self[attr], 2)
267
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
268
268
  end
269
269
  end
270
270
  str
@@ -40,6 +40,7 @@ module PacketGen
40
40
  # @return [PPI] self
41
41
  def read(str)
42
42
  return self if str.nil?
43
+
43
44
  force_binary str
44
45
  self[:version].read str[0, 1]
45
46
  self[:flags].read str[1, 1]
@@ -102,6 +103,7 @@ module PacketGen
102
103
  # @return [RadioTap] self
103
104
  def read(str)
104
105
  return self if str.nil?
106
+
105
107
  force_binary str
106
108
  self[:version].read str[0, 1]
107
109
  self[:pad].read str[1, 1]
@@ -331,6 +333,7 @@ module PacketGen
331
333
 
332
334
  if self.class == Dot11
333
335
  return self if str.nil?
336
+
334
337
  force_binary str
335
338
  self[:frame_ctrl].read str[0, 2]
336
339
 
@@ -372,16 +375,18 @@ module PacketGen
372
375
  # @return [String]
373
376
  def inspect
374
377
  str = if self.class == Dot11
375
- Inspect.dashed_line("#{self.class} #{human_type}", 2)
378
+ Inspect.dashed_line("#{self.class} #{human_type}", 1)
376
379
  elsif self.respond_to? :human_subtype
377
- Inspect.dashed_line("#{self.class} #{human_subtype}", 2)
380
+ Inspect.dashed_line("#{self.class} #{human_subtype}", 1)
378
381
  else
379
- Inspect.dashed_line(self.class.to_s, 2)
382
+ Inspect.dashed_line(self.class.to_s, 1)
380
383
  end
384
+
381
385
  define_applicable_fields
382
386
  @applicable_fields.each do |attr|
383
387
  next if attr == :body
384
- str << Inspect.inspect_attribute(attr, @fields[attr], 2)
388
+
389
+ str << Inspect.inspect_attribute(attr, @fields[attr], 1)
385
390
  end
386
391
  str
387
392
  end
@@ -403,6 +408,7 @@ module PacketGen
403
408
  # @return [void]
404
409
  def added_to_packet(packet)
405
410
  return if packet.respond_to? :dot11
411
+
406
412
  packet.instance_eval("def dot11(arg=nil); header(#{self.class}, arg); end")
407
413
  end
408
414
 
@@ -45,9 +45,9 @@ module PacketGen
45
45
  # @return [String]
46
46
  def inspect
47
47
  str = super
48
- str << Inspect.dashed_line('Dot11 Elements', 3)
48
+ str << Inspect.dashed_line('Dot11 Elements', 2)
49
49
  @elements.each do |el|
50
- str << Inspect.shift_level(4) << el.to_human << "\n"
50
+ str << Inspect.shift_level(2) << el.to_human << "\n"
51
51
  end
52
52
  str
53
53
  end
@@ -14,7 +14,6 @@ module PacketGen
14
14
  # @since 2.1.4
15
15
  class MD5 < EAP
16
16
  delete_field :body
17
- undef body
18
17
 
19
18
  # @!attribute value_size
20
19
  # @return [Integer] 8-bit value size
@@ -51,19 +51,20 @@ module PacketGen
51
51
 
52
52
  # @return [String]
53
53
  def inspect
54
- str = Inspect.dashed_line(self.class, 2)
54
+ str = Inspect.dashed_line(self.class, 1)
55
55
  fields.each do |attr|
56
56
  next if attr == :body
57
- next unless is_present?(attr)
57
+ next unless present?(attr)
58
+
58
59
  if attr == :flags
59
- shift = Inspect.shift_level(2)
60
+ shift = Inspect.shift_level(1)
60
61
  value = %i[l m s].map { |f| send("#{f}?") ? f.to_s : '.' }.join
61
- value = '%-10s (0x%02x)' % [value, self.flags]
62
+ value = '%-16s (0x%02x)' % [value, self.flags]
62
63
  str << shift
63
64
  str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
64
65
  attr, value]
65
66
  else
66
- str << Inspect.inspect_attribute(attr, self[attr], 2)
67
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
67
68
  end
68
69
  end
69
70
  str
@@ -55,20 +55,21 @@ module PacketGen
55
55
 
56
56
  # @return [String]
57
57
  def inspect
58
- str = Inspect.dashed_line(self.class, 2)
58
+ str = Inspect.dashed_line(self.class, 1)
59
59
  fields.each do |attr|
60
60
  next if attr == :body
61
61
  next unless is_present?(attr)
62
+
62
63
  if attr == :flags
63
- shift = Inspect.shift_level(2)
64
+ shift = Inspect.shift_level(1)
64
65
  value = %i[l m s].map { |f| send("#{f}?") ? f.to_s : '.' }.join
65
- value = '%-10s (0x%02x)' % [value, self.flags]
66
+ value = '%-16s (0x%02x)' % [value, self.flags]
66
67
  str << shift
67
68
  str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
68
69
  attr, value]
69
70
  str << Inspect::FMT_ATTR % ['', 'version', self.version]
70
71
  else
71
- str << Inspect.inspect_attribute(attr, self[attr], 2)
72
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
72
73
  end
73
74
  end
74
75
  str
@@ -189,9 +189,10 @@ module PacketGen
189
189
 
190
190
  # @return [String]
191
191
  def inspect
192
- str = Inspect.dashed_line(self.class, 2)
192
+ str = Inspect.dashed_line(self.class, )
193
193
  fields.each do |attr|
194
194
  next if attr == :body
195
+
195
196
  case attr
196
197
  when :flags
197
198
  str_flags = ''.dup
@@ -71,17 +71,17 @@ module PacketGen
71
71
 
72
72
  # @return [String]
73
73
  def inspect
74
- str = Inspect.dashed_line(self.class, 2)
74
+ str = Inspect.dashed_line(self.class, 1)
75
75
  fields.each do |attr|
76
76
  case attr
77
77
  when :body
78
78
  next
79
79
  when :encoding
80
- str << Inspect.shift_level(2)
80
+ str << Inspect.shift_level(1)
81
81
  str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr,
82
82
  human_encoding]
83
83
  else
84
- str << Inspect.inspect_attribute(attr, self[attr], 2)
84
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
85
85
  end
86
86
  end
87
87
  str
@@ -52,16 +52,16 @@ module PacketGen
52
52
 
53
53
  # @return [String]
54
54
  def inspect
55
- str = Inspect.dashed_line(self.class, 2)
55
+ str = Inspect.dashed_line(self.class, 1)
56
56
  fields.each do |attr|
57
57
  case attr
58
58
  when :body
59
59
  next
60
60
  when :content
61
- str << Inspect.shift_level(2)
61
+ str << Inspect.shift_level(1)
62
62
  str << Inspect::FMT_ATTR % ['hashes', :content, human_content]
63
63
  else
64
- str << Inspect.inspect_attribute(attr, self[attr], 2)
64
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
65
65
  end
66
66
  end
67
67
  str
@@ -160,15 +160,16 @@ module PacketGen
160
160
 
161
161
  # @return [String]
162
162
  def inspect
163
- str = Inspect.dashed_line(self.class, 2)
163
+ str = Inspect.dashed_line(self.class, 1)
164
164
  fields.each do |attr|
165
165
  next if attr == :body
166
+
166
167
  if %i[protocol message_type].include? attr
167
- str << Inspect.shift_level(2)
168
+ str << Inspect.shift_level(1)
168
169
  str << Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''), attr,
169
170
  send("human_#{attr}")]
170
171
  else
171
- str << Inspect.inspect_attribute(attr, self[attr], 2)
172
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
172
173
  end
173
174
  end
174
175
  str
@@ -529,7 +529,6 @@ module PacketGen
529
529
  PAYLOAD_TYPE = 33
530
530
 
531
531
  delete_field :content
532
- undef content
533
532
 
534
533
  # @!attribute proposals
535
534
  # Set of SA proposals
@@ -221,7 +221,6 @@ module PacketGen
221
221
  PAYLOAD_TYPE = 44
222
222
 
223
223
  delete_field :content
224
- undef content
225
224
 
226
225
  # @!attribute num_ts
227
226
  # 8-bit Number of TSs
@@ -84,7 +84,7 @@ module PacketGen
84
84
  define_field :length, Types::Int16, default: 20
85
85
  # @!attribute id
86
86
  # @return [Integer] 16-bit ID
87
- define_field :id, Types::Int16, default: -> { rand(65_535) }
87
+ define_field :id, Types::Int16, default: ->(h) { rand(65_535) }
88
88
  # @!attribute frag
89
89
  # @return [Integer] 16-bit frag word
90
90
  define_field :frag, Types::Int16, default: 0
@@ -235,11 +235,12 @@ module PacketGen
235
235
 
236
236
  # @return [String]
237
237
  def inspect
238
- str = Inspect.dashed_line(self.class, 2)
239
- shift = Inspect.shift_level(2)
238
+ str = Inspect.dashed_line(self.class, 1)
239
+ shift = Inspect.shift_level(1)
240
240
  fields.each do |attr|
241
241
  next if attr == :body
242
- str << Inspect.inspect_attribute(attr, self[attr], 2)
242
+
243
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
243
244
  if attr == :u8
244
245
  str << shift + Inspect::FMT_ATTR % ['', 'version', version]
245
246
  str << shift + Inspect::FMT_ATTR % ['', 'ihl', ihl]
@@ -110,9 +110,7 @@ module PacketGen
110
110
  # End-of-option-List IP option
111
111
  class EOL < Option
112
112
  delete_field :length
113
- undef length
114
113
  delete_field :data
115
- undef data
116
114
  end
117
115
 
118
116
  # No OPeration IP option
@@ -122,7 +120,6 @@ module PacketGen
122
120
  # Loose Source and Record Route IP option
123
121
  class LSRR < Option
124
122
  delete_field :data
125
- undef data
126
123
 
127
124
  # @!attribute pointer
128
125
  # 8-bit pointer on next address
@@ -169,7 +166,6 @@ module PacketGen
169
166
  # Stream Identifier IP option
170
167
  class SI < Option
171
168
  delete_field :data
172
- undef data
173
169
 
174
170
  # @!attribute id
175
171
  # 16-bit stream ID
@@ -180,7 +176,6 @@ module PacketGen
180
176
  # Router Alert IP option
181
177
  class RA < Option
182
178
  delete_field :data
183
- undef data
184
179
 
185
180
  # @!attribute value
186
181
  # 16-bit value. Should be 0.
@@ -137,10 +137,11 @@ module PacketGen
137
137
 
138
138
  # @return [String]
139
139
  def inspect
140
- str = Inspect.dashed_line(self.class, 2)
140
+ str = Inspect.dashed_line(self.class, 1)
141
141
  fields.each do |attr|
142
142
  next if attr == :body
143
- str << Inspect.inspect_attribute(attr, self[attr], 2)
143
+
144
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
144
145
  if attr == :u32
145
146
  shift = Inspect.shift_level(2)
146
147
  str << shift + Inspect::FMT_ATTR % ['', 'version', version]
@@ -93,8 +93,8 @@ module PacketGen
93
93
  # @return [Integer] calculated length
94
94
  def calc_length
95
95
  length = self[:body].sz
96
- length += self[:src_name].sz if is_present?(:src_name)
97
- length += self[:dst_name].sz if is_present?(:dst_name)
96
+ length += self[:src_name].sz if present?(:src_name)
97
+ length += self[:dst_name].sz if present?(:dst_name)
98
98
  self.dgm_length = length
99
99
  end
100
100
  end
@@ -280,13 +280,13 @@ module PacketGen
280
280
 
281
281
  def inspect
282
282
  str = super
283
- str << Inspect.shift_level(2)
283
+ str << Inspect.shift_level(1)
284
284
  if self[:data].chosen.nil?
285
285
  str << Inspect::FMT_ATTR % [self[:data].type, :data, '']
286
286
  else
287
287
  data = self[:data]
288
288
  str << Inspect::FMT_ATTR % [data.type, :data, data.chosen_value.type]
289
- str << Inspect.dashed_line('ASN.1 content', 2)
289
+ str << Inspect.dashed_line('ASN.1 content', 1)
290
290
  str << data.chosen_value.inspect(1)
291
291
  begin
292
292
  str << Inspect.inspect_body(self[:message].to_der, 'ASN.1 DER')
@@ -78,7 +78,7 @@ module PacketGen
78
78
  # @!attribute seqnum
79
79
  # 32-bit TCP sequence number
80
80
  # @return [Integer]
81
- define_field :seqnum, Types::Int32, default: -> { rand(2**32) }
81
+ define_field :seqnum, Types::Int32, default: ->(h) { rand(2**32) }
82
82
  # @!attribute acknum
83
83
  # 32-bit TCP acknowledgement number
84
84
  # @return [Integer]
@@ -206,11 +206,12 @@ module PacketGen
206
206
 
207
207
  # @return [String]
208
208
  def inspect
209
- str = Inspect.dashed_line(self.class, 2)
210
- shift = Inspect.shift_level(2)
209
+ str = Inspect.dashed_line(self.class, 1)
210
+ shift = Inspect.shift_level(1)
211
211
  fields.each do |attr|
212
212
  next if attr == :body
213
- str << Inspect.inspect_attribute(attr, self[attr], 2)
213
+
214
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
214
215
  if attr == :u16
215
216
  doff = Inspect.int_dec_hex(data_offset, 1)
216
217
  str << shift + Inspect::FMT_ATTR % ['', 'data_offset', doff]
@@ -138,7 +138,6 @@ module PacketGen
138
138
  # TFTP Read Request header
139
139
  class RRQ < TFTP
140
140
  delete_field :body
141
- undef body
142
141
 
143
142
  # @!attribute filename
144
143
  # Filename to access
@@ -165,7 +164,6 @@ module PacketGen
165
164
  # TFTP ACK header
166
165
  class ACK < TFTP
167
166
  delete_field :body
168
- undef body
169
167
 
170
168
  # @!attribute block_num
171
169
  # 16-bit block number
@@ -176,7 +174,6 @@ module PacketGen
176
174
  # TFTP ERROR header
177
175
  class ERROR < TFTP
178
176
  delete_field :body
179
- undef body
180
177
 
181
178
  # @!attribute error_code
182
179
  # 16-bit error code
@@ -14,7 +14,7 @@ module PacketGen
14
14
  MAX_WIDTH = 70
15
15
 
16
16
  # Format to inspect attribute
17
- FMT_ATTR = "%12s %12s: %s\n"
17
+ FMT_ATTR = "%14s %16s: %s\n"
18
18
 
19
19
  # Create a dashed line with +obj+ class writing in it
20
20
  # @param [String] name
@@ -34,7 +34,7 @@ module PacketGen
34
34
  # @param [Integer] hexsize
35
35
  # @return [String]
36
36
  def self.int_dec_hex(value, hexsize)
37
- "%-10s (0x%0#{hexsize}x)" % [value.to_i, value.to_i]
37
+ "%-16s (0x%0#{hexsize}x)" % [value.to_i, value.to_i]
38
38
  end
39
39
 
40
40
  # Format an attribute for +#inspect+.
@@ -49,16 +49,21 @@ module PacketGen
49
49
  # @return [String]
50
50
  def self.inspect_attribute(attr, value, level=1)
51
51
  str = shift_level(level)
52
- val = if value.is_a?(Types::Enum)
53
- "%-10s (0x%0#{value.sz * 2}x)" % [value.to_human, value.to_i]
54
- elsif value.is_a?(Types::Int) || value.is_a?(Integer)
52
+ val = case value
53
+ when Types::Enum
54
+ "%-16s (0x%0#{value.sz * 2}x)" % [value.to_human, value.to_i]
55
+ when Types::Int
55
56
  int_dec_hex(value, value.sz * 2)
56
- elsif value.is_a?(String)
57
+ when Integer
58
+ int_dec_hex(value, value.sz * 2)
59
+ when String
57
60
  value.to_s.inspect
58
- elsif value.respond_to? :to_human
59
- value.to_human
60
61
  else
61
- value.to_s.inspect
62
+ if value.respond_to? :to_human
63
+ value.to_human
64
+ else
65
+ value.to_s.inspect
66
+ end
62
67
  end
63
68
  str << FMT_ATTR % [value.class.to_s.sub(/.*::/, ''), attr, val]
64
69
  end
@@ -80,7 +85,7 @@ module PacketGen
80
85
  val = case attr
81
86
  when RASN1::Types::Enumerated
82
87
  hexsize = attr.value_size * 2
83
- "%-10s (0x%0#{hexsize}x)" % [attr.value, attr.to_i]
88
+ "%-16s (0x%0#{hexsize}x)" % [attr.value, attr.to_i]
84
89
  when RASN1::Types::Integer
85
90
  int_dec_hex(attr.value, attr.value_size * 2)
86
91
  when RASN1::Model
@@ -95,6 +100,7 @@ module PacketGen
95
100
  # @return [String]
96
101
  def self.inspect_body(body, name='Body')
97
102
  return '' if body.nil? || body.empty?
103
+
98
104
  str = dashed_line(name, 2)
99
105
  str << (0..15).to_a.map { |v| ' %02d' % v }.join << "\n"
100
106
  str << '-' * MAX_WIDTH << "\n"
@@ -143,7 +143,7 @@ module PacketGen
143
143
  def add(protocol, options={})
144
144
  klass = check_protocol(protocol)
145
145
 
146
- header = klass.new(options)
146
+ header = klass.new(options.merge!(packet: self))
147
147
  add_header header
148
148
  self
149
149
  end
@@ -158,7 +158,7 @@ module PacketGen
158
158
  klass = check_protocol(protocol)
159
159
 
160
160
  nxt = prev.body
161
- header = klass.new(options)
161
+ header = klass.new(options.merge!(packet: self))
162
162
  add_header header, previous_header: prev
163
163
  idx = @headers.index(prev) + 1
164
164
  @headers[idx, 0] = header
@@ -422,7 +422,7 @@ module PacketGen
422
422
  def guess_first_header(binary_str)
423
423
  first_header = nil
424
424
  Header.all.each do |hklass|
425
- hdr = hklass.new
425
+ hdr = hklass.new(packet: self)
426
426
  # #read may return another object (more specific class)
427
427
  hdr = hdr.read(binary_str)
428
428
  # First header is found when:
@@ -446,7 +446,7 @@ module PacketGen
446
446
  break if last_known_hdr.body.empty?
447
447
  search_header(last_known_hdr) do |nh|
448
448
  str = last_known_hdr.body
449
- nheader = nh.new
449
+ nheader = nh.new(packet: self)
450
450
  nheader = nheader.read(str)
451
451
  next unless nheader.parse?
452
452
  add_header nheader, parsing: true
@@ -99,7 +99,7 @@ module PacketGen
99
99
  # @private
100
100
  @field_defs = {}
101
101
  # @private
102
- @bit_fields = []
102
+ @bit_fields = {}
103
103
 
104
104
  # On inheritage, create +@field_defs+ class variable
105
105
  # @param [Class] klass
@@ -132,7 +132,8 @@ module PacketGen
132
132
  # @param [Object] type class or instance
133
133
  # @param [Hash] options Unrecognized options are passed to object builder if
134
134
  # +:builder+ option is not set.
135
- # @option options [Object] :default default value
135
+ # @option options [Object] :default default value. May be a proc. This lambda
136
+ # take one argument: the caller object.
136
137
  # @option options [Lambda] :builder lambda to construct this field.
137
138
  # Parameters to this lambda is the caller object and the field type class.
138
139
  # @option options [Lambda] :optional define this field as optional. Given lambda
@@ -180,9 +181,11 @@ module PacketGen
180
181
  def self.define_field_before(other, name, type, options={})
181
182
  define_field name, type, options
182
183
  return if other.nil?
184
+
183
185
  @ordered_fields.delete name
184
186
  idx = @ordered_fields.index(other)
185
187
  raise ArgumentError, "unknown #{other} field" if idx.nil?
188
+
186
189
  @ordered_fields[idx, 0] = name
187
190
  end
188
191
 
@@ -197,9 +200,11 @@ module PacketGen
197
200
  def self.define_field_after(other, name, type, options={})
198
201
  define_field name, type, options
199
202
  return if other.nil?
203
+
200
204
  @ordered_fields.delete name
201
205
  idx = @ordered_fields.index(other)
202
206
  raise ArgumentError, "unknown #{other} field" if idx.nil?
207
+
203
208
  @ordered_fields[idx + 1, 0] = name
204
209
  end
205
210
 
@@ -209,6 +214,8 @@ module PacketGen
209
214
  def self.delete_field(name)
210
215
  @ordered_fields.delete name
211
216
  @field_defs.delete name
217
+ undef_method name
218
+ undef_method "#{name}="
212
219
  end
213
220
 
214
221
  # Define a bitfield on given attribute
@@ -233,16 +240,19 @@ module PacketGen
233
240
  def self.define_bit_fields_on(attr, *args)
234
241
  attr_def = @field_defs[attr]
235
242
  raise ArgumentError, "unknown #{attr} field" if attr_def.nil?
243
+
236
244
  type = attr_def.first
237
245
  unless type < Types::Int
238
246
  raise TypeError, "#{attr} is not a PacketGen::Types::Int"
239
247
  end
248
+
240
249
  total_size = type.new.width * 8
241
250
  idx = total_size - 1
242
251
 
243
252
  field = args.shift
244
253
  while field
245
254
  next unless field.is_a? Symbol
255
+
246
256
  size = if args.first.is_a? Integer
247
257
  args.shift
248
258
  else
@@ -277,7 +287,8 @@ module PacketGen
277
287
  METHODS
278
288
  end
279
289
 
280
- @bit_fields << field
290
+ @bit_fields[attr] = {} if @bit_fields[attr].nil?
291
+ @bit_fields[attr][field] = size
281
292
  end
282
293
 
283
294
  idx -= size
@@ -294,7 +305,7 @@ module PacketGen
294
305
 
295
306
  self.class.class_eval { @field_defs }.each do |field, ary|
296
307
  type, default, builder, optional, enum, field_options = ary
297
- default = default.call if default.is_a?(Proc)
308
+ default = default.to_proc.call(self) if default.is_a?(Proc)
298
309
  @fields[field] = if builder
299
310
  builder.call(self, type)
300
311
  elsif enum
@@ -325,8 +336,10 @@ module PacketGen
325
336
 
326
337
  @optional_fields[field] = optional if optional
327
338
  end
328
- self.class.class_eval { @bit_fields }.each do |bit_field|
329
- self.send "#{bit_field}=", options[bit_field] if options[bit_field]
339
+ self.class.class_eval { @bit_fields }.each do |_, hsh|
340
+ hsh.each_key do |bit_field|
341
+ self.send "#{bit_field}=", options[bit_field] if options[bit_field]
342
+ end
330
343
  end
331
344
  end
332
345
 
@@ -358,26 +371,42 @@ module PacketGen
358
371
 
359
372
  # Say if this field is optional
360
373
  # @return [Boolean]
361
- def is_optional?(field)
374
+ def optional?(field)
362
375
  @optional_fields.key? field
363
376
  end
364
377
 
378
+ # @deprecated Use {#optional?} instead.
379
+ def is_optional?(field)
380
+ Deprecation.deprecated(self.class, __method__, 'optional?', klass_method: true)
381
+ optional? field
382
+ end
383
+
365
384
  # Say if an optional field is present
366
385
  # @return [Boolean]
367
- def is_present?(field)
368
- return true unless is_optional?(field)
386
+ def present?(field)
387
+ return true unless optional?(field)
388
+
369
389
  @optional_fields[field].call(self)
370
390
  end
371
391
 
392
+ # Say if an optional field is present
393
+ # @return [Boolean]
394
+ def is_present?(field)
395
+ Deprecation.deprecated(self.class, __method__, 'present?', klass_method: true)
396
+ present? field
397
+ end
398
+
372
399
  # Populate object from a binary string
373
400
  # @param [String] str
374
401
  # @return [Fields] self
375
402
  def read(str)
376
403
  return self if str.nil?
404
+
377
405
  force_binary str
378
406
  start = 0
379
407
  fields.each do |field|
380
- next unless is_present?(field)
408
+ next unless present?(field)
409
+
381
410
  obj = nil
382
411
  if self[field].respond_to? :width
383
412
  width = self[field].width
@@ -400,11 +429,12 @@ module PacketGen
400
429
  # Common inspect method for headers
401
430
  # @return [String]
402
431
  def inspect
403
- str = Inspect.dashed_line(self.class, 2)
432
+ str = Inspect.dashed_line(self.class, 1)
404
433
  fields.each do |attr|
405
434
  next if attr == :body
406
- next unless is_present?(attr)
407
- str << Inspect.inspect_attribute(attr, self[attr], 2)
435
+ next unless present?(attr)
436
+
437
+ str << Inspect.inspect_attribute(attr, self[attr], 1)
408
438
  end
409
439
  str
410
440
  end
@@ -412,7 +442,7 @@ module PacketGen
412
442
  # Return object as a binary string
413
443
  # @return [String]
414
444
  def to_s
415
- fields.select { |f| is_present?(f) }
445
+ fields.select { |f| present?(f) }
416
446
  .map! { |f| force_binary @fields[f].to_s }.join
417
447
  end
418
448
 
@@ -435,6 +465,7 @@ module PacketGen
435
465
  # @raise [ArgumentError] cannot cram +body+ in +:body+ field
436
466
  def body=(value)
437
467
  raise BodyError, 'no body field' unless @fields.key? :body
468
+
438
469
  case body
439
470
  when ::String
440
471
  self[:body].read value
@@ -460,14 +491,24 @@ module PacketGen
460
491
  # @raise [ArgumentError] unknown field
461
492
  def offset_of(field)
462
493
  raise ArgumentError, "#{field} is an unknown field of #{self.class}" unless @fields.include?(field)
494
+
463
495
  offset = 0
464
496
  fields.each do |f|
465
497
  break offset if f == field
466
- next unless is_present?(f)
498
+ next unless present?(f)
499
+
467
500
  offset += self[f].sz
468
501
  end
469
502
  end
470
503
 
504
+ # Get bit fields definition for given field.
505
+ # @param [Symbol] field defining bit fields
506
+ # @return [Hash,nil] keys: bit fields, values: their size in bits
507
+ # @since 2.8.3
508
+ def bits_on(field)
509
+ self.class.class_eval { @bit_fields }[field]
510
+ end
511
+
471
512
  private
472
513
 
473
514
  # Deeply duplicate +@fields+
@@ -56,6 +56,7 @@ module PacketGen
56
56
  unless defined? @packstr
57
57
  raise StandardError, 'PacketGen::Types::Int#to_s is an abstract method'
58
58
  end
59
+
59
60
  [to_i].pack(@packstr[@endian])
60
61
  end
61
62
 
@@ -79,7 +80,7 @@ module PacketGen
79
80
  end
80
81
  end
81
82
 
82
- # One byte integer
83
+ # One byte unsigned integer
83
84
  # @author Sylvain Daubert
84
85
  class Int8 < Int
85
86
  # @param [Integer,nil] value
@@ -89,7 +90,18 @@ module PacketGen
89
90
  end
90
91
  end
91
92
 
92
- # 2-byte integer
93
+ # One byte signed integer
94
+ # @author Sylvain Daubert
95
+ # @since 2.8.2
96
+ class SInt8 < Int
97
+ # @param [Integer,nil] value
98
+ def initialize(value=nil)
99
+ super(value, nil, 1)
100
+ @packstr = { nil => 'c' }
101
+ end
102
+ end
103
+
104
+ # 2-byte unsigned integer
93
105
  # @author Sylvain Daubert
94
106
  class Int16 < Int
95
107
  # @param [Integer,nil] value
@@ -100,13 +112,13 @@ module PacketGen
100
112
  end
101
113
  end
102
114
 
103
- # big endian 2-byte integer
115
+ # big endian 2-byte unsigned integer
104
116
  # @author Sylvain Daubert
105
117
  class Int16be < Int16
106
118
  undef endian=
107
119
  end
108
120
 
109
- # little endian 2-byte integer
121
+ # little endian 2-byte unsigned integer
110
122
  # @author Sylvain Daubert
111
123
  class Int16le < Int16
112
124
  # @param [Integer,nil] value
@@ -118,7 +130,39 @@ module PacketGen
118
130
  end
119
131
  end
120
132
 
121
- # 3-byte integer
133
+ # 2-byte signed integer
134
+ # @author Sylvain Daubert
135
+ # @since 2.8.2
136
+ class SInt16 < Int16
137
+ # @param [Integer,nil] value
138
+ # @param [:big, :little] endian
139
+ def initialize(value=nil, endian=:big)
140
+ super
141
+ @packstr = { big: 's>', little: 's<' }
142
+ end
143
+ end
144
+
145
+ # big endian 2-byte signed integer
146
+ # @author Sylvain Daubert
147
+ # @since 2.8.2
148
+ class SInt16be < SInt16
149
+ undef endian=
150
+ end
151
+
152
+ # little endian 2-byte signed integer
153
+ # @author Sylvain Daubert
154
+ # @since 2.8.2
155
+ class SInt16le < SInt16
156
+ # @param [Integer,nil] value
157
+ undef endian=
158
+
159
+ # @param [Integer, nil] value
160
+ def initialize(value=nil)
161
+ super(value, :little)
162
+ end
163
+ end
164
+
165
+ # 3-byte unsigned integer
122
166
  # @author Sylvain Daubert
123
167
  # @since 2.1.4
124
168
  class Int24 < Int
@@ -133,6 +177,7 @@ module PacketGen
133
177
  # @return [self]
134
178
  def read(value)
135
179
  return self if value.nil?
180
+
136
181
  @value = if value.is_a?(Integer)
137
182
  value.to_i
138
183
  else
@@ -159,14 +204,14 @@ module PacketGen
159
204
  end
160
205
  end
161
206
 
162
- # big endian 3-byte integer
207
+ # big endian 3-byte unsigned integer
163
208
  # @author Sylvain Daubert
164
209
  # @since 2.1.4
165
210
  class Int24be < Int24
166
211
  undef endian=
167
212
  end
168
213
 
169
- # little endian 3-byte integer
214
+ # little endian 3-byte unsigned integer
170
215
  # @author Sylvain Daubert
171
216
  # @since 2.1.4
172
217
  class Int24le < Int24
@@ -179,7 +224,7 @@ module PacketGen
179
224
  end
180
225
  end
181
226
 
182
- # 4-byte integer
227
+ # 4-byte unsigned integer
183
228
  # @author Sylvain Daubert
184
229
  class Int32 < Int
185
230
  # @param [Integer,nil] value
@@ -190,13 +235,13 @@ module PacketGen
190
235
  end
191
236
  end
192
237
 
193
- # big endian 4-byte integer
238
+ # big endian 4-byte unsigned integer
194
239
  # @author Sylvain Daubert
195
240
  class Int32be < Int32
196
241
  undef endian=
197
242
  end
198
243
 
199
- # little endian 4-byte integer
244
+ # little endian 4-byte unsigned integer
200
245
  # @author Sylvain Daubert
201
246
  class Int32le < Int32
202
247
  # @param [Integer,nil] value
@@ -208,7 +253,39 @@ module PacketGen
208
253
  end
209
254
  end
210
255
 
211
- # 8-byte integer
256
+ # 4-byte unsigned integer
257
+ # @author Sylvain Daubert
258
+ # @since 2.8.2
259
+ class SInt32 < Int32
260
+ # @param [Integer,nil] value
261
+ # @param [:big, :little] endian
262
+ def initialize(value=nil, endian=:big)
263
+ super
264
+ @packstr = { big: 'l>', little: 'l<' }
265
+ end
266
+ end
267
+
268
+ # big endian 4-byte unsigned integer
269
+ # @author Sylvain Daubert
270
+ # @since 2.8.2
271
+ class SInt32be < SInt32
272
+ undef endian=
273
+ end
274
+
275
+ # little endian 4-byte unsigned integer
276
+ # @author Sylvain Daubert
277
+ # @since 2.8.2
278
+ class SInt32le < SInt32
279
+ # @param [Integer,nil] value
280
+ undef endian=
281
+
282
+ # @param [Integer, nil] value
283
+ def initialize(value=nil)
284
+ super(value, :little)
285
+ end
286
+ end
287
+
288
+ # 8-byte unsigned integer
212
289
  # @author Sylvain Daubert
213
290
  class Int64 < Int
214
291
  # @param [Integer,nil] value
@@ -219,13 +296,13 @@ module PacketGen
219
296
  end
220
297
  end
221
298
 
222
- # big endian 8-byte integer
299
+ # big endian 8-byte unsigned integer
223
300
  # @author Sylvain Daubert
224
301
  class Int64be < Int64
225
302
  undef endian=
226
303
  end
227
304
 
228
- # little endian 8-byte integer
305
+ # little endian 8-byte unsigned integer
229
306
  # @author Sylvain Daubert
230
307
  class Int64le < Int64
231
308
  # @param [Integer,nil] value
@@ -236,5 +313,37 @@ module PacketGen
236
313
  super(value, :little)
237
314
  end
238
315
  end
316
+
317
+ # 8-byte unsigned integer
318
+ # @author Sylvain Daubert
319
+ # @since 2.8.2
320
+ class SInt64 < Int64
321
+ # @param [Integer,nil] value
322
+ # @param [:big, :little] endian
323
+ def initialize(value=nil, endian=:big)
324
+ super
325
+ @packstr = { big: 'q>', little: 'q<' }
326
+ end
327
+ end
328
+
329
+ # big endian 8-byte unsigned integer
330
+ # @author Sylvain Daubert
331
+ # @since 2.8.2
332
+ class SInt64be < SInt64
333
+ undef endian=
334
+ end
335
+
336
+ # little endian 8-byte unsigned integer
337
+ # @author Sylvain Daubert
338
+ # @since 2.8.2
339
+ class SInt64le < SInt64
340
+ # @param [Integer,nil] value
341
+ undef endian=
342
+
343
+ # @param [Integer, nil] value
344
+ def initialize(value=nil)
345
+ super(value, :little)
346
+ end
347
+ end
239
348
  end
240
349
  end
@@ -10,5 +10,5 @@
10
10
  # @author Sylvain Daubert
11
11
  module PacketGen
12
12
  # PacketGen version
13
- VERSION = '2.8.1'
13
+ VERSION = '2.8.3'
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: 2.8.1
4
+ version: 2.8.3
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-09-16 00:00:00.000000000 Z
11
+ date: 2018-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: interfacez