Re: libnetfilter_queue man page

Top Page

Reply to this message
Author: Brad Fisher
Date:  
To: Harald Welte, Kevin Spiteri, Netfilter Development Mailinglist
CC: 
Subject: Re: libnetfilter_queue man page
Attached you should find my attempt at some documentation for
libnetfilter_queue... Mostly just notes I've been accumulating as I
write an application using the queuing mechanism. It's definitely not
good enough for a man page, and most of it is probably incorrect
garbage, so don't trust it too far. If it helps someone, free free to
use it.

One small thing I should mention - possibly a bug: I tried playing
around with nfq_get_packet_hw() yesterday and the hw_addrlen returned
seemed to be much too large... For an ethernet packet I'd expect it to
be 6 (ethernet MAC address is 6 octets), but it was something like 1520
or so. Needless to say, much larger than expected. Perhaps I'm
interpreting it wrong. I haven't had a chance to look too deeply into
it yet.

-Brad

Harald Welte wrote:
> On Mon, Feb 06, 2006 at 03:19:09PM +0100, Kevin Spiteri wrote:
>
>> Hi Harald
>>
>> I read on the netfilter page that libnetfilter_queue deprecates libipq.
>> However, I only managed to find man pages for libipq. Could you please
>> point me to a man page (or any documentation) for using
>> libnetfilter_queue?
>>
>
> there is no manpage, but we're always open for contributions.
>
>
> ------------------------------------------------------------------------
>
> !DSPAM:3824,43e9fe2e229121152316338!



----------
nfq_open()
----------


Prototype:
    struct nfq_handle *nfq_open(void)

Parameters:
    None.

Returns:
    Pointer to a new queue handle or NULL on failure.

Description:
    Obtains a netfilter queue connection handle. When you are finished with
    the handle returned by this function, you should destroy it by calling
    nfq_close(). A new netlink connection is obtained internally and
    associated with the    queue connection handle returned.

---------------
nfq_open_nfnl()
---------------


Prototype:
    struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh)

Parameters:
    nfnlh    Netfilter netlink connection handle obtained by calling nfnl_open()

Returns:
    Pointer to a new queue handle or NULL on failure.

Description:
    Obtains a netfilter queue connection handle using an existing netlink
    connection. This function is used internally to implement nfq_open(),
    and should typically not be called directly.

-----------
nfq_close()
-----------


Prototype:
    int nfq_close(struct nfq_handle *h)    

Parameters:
    h        Netfilter queue connection handle obtained via call to nfq_open()

Returns:
    0 on success, non-zero on failure. (see nfnl_close() return value)

Description:
    Close connection associated with the queue connection handle and free
    associated resources.

-----------
nfq_nfnlh()
-----------


Prototype:
    struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h)

Parameters:
    h        Netfilter queue connection handle obtained via call to nfq_open()

Returns:
    The netlink handle assocated with the given queue connection handle. If
    passed an invalid handle, this function will more than likely cause a
    segfault as it performs no checks on the provided handle.

Description:
    Returns the netlink handle associated with the given queue connection
    handle. Possibly useful if you wish to perform other netlink communication
    directly after opening a queue without opening a new netlink connection
    to do so.

--------
nfq_fd()
--------


Prototype:
    int nfq_fd(struct nfq_handle *h)

Parameters:
    h        Netfilter queue connection handle obtained via call to nfq_open()

Returns:
    A file descriptor that can be used for communication over the netlink
    connection associated with the given queue connection handle. On failure,
    returns ??? -1 ???. (See nfnl_fd() return value)

Description:
    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.

    Example:

        fd = nfq_fd(h);

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

-------------
nfq_bind_pf()
-------------


Prototype:
    int nfq_bind_pf(struct nfq_handle *h, u_int16_t pf)

Parameters:
    h        Netfilter queue connection handle obtained via call to nfq_open()
    pf        Protocol family to bind handle to

Returns:
    ??? (See nfnl_talk() return value)

Description:

    Binds the given queue connection handle to process packets belonging to the given
    protocol family (ie. PF_INET, PF_INET6, etc).

How many applications can bind to a given PF?
Is it per-queue, or per PF only?

??? Investigate kernel code to verify NFQNL_CFG_CMD_PF_BIND ???

---------------
nfq_unbind_pf()
---------------


Prototype:
    int nfq_unbind_pf(struct nfq_handle *h, u_int16_t pf)

Parameters:
    h        Netfilter queue connection handle obtained via call to nfq_open()
    pf        Protocol family to unbind family from

Returns:
    ??? (See nfnl_talk() return value)

Description:

    Unbinds the given queue connection handle from processing packets belonging
    to the given protocol family.
??? Investigate kernel code NFQNL_CFG_CMD_PF_UNBIND ???

------------------
nfq_create_queue()
------------------


Prototype:
    struct nfq_q_handle *nfq_create_queue(struct nfq_handle *h, u_int16_t num, nfq_callback *cb, void *data)

Parameters:
    h        Netfilter queue connection handle obtained via call to nfq_open()
    num        The number of the queue to bind to
    cb        Callback function to call for each queued packet
    data    Custom data to pass to the callback function

Returns:
    A new queue handle. (Actually a pointer to a linked list entry maintained
    by the libnetfilter_queue library) Returns NULL on failure.

Description:
    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/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        ???
        nfq_data    Netlink packet data handle (required as parameter of many
                    of the informational functions)
        data        ??? The value passed to the data parameter of nfq_create_queue

    The callback should return ???


    /* General form of address family dependent message.
     * Defined in "libnfnetlink/linux_libnfnetlink.h"
     */
    struct nfgenmsg {
        u_int8_t nfgen_family;        /* AF_xxx */
        u_int8_t version;            /* nfnetlink version */
        u_int16_t res_id;            /* resource id */
    } __attribute__ ((packed));


??? How many queues can exist?
    - Could be unlimited. Library implements as linked list.

??? Can multiple apps bind to the same queue?
    - looks like it's per app on lib side
    - ...need to check out kernel side implementation...

??? Can separate queues be processed separately by separate apps?

??? Investigate kernel code NFQNL_CFG_CMD_BIND ???

-------------------
nfq_destroy_queue()
-------------------


Prototype:
    int nfq_destroy_queue(struct nfq_q_handle *qh)

Parameters:
    qh        Netfilter queue handle obtained by call to nfq_create_queue().

Returns:
    0 on success, non-zero on failure. (See NFQNL_CFG_CMD_UNBIND return value)

Description:
    Removes the binding for the specified queue handle. (The queue handles are
    maintained in the libnetfilter_queue library as a linked list. The <qh>
    is actually just a pointer to an entry in that list. When unbinding,
    a NFQNL_CFG_CMD_UNBIND message is sent to netlink, and if successful, the
    handle entry is removed from the linked list)

??? Investigate kernel code NFQNL_CFG_CMD_UNBIND ???

-------------------
nfq_handle_packet()
-------------------


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

Parameters:
    h        Netfilter queue connection handle obtained via call to nfq_open()
    buf        Buffer containing packet data to process
    len        Length of packet data in buffer

Returns:
    Returns 0 on success, non-zero on failure. (See nfnl_handle_packet() return value)

Description:
    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().

--------------
nfq_set_mode()
--------------


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

Parameters:
    qh        Netfilter queue handle obtained by call to nfq_create_queue().
    mode    ???
                NFQNL_COPY_NONE        ??? Do not copy any data
                NFQNL_COPY_META        ??? Copy only packet metadata
                NFQNL_COPY_PACKET    ??? Copy entire packet
    range    ???

Returns:
    0 on success, non-zero on failure. (see nfnl_talk() return value)

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

-----------------
nfq_set_verdict()
-----------------


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

Parameters:
    qh            Netfilter queue handle obtained by call to nfq_create_queue().
    id            ID assigned to packet by netfilter. 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);
    verdict        Verdict to return to netfilter
                    NF_ACCEPT    - Accept the packet
                    NF_DROP        - Drop the packet
                    ???            - anything else possible? (ie. continue?,
                                    jump? goto? log?)
    data_len    ??? Number of bytes of data pointed to by <buf>
    buf            ??? Pointer to data buffer...

Returns:
    0 on success, non-zero on failure. (See nfnl_sendiov() return value)

Description:
    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, or by calling the nfq_set_verdict_mark() function.

----------------------
nfq_set_verdict_mark()
----------------------


Prototype:
    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, unsigned char *buf)

Parameters:
    qh            Netfilter queue handle obtained by call to nfq_create_queue().
    id            ID assigned to packet by netfilter. Can be obtained by:
                    ph = nfq_get_msg_packet_hdr(tb);
                    if (ph) id = ntohl(ph->packet_id);
    verdict        Verdict to return to netfilter
                    NF_ACCEPT    - Accept the packet
                    NF_DROP        - Drop the packet
                    ???            - anything else possible? (ie. continue?,
                                    jump? goto? log?)
    mark        Netfilter mark value to mark packet with
    data_len    ??? Number of bytes of data pointed to by <buf>
    buf            ??? Pointer to data buffer...

Returns:
    0 on success, non-zero on failure. (See nfnl_sendiov() return value)

Description:
    Notifies netfilter of the userspace verdict for the given packet, and also
    marks the packet with the given netfilter mark value. Every queued packet
    _must_ have a verdict specified by userspace, either by calling this
    function, or by calling the nfq_set_verdict() function.

------------------------
nfq_get_msg_packet_hdr()
------------------------


Prototype:
    struct nfqnl_msg_packet_hdr *nfq_get_msg_packet_hdr(struct nfq_data *nfad)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    Returns the netlink packet header for the given packet data.

Description:
    Returns the netfilter queue netlink packet header for the given
    nfq_data argument. Typically, the nfq_data value is passed as the 3rd
    parameter to the callback function set by a call to nfq_create_queue().

    The nfqnl_msg_packet_hdr structure is defined in "libnetfilter_queue/libnetfilter_queue.h" as:

        struct nfqnl_msg_packet_hdr {
            u_int32_t    packet_id;        /* unique ID of packet in queue */
            u_int16_t    hw_protocol;    /* hw protocol (network order) */
            u_int8_t    hook;            /* netfilter hook */
        } __attribute__ ((packed));

----------------
nfq_get_nfmark()
----------------


Prototype:
    uint32_t nfq_get_nfmark(struct nfq_data *nfad)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    The netfilter mark currently assigned to the packet.

Description:
    Returns the netfilter mark currently assigned to the given queued packet.

-------------------
nfq_get_timestamp()
-------------------


Prototype:
    int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv)

Parameters:
    nfad    Netlink packet data handle passed to callback function
    tv        Structure to fill with timestamp info

Returns:
    0 on success, non-zero on failure.

Description:
    Retrieves the received timestamp when the given queued packet.

---------------
nfq_get_indev()
---------------


Prototype:
    u_int32_t nfq_get_indev(struct nfq_data *nfad)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    The index of the device the queued packet was received via. If the
    returned index is 0, the packet was locally generated or the input
    interface is no longer known (ie. POSTROUTING?).

Description:
    Retrieves the interface that the queued packet was received through.

--------------------
nfq_get_physindev()
--------------------


Prototype:
    u_int32_t nfq_get_physindev(struct nfq_data *nfad)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    The index of the physical device the queued packet was received via.
    If the returned index is 0, the packet was locally generated or the
    physical input interface is no longer known (ie. POSTROUTING?).

Description:
    Retrieves the physical interface that the queued packet was received
    through.

----------------
nfq_get_outdev()
----------------


Prototype:
    u_int32_t nfq_get_outdev(struct nfq_data *nfad)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    The index of the device the queued packet will be sent out. If the
    returned index is 0, the packet is destined for localhost or the output
    interface is not yet known (ie. PREROUTING?).

Description:
    Retrieves the interface that the queued packet will be routed out.

--------------------
nfq_get_physoutdev()
--------------------


Prototype:
    u_int32_t nfq_get_physoutdev(struct nfq_data *nfad)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    The index of the physical device the queued packet will be sent out.
    If the returned index is 0, the packet is destined for localhost or the
    physical output interface is not yet known (ie. PREROUTING?).

Description:
    Retrieves the physical interface that the queued packet will be routed out.

-------------------
nfq_get_packet_hw()
-------------------


Prototype:
    struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    The source hardware address associated with the queued packet, or NULL if
    unknown.

Description:
    Retrieves the hardware address associated with the given queued packet.
    For ethernet packets, the hardware address returned (if any) will be the
    MAC address of the packet source host. The destination MAC address is not
    known until after POSTROUTING and a successful ARP request, so cannot
    currently be retrieved.

    The nfqnl_msg_packet_hw structure is defined in "libnetfilter_queue/libnetfilter_queue.h" as:

        struct nfqnl_msg_packet_hw {
            u_int16_t    hw_addrlen;
            u_int16_t    _pad;
            u_int8_t    hw_addr[8];
        } __attribute__ ((packed));

-----------------
nfq_get_payload()
-----------------


Prototype:
    int nfq_get_payload(struct nfq_data *nfad, char **data)

Parameters:
    nfad    Netlink packet data handle passed to callback function

Returns:
    The size of the data whose address is placed in <data> on success, -1 on
    failure.

Description:
    Retrieve the payload for a queued packet. The actual amount and type of
    data retrieved by this function will depend on the mode set with the
    nfq_set_mode() function:
        NFQNL_COPY_NONE        No data will be returned
        NFQNL_COPY_META Only packet headers will be returned
        NFQNL_COPY_PACKET    Entire packet will be returned

/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/