module FFI::PCap

Constants

DEFAULT_SNAPLEN

Public Class Methods

device_names() click to toggle source

Returns an array of device names for each interface found on the system.

# File lib/ffi/pcap/pcap.rb, line 181
def PCap.device_names
  PCap.enum_for(:each_device).map { |dev| dev.name }
end
drop_sudo_privs() click to toggle source

Drops privileges back to the uid of the SUDO_USER environment variable.

Only available on Unix.

This is useful for the paranoid when sudo is used to run a ruby pcap program as root.

This method can generally be called right after a call to open_live() has returned a pcap handle or another privileged call has completed. Note, however, that once privileges are dropped, pcap functions that a require higher privilege will no longer work.

@raise [StandardError]

An error is raised if privileges cannot be dropped for 
some reason. This may be because the SUDO_USER environment 
variable is not set, because we already have a lower
privilige and the SUDO_USER id is not the current uid,
or because the SUDO_USER environment variable is not
a valid user.
# File lib/ffi/pcap/pcap.rb, line 246
def PCap.drop_sudo_privs
  if ENV["SUDO_USER"]
    if (pwent = Etc.getpwnam(ENV["SUDO_USER"]))
      Process::Sys.setgid(pwent.gid) 
      Process::Sys.setegid(pwent.gid) 
      Process::Sys.setuid(pwent.uid)
      Process::Sys.seteuid(pwent.uid)

      return true if ( 
                      Process::Sys.getuid  == pwent.uid and 
                      Process::Sys.geteuid == pwent.uid and 
                      Process::Sys.getgid  == pwent.gid and 
                      Process::Sys.getegid == pwent.gid
                     )
    end
  end

  raise(StandardError,"Unable to drop privileges",caller)
end
dump_devices() click to toggle source

Returns an array of device name and network/netmask pairs for each interface found on the system.

If an interface does not have an address assigned, its network/netmask value is returned as a nil value.

# File lib/ffi/pcap/pcap.rb, line 166
def PCap.dump_devices
  PCap.enum_for(:each_device).map do |dev| 
    net = begin
            PCap.lookupnet(dev.name)
          rescue LibError
          end

    [dev.name, net]
  end
end
each_device() { |device| ... } click to toggle source

List all capture devices and yield them each to a block.

@yield [dev]

@yieldparam [Interface] dev

An Interface structure for each device.

@return [nil]

@raise [LibError]

On failure, an exception is raised with the relevant error 
message from libpcap.
# File lib/ffi/pcap/pcap.rb, line 136
def PCap.each_device
  devices = FFI::MemoryPointer.new(:pointer)
  errbuf  = ErrorBuffer.new

  PCap.pcap_findalldevs(devices, errbuf)
  node = devices.get_pointer(0)

  if node.null?
    raise(LibError,"pcap_findalldevs(): #{errbuf}",caller)
  end

  device = Interface.new(node)

  while device
    yield(device)

    device = device.next
  end

  PCap.pcap_freealldevs(node)
  return nil
end
lib_version() click to toggle source

Get the version information for libpcap.

@return [String]

Information about the version of the libpcap library being used; 
note that it contains more information than just a version number.
# File lib/ffi/pcap/pcap.rb, line 194
def PCap.lib_version
  PCap.pcap_lib_version
end
lib_version_number() click to toggle source

Extract just the version number from the {PCap.lib_version} string.

@return [String]

Version number.
# File lib/ffi/pcap/pcap.rb, line 204
def PCap.lib_version_number
  if (version = PCap.lib_version.match(/libpcap version (\d+\.\d+.\d+)/))
    return version[1]
  end
end
lookupdev() click to toggle source

Find the default device on which to capture.

@return [String]

Name of default device

@raise [LibError]

On failure, an exception is raised with the relevant error 
message from libpcap.
# File lib/ffi/pcap/pcap.rb, line 23
def PCap.lookupdev
  e = ErrorBuffer.new

  unless (name = PCap.pcap_lookupdev(e))
    raise(LibError,"pcap_lookupdev(): #{e}",caller)
  end

  return name
end
lookupnet(device) { |netp, maskp| ... } click to toggle source

Determine the IPv4 network number and mask relevant with a network device.

@param [String] device

The name of the device to look up.

@yield [netp, maskp]

@yieldparam [FFI::MemoryPointer] netp

A pointer to the network return value.

@yieldparam [FFI::MemoryPointer] maskp

A pointer to the netmask return value.

@return [nil, String]

The IPv4 network number and mask presented as `n.n.n.n/m.m.m.m`.
`nil` is returned when a block is specified.

@raise [LibError]

On failure, an exception is raised with the relevant error message 
from libpcap.
# File lib/ffi/pcap/pcap.rb, line 59
def PCap.lookupnet(device)
  netp   = MemoryPointer.new(find_type(:bpf_uint32))
  maskp  = MemoryPointer.new(find_type(:bpf_uint32))
  errbuf = ErrorBuffer.new

  unless PCap.pcap_lookupnet(device, netp, maskp, errbuf) == 0
    raise(LibError, "pcap_lookupnet(): #{errbuf}",caller)
  end

  if block_given?
    yield netp, maskp
  else
    net = netp.get_array_of_uchar(0,4).join('.')
    net << '/'
    net << maskp.get_array_of_uchar(0,4).join('.')

    return net
  end
end
open_dead(opts={}, &block) click to toggle source

Opens a new Dead pcap interface for compiling filters or opening a capture for output.

@see Dead#initialize

# File lib/ffi/pcap/pcap.rb, line 97
def PCap.open_dead(opts={}, &block)
  ret = Dead.new(opts, &block)
  return block_given? ? ret.close : ret
end
open_file(path, opts={}, &block) click to toggle source

@see Pcap.open_offline

# File lib/ffi/pcap/pcap.rb, line 115
def PCap.open_file(path, opts={}, &block)
  open_offline(path, opts, &block)
end
open_live(opts={},&block) click to toggle source

Opens a new Live device for capturing from the network. See {Live#initialize} for arguments.

If passed a block, the block is passed to {Live#initialize} and the {Live} object is closed after completion of the block

# File lib/ffi/pcap/pcap.rb, line 86
def PCap.open_live(opts={},&block)
  ret = Live.new(opts, &block)
  return block_given? ? ret.close : ret
end
open_offline(path, opts={}, &block) click to toggle source

Opens a saved capture file for reading.

@see Offline#initialize

# File lib/ffi/pcap/pcap.rb, line 107
def PCap.open_offline(path, opts={}, &block)
  ret = Offline.new(path, opts={}, &block)
  return block_given? ? ret.close : ret
end