netfilter
firewalling, NAT, and packet mangling for linux
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Queue handling [DEPRECATED]

Once libnetfilter_queue library has been initialised (See LibrarySetup), it is possible to bind the program to a specific queue. More...

Functions

int nfq_fd (struct nfq_handle *h)
 nfq_fd - get the file descriptor associated with the nfqueue handler More...
 
 EXPORT_SYMBOL (nfq_fd)
 
struct nfq_q_handlenfq_create_queue (struct nfq_handle *h, u_int16_t num, nfq_callback *cb, void *data)
 nfq_create_queue - create a new queue handle and return it. More...
 
 EXPORT_SYMBOL (nfq_create_queue)
 
int nfq_destroy_queue (struct nfq_q_handle *qh)
 nfq_destroy_queue - destroy a queue handle More...
 
 EXPORT_SYMBOL (nfq_destroy_queue)
 
int nfq_handle_packet (struct nfq_handle *h, char *buf, int len)
 nfq_handle_packet - handle a packet received from the nfqueue subsystem More...
 
 EXPORT_SYMBOL (nfq_handle_packet)
 
int nfq_set_mode (struct nfq_q_handle *qh, u_int8_t mode, u_int32_t range)
 nfq_set_mode - set the amount of packet data that nfqueue copies to userspace More...
 
 EXPORT_SYMBOL (nfq_set_mode)
 
int nfq_set_queue_flags (struct nfq_q_handle *qh, uint32_t mask, uint32_t flags)
 nfq_set_queue_flags - set flags (options) for the kernel queue More...
 
 EXPORT_SYMBOL (nfq_set_queue_flags)
 
int nfq_set_queue_maxlen (struct nfq_q_handle *qh, u_int32_t queuelen)
 nfq_set_queue_maxlen - Set kernel queue maximum length parameter More...
 
 EXPORT_SYMBOL (nfq_set_queue_maxlen)
 
int nfq_set_verdict (struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t data_len, const unsigned char *buf)
 nfq_set_verdict - issue a verdict on a packet More...
 
 EXPORT_SYMBOL (nfq_set_verdict)
 
int nfq_set_verdict2 (struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t mark, u_int32_t data_len, const unsigned char *buf)
 nfq_set_verdict2 - like nfq_set_verdict, but you can set the mark. More...
 
 EXPORT_SYMBOL (nfq_set_verdict2)
 
int nfq_set_verdict_batch (struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict)
 nfq_set_verdict_batch - issue verdicts on several packets at once More...
 
 EXPORT_SYMBOL (nfq_set_verdict_batch)
 
int nfq_set_verdict_batch2 (struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t mark)
 nfq_set_verdict_batch2 - like nfq_set_verdict_batch, but you can set a mark. More...
 
 EXPORT_SYMBOL (nfq_set_verdict_batch2)
 
int nfq_set_verdict_mark (struct nfq_q_handle *qh, u_int32_t id, u_int32_t verdict, u_int32_t mark, u_int32_t data_len, const unsigned char *buf)
 nfq_set_verdict_mark - like nfq_set_verdict, but you can set the mark. More...
 
 EXPORT_SYMBOL (nfq_set_verdict_mark)
 

Detailed Description

Once libnetfilter_queue library has been initialised (See LibrarySetup), it is possible to bind the program to a specific queue.

This can be done by using nfq_create_queue().

The queue can then be tuned via nfq_set_mode() or nfq_set_queue_maxlen().

Here's a little code snippet that create queue numbered 0:

    printf("binding this socket to queue '0'\n");
    qh = nfq_create_queue(h,  0, &cb, NULL);
    if (!qh) {
        fprintf(stderr, "error during nfq_create_queue()\n");
        exit(1);
    }

    printf("setting copy_packet mode\n");
    if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
        fprintf(stderr, "can't set packet_copy mode\n");
        exit(1);
    }

Next step is the handling of incoming packets which can be done via a loop:

    fd = nfq_fd(h);

    while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
        printf("pkt received\n");
        nfq_handle_packet(h, buf, rv);
    }

When the decision on a packet has been choosed, the verdict has to be given by calling nfq_set_verdict() or nfq_set_verdict2(). The verdict determines the destiny of the packet as follows:

The verdict NF_STOLEN must not be used, as it has special meaning in the kernel. When using NF_REPEAT, one way to prevent re-queueing of the same packet is to also set an nfmark using nfq_set_verdict2, and set up the nefilter rules to only queue a packet when the mark is not (yet) set.

Data and information about the packet can be fetch by using message parsing functions (See Parsing).

Function Documentation

EXPORT_SYMBOL ( nfq_fd  )
EXPORT_SYMBOL ( nfq_create_queue  )
EXPORT_SYMBOL ( nfq_destroy_queue  )
EXPORT_SYMBOL ( nfq_handle_packet  )
EXPORT_SYMBOL ( nfq_set_mode  )
EXPORT_SYMBOL ( nfq_set_queue_flags  )
EXPORT_SYMBOL ( nfq_set_queue_maxlen  )
EXPORT_SYMBOL ( nfq_set_verdict  )
EXPORT_SYMBOL ( nfq_set_verdict2  )
EXPORT_SYMBOL ( nfq_set_verdict_batch  )
EXPORT_SYMBOL ( nfq_set_verdict_batch2  )
EXPORT_SYMBOL ( nfq_set_verdict_mark  )
struct nfq_q_handle* nfq_create_queue ( struct nfq_handle h,
u_int16_t  num,
nfq_callback cb,
void *  data 
)

nfq_create_queue - create a new queue handle and return it.

Parameters
hNetfilter queue connection handle obtained via call to nfq_open()
numthe number of the queue to bind to
cbcallback function to call for each queued packet
datacustom data to pass to the callback function
Returns
a nfq_q_handle pointing to the newly created queue

Creates a new queue handle, and returns it. The new queue is identified by #num, and the callback specified by #cb will be called for each enqueued packet. The data argument will be passed unchanged to the callback. If a queue entry with id #num already exists, this function will return failure and the existing entry is unchanged.

The nfq_callback type is defined in libnetfilter_queue.h as:

typedef int nfq_callback(struct nfq_q_handle *qh,
                 struct nfgenmsg *nfmsg,
             struct nfq_data *nfad, void *data);

Parameters:

  • qh The queue handle returned by nfq_create_queue
  • nfmsg message objetc that contains the packet
  • nfad Netlink packet data handle
  • data the value passed to the data parameter of nfq_create_queue

The callback should return < 0 to stop processing.

References nfq_q_handle::cb, nfq_q_handle::data, data, nfq_q_handle::h, nfq_q_handle::id, nfq_errno, NFQNL_CFG_CMD_BIND, and NULL.

Referenced by main().

Here is the caller graph for this function:

int nfq_destroy_queue ( struct nfq_q_handle qh)

nfq_destroy_queue - destroy a queue handle

Parameters
qhqueue handle that we want to destroy created via nfq_create_queue

Removes the binding for the specified queue handle. This call also unbind from the nfqueue handler, so you don't have to call nfq_unbind_pf.

References nfq_q_handle::h, nfq_q_handle::id, and NFQNL_CFG_CMD_UNBIND.

Referenced by main().

Here is the caller graph for this function:

int nfq_fd ( struct nfq_handle h)

nfq_fd - get the file descriptor associated with the nfqueue handler

Parameters
hNetfilter queue connection handle obtained via call to nfq_open()
Returns
a file descriptor for the netlink connection associated with the given queue connection handle. The file descriptor can then be used for receiving the queued packets for processing.

This function returns a file descriptor that can be used for communication over the netlink connection associated with the given queue connection handle.

References nfnl_fd(), and nfq_nfnlh().

Referenced by main().

Here is the call graph for this function:

Here is the caller graph for this function:

int nfq_handle_packet ( struct nfq_handle h,
char *  buf,
int  len 
)

nfq_handle_packet - handle a packet received from the nfqueue subsystem

Parameters
hNetfilter queue connection handle obtained via call to nfq_open()
bufdata to pass to the callback
lenlength of packet data in buffer

Triggers an associated callback for the given packet received from the queue. Packets can be read from the queue using nfq_fd() and recv(). See example code for nfq_fd().

Returns
0 on success, non-zero on failure.

References nfnl_handle_packet(), and nfq_handle::nfnlh.

Referenced by main().

Here is the call graph for this function:

Here is the caller graph for this function:

int nfq_set_mode ( struct nfq_q_handle qh,
u_int8_t  mode,
u_int32_t  range 
)

nfq_set_mode - set the amount of packet data that nfqueue copies to userspace

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
modethe part of the packet that we are interested in
rangesize of the packet that we want to get

Sets the amount of data to be copied to userspace for each packet queued to the given queue.

  • NFQNL_COPY_NONE - noop, do not use it
  • NFQNL_COPY_META - copy only packet metadata
  • NFQNL_COPY_PACKET - copy entire packet
Returns
-1 on error; >=0 otherwise.

References buf, nfqnl_msg_config_params::copy_mode, nfqnl_msg_config_params::copy_range, nfq_q_handle::h, nfq_q_handle::id, NFA_LENGTH, nfnl_addattr_l(), nfnl_fill_hdr(), NFNL_HEADER_LEN, nfnl_query(), nfq_handle::nfnlh, nfq_handle::nfnlssh, NFQA_CFG_PARAMS, NFQNL_MSG_CONFIG, NLM_F_ACK, and NLM_F_REQUEST.

Here is the call graph for this function:

int nfq_set_queue_flags ( struct nfq_q_handle qh,
uint32_t  mask,
uint32_t  flags 
)

nfq_set_queue_flags - set flags (options) for the kernel queue

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
maskspecifies which flag bits to modify
flagbitmask of flags

Existing flags, that you may want to combine, are:

  • NFQA_CFG_F_FAIL_OPEN (requires Linux kernel >= 3.6): the kernel will accept the packets if the kernel queue gets full. If this flag is not set, the default action in this case is to drop packets.
  • NFQA_CFG_F_CONNTRACK (requires Linux kernel >= 3.6): the kernel will include the Connection Tracking system information.
  • NFQA_CFG_F_GSO (requires Linux kernel >= 3.10): the kernel will not normalize offload packets, i.e. your application will need to be able to handle packets larger than the mtu (up to 64k).

    If your application validates checksums (e.g., tcp checksum), then you must also check if the NFQA_SKB_INFO attribute is present. If it is, you need to test the NFQA_SKB_CSUMNOTREADY bit:

        if (attr[NFQA_SKB_INFO]) {
            uint32_t info = ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO]));
            if (info & NFQA_SKB_CSUMNOTREADY)
                validate_checksums = false;
        }
    

    if this bit is set, the layer 3/4 checksums of the packet appear incorrect, but are not (because they will be corrected later by the kernel).

    • NFQA_CFG_F_UID_GID: the kernel will dump UID and GID of the socket to which each packet belongs.

Here's a little code snippet to show how to use this API:

    uint32_t flags = NFQA_CFG_F_FAIL_OPEN;
    uint32_t mask = NFQA_CFG_F_FAIL_OPEN;

    printf("Enabling fail-open on this q\n");
    err = nfq_set_queue_flags(qh, mask, flags);

    printf("Disabling fail-open on this q\n");
    flags &= ~NFQA_CFG_F_FAIL_OPEN;
    err = nfq_set_queue_flags(qh, mask, flags);
Returns
-1 on error with errno set appropriately; =0 otherwise.

References buf, nfq_q_handle::h, nfq_q_handle::id, NFA_LENGTH, nfnl_addattr32(), nfnl_fill_hdr(), NFNL_HEADER_LEN, nfnl_query(), nfq_handle::nfnlh, nfq_handle::nfnlssh, NFQA_CFG_FLAGS, NFQA_CFG_MASK, NFQNL_MSG_CONFIG, NLM_F_ACK, and NLM_F_REQUEST.

Referenced by main().

Here is the call graph for this function:

Here is the caller graph for this function:

int nfq_set_queue_maxlen ( struct nfq_q_handle qh,
u_int32_t  queuelen 
)

nfq_set_queue_maxlen - Set kernel queue maximum length parameter

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
queuelenthe length of the queue

Sets the size of the queue in kernel. This fixes the maximum number of packets the kernel will store before internally before dropping upcoming packets.

Returns
-1 on error; >=0 otherwise.

References buf, nfq_q_handle::h, nfq_q_handle::id, NFA_LENGTH, nfnl_addattr_l(), nfnl_fill_hdr(), NFNL_HEADER_LEN, nfnl_query(), nfq_handle::nfnlh, nfq_handle::nfnlssh, NFQA_CFG_QUEUE_MAXLEN, NFQNL_MSG_CONFIG, NLM_F_ACK, and NLM_F_REQUEST.

Here is the call graph for this function:

int nfq_set_verdict ( struct nfq_q_handle qh,
u_int32_t  id,
u_int32_t  verdict,
u_int32_t  data_len,
const unsigned char *  buf 
)

nfq_set_verdict - issue a verdict on a packet

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
idID assigned to packet by netfilter.
verdictverdict to return to netfilter (NF_ACCEPT, NF_DROP)
data_lennumber of bytes of data pointed to by buf
bufthe buffer that contains the packet data

Can be obtained by:

    int id;
    struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(tb);
    if (ph)
        id = ntohl(ph->packet_id);

Notifies netfilter of the userspace verdict for the given packet. Every queued packet must have a verdict specified by userspace, either by calling this function, the nfq_set_verdict2() function, or the _batch versions of these functions.

Returns
-1 on error; >= 0 otherwise.

References NFQNL_MSG_VERDICT.

int nfq_set_verdict2 ( struct nfq_q_handle qh,
u_int32_t  id,
u_int32_t  verdict,
u_int32_t  mark,
u_int32_t  data_len,
const unsigned char *  buf 
)

nfq_set_verdict2 - like nfq_set_verdict, but you can set the mark.

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
idID assigned to packet by netfilter.
verdictverdict to return to netfilter (NF_ACCEPT, NF_DROP)
markmark to put on packet
data_lennumber of bytes of data pointed to by buf
bufthe buffer that contains the packet data

References NFQNL_MSG_VERDICT.

int nfq_set_verdict_batch ( struct nfq_q_handle qh,
u_int32_t  id,
u_int32_t  verdict 
)

nfq_set_verdict_batch - issue verdicts on several packets at once

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
idmaximum ID of the packets that the verdict should be applied to.
verdictverdict to return to netfilter (NF_ACCEPT, NF_DROP)

Unlike nfq_set_verdict, the verdict is applied to all queued packets whose packet id is smaller or equal to id.

batch support was added in Linux 3.1. These functions will fail silently on older kernels.

References NFQNL_MSG_VERDICT_BATCH, and NULL.

int nfq_set_verdict_batch2 ( struct nfq_q_handle qh,
u_int32_t  id,
u_int32_t  verdict,
u_int32_t  mark 
)

nfq_set_verdict_batch2 - like nfq_set_verdict_batch, but you can set a mark.

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
idmaximum ID of the packets that the verdict should be applied to.
verdictverdict to return to netfilter (NF_ACCEPT, NF_DROP)
markmark to put on packet

References NFQNL_MSG_VERDICT_BATCH, and NULL.

int nfq_set_verdict_mark ( struct nfq_q_handle qh,
u_int32_t  id,
u_int32_t  verdict,
u_int32_t  mark,
u_int32_t  data_len,
const unsigned char *  buf 
)

nfq_set_verdict_mark - like nfq_set_verdict, but you can set the mark.

Parameters
qhNetfilter queue handle obtained by call to nfq_create_queue().
idID assigned to packet by netfilter.
verdictverdict to return to netfilter (NF_ACCEPT, NF_DROP)
markthe mark to put on the packet, in network byte order.
data_lennumber of bytes of data pointed to by buf
bufthe buffer that contains the packet data
Returns
-1 on error; >= 0 otherwise.

This function is deprecated since it is broken, its use is highly discouraged. Please, use nfq_set_verdict2 instead.

References NFQNL_MSG_VERDICT.