class FFI::PCap::Packet

Attributes

body_ptr[R]
header[R]

Public Class Methods

_load(s) click to toggle source

Unmarshall a marshalled {Packet}

# File lib/ffi/pcap/packet.rb, line 10
def self._load(s)
  time, body = Marshal.load(s)
  self.from_string(body, :timestamp => time)
end
allocate(phdr, buf) click to toggle source

Allocates a {Packet} using new memory. Used primarily for ‘pcap_loop` and `pcap_dispatch` to retain packets after new ones have been received or a pcap device is closed.

# File lib/ffi/pcap/packet.rb, line 34
def self.allocate(phdr, buf)
  new(phdr, buf).copy()
end
from_string(body, opts={}) click to toggle source

Creates a {Packet} from a Ruby string object.

@see new

# File lib/ffi/pcap/packet.rb, line 25
def self.from_string(body, opts={})
  new(nil, body, opts)
end
new(hdr, body, opts={}) click to toggle source

@param [PacketHeader, nil] hdr

The pcap pkthdr struct for this packet or `nil`.  hdr may only be
nil if a string is supplied for the body. A header will be 
created automatically and {#set_body} called with opts.

@param [FFI::Pointer, String] body

A string or pointer for the body of the packet. A String may
only be specified if hdr is set to `nil`.

@param [optional, Hash] opts

Specifies additional options at creation time. Only those
below are applicable for all initiatialization styles.
All other options are sent to {#set_body}, but only if the header
is nil and body is a String. See {#set_body} for more info.

@option opts [optional, Time] :time, :timestamp

Sets the timestamp in the header.

@raise [ArgumentError, TypeError]

An exception is raised if any of the parameter rules described 
are not followed.
# File lib/ffi/pcap/packet.rb, line 61
def initialize(hdr, body, opts={})
  o = opts.dup
  ts = (o.delete(:time) || o.delete(:timestamp))

  case hdr
  when PacketHeader
    if hdr.to_ptr.null?
      raise(ArgumentError,"NULL header pointer",caller)
    end

    @header = hdr
  when ::FFI::Pointer
    if hdr.null?
      raise(ArgumentError, "NULL header pointer",caller)
    end

    @header = PacketHeader.new(hdr)
  when nil 
    if body.is_a?(String)
      set_body(body, o)
    else
      raise(TypeError,"invalid body with nil header: #{body.class}",caller)
    end
  else
    raise(TypeError,"invalid header: #{hdr.class}",caller)
  end

  @header.ts.time = ts if ts

  unless @body_ptr
    if (body.is_a?(FFI::Pointer) && !(body.null?))
      @body_ptr = body
    else
      raise(TypeError,"invalid body for header: #{body.class}",caller)
    end
  end
end

Public Instance Methods

_dump(lv) click to toggle source

Marshal this {Packet}

# File lib/ffi/pcap/packet.rb, line 16
def _dump(lv)
  Marshal.dump([self.time, self.body])
end
body() click to toggle source

@return [String]

A String representation of the packet data.
The reference to the string is not kept by the object and changes
won't affect the data in this packet.
# File lib/ffi/pcap/packet.rb, line 144
def body
  @body_ptr.read_string(@header.caplen)
end
body=(data, opts={})
Alias for: set_body
caplen() click to toggle source
# File lib/ffi/pcap/packet.rb, line 165
def caplen
  @header.caplen
end
Also aliased as: captured
captured()
Alias for: caplen
copy() click to toggle source

An optimized copy which allocates new memory for a {PacketHeader} and body.

DANGEROUS: This method uses direct FFI bindings for the copy and may crash Ruby if the packet header or body is incorrect.

@raise [StandardError]

An exception is raised if the header or body is a `NULL` pointer.
# File lib/ffi/pcap/packet.rb, line 187
def copy
  if @header.to_ptr.null?
    raise(StandardError,"header is a NULL pointer",caller)
  end

  if body_ptr.null?
    raise(StandardError,"body is a NULL pointer",caller)
  end

  cpy_hdr = PacketHeader.new
  cpy_buf = FFI::MemoryPointer.new(@header.caplen)

  CRT.memcpy(cpy_hdr, @header, PacketHeader.size)
  CRT.memcpy(cpy_buf, @body_ptr, @header.caplen)

  return self.class.new( cpy_hdr, cpy_buf )
end
len() click to toggle source
# File lib/ffi/pcap/packet.rb, line 171
def len
  @header.len
end
Also aliased as: length
length()
Alias for: len
set_body(data, opts={}) click to toggle source

Sets the body from a string. A pointer is automatically derived from.

@param [String] data

The body to set

@param [Hash] opts

Body length options.

@option opts [optional, Integer] :caplen, :captured

The captured length (or snaplen) for this packet.
Length of data portion present. Defaults to `body.size()`. If
caplen is larger than the body, then it is overridden with
`body.size`.

@option opts [optional, Integer] :len, :length

The total length of the packet (off wire). Defaults to caplen.
If :length is less than the :caplen, it is overridden as :caplen.

@return [String]

Returns the data as supplied per `attr_writer` convention.
# File lib/ffi/pcap/packet.rb, line 122
def set_body(data, opts={})
  cl = (opts[:caplen] || opts[:captured] || data.size)
  l = (opts[:length] || opts[:len] || cl)

  clen = [cl, data.size].min
  len  = [l, clen].max

  @header ||= PacketHeader.new
  @header.caplen = len || @header.caplen
  @header.len = len || @header.caplen
  @body_ptr = MemoryPointer.from_string(data)
  return self
end
Also aliased as: body=
time() click to toggle source

@return [Time]

Returns the pcap timestamp as a Time object
# File lib/ffi/pcap/packet.rb, line 152
def time
  @header.ts.time
end
Also aliased as: timestamp
time=(t) click to toggle source

Sets the pcap timestamp.

# File lib/ffi/pcap/packet.rb, line 161
def time=(t)
  @header.ts.time = t
end
timestamp()
Alias for: time