packetgen 3.3.3 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -21
  3. data/lib/packetgen/capture.rb +2 -2
  4. data/lib/packetgen/config.rb +0 -1
  5. data/lib/packetgen/deprecation.rb +7 -7
  6. data/lib/packetgen/header/arp.rb +13 -13
  7. data/lib/packetgen/header/asn1_base.rb +1 -1
  8. data/lib/packetgen/header/base.rb +17 -18
  9. data/lib/packetgen/header/bootp.rb +32 -34
  10. data/lib/packetgen/header/dhcp/option.rb +19 -19
  11. data/lib/packetgen/header/dhcp/options.rb +1 -1
  12. data/lib/packetgen/header/dhcp.rb +3 -3
  13. data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
  14. data/lib/packetgen/header/dhcpv6/option.rb +53 -53
  15. data/lib/packetgen/header/dhcpv6/options.rb +1 -1
  16. data/lib/packetgen/header/dhcpv6/relay.rb +5 -5
  17. data/lib/packetgen/header/dhcpv6.rb +6 -6
  18. data/lib/packetgen/header/dns/name.rb +14 -10
  19. data/lib/packetgen/header/dns/opt.rb +2 -2
  20. data/lib/packetgen/header/dns/option.rb +11 -11
  21. data/lib/packetgen/header/dns/qdsection.rb +1 -1
  22. data/lib/packetgen/header/dns/question.rb +6 -8
  23. data/lib/packetgen/header/dns/rr.rb +56 -43
  24. data/lib/packetgen/header/dns/rrsection.rb +4 -4
  25. data/lib/packetgen/header/dns.rb +27 -30
  26. data/lib/packetgen/header/dot11/control.rb +11 -11
  27. data/lib/packetgen/header/dot11/data.rb +20 -20
  28. data/lib/packetgen/header/dot11/element.rb +4 -4
  29. data/lib/packetgen/header/dot11/management.rb +8 -8
  30. data/lib/packetgen/header/dot11/sub_mngt.rb +39 -53
  31. data/lib/packetgen/header/dot11.rb +88 -93
  32. data/lib/packetgen/header/dot1q.rb +10 -12
  33. data/lib/packetgen/header/dot1x.rb +9 -9
  34. data/lib/packetgen/header/eap/fast.rb +4 -4
  35. data/lib/packetgen/header/eap/md5.rb +6 -6
  36. data/lib/packetgen/header/eap/tls.rb +13 -15
  37. data/lib/packetgen/header/eap/ttls.rb +13 -15
  38. data/lib/packetgen/header/eap.rb +22 -22
  39. data/lib/packetgen/header/eth.rb +18 -18
  40. data/lib/packetgen/header/gre.rb +8 -10
  41. data/lib/packetgen/header/http/headers.rb +2 -2
  42. data/lib/packetgen/header/http/request.rb +17 -16
  43. data/lib/packetgen/header/http/response.rb +18 -17
  44. data/lib/packetgen/header/http/verbs.rb +1 -3
  45. data/lib/packetgen/header/icmp.rb +8 -8
  46. data/lib/packetgen/header/icmpv6.rb +3 -3
  47. data/lib/packetgen/header/igmp.rb +8 -8
  48. data/lib/packetgen/header/igmpv3/group_record.rb +12 -12
  49. data/lib/packetgen/header/igmpv3/mq.rb +16 -18
  50. data/lib/packetgen/header/igmpv3/mr.rb +4 -4
  51. data/lib/packetgen/header/igmpv3.rb +7 -7
  52. data/lib/packetgen/header/ip/addr.rb +13 -13
  53. data/lib/packetgen/header/ip/option.rb +31 -33
  54. data/lib/packetgen/header/ip/options.rb +1 -1
  55. data/lib/packetgen/header/ip.rb +37 -72
  56. data/lib/packetgen/header/ipv6/addr.rb +14 -14
  57. data/lib/packetgen/header/ipv6/extension.rb +8 -8
  58. data/lib/packetgen/header/ipv6/hop_by_hop.rb +9 -9
  59. data/lib/packetgen/header/ipv6.rb +20 -22
  60. data/lib/packetgen/header/llc.rb +17 -17
  61. data/lib/packetgen/header/mdns.rb +1 -1
  62. data/lib/packetgen/header/mld.rb +6 -6
  63. data/lib/packetgen/header/mldv2/mcast_address_record.rb +11 -11
  64. data/lib/packetgen/header/mldv2/mlq.rb +21 -23
  65. data/lib/packetgen/header/mldv2/mlr.rb +8 -8
  66. data/lib/packetgen/header/ospfv2/db_description.rb +11 -12
  67. data/lib/packetgen/header/ospfv2/hello.rb +11 -11
  68. data/lib/packetgen/header/ospfv2/ls_ack.rb +1 -1
  69. data/lib/packetgen/header/ospfv2/ls_request.rb +9 -9
  70. data/lib/packetgen/header/ospfv2/ls_update.rb +3 -3
  71. data/lib/packetgen/header/ospfv2/lsa.rb +54 -58
  72. data/lib/packetgen/header/ospfv2/lsa_header.rb +9 -9
  73. data/lib/packetgen/header/ospfv2.rb +27 -29
  74. data/lib/packetgen/header/ospfv3/db_description.rb +13 -14
  75. data/lib/packetgen/header/ospfv3/hello.rb +12 -12
  76. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +17 -19
  77. data/lib/packetgen/header/ospfv3/ls_ack.rb +2 -2
  78. data/lib/packetgen/header/ospfv3/ls_request.rb +9 -9
  79. data/lib/packetgen/header/ospfv3/ls_update.rb +4 -4
  80. data/lib/packetgen/header/ospfv3/lsa.rb +48 -51
  81. data/lib/packetgen/header/ospfv3/lsa_header.rb +9 -9
  82. data/lib/packetgen/header/ospfv3.rb +25 -27
  83. data/lib/packetgen/header/sctp/chunk.rb +44 -41
  84. data/lib/packetgen/header/sctp/error.rb +52 -52
  85. data/lib/packetgen/header/sctp/parameter.rb +38 -38
  86. data/lib/packetgen/header/sctp.rb +5 -5
  87. data/lib/packetgen/header/snmp.rb +2 -2
  88. data/lib/packetgen/header/tcp/option.rb +45 -39
  89. data/lib/packetgen/header/tcp/options.rb +2 -2
  90. data/lib/packetgen/header/tcp.rb +55 -44
  91. data/lib/packetgen/header/tftp.rb +16 -16
  92. data/lib/packetgen/header/udp.rb +8 -8
  93. data/lib/packetgen/header.rb +9 -10
  94. data/lib/packetgen/headerable.rb +13 -3
  95. data/lib/packetgen/inspect.rb +2 -2
  96. data/lib/packetgen/packet.rb +54 -37
  97. data/lib/packetgen/pcap.rb +15 -4
  98. data/lib/packetgen/pcapng/block.rb +18 -17
  99. data/lib/packetgen/pcapng/epb.rb +13 -15
  100. data/lib/packetgen/pcapng/file.rb +3 -97
  101. data/lib/packetgen/pcapng/idb.rb +9 -11
  102. data/lib/packetgen/pcapng/shb.rb +13 -15
  103. data/lib/packetgen/pcapng/spb.rb +8 -10
  104. data/lib/packetgen/pcapng/unknown_block.rb +6 -17
  105. data/lib/packetgen/pcapng.rb +4 -4
  106. data/lib/packetgen/pcaprub_wrapper.rb +17 -1
  107. data/lib/packetgen/proto.rb +1 -1
  108. data/lib/packetgen/unknown_packet.rb +2 -2
  109. data/lib/packetgen/utils/arp_spoofer.rb +18 -19
  110. data/lib/packetgen/utils.rb +2 -2
  111. data/lib/packetgen/version.rb +1 -1
  112. data/lib/packetgen.rb +4 -3
  113. metadata +29 -38
  114. data/lib/packetgen/types/abstract_tlv.rb +0 -278
  115. data/lib/packetgen/types/array.rb +0 -287
  116. data/lib/packetgen/types/cstring.rb +0 -109
  117. data/lib/packetgen/types/enum.rb +0 -171
  118. data/lib/packetgen/types/fieldable.rb +0 -66
  119. data/lib/packetgen/types/fields.rb +0 -622
  120. data/lib/packetgen/types/int.rb +0 -473
  121. data/lib/packetgen/types/int_string.rb +0 -102
  122. data/lib/packetgen/types/length_from.rb +0 -54
  123. data/lib/packetgen/types/oui.rb +0 -52
  124. data/lib/packetgen/types/string.rb +0 -97
  125. data/lib/packetgen/types/tlv.rb +0 -161
  126. data/lib/packetgen/types.rb +0 -26
@@ -61,20 +61,20 @@ module PacketGen
61
61
  # @param [Hash] options specific options for +protocol+
62
62
  # @return [Packet]
63
63
  def self.gen(protocol, options={})
64
- self.new.add protocol, options
64
+ self.new.add(protocol, options)
65
65
  end
66
66
 
67
67
  # Parse a binary string and generate a Packet from it.
68
68
  # # auto-detect first header
69
- # Packet.parse str
69
+ # Packet.parse(str)
70
70
  # # force decoding a Ethernet header for first header
71
- # Packet.parse str, first_header: 'Eth'
71
+ # Packet.parse(str, first_header: 'Eth')
72
72
  # @param [String] binary_str
73
73
  # @param [String,nil] first_header First protocol header. +nil+ means discover it!
74
74
  # @return [Packet]
75
75
  # @raise [ArgumentError] +first_header+ is an unknown header
76
76
  def self.parse(binary_str, first_header: nil)
77
- new.parse binary_str, first_header: first_header
77
+ new.parse(binary_str, first_header: first_header)
78
78
  end
79
79
 
80
80
  # Capture packets from wire.
@@ -112,16 +112,23 @@ module PacketGen
112
112
  Pcap.read(filename)
113
113
  end
114
114
 
115
- # Write packets to +filename+
115
+ # Write packets to +filename+, as pcap or PcapNG file
116
116
  #
117
117
  # For more options, see {PcapNG::File}.
118
118
  # @param [String] filename
119
119
  # @param [Array<Packet>] packets packets to write
120
120
  # @return [void]
121
+ # @since 4.0.0 write a pcap file if filename extension is +.pcap+
122
+ # @author Sylvain Daubert
123
+ # @author LemonTree55 (pcap)
121
124
  def self.write(filename, packets)
122
- pf = PcapNG::File.new
123
- pf.array_to_file packets
124
- pf.to_f filename
125
+ if filename.end_with?('.pcap')
126
+ Pcap.write(filename, packets)
127
+ else
128
+ pf = PcapNG::File.new
129
+ pf.read_array(packets)
130
+ pf.to_f(filename)
131
+ end
125
132
  end
126
133
 
127
134
  # @private
@@ -142,7 +149,7 @@ module PacketGen
142
149
  # options[:packet]= self is speedier than options.merge(packet: self)
143
150
  options[:packet] = self
144
151
  header = klass.new(options)
145
- add_header header
152
+ add_header(header)
146
153
  self
147
154
  end
148
155
 
@@ -159,7 +166,7 @@ module PacketGen
159
166
  # options[:packet]= self is speedier than options.merge(packet: self)
160
167
  options[:packet] = self
161
168
  header = klass.new(options)
162
- add_header header, previous_header: prev
169
+ add_header(header, previous_header: prev)
163
170
  idx = headers.index(prev) + 1
164
171
  headers[idx, 0] = header
165
172
  header[:body] = nxt
@@ -173,7 +180,7 @@ module PacketGen
173
180
  # @return [Boolean]
174
181
  # @raise [ArgumentError] unknown protocol
175
182
  def is?(protocol)
176
- klass = check_protocol protocol
183
+ klass = check_protocol(protocol)
177
184
  headers.any?(klass)
178
185
  end
179
186
 
@@ -181,7 +188,7 @@ module PacketGen
181
188
  # @return [void]
182
189
  def calc_checksum
183
190
  headers.reverse_each do |header|
184
- header.calc_checksum if header.respond_to? :calc_checksum
191
+ header.calc_checksum if header.respond_to?(:calc_checksum)
185
192
  end
186
193
  end
187
194
 
@@ -189,21 +196,24 @@ module PacketGen
189
196
  # @return [void]
190
197
  def calc_length
191
198
  headers.reverse_each do |header|
192
- header.calc_length if header.respond_to? :calc_length
199
+ header.calc_length if header.respond_to?(:calc_length)
193
200
  end
194
201
  end
195
202
 
196
203
  # Recalculate all calculatable fields (for now: length and checksum)
197
204
  # @return [void]
205
+ # @author LemonTree55
198
206
  def calc
199
- calc_length
200
- calc_checksum
207
+ headers.reverse_each do |header|
208
+ header.calc_length if header.respond_to?(:calc_length)
209
+ header.calc_checksum if header.respond_to?(:calc_checksum)
210
+ end
201
211
  end
202
212
 
203
213
  # Get packet body
204
214
  # @return [Types]
205
215
  def body
206
- last_header[:body] if last_header.respond_to? :body
216
+ last_header[:body] if last_header.respond_to?(:body)
207
217
  end
208
218
 
209
219
  # Set packet body
@@ -229,7 +239,7 @@ module PacketGen
229
239
  alias write to_f
230
240
 
231
241
  # Send packet on wire. Use first header +#to_w+ method.
232
- # @param [String] iface interface name. Default to first non-loopback interface
242
+ # @param [String,nil] iface interface name. Default to first non-loopback interface
233
243
  # @param [Boolean] calc if +true+, call {#calc} on packet before sending it.
234
244
  # @param [Integer] number number of times to send the packets
235
245
  # @param [Integer,Float] interval time, in seconds, between sending 2 packets
@@ -239,12 +249,12 @@ module PacketGen
239
249
  def to_w(iface=nil, calc: true, number: 1, interval: 1)
240
250
  iface ||= PacketGen.default_iface
241
251
 
242
- if first_header.respond_to? :to_w
252
+ if first_header.respond_to?(:to_w)
243
253
  self.calc if calc
244
254
 
245
255
  number.times do
246
256
  first_header.to_w(iface)
247
- sleep interval if number > 1
257
+ sleep(interval) if number > 1
248
258
  end
249
259
  else
250
260
  type = first_header.protocol_name
@@ -257,12 +267,12 @@ module PacketGen
257
267
  # @param [Boolean] parsing set to +true+ to not update last current header field
258
268
  # from binding with first other's one. Use only when current header field
259
269
  # has its value set accordingly.
260
- # @return [self] +self+ with new headers from +other+
270
+ # @return [self] +self+ updated with new headers from +other+
261
271
  # @raise [BindingError] do not known how to encapsulate
262
272
  # @since 1.1.0
263
273
  def encapsulate(other, parsing: false)
264
274
  other.headers.each_with_index do |h, i|
265
- add_header h, parsing: i.positive? || parsing
275
+ add_header(h, parsing: i.positive? || parsing)
266
276
  end
267
277
  end
268
278
 
@@ -286,8 +296,8 @@ module PacketGen
286
296
 
287
297
  # Parse a binary string and populate Packet from it.
288
298
  # @param [String] binary_str
289
- # @param [String,nil] first_header First protocol header. +nil+ means discover it!
290
- # @return [Packet] self
299
+ # @param [String,nil] first_header First protocol header name. +nil+ means discover it!
300
+ # @return [self]
291
301
  # @raise [ParseError] +first_header+ is an unknown header
292
302
  # @raise [BindingError] unknwon binding between some headers
293
303
  def parse(binary_str, first_header: nil)
@@ -299,7 +309,7 @@ module PacketGen
299
309
  raise ParseError, "cannot identify first header in string: #{binary_str.inspect}" if first_header.nil?
300
310
  end
301
311
 
302
- add first_header
312
+ add(first_header)
303
313
  headers[-1, 1] = last_header.read(binary_str)
304
314
 
305
315
  # Decode upper headers recursively
@@ -317,12 +327,14 @@ module PacketGen
317
327
  str << Inspect.inspect_body(body)
318
328
  end
319
329
 
330
+ # Check equality at binary level
320
331
  # @param [Packet] other
321
332
  # @return [Boolean]
322
333
  def ==(other)
323
334
  to_s == other.to_s
324
335
  end
325
336
 
337
+ # +true+ is {#==} is +true+ with another packet, or if +other+ is a protocol name String, whose protocol is in Packet.
326
338
  # @param [Packet] other
327
339
  # @return [Boolean]
328
340
  # @since 3.1.2
@@ -331,13 +343,13 @@ module PacketGen
331
343
  when PacketGen::Packet
332
344
  self == other
333
345
  when String
334
- is? other
346
+ is?(other)
335
347
  else
336
348
  false
337
349
  end
338
350
  end
339
351
 
340
- # Invert all possible fields in packet to create a reply.
352
+ # Invert all possible attributes.in packet to create a reply.
341
353
  # @return [self]
342
354
  # @since 2.7.0
343
355
  def reply!
@@ -363,7 +375,7 @@ module PacketGen
363
375
  def initialize_copy(_other)
364
376
  @headers = headers.map(&:dup)
365
377
  headers.each do |header|
366
- add_magic_header_method header
378
+ add_magic_header_method(header)
367
379
  end
368
380
  invalidate_header_cache
369
381
  end
@@ -410,17 +422,20 @@ module PacketGen
410
422
  end
411
423
 
412
424
  # @overload header(klass, layer=1)
425
+ # Get a header given its class and its layer (example: IP-in-IP encapsulation)
413
426
  # @param [Class] klass
414
427
  # @param [Integer] layer
415
428
  # @overload header(klass, options={})
429
+ # Get a header given its class, and set some attributes
416
430
  # @param [String] klass
417
- # @param [Hash] options
418
- # @raise [ArgumentError] unknown option
419
- # @return [Header::Base]
431
+ # @param [Hash] options attributes to set
432
+ # @raise [ArgumentError] unknown attribute
433
+ # @return [Header::Base,nil]
420
434
  def header(klass, arg)
421
435
  layer = arg.is_a?(Integer) ? arg : 1
422
436
  header = find_header(klass, layer)
423
- return header unless arg.is_a? Hash
437
+ return nil if header.nil?
438
+ return header unless arg.is_a?(Hash)
424
439
 
425
440
  arg.each do |key, value|
426
441
  raise ArgumentError, "unknown #{key} attribute for #{klass}" unless header.respond_to?(:"#{key}=")
@@ -434,12 +449,14 @@ module PacketGen
434
449
  # Get header from cache, or find it in packet
435
450
  # @param [Class] klass
436
451
  # @param [Integer] layer
437
- # @return [Header::Base]
452
+ # @return [Header::Base,nil]
438
453
  def find_header(klass, layer)
439
454
  header = fetch_header_from_cache(klass, layer)
440
455
  return header if header
441
456
 
442
- header = headers.select { |h| h.is_a? klass }[layer - 1]
457
+ header = headers.select { |h| h.is_a?(klass) }[layer - 1]
458
+ return nil if header.nil?
459
+
443
460
  add_header_to_cache(header, klass, layer)
444
461
  header
445
462
  end
@@ -468,9 +485,9 @@ module PacketGen
468
485
  header.packet = self
469
486
  headers << header unless previous_header
470
487
 
471
- return if respond_to? header.method_name
488
+ return if respond_to?(header.method_name)
472
489
 
473
- add_magic_header_method header
490
+ add_magic_header_method(header)
474
491
  end
475
492
 
476
493
  # Bind +header+ to +prev_header+.
@@ -497,7 +514,7 @@ module PacketGen
497
514
 
498
515
  # Try to guess header from +binary_str+
499
516
  # @param [String] binary_str
500
- # @return [String] header/protocol name
517
+ # @return [String,nil] header/protocol name, or nil if cannot be guessed
501
518
  def guess_first_header(binary_str)
502
519
  first_header = nil
503
520
  Header.all.each do |hklass|
@@ -529,7 +546,7 @@ module PacketGen
529
546
  nheader = nheader.read(last_known_hdr.body)
530
547
  next unless nheader.parse?
531
548
 
532
- add_header nheader, parsing: true
549
+ add_header(nheader, parsing: true)
533
550
  break if last_header == last_known_hdr
534
551
  end
535
552
  end
@@ -8,8 +8,7 @@
8
8
  require_relative 'pcaprub_wrapper'
9
9
 
10
10
  module PacketGen
11
- # Module to read PCAP files
12
- # @author Sylvain Daubert
11
+ # Module to read/write PCAP files
13
12
  # @api private
14
13
  # @since 3.1.4
15
14
  module Pcap
@@ -17,14 +16,26 @@ module PacketGen
17
16
  # @param [String] filename
18
17
  # @return [Array<Packet>]
19
18
  # @author Kent Gruber
19
+ # @author LemonTree55
20
20
  def self.read(filename)
21
21
  packets = []
22
- PCAPRUBWrapper.read_pcap(filename: filename) do |packet|
23
- next unless (packet = PacketGen.parse(packet.to_s))
22
+ PCAPRUBWrapper.read_pcap(filename: filename) do |raw_packet|
23
+ packet = PacketGen.parse(raw_packet.to_s)
24
+ next if packet.nil?
24
25
 
25
26
  packets << packet
26
27
  end
27
28
  packets
28
29
  end
30
+
31
+ # Write binary packets to a PCAP file
32
+ # @param [String] filename
33
+ # @param [Array<String>] packets
34
+ # @return [void]
35
+ # @since 4.0.0
36
+ # @author LemonTree55
37
+ def self.write(filename, packets)
38
+ PCAPRUBWrapper.pcap_write(filename, packets.map(&:to_s))
39
+ end
29
40
  end
30
41
  end
@@ -10,63 +10,64 @@ module PacketGen
10
10
  module PcapNG
11
11
  # @abstract Base class for all block types
12
12
  # @author Sylvain Daubert
13
- class Block < Types::Fields
13
+ class Block < BinStruct::Struct
14
14
  # @return [:little, :big]
15
15
  attr_accessor :endian
16
16
 
17
17
  # @!attribute type
18
18
  # 32-bit block type
19
19
  # @return [Integer]
20
- define_field :type, Types::Int32
20
+ define_attr :type, BinStruct::Int32
21
21
  # @!attribute block_len
22
22
  # 32-bit block length
23
23
  # @return [Integer]
24
- define_field :block_len, Types::Int32
25
- # @!attribute block_len
24
+ define_attr :block_len, BinStruct::Int32
25
+ # @!attribute block_len2
26
26
  # 32-bit block length
27
27
  # @return [Integer]
28
- define_field :block_len2, Types::Int32
28
+ define_attr :block_len2, BinStruct::Int32
29
29
 
30
30
  def initialize(options={})
31
31
  super
32
+ endianness(options[:endian] || :little)
33
+ recalc_block_len
32
34
  end
33
35
 
34
36
  # Has this block option?
35
37
  # @return [Boolean]
36
38
  # @since 2.7.0
37
39
  def options?
38
- @fields.key?(:options) && @fields[:options].sz.positive?
40
+ @attributes.key?(:options) && @attributes[:options].sz.positive?
39
41
  end
40
42
 
41
- # Calculate block length and update :block_len and block_len2 fields
43
+ # Calculate block length and update +block_len+ and +block_len2+ fields
42
44
  # @return [void]
43
45
  def recalc_block_len
44
- len = fields.map { |f| @fields[f].to_s }.join.size
46
+ len = attributes.map { |f| @attributes[f].to_s }.join.size
45
47
  self.block_len = self.block_len2 = len
46
48
  end
47
49
 
48
50
  # Pad given field to 32 bit boundary, if needed
49
- # @param [Array<Symbol>] fields block fields to pad
51
+ # @param [Array<Symbol>] fields fields to pad
50
52
  # @return [void]
53
+ # @author LemonTree55
51
54
  def pad_field(*fields)
52
55
  fields.each do |field|
53
- obj = @fields[field]
54
- pad_size = (obj.sz % 4).zero? ? 0 : (4 - (obj.sz % 4))
55
- obj << "\x00" * pad_size
56
+ obj = @attributes[field]
57
+ obj << "\x00" * -(obj.sz % -4)
56
58
  end
57
59
  end
58
60
 
59
61
  private
60
62
 
61
63
  # Set the endianness for the various Int classes handled by self.
62
- # Must be called by all subclass #initialize method.
63
64
  # @param [:little, :big] endian
64
65
  # @return [:little, :big] returns endian
65
66
  def endianness(endian)
66
67
  raise ArgumentError, "unknown endianness for #{self.class}" unless %i[little big].include?(endian)
67
68
 
68
69
  @endian = endian
69
- @fields.each_value { |v| v.endian = endian if v.is_a?(Types::Int) }
70
+ @attributes.each_value { |v| v.endian = endian if v.is_a?(BinStruct::Int) }
70
71
  endian
71
72
  end
72
73
 
@@ -75,19 +76,19 @@ module PacketGen
75
76
  end
76
77
 
77
78
  def to_io(str_or_io)
78
- return str_or_io if str_or_io.respond_to? :read
79
+ return str_or_io if str_or_io.respond_to?(:read)
79
80
 
80
81
  StringIO.new(force_binary(str_or_io.to_s))
81
82
  end
82
83
 
83
84
  def remove_padding(io, data_len)
84
85
  data_pad_len = (4 - (data_len % 4)) % 4
85
- io.read data_pad_len
86
+ io.read(data_pad_len)
86
87
  data_pad_len
87
88
  end
88
89
 
89
90
  def read_blocklen2_and_check(io)
90
- self[:block_len2].read io.read(4)
91
+ self[:block_len2].read(io.read(4))
91
92
  check_len_coherency
92
93
  end
93
94
  end
@@ -34,29 +34,29 @@ module PacketGen
34
34
  # @!attribute interface_id
35
35
  # 32-bit interface ID
36
36
  # @return [Integer]
37
- define_field_before :block_len2, :interface_id, Types::Int32, default: 0
37
+ define_attr_before :block_len2, :interface_id, BinStruct::Int32, default: 0
38
38
  # @!attribute tsh
39
39
  # high 32-bit timestamp value
40
40
  # @return [Integer]
41
- define_field_before :block_len2, :tsh, Types::Int32, default: 0
41
+ define_attr_before :block_len2, :tsh, BinStruct::Int32, default: 0
42
42
  # @!attribute tsl
43
43
  # low 32-bit imestamp value
44
44
  # @return [Integer]
45
- define_field_before :block_len2, :tsl, Types::Int32, default: 0
45
+ define_attr_before :block_len2, :tsl, BinStruct::Int32, default: 0
46
46
  # @!attribute cap_len
47
47
  # 32-bit capture length
48
48
  # @return [Integer]
49
- define_field_before :block_len2, :cap_len, Types::Int32, default: 0
49
+ define_attr_before :block_len2, :cap_len, BinStruct::Int32, default: 0
50
50
  # @!attribute orig_len
51
51
  # 32-bit original length
52
52
  # @return [Integer]
53
- define_field_before :block_len2, :orig_len, Types::Int32, default: 0
53
+ define_attr_before :block_len2, :orig_len, BinStruct::Int32, default: 0
54
54
  # @!attribute data
55
- # @return [Types::String]
56
- define_field_before :block_len2, :data, Types::String
55
+ # @return [BinStruct::String]
56
+ define_attr_before :block_len2, :data, BinStruct::String
57
57
  # @!attribute options
58
- # @return [Types::String]
59
- define_field_before :block_len2, :options, Types::String
58
+ # @return [BinStruct::String]
59
+ define_attr_before :block_len2, :options, BinStruct::String
60
60
 
61
61
  # @param [Hash] options
62
62
  # @option options [:little, :big] :endian set block endianness
@@ -74,8 +74,6 @@ module PacketGen
74
74
  # @option options [Integer] :block_len2 block total length
75
75
  def initialize(options={})
76
76
  super
77
- endianness(options[:endian] || :little)
78
- recalc_block_len
79
77
  self.type = options[:type] || PcapNG::EPB_TYPE.to_i
80
78
  end
81
79
 
@@ -87,9 +85,9 @@ module PacketGen
87
85
  return self if io.eof?
88
86
 
89
87
  %i[type block_len interface_id tsh tsl cap_len orig_len].each do |attr|
90
- self[attr].read io.read(self[attr].sz)
88
+ self[attr].read(io.read(self[attr].sz))
91
89
  end
92
- self[:data].read io.read(self.cap_len)
90
+ self[:data].read(io.read(self.cap_len))
93
91
  read_options(io)
94
92
  read_blocklen2_and_check(io)
95
93
 
@@ -115,7 +113,7 @@ module PacketGen
115
113
  # Return the object as a String
116
114
  # @return [String]
117
115
  def to_s
118
- pad_field :data, :options
116
+ pad_field(:data, :options)
119
117
  recalc_block_len
120
118
  super
121
119
  end
@@ -133,7 +131,7 @@ module PacketGen
133
131
  def read_options(io)
134
132
  data_pad_len = remove_padding(io, self.cap_len)
135
133
  options_len = self.block_len - self.cap_len - data_pad_len - MIN_SIZE
136
- self[:options].read io.read(options_len)
134
+ self[:options].read(io.read(options_len))
137
135
  end
138
136
  end
139
137
  end
@@ -140,35 +140,6 @@ module PacketGen
140
140
  @sections.clear
141
141
  end
142
142
 
143
- # @deprecated
144
- # Prefer use of {#to_a} or {#to_h}.
145
- # Translates a {File} into an array of packets.
146
- # @param [Hash] options
147
- # @option options [String] :file if given, object is cleared and filename
148
- # is analyzed before generating array. Else, array is generated from +self+
149
- # @option options [Boolean] :keep_timestamps if +true+ (default value: +false+),
150
- # generates an array of hashes, each one with timestamp as key and packet
151
- # as value. There is one hash per packet.
152
- # @return [Array<Packet>,Array<Hash>]
153
- def file_to_array(options={})
154
- Deprecation.deprecated(self.class, __method__)
155
-
156
- file = options[:file] || options[:filename]
157
- reread file
158
-
159
- ary = []
160
- blk = if options[:keep_timestamps] || options[:keep_ts]
161
- proc { |pkt| { pkt.timestamp => pkt.data.to_s } }
162
- else
163
- proc { |pkt| pkt.data.to_s }
164
- end
165
- each_packet_with_interface do |pkt, _itf|
166
- ary << blk.call(pkt)
167
- end
168
-
169
- ary
170
- end
171
-
172
143
  # Translates a {File} into an array of packets.
173
144
  # @return [Array<Packet>]
174
145
  # @since 3.1.6
@@ -223,41 +194,6 @@ module PacketGen
223
194
  self.to_file(filename.to_s, append: true)
224
195
  end
225
196
 
226
- # @deprecated Prefer use of {#read_array} or {#read_hash}.
227
- # @overload array_to_file(ary)
228
- # Update {File} object with packets.
229
- # @param [Array] ary as generated by {#file_to_array} or Array of Packet objects.
230
- # Update {File} object without writing file on disk
231
- # @return [self]
232
- # @overload array_to_file(options={})
233
- # Update {File} and/or write it to a file
234
- # @param [Hash] options
235
- # @option options [String] :file file written on disk only if given
236
- # @option options [Array] :array can either be an array of packet data,
237
- # or a hash-value pair of timestamp => data.
238
- # @option options [Time] :timestamp set an initial timestamp
239
- # @option options [Integer] :ts_inc set the increment between timestamps.
240
- # Defaults to 1
241
- # @option options [Boolean] :append if +true+, append packets to the end of
242
- # the file
243
- # @return [Array] see return value from {#to_file}
244
- def array_to_file(options={})
245
- filename, ary, ts, ts_inc, append = array_to_file_options(options)
246
-
247
- section = create_new_shb_section
248
-
249
- ary.each do |pkt|
250
- classify_block(section, epb_from_pkt(pkt, section, ts))
251
- ts += ts_inc
252
- end
253
-
254
- if filename
255
- self.to_f(filename, append: append)
256
- else
257
- self
258
- end
259
- end
260
-
261
197
  # Update current object from an array of packets
262
198
  # @param [Array<Packet>] packets
263
199
  # @param [Time, nil] timestamp initial timestamp, used for first packet
@@ -335,13 +271,13 @@ module PacketGen
335
271
  # @param [IO] io stream from which parse SHB
336
272
  # @return [SHB]
337
273
  def parse_shb(shb, io)
338
- type = Types::Int32.new(0, shb.endian).read(io.read(4))
274
+ type = BinStruct::Int32.new(value: 0, endian: shb.endian).read(io.read(4))
339
275
  io.seek(-4, IO::SEEK_CUR)
340
276
  parse(type, io, shb)
341
277
  end
342
278
 
343
279
  # Parse a block from its type
344
- # @param [Types::Int32] type
280
+ # @param [BinStruct::Int32] type
345
281
  # @param [IO] io stream from which parse block
346
282
  # @param [SHB] shb header of current section
347
283
  # @return [Block]
@@ -352,7 +288,7 @@ module PacketGen
352
288
  end
353
289
 
354
290
  # Guess class to use from type
355
- # @param [Types::Int] type
291
+ # @param [BinStruct::Int] type
356
292
  # @return [Block]
357
293
  def guess_block_type(type)
358
294
  BLOCK_TYPES.key?(type.to_i) ? BLOCK_TYPES[type.to_i] : UnknownBlock
@@ -376,36 +312,6 @@ module PacketGen
376
312
  end
377
313
  end
378
314
 
379
- def array_to_file_options(options)
380
- case options
381
- when Hash
382
- array_to_file_options_from_hash(options)
383
- when Array
384
- [nil, options, Time.now, 1, false]
385
- else
386
- raise ArgumentError, 'unknown argument. Need either a Hash or Array'
387
- end
388
- end
389
-
390
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
391
- # Extract and check options for #array_to_file
392
- def array_to_file_options_from_hash(options)
393
- %i[filename arr ts].each do |deprecated_opt|
394
- Deprecation.deprecated_option(self.class, :array_to_file, deprecated_opt) if options[deprecated_opt]
395
- end
396
-
397
- filename = options[:filename] || options[:file]
398
- ary = options[:array] || options[:arr]
399
- raise ArgumentError, ':array parameter needs to be an array' unless ary.is_a? Array
400
-
401
- ts = options[:timestamp] || options[:ts] || Time.now
402
- ts_inc = options[:ts_inc] || 1
403
- append = !options[:append].nil?
404
-
405
- [filename, ary, ts, ts_inc, append]
406
- end
407
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
408
-
409
315
  def create_new_shb_section
410
316
  section = SHB.new
411
317
  @sections << section