Class: Netfilter::Queue

Inherits:
Object
  • Object
show all
Extended by:
FFI::Library
Defined in:
lib/nfqueue.rb

Defined Under Namespace

Modules: CopyMode

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(qnumber, mode = CopyMode::PACKET) ⇒ Queue

Creates a new Queue at slot qnumber.

Raises:



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# 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

Instance Attribute Details

#net_interfacesObject (readonly)

Returns the value of attribute net_interfaces.



246
247
248
# File 'lib/nfqueue.rb', line 246

def net_interfaces
  @net_interfaces
end

#queue_numberObject (readonly)

Returns the value of attribute queue_number.



245
246
247
# File 'lib/nfqueue.rb', line 245

def queue_number
  @queue_number
end

Class Method Details

.create(qnumber, mode = CopyMode::PACKET, &callback) ⇒ Object

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



349
350
351
352
353
354
355
356
357
# 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

Instance Method Details

#destroyObject

Close the queue.



340
341
342
343
# File 'lib/nfqueue.rb', line 340

def destroy
    Queue.nfq_destroy_queue(@qhandle)
    close
end

#process(&callback) ⇒ Object

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

Raises:



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# 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) ⇒ Object

Sets the maximum number of elements in the queue.



308
309
310
311
312
313
314
# 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) ⇒ Object

Changes the copy mode for the queue.



297
298
299
300
301
302
303
# 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