class Ethernet::RawSocketFactory::BpfSocketWrapper

Wraps a BPF file descriptor into a socket-like interface.

Public Class Methods

new(bpf) click to toggle source

Creates a wrapper for a BPF file descriptor.

# File lib/ethernet/raw_socket_factory_darwin.rb, line 130
def initialize(bpf)
  @bpf = bpf
  @read_size = read_buffer_length
  @queue = []
end

Public Instance Methods

close() click to toggle source

Implements Socket#close.

# File lib/ethernet/raw_socket_factory_darwin.rb, line 160
def close
  @bpf.close
end
recv(buffer_size) click to toggle source

Implements Socket#recv.

# File lib/ethernet/raw_socket_factory_darwin.rb, line 137
def recv(buffer_size)
  while @queue.empty?
    read_buffer = @bpf.sysread @read_size
    bytes_read = read_buffer.length
    offset = 0
    while offset < bytes_read
      # struct bpf_hdr in /usr/include/net/bpf.h
      timestamp, captured_size, original_size, header_size =
          *read_buffer.unpack('QLLS')
      @queue.push read_buffer[header_size, captured_size]
      # BPF_WORDALIGN in /usr/include/net/bpf.h
      offset += (header_size + captured_size + 3) & 0xFFF4
    end
  end
  @queue.shift
end
send(buffer, flags) click to toggle source

Implements Socket#send.

# File lib/ethernet/raw_socket_factory_darwin.rb, line 155
def send(buffer, flags)
  @bpf.write buffer
end

Private Instance Methods

read_buffer_length() click to toggle source

The required length of the buffer passed to the read command.

# File lib/ethernet/raw_socket_factory_darwin.rb, line 165
def read_buffer_length
  io_buffer = [0].pack('L')
  # BIOCGBLEN in /usr/include/net/bpf.h
  # _IOR in /usr/include/sys/ioccom.h
  @bpf.ioctl 0x40044266, io_buffer
  io_buffer.unpack('L').first
end