packetgen 3.3.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -22
  3. data/lib/packetgen/capture.rb +2 -2
  4. data/lib/packetgen/config.rb +0 -1
  5. data/lib/packetgen/deprecation.rb +14 -8
  6. data/lib/packetgen/header/arp.rb +17 -18
  7. data/lib/packetgen/header/asn1_base.rb +2 -1
  8. data/lib/packetgen/header/base.rb +42 -40
  9. data/lib/packetgen/header/bootp.rb +35 -37
  10. data/lib/packetgen/header/dhcp/option.rb +21 -21
  11. data/lib/packetgen/header/dhcp/options.rb +3 -3
  12. data/lib/packetgen/header/dhcp.rb +8 -9
  13. data/lib/packetgen/header/dhcpv6/duid.rb +16 -16
  14. data/lib/packetgen/header/dhcpv6/option.rb +83 -61
  15. data/lib/packetgen/header/dhcpv6/options.rb +4 -4
  16. data/lib/packetgen/header/dhcpv6/relay.rb +6 -5
  17. data/lib/packetgen/header/dhcpv6.rb +17 -18
  18. data/lib/packetgen/header/dns/name.rb +21 -16
  19. data/lib/packetgen/header/dns/opt.rb +5 -2
  20. data/lib/packetgen/header/dns/option.rb +14 -14
  21. data/lib/packetgen/header/dns/qdsection.rb +3 -3
  22. data/lib/packetgen/header/dns/question.rb +7 -8
  23. data/lib/packetgen/header/dns/rr.rb +56 -43
  24. data/lib/packetgen/header/dns/rrsection.rb +6 -6
  25. data/lib/packetgen/header/dns.rb +103 -90
  26. data/lib/packetgen/header/dot11/control.rb +12 -12
  27. data/lib/packetgen/header/dot11/data.rb +25 -24
  28. data/lib/packetgen/header/dot11/element.rb +4 -4
  29. data/lib/packetgen/header/dot11/management.rb +21 -18
  30. data/lib/packetgen/header/dot11/sub_mngt.rb +40 -53
  31. data/lib/packetgen/header/dot11.rb +117 -122
  32. data/lib/packetgen/header/dot1q.rb +12 -13
  33. data/lib/packetgen/header/dot1x.rb +13 -13
  34. data/lib/packetgen/header/eap/fast.rb +4 -4
  35. data/lib/packetgen/header/eap/md5.rb +16 -8
  36. data/lib/packetgen/header/eap/tls.rb +18 -19
  37. data/lib/packetgen/header/eap/ttls.rb +22 -21
  38. data/lib/packetgen/header/eap.rb +73 -48
  39. data/lib/packetgen/header/eth.rb +41 -27
  40. data/lib/packetgen/header/gre.rb +33 -11
  41. data/lib/packetgen/header/http/headers.rb +7 -6
  42. data/lib/packetgen/header/http/request.rb +38 -29
  43. data/lib/packetgen/header/http/response.rb +35 -27
  44. data/lib/packetgen/header/http/verbs.rb +1 -3
  45. data/lib/packetgen/header/icmp.rb +14 -14
  46. data/lib/packetgen/header/icmpv6.rb +10 -9
  47. data/lib/packetgen/header/igmp.rb +26 -15
  48. data/lib/packetgen/header/igmpv3/group_record.rb +18 -13
  49. data/lib/packetgen/header/igmpv3/mq.rb +16 -18
  50. data/lib/packetgen/header/igmpv3/mr.rb +5 -5
  51. data/lib/packetgen/header/igmpv3.rb +12 -11
  52. data/lib/packetgen/header/ip/addr.rb +19 -15
  53. data/lib/packetgen/header/ip/option.rb +47 -36
  54. data/lib/packetgen/header/ip/options.rb +1 -1
  55. data/lib/packetgen/header/ip.rb +77 -95
  56. data/lib/packetgen/header/ipv6/addr.rb +28 -27
  57. data/lib/packetgen/header/ipv6/extension.rb +13 -11
  58. data/lib/packetgen/header/ipv6/hop_by_hop.rb +32 -13
  59. data/lib/packetgen/header/ipv6.rb +42 -35
  60. data/lib/packetgen/header/llc.rb +28 -21
  61. data/lib/packetgen/header/mdns.rb +10 -3
  62. data/lib/packetgen/header/mld.rb +15 -13
  63. data/lib/packetgen/header/mldv2/mcast_address_record.rb +17 -12
  64. data/lib/packetgen/header/mldv2/mlq.rb +22 -24
  65. data/lib/packetgen/header/mldv2/mlr.rb +8 -8
  66. data/lib/packetgen/header/mldv2.rb +1 -1
  67. data/lib/packetgen/header/ospfv2/db_description.rb +17 -18
  68. data/lib/packetgen/header/ospfv2/hello.rb +18 -17
  69. data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
  70. data/lib/packetgen/header/ospfv2/ls_request.rb +14 -13
  71. data/lib/packetgen/header/ospfv2/ls_update.rb +9 -9
  72. data/lib/packetgen/header/ospfv2/lsa.rb +79 -60
  73. data/lib/packetgen/header/ospfv2/lsa_header.rb +12 -11
  74. data/lib/packetgen/header/ospfv2.rb +49 -46
  75. data/lib/packetgen/header/ospfv3/db_description.rb +20 -22
  76. data/lib/packetgen/header/ospfv3/hello.rb +17 -16
  77. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +22 -20
  78. data/lib/packetgen/header/ospfv3/ls_ack.rb +7 -8
  79. data/lib/packetgen/header/ospfv3/ls_request.rb +18 -18
  80. data/lib/packetgen/header/ospfv3/ls_update.rb +10 -10
  81. data/lib/packetgen/header/ospfv3/lsa.rb +62 -51
  82. data/lib/packetgen/header/ospfv3/lsa_header.rb +12 -11
  83. data/lib/packetgen/header/ospfv3.rb +54 -52
  84. data/lib/packetgen/header/sctp/chunk.rb +80 -56
  85. data/lib/packetgen/header/sctp/error.rb +174 -202
  86. data/lib/packetgen/header/sctp/padded32.rb +3 -3
  87. data/lib/packetgen/header/sctp/parameter.rb +89 -136
  88. data/lib/packetgen/header/sctp.rb +19 -8
  89. data/lib/packetgen/header/snmp.rb +108 -7
  90. data/lib/packetgen/header/tcp/option.rb +52 -39
  91. data/lib/packetgen/header/tcp/options.rb +13 -5
  92. data/lib/packetgen/header/tcp.rb +83 -65
  93. data/lib/packetgen/header/tftp.rb +31 -25
  94. data/lib/packetgen/header/udp.rb +21 -19
  95. data/lib/packetgen/header.rb +23 -18
  96. data/lib/packetgen/headerable.rb +21 -5
  97. data/lib/packetgen/inspect.rb +3 -8
  98. data/lib/packetgen/packet.rb +146 -71
  99. data/lib/packetgen/pcap.rb +15 -4
  100. data/lib/packetgen/pcapng/block.rb +20 -18
  101. data/lib/packetgen/pcapng/epb.rb +13 -15
  102. data/lib/packetgen/pcapng/file.rb +44 -111
  103. data/lib/packetgen/pcapng/idb.rb +11 -12
  104. data/lib/packetgen/pcapng/shb.rb +15 -16
  105. data/lib/packetgen/pcapng/spb.rb +9 -11
  106. data/lib/packetgen/pcapng/unknown_block.rb +6 -17
  107. data/lib/packetgen/pcapng.rb +6 -4
  108. data/lib/packetgen/pcaprub_wrapper.rb +17 -1
  109. data/lib/packetgen/proto.rb +5 -1
  110. data/lib/packetgen/unknown_packet.rb +5 -5
  111. data/lib/packetgen/utils/arp_spoofer.rb +18 -19
  112. data/lib/packetgen/utils.rb +4 -3
  113. data/lib/packetgen/version.rb +1 -1
  114. data/lib/packetgen.rb +12 -5
  115. metadata +29 -38
  116. data/lib/packetgen/types/abstract_tlv.rb +0 -278
  117. data/lib/packetgen/types/array.rb +0 -287
  118. data/lib/packetgen/types/cstring.rb +0 -109
  119. data/lib/packetgen/types/enum.rb +0 -171
  120. data/lib/packetgen/types/fieldable.rb +0 -66
  121. data/lib/packetgen/types/fields.rb +0 -622
  122. data/lib/packetgen/types/int.rb +0 -473
  123. data/lib/packetgen/types/int_string.rb +0 -102
  124. data/lib/packetgen/types/length_from.rb +0 -54
  125. data/lib/packetgen/types/oui.rb +0 -52
  126. data/lib/packetgen/types/string.rb +0 -97
  127. data/lib/packetgen/types/tlv.rb +0 -161
  128. data/lib/packetgen/types.rb +0 -26
@@ -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
@@ -8,9 +8,24 @@
8
8
 
9
9
  module PacketGen
10
10
  module PcapNG
11
- # PcapNG::File is a complete Pcap-NG file handler.
11
+ # PcapNG::File is a complete Pcap-NG file handler. It provides methods to:
12
+ # * read and write PcapNG files,
13
+ # * process packets from such files.
14
+ #
15
+ # @example Writing a file
16
+ # pkt1 = PacketGen.gen('IP', id: 1).add('TCP')
17
+ # pkt2 = PacketGen.gen('IP', id: 2).add('UDP')
18
+ # file = PacketGen::PcapNG::File.new
19
+ # file.read_array([pkt1, pkt2])
20
+ # file.write('/tmp/file.pcapng')
21
+ #
22
+ # @example Reading a file
23
+ # file = PacketGen::PcapNG::File.new
24
+ # pkts = file.read_packets('/tmp/file.pcapng')
25
+ #
12
26
  # @author Sylvain Daubert
13
- class File # rubocop:disable Metrics/ClassLength
27
+ # @author LemonTree55
28
+ class File
14
29
  # Known link types
15
30
  KNOWN_LINK_TYPES = {
16
31
  LINKTYPE_ETHERNET => 'Eth',
@@ -29,19 +44,19 @@ module PacketGen
29
44
  end.freeze
30
45
 
31
46
  # Get file sections
32
- # @return [Array]
47
+ # @return [Array<SHB>]
33
48
  attr_accessor :sections
34
49
 
35
50
  def initialize
36
51
  @sections = []
37
52
  end
38
53
 
39
- # Read a string to populate the object. Note that this appends new blocks to
54
+ # Read a binary string to populate the object. Note that this appends new blocks to
40
55
  # the Pcapng::File object.
41
56
  # @param [String] str
42
57
  # @return [self]
43
58
  def read(str)
44
- PacketGen.force_binary(str)
59
+ str = str.b unless str.encoding == Encoding::BINARY
45
60
  io = StringIO.new(str)
46
61
  parse_section(io)
47
62
  self
@@ -59,11 +74,19 @@ module PacketGen
59
74
 
60
75
  # Read a given file and analyze it.
61
76
  # If given a block, it will yield PcapNG::EPB or PcapNG::SPB objects.
62
- # This is the only way to get packet timestamps.
77
+ # This is the only way to get packet timestamps (via {EPB#timestamp}).
63
78
  # @param [String] fname pcapng file name
64
79
  # @yieldparam [EPB,SPB] block
65
80
  # @return [Integer] return number of yielded blocks (only if a block is given)
66
81
  # @raise [ArgumentError] cannot read +fname+
82
+ # @example Parse packets and get their timestamp
83
+ # hsh = {}
84
+ # file = PacketGen::PcapNG::File.new
85
+ # file.readfile('/tmp/file.pcapng') do |xpb|
86
+ # ts = xpb.is_a?(PacketGen::PcapNG::EPB) ? xpb.timestamp : nil
87
+ # pkt = PacketGen.parse(xpb.data)
88
+ # hsh[pkt] = ts
89
+ # end
67
90
  def readfile(fname, &blk)
68
91
  raise ArgumentError, "cannot read file #{fname}" unless ::File.readable?(fname)
69
92
 
@@ -140,35 +163,6 @@ module PacketGen
140
163
  @sections.clear
141
164
  end
142
165
 
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
166
  # Translates a {File} into an array of packets.
173
167
  # @return [Array<Packet>]
174
168
  # @since 3.1.6
@@ -197,13 +191,15 @@ module PacketGen
197
191
  end
198
192
 
199
193
  # Writes the {File} to a file.
200
- # @param [Hash] options
201
- # @option options [Boolean] :append (default: +false+) if set to +true+,
194
+ # @param [String] filename file name to write
195
+ # @param [Boolean] append if set to +true+,
202
196
  # the packets are appended to the file, rather than overwriting it
203
- # @return [Array] array of 2 elements: filename and size written
204
- # @todo for 4.0, replace +options+ by +append+ kwarg
205
- def to_file(filename, options={})
206
- mode = options[:append] && ::File.exist?(filename) ? 'ab' : 'wb'
197
+ # @return [Array(String, Integer)] array of 2 elements: filename and size written
198
+ # @since 4.1.0 Options hash with single +:append+ option is replaced by +append+ keyword argument.
199
+ # @see #append
200
+ # @see #write
201
+ def to_file(filename, append: false)
202
+ mode = append && ::File.exist?(filename) ? 'ab' : 'wb'
207
203
  ::File.open(filename, mode) { |f| f.write(self.to_s) }
208
204
  [filename, self.to_s.size]
209
205
  end
@@ -211,53 +207,20 @@ module PacketGen
211
207
 
212
208
  # Shorthand method for writing to a file.
213
209
  # @param [#to_s] filename
214
- # @return [Array] see return value from {#to_file}
210
+ # @return [Array(String, Integer)]
211
+ # @see #to_file
215
212
  def write(filename='out.pcapng')
216
213
  self.to_file(filename.to_s, append: false)
217
214
  end
218
215
 
219
216
  # Shorthand method for appending to a file.
220
217
  # @param [#to_s] filename
221
- # @return [Array] see return value from {#to_file}
218
+ # @return [Array(String, Integer)]
219
+ # @see #to_file
222
220
  def append(filename='out.pcapng')
223
221
  self.to_file(filename.to_s, append: true)
224
222
  end
225
223
 
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
224
  # Update current object from an array of packets
262
225
  # @param [Array<Packet>] packets
263
226
  # @param [Time, nil] timestamp initial timestamp, used for first packet
@@ -335,13 +298,13 @@ module PacketGen
335
298
  # @param [IO] io stream from which parse SHB
336
299
  # @return [SHB]
337
300
  def parse_shb(shb, io)
338
- type = Types::Int32.new(0, shb.endian).read(io.read(4))
301
+ type = BinStruct::Int32.new(value: 0, endian: shb.endian).read(io.read(4))
339
302
  io.seek(-4, IO::SEEK_CUR)
340
303
  parse(type, io, shb)
341
304
  end
342
305
 
343
306
  # Parse a block from its type
344
- # @param [Types::Int32] type
307
+ # @param [BinStruct::Int32] type
345
308
  # @param [IO] io stream from which parse block
346
309
  # @param [SHB] shb header of current section
347
310
  # @return [Block]
@@ -352,7 +315,7 @@ module PacketGen
352
315
  end
353
316
 
354
317
  # Guess class to use from type
355
- # @param [Types::Int] type
318
+ # @param [BinStruct::Int] type
356
319
  # @return [Block]
357
320
  def guess_block_type(type)
358
321
  BLOCK_TYPES.key?(type.to_i) ? BLOCK_TYPES[type.to_i] : UnknownBlock
@@ -376,36 +339,6 @@ module PacketGen
376
339
  end
377
340
  end
378
341
 
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
342
  def create_new_shb_section
410
343
  section = SHB.new
411
344
  @sections << section
@@ -8,7 +8,8 @@
8
8
 
9
9
  module PacketGen
10
10
  module PcapNG
11
- # {IDB} represents a Interface Description Block (IDB) of a pcapng file.
11
+ # {IDB} represents an Interface Description Block (IDB) of a pcapng file. It is associated to a network interfaces.
12
+ # It contains packet data as {EPB} and/or {SPB}.
12
13
  #
13
14
  # == IDB Definition
14
15
  # Int32 :type Default: 0x00000001
@@ -36,18 +37,18 @@ module PacketGen
36
37
  # @!attribute link_type
37
38
  # 16-bit link type
38
39
  # @return [Integer]
39
- define_field_before :block_len2, :link_type, Types::Int16, default: 1
40
+ define_attr_before :block_len2, :link_type, BinStruct::Int16, default: 1
40
41
  # @!attribute reserved
41
42
  # 16-bit reserved field
42
43
  # @return [Integer]
43
- define_field_before :block_len2, :reserved, Types::Int16, default: 0
44
+ define_attr_before :block_len2, :reserved, BinStruct::Int16, default: 0
44
45
  # @!attribute snaplen
45
46
  # 32-bit snap length
46
47
  # @return [Integer]
47
- define_field_before :block_len2, :snaplen, Types::Int32, default: 0
48
+ define_attr_before :block_len2, :snaplen, BinStruct::Int32, default: 0
48
49
  # @!attribute options
49
- # @return [Types::String]
50
- define_field_before :block_len2, :options, Types::String
50
+ # @return [BinStruct::String]
51
+ define_attr_before :block_len2, :options, BinStruct::String
51
52
 
52
53
  # @param [Hash] options
53
54
  # @option options [:little, :big] :endian set block endianness
@@ -61,10 +62,8 @@ module PacketGen
61
62
  # @option options [Integer] :block_len2 block total length
62
63
  def initialize(options={})
63
64
  super
64
- endianness(options[:endian] || :little)
65
65
  @packets = []
66
66
  @options_decoded = false
67
- recalc_block_len
68
67
  self.type = options[:type] || PcapNG::IDB_TYPE.to_i
69
68
  end
70
69
 
@@ -76,9 +75,9 @@ module PacketGen
76
75
  return self if io.eof?
77
76
 
78
77
  %i[type block_len link_type reserved snaplen].each do |attr|
79
- self[attr].read io.read(self[attr].sz)
78
+ self[attr].read(io.read(self[attr].sz))
80
79
  end
81
- self[:options].read io.read(self.block_len - MIN_SIZE)
80
+ self[:options].read(io.read(self.block_len - MIN_SIZE))
82
81
  read_blocklen2_and_check(io)
83
82
 
84
83
  self
@@ -107,7 +106,7 @@ module PacketGen
107
106
  # Return the object as a String
108
107
  # @return [String]
109
108
  def to_s
110
- pad_field :options
109
+ pad_field(:options)
111
110
  recalc_block_len
112
111
  super << @packets.map(&:to_s).join
113
112
  end
@@ -119,7 +118,7 @@ module PacketGen
119
118
  @options_decoded = true
120
119
  return @ts_resol = 1E-6 if tsresol.nil?
121
120
 
122
- @ts_resol = if (tsresol & 0x80).zero?
121
+ @ts_resol = if tsresol.nobits?(0x80)
123
122
  10**-tsresol
124
123
  else
125
124
  2**-(tsresol & 0x7f)
@@ -8,7 +8,8 @@
8
8
 
9
9
  module PacketGen
10
10
  module PcapNG
11
- # {SHB} represents a Section Header Block (SHB) of a pcapng file.
11
+ # {SHB} represents a Section Header Block (SHB) of a pcapng file. A SHB contains {IDB}, which contain
12
+ # {EPB} and/or {SPB}.
12
13
  #
13
14
  # == SHB Definition
14
15
  # Int32 :type Default: 0x0A0D0D0A
@@ -45,23 +46,23 @@ module PacketGen
45
46
  # @!attribute magic
46
47
  # 32-bit magic number
47
48
  # @return [Integer]
48
- define_field_before :block_len2, :magic, Types::Int32, default: MAGIC_INT32
49
+ define_attr_before :block_len2, :magic, BinStruct::Int32, default: MAGIC_INT32
49
50
  # @!attribute ver_major
50
51
  # 16-bit major version number
51
52
  # @return [Integer]
52
- define_field_before :block_len2, :ver_major, Types::Int16, default: 1
53
+ define_attr_before :block_len2, :ver_major, BinStruct::Int16, default: 1
53
54
  # @!attribute ver_major
54
55
  # 16-bit minor version number
55
56
  # @return [Integer]
56
- define_field_before :block_len2, :ver_minor, Types::Int16, default: 0
57
+ define_attr_before :block_len2, :ver_minor, BinStruct::Int16, default: 0
57
58
  # @!attribute section_len
58
59
  # 64-bit section length
59
60
  # @return [Integer]
60
- define_field_before :block_len2, :section_len, Types::Int64,
61
- default: SECTION_LEN_UNDEFINED
61
+ define_attr_before :block_len2, :section_len, BinStruct::Int64,
62
+ default: SECTION_LEN_UNDEFINED
62
63
  # @!attribute options
63
- # @return [Types::String]
64
- define_field_before :block_len2, :options, Types::String
64
+ # @return [BinStruct::String]
65
+ define_attr_before :block_len2, :options, BinStruct::String
65
66
 
66
67
  # @param [Hash] options
67
68
  # @option options [:little, :big] :endian set block endianness
@@ -81,8 +82,6 @@ module PacketGen
81
82
  super
82
83
  @interfaces = []
83
84
  @unknown_blocks = []
84
- endianness(options[:endian] || :little)
85
- recalc_block_len
86
85
  self.type = options[:type] || PcapNG::SHB_TYPE.to_i
87
86
  end
88
87
 
@@ -93,9 +92,9 @@ module PacketGen
93
92
  io = to_io(str_or_io)
94
93
  return self if io.eof?
95
94
 
96
- self[:type].read check_shb(io)
95
+ self[:type].read(check_shb(io))
97
96
  %i[block_len magic ver_major ver_minor section_len].each do |attr|
98
- self[attr].read io.read(self[attr].sz)
97
+ self[attr].read(io.read(self[attr].sz))
99
98
  end
100
99
  handle_magic_and_check(self[:magic].to_s)
101
100
 
@@ -120,7 +119,7 @@ module PacketGen
120
119
  body = @interfaces.map(&:to_s).join
121
120
  self.section_len = body.size unless self.section_len == SECTION_LEN_UNDEFINED
122
121
 
123
- pad_field :options
122
+ pad_field(:options)
124
123
  recalc_block_len
125
124
  super + body
126
125
  end
@@ -135,12 +134,12 @@ module PacketGen
135
134
  def force_endianness(endian)
136
135
  @endian = endian
137
136
  %i[type block_len magic block_len2].each do |attr|
138
- self[attr] = Types::Int32.new(0, endian).read(self[attr].to_s)
137
+ self[attr] = BinStruct::Int32.new(value: 0, endian: endian).read(self[attr].to_s)
139
138
  end
140
139
  %i[ver_major ver_minor].each do |attr|
141
- self[attr] = Types::Int16.new(0, endian).read(self[attr].to_s)
140
+ self[attr] = BinStruct::Int16.new(value: 0, endian: endian).read(self[attr].to_s)
142
141
  end
143
- self[:section_len] = Types::Int64.new(0, endian).read(self[:section_len].to_s)
142
+ self[:section_len] = BinStruct::Int64.new(value: 0, endian: endian).read(self[:section_len].to_s)
144
143
  end
145
144
 
146
145
  # Check io contains a SHB
@@ -8,7 +8,7 @@
8
8
 
9
9
  module PacketGen
10
10
  module PcapNG
11
- # {SPB} represents a Section Simple Packet Block (SPB) of a pcapng file.
11
+ # {SPB} represents a Simple Packet Block (SPB) of a pcapng file.
12
12
  #
13
13
  # == Pcapng::SPB Definition
14
14
  # Int32 :type Default: 0x00000003
@@ -29,10 +29,10 @@ module PacketGen
29
29
  # @!attribute orig_len
30
30
  # 32-bit original length
31
31
  # @return [Integer]
32
- define_field_before :block_len2, :orig_len, Types::Int32, default: 0
32
+ define_attr_before :block_len2, :orig_len, BinStruct::Int32, default: 0
33
33
  # @!attribute data
34
- # @return [Types::String]
35
- define_field_before :block_len2, :data, Types::String
34
+ # @return [BinStruct::String]
35
+ define_attr_before :block_len2, :data, BinStruct::String
36
36
 
37
37
  # @param [Hash] options
38
38
  # @option options [:little, :big] :endian set block endianness
@@ -45,8 +45,6 @@ module PacketGen
45
45
  # @option options [Integer] :block_len2 block total length
46
46
  def initialize(options={})
47
47
  super
48
- endianness(options[:endian] || :little)
49
- recalc_block_len
50
48
  self.type = options[:type] || PcapNG::SPB_TYPE.to_i
51
49
  end
52
50
 
@@ -64,11 +62,11 @@ module PacketGen
64
62
  io = to_io(str_or_io)
65
63
  return self if io.eof?
66
64
 
67
- self[:type].read io.read(4)
68
- self[:block_len].read io.read(4)
69
- self[:orig_len].read io.read(4)
65
+ self[:type].read(io.read(4))
66
+ self[:block_len].read(io.read(4))
67
+ self[:orig_len].read(io.read(4))
70
68
  data_len = compute_data_len
71
- self[:data].read io.read(data_len)
69
+ self[:data].read(io.read(data_len))
72
70
  remove_padding(io, data_len)
73
71
  read_blocklen2_and_check(io)
74
72
 
@@ -79,7 +77,7 @@ module PacketGen
79
77
  # Return the object as a String
80
78
  # @return [String]
81
79
  def to_s
82
- pad_field :data
80
+ pad_field(:data)
83
81
  recalc_block_len
84
82
  super
85
83
  end
@@ -20,19 +20,8 @@ module PacketGen
20
20
  attr_accessor :section
21
21
 
22
22
  # @!attribute body
23
- # @return [Types::String]
24
- define_field_before :block_len2, :body, Types::String
25
-
26
- # @option options [:little, :big] :endian set block endianness
27
- # @option options [Integer] :type
28
- # @option options [Integer] :block_len block total length
29
- # @option options [::String] :body
30
- # @option options [Integer] :block_len2 block total length
31
- def initialize(options={})
32
- super
33
- endianness(options[:endian] || :little)
34
- recalc_block_len
35
- end
23
+ # @return [BinStruct::String]
24
+ define_attr_before :block_len2, :body, BinStruct::String
36
25
 
37
26
  # Has this block options?
38
27
  # @return [false]
@@ -48,9 +37,9 @@ module PacketGen
48
37
  io = to_io(str_or_io)
49
38
  return self if io.eof?
50
39
 
51
- self[:type].read io.read(4)
52
- self[:block_len].read io.read(4)
53
- self[:body].read io.read(self[:block_len].to_i - MIN_SIZE)
40
+ self[:type].read(io.read(4))
41
+ self[:block_len].read(io.read(4))
42
+ self[:body].read(io.read(self[:block_len].to_i - MIN_SIZE))
54
43
  read_blocklen2_and_check(io)
55
44
 
56
45
  self
@@ -59,7 +48,7 @@ module PacketGen
59
48
  # Return the object as a String
60
49
  # @return [String]
61
50
  def to_s
62
- pad_field :body
51
+ pad_field(:body)
63
52
  recalc_block_len
64
53
  super
65
54
  end
@@ -11,16 +11,18 @@ require 'stringio'
11
11
  module PacketGen
12
12
  # Module to handle PCAP-NG file format.
13
13
  # See http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii
14
+ #
15
+ # See {PcapNG::File} to handle Pcap-NG files.
14
16
  # @author Sylvain Daubert
15
17
  module PcapNG
16
18
  # Section Header Block type number
17
- SHB_TYPE = Types::Int32.new(0x0A0D0D0A, :little).freeze
19
+ SHB_TYPE = BinStruct::Int32.new(value: 0x0A0D0D0A, endian: :little).freeze
18
20
  # Interface Description Block type number
19
- IDB_TYPE = Types::Int32.new(1, :little).freeze
21
+ IDB_TYPE = BinStruct::Int32.new(value: 1, endian: :little).freeze
20
22
  # Simple Packet Block type number
21
- SPB_TYPE = Types::Int32.new(3, :little).freeze
23
+ SPB_TYPE = BinStruct::Int32.new(value: 3, endian: :little).freeze
22
24
  # Enhanced Packet Block type number
23
- EPB_TYPE = Types::Int32.new(6, :little).freeze
25
+ EPB_TYPE = BinStruct::Int32.new(value: 6, endian: :little).freeze
24
26
 
25
27
  # IEEE 802.3 Ethernet (10Mb, 100Mb, 1000Mb, and up)
26
28
  LINKTYPE_ETHERNET = 1
@@ -10,6 +10,7 @@ require 'pcaprub'
10
10
  module PacketGen
11
11
  # Wrapper around PCAPRUB
12
12
  # @author Sylvain Daubert
13
+ # @author LemonTree55
13
14
  # @api private
14
15
  # @since 3.1.4
15
16
  module PCAPRUBWrapper
@@ -35,8 +36,9 @@ module PacketGen
35
36
  pcap.setpromisc(promisc)
36
37
  pcap.settimeout(TIMEOUT)
37
38
  # Monitor MUST be set before pcap is activated
38
- pcap.setmonitor monitor unless monitor.nil?
39
+ pcap.setmonitor(monitor) unless monitor.nil?
39
40
  pcap.activate
41
+ pcap
40
42
  end
41
43
 
42
44
  # Capture packets from a network interface
@@ -74,5 +76,19 @@ module PacketGen
74
76
  def self.read_pcap(filename:, &block)
75
77
  PCAPRUB::Pcap.open_offline(filename).each_packet(&block)
76
78
  end
79
+
80
+ # Write binary packets to a PCAP file
81
+ # @param [String] filename
82
+ # @param [Array<String>] packets
83
+ # @return [void]
84
+ # @since 4.0.0
85
+ # @author LemonTree55
86
+ def self.write_pcap(filename:, packets:)
87
+ PCAPRUB::Pcap.dump_open(filename) do |pcap|
88
+ packets.each do |packet|
89
+ pcap.dump(packet)
90
+ end
91
+ end
92
+ end
77
93
  end
78
94
  end
@@ -10,7 +10,7 @@
10
10
  require 'socket'
11
11
 
12
12
  module PacketGen
13
- # Module handling some helper methods for protocols
13
+ # Module handling some helper methods for well_known protocols
14
14
  # @author Sylvain Daubert
15
15
  # @since 2.1.2
16
16
  module Proto
@@ -30,6 +30,8 @@ module PacketGen
30
30
  # Get protocol number from its name
31
31
  # @param [String] name
32
32
  # @return [Integer,nil] return nil for unknown protocol names
33
+ # @example
34
+ # PacketGen::Proto.getprotobyname('tcp') #=> 6
33
35
  def self.getprotobyname(name)
34
36
  @cache[name]
35
37
  end
@@ -37,6 +39,8 @@ module PacketGen
37
39
  # Get protocol name from its number
38
40
  # @param [Integer] num
39
41
  # @return [String,nil] return nil for unknown protocol numbers
42
+ # @example
43
+ # PacketGen::Proto.getprotobynumber(6) #=> 'tcp'
40
44
  def self.getprotobynumber(num)
41
45
  @cache.key(num)
42
46
  end