Class: PacketGen::PcapNG::File

Inherits:
Object
  • Object
show all
Defined in:
lib/packetgen/pcapng/file.rb

Overview

PcapNG::File is a complete Pcap-NG file handler.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFile

Returns a new instance of File.



15
16
17
# File 'lib/packetgen/pcapng/file.rb', line 15

def initialize
  @sections = []
end

Instance Attribute Details

#sectionsArray

Get file sections

Returns:

  • (Array)


13
14
15
# File 'lib/packetgen/pcapng/file.rb', line 13

def sections
  @sections
end

Instance Method Details

#append(filename = 'out.pcapng') ⇒ Array

Shorthand method for appending to a file.

Parameters:

  • filename (#to_s) (defaults to: 'out.pcapng')

Returns:

  • (Array)

    see return value from #to_file



193
194
195
# File 'lib/packetgen/pcapng/file.rb', line 193

def append(filename='out.pcapng')
  self.to_file(filename.to_s, :append => true)
end

#array_to_file(ary) ⇒ self #array_to_file(options = {}) ⇒ Array

Overloads:

  • #array_to_file(ary) ⇒ self

    Update PacketGen::PcapNG::File object with packets.

    Parameters:

    Returns:

    • (self)
  • #array_to_file(options = {}) ⇒ Array

    Update PacketGen::PcapNG::File and/or write it to a file

    Parameters:

    • options (Hash) (defaults to: {})

    Options Hash (options):

    • :filename (String)

      file written on disk only if given

    • :array (Array)

      can either be an array of packet data, or a hash-value pair of timestamp => data.

    • :timestamp (Time)

      set an initial timestamp

    • :ts_inc (Integer)

      set the increment between timestamps. Defaults to 1

    • :append (Boolean)

      if true, append packets to the end of the file

    Returns:

    • (Array)

      see return value from #to_file



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/packetgen/pcapng/file.rb', line 214

def array_to_file(options={})
  case options
  when Hash
    filename = options[:filename] || options[:file]
    ary = options[:array] || options[:arr]
    unless ary.kind_of? Array
      raise ArgumentError, ':array parameter needs to be an array'
    end
    ts = options[:timestamp] || options[:ts] || Time.now
    ts_inc = options[:ts_inc] || 1
    append = !!options[:append]
  when Array
    ary = options
    ts = Time.now
    ts_inc = 1
    filename = nil
    append = false
  else
    raise ArgumentError, 'unknown argument. Need either a Hash or Array'
  end

  section = SHB.new
  @sections << section
  itf = IDB.new(:endian => section.endian)
  classify_block section, itf

  ary.each_with_index do |pkt, i|
    case pkt
    when Hash
      this_ts = pkt.keys.first.to_i
      this_cap_len = pkt.values.first.to_s.size
      this_data = pkt.values.first.to_s
    else
      this_ts = (ts + ts_inc * i).to_i
      this_cap_len = pkt.to_s.size
      this_data = pkt.to_s
    end
    this_ts = (this_ts / itf.ts_resol).to_i
    this_tsh = this_ts >> 32
    this_tsl = this_ts & 0xffffffff
    this_pkt = EPB.new(:endian       => section.endian,
                       :interface_id => 0,
                       :tsh          => this_tsh,
                       :tsl          => this_tsl,
                       :cap_len      => this_cap_len,
                       :orig_len     => this_cap_len,
                       :data         => this_data)
    classify_block section, this_pkt
  end

  if filename
    self.to_f(filename, :append => append)
  else
    self
  end
end

#clearvoid

This method returns an undefined value.

Clear the contents of the Pcapng::File.



129
130
131
# File 'lib/packetgen/pcapng/file.rb', line 129

def clear
  @sections.clear
end

#file_to_array(options = {}) ⇒ Array<Packet>, Array<Hash>

Translates a PacketGen::PcapNG::File into an array of packets. Note that this strips out timestamps – if you’d like to retain timestamps and other pcapng file information, you will want to use #read instead.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :filename (String)

    if given, object is cleared and filename is analyzed before generating array. Else, array is generated from self

  • :file (String)

    same as :filename

  • :keep_timestamps (Boolean)

    if true (default value: false), generates an array of hashes, each one with timestamp as key and packet as value. There is one hash per packet.

  • :keep_ts (Boolean)

    same as :keep_timestamp

Returns:

  • (Array<Packet>, Array<Hash>)


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/packetgen/pcapng/file.rb', line 146

def file_to_array(options={})
  filename = options[:filename] || options[:file]
  if filename
    clear
    readfile filename
  end

  ary = []
  @sections.each do |section|
    section.interfaces.each do |itf|
      if options[:keep_timestamps] || options[:keep_ts]
        ary.concat itf.packets.map { |pkt| { pkt.timestamp => pkt.data.to_s } }
      else
        ary.concat itf.packets.map { |pkt| pkt.data.to_s}
      end
    end
  end
  ary
end

#read(str) ⇒ self

Read a string to populate the object. Note that this appends new blocks to the Pcapng::File object.

Parameters:

  • str (String)

Returns:

  • (self)


23
24
25
26
27
28
# File 'lib/packetgen/pcapng/file.rb', line 23

def read(str)
  PacketGen.force_binary(str)
  io = StringIO.new(str)
  parse_section(io)
  self
end

#read!(str) ⇒ self

Clear the contents of the Pcapng::File prior to reading in a new string. This string should contain a Section Header Block and an Interface Description Block to create a conform pcapng file.

Parameters:

  • str (String)

Returns:

  • (self)


35
36
37
38
# File 'lib/packetgen/pcapng/file.rb', line 35

def read!(str)
  clear
  read(str)
end

#read_packet_bytes(fname) ⇒ Array #read_packet_bytes(fname) {|raw| ... } ⇒ Integer

Give an array of parsed packets (raw data from packets). If a block is given, yield raw packet data from the given file.

Overloads:

  • #read_packet_bytes(fname) ⇒ Array

    Returns array of packet raw data.

    Parameters:

    • fname (String)

      pcapng file name

    Returns:

    • (Array)

      array of packet raw data

  • #read_packet_bytes(fname) {|raw| ... } ⇒ Integer

    Returns number of packets.

    Parameters:

    • fname (String)

      pcapng file name

    Yield Parameters:

    • raw (String)

      packet raw data

    Returns:

    • (Integer)

      number of packets

Raises:

  • (ArgumentError)

    cannot read fname



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/packetgen/pcapng/file.rb', line 79

def read_packet_bytes(fname, &blk)
  count = 0
  packets = [] unless blk

  readfile(fname) do |packet|
    if blk
      count += 1
      yield packet.data.to_s
    else
      packets << packet.data.to_s
    end
  end

  blk ? count : packets
end

#read_packets(fname) ⇒ Array<Packet> #read_packets(fname) {|packet| ... } ⇒ Integer

Return an array of parsed packets. If a block is given, yield parsed packets from the given file.

Overloads:

  • #read_packets(fname) ⇒ Array<Packet>

    Parameters:

    • fname (String)

      pcapng file name

    Returns:

  • #read_packets(fname) {|packet| ... } ⇒ Integer

    Returns number of packets.

    Parameters:

    • fname (String)

      pcapng file name

    Yield Parameters:

    Returns:

    • (Integer)

      number of packets

Raises:

  • (ArgumentError)

    cannot read fname



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/packetgen/pcapng/file.rb', line 105

def read_packets(fname, &blk)
  count = 0
  packets = [] unless blk

  read_packet_bytes(fname) do |packet|
    if blk
      count += 1
      yield Packet.parse(packet)
    else
      packets << Packet.parse(packet)
    end
  end

  blk ? count : packets
end

#readfile(fname) {|block| ... } ⇒ Integer

Read a given file and analyze it. If given a block, it will yield PcapNG::EPB or PcapNG::SPB objects. This is the only way to get packet timestamps.

Parameters:

  • fname (String)

    pcapng file name

Yield Parameters:

Returns:

  • (Integer)

    return number of yielded blocks (only if a block is given)

Raises:

  • (ArgumentError)

    cannot read fname



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/packetgen/pcapng/file.rb', line 47

def readfile(fname, &blk)
  unless ::File.readable?(fname)
    raise ArgumentError, "cannot read file #{fname}"
  end

  ::File.open(fname, 'rb') do |f|
    while !f.eof? do
      parse_section(f)
    end
  end

  if blk
    count = 0
    @sections.each do |section|
      section.interfaces.each do |intf|
        intf.packets.each { |pkt| count += 1; yield pkt }
      end
    end
    count
  end
end

#to_file(filename, options = {}) ⇒ Array Also known as: to_f

Writes the PacketGen::PcapNG::File to a file.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :append (Boolean) — default: default: +false+

    if set to true, the packets are appended to the file, rather than overwriting it

Returns:

  • (Array)

    array of 2 elements: filename and size written



171
172
173
174
175
176
177
178
179
180
# File 'lib/packetgen/pcapng/file.rb', line 171

def to_file(filename, options={})
  mode = ''
  if options[:append] and ::File.exists? filename
    mode = 'ab'
  else
    mode = 'wb'
  end
  ::File.open(filename, mode) {|f| f.write(self.to_s)}
  [filename, self.to_s.size]
end

#to_sString

Return the object as a String

Returns:

  • (String)


123
124
125
# File 'lib/packetgen/pcapng/file.rb', line 123

def to_s
  @sections.map { |section| section.to_s }.join
end

#write(filename = 'out.pcapng') ⇒ Array

Shorthand method for writing to a file.

Parameters:

  • filename (#to_s) (defaults to: 'out.pcapng')

Returns:

  • (Array)

    see return value from #to_file



186
187
188
# File 'lib/packetgen/pcapng/file.rb', line 186

def write(filename='out.pcapng')
  self.to_file(filename.to_s, :append => false)
end