class Netfilter::Queue

Attributes

net_interfaces[R]
queue_number[R]

Public Class Methods

create(qnumber, mode = CopyMode::PACKET, &callback) click to toggle source

Creates a new Queue with the provided callback. The queue will be automatically destroyed at return.

# File lib/nfqueue.rb, line 349
def self.create(qnumber, mode = CopyMode::PACKET, &callback)
    queue = self.new(qnumber, mode)

    begin
        queue.process(&callback)
    ensure
        queue.destroy
    end
end
new(qnumber, mode = CopyMode::PACKET) click to toggle source

Creates a new Queue at slot qnumber.

# File lib/nfqueue.rb, line 251
def initialize(qnumber, mode = CopyMode::PACKET)
    @queue_number = qnumber
    @net_interfaces = Netfilter::Netlink.interfaces

    @conn_handle = Queue.nfq_open
    raise QueueError, "nfq_open has failed" if @conn_handle.null?

    if Queue.nfq_unbind_pf(@conn_handle, Socket::AF_INET) < 0
        close
        raise QueueError, "nfq_unbind_pf has failed"
    end
      
    if Queue.nfq_bind_pf(@conn_handle, Socket::AF_INET) < 0
        close
        raise QueueError, "nfq_unbind_pf has failed"
    end

    @callback = Proc.new {|packet| raise QueueError, "Undefined callback method."}
    @callback_handler =
       FFI::Function.new(:int, [:pointer, :pointer, :pointer, :buffer_in]) do |qhandler, nfmsg, nfad, data|
            packet = Packet.new(self, nfad)
            verdict = @callback[packet]

            data = packet.data

            Queue.nfq_set_verdict(
                qhandler,
                packet.id,
                verdict,
                data.size,
                data
            )
       end

    @qhandle = Queue.nfq_create_queue(@conn_handle, qnumber, @callback_handler, nil)
    if @qhandle.null?
        close
        raise QueueError, "nfq_create_queue has failed" if @qhandle.null?
    end

    set_mode(mode)
end

Public Instance Methods

destroy() click to toggle source

Close the queue.

# File lib/nfqueue.rb, line 340
def destroy
    Queue.nfq_destroy_queue(@qhandle)
    close
end
process(&callback) click to toggle source

Processes packets in the queue, passing them through the provided callback.

# File lib/nfqueue.rb, line 319
def process(&callback)
    @callback = callback

    fd = Queue.nfq_fd(@conn_handle)
    raise QueueError, "nfq_fd has failed" if fd < 0

    io = IO.new(fd)
    io.autoclose = false

    begin
        while data = io.sysread(4096)
            Queue.nfq_handle_packet(@conn_handle, data, data.size)
        end
    ensure
        io.close
    end
end
set_max_length(len) click to toggle source

Sets the maximum number of elements in the queue.

# File lib/nfqueue.rb, line 308
def set_max_length(len)
    if Queue.nfq_set_queue_maxlen(@qhandle, len) < 0
        raise QueueError, "nfq_queue_maxlen has failed"
    end

    self
end
set_mode(mode, range = 0xffff_ffff) click to toggle source

Changes the copy mode for the queue.

# File lib/nfqueue.rb, line 297
def set_mode(mode, range = 0xffff_ffff)
    if Queue.nfq_set_mode(@qhandle, mode, range) < 0
        raise QueueError, "nfq_set_mode has failed"
    end

    self
end