1 /* libnetfilter_queue.c: generic library for access to nf_queue
3 * (C) 2005 by Harald Welte <laforge@gnumonks.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * 2006-01-23 Andreas Florath <andreas@florath.net>
19 * Fix __set_verdict() that it can now handle payload.
29 #include <netinet/in.h>
30 #include <sys/socket.h>
32 #include <libnfnetlink/libnfnetlink.h>
33 #include <libnetfilter_queue/libnetfilter_queue.h>
38 * libnetfilter_queue is a userspace library providing an API to packets that
39 * have been queued by the kernel packet filter. It is is part of a system that
40 * deprecates the old ip_queue / libipq mechanism.
42 * libnetfilter_queue homepage is:
43 * http://netfilter.org/projects/libnetfilter_queue/
45 * \section Dependencies
46 * libnetfilter_queue requires libnfnetlink and a kernel that includes the
47 * nfnetlink_queue subsystem (i.e. 2.6.14 or later).
49 * \section Main Features
50 * - receiving queued packets from the kernel nfnetlink_queue subsystem
51 * - issuing verdicts and/or reinjecting altered packets to the kernel
52 * nfnetlink_queue subsystem
55 * The current development version of libnetfilter_queue can be accessed
56 * at https://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnetfilter_queue.git;a=summary.
59 * You need the CAP_NET_ADMIN capability in order to allow your application
60 * to receive from and to send packets to kernel-space.
62 * \section Using libnetfilter_queue
64 * To write your own program using libnetfilter_queue, you should start by reading
65 * the doxygen documentation (start by \link LibrarySetup \endlink page) and nfqnl_test.c source file.
71 struct nfnl_handle *nfnlh;
72 struct nfnl_subsys_handle *nfnlssh;
73 struct nfq_q_handle *qh_list;
78 struct nfq_q_handle *next;
92 /***********************************************************************
94 ***********************************************************************/
96 static void del_qh(struct nfq_q_handle *qh)
98 struct nfq_q_handle *cur_qh, *prev_qh = NULL;
100 for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) {
103 prev_qh->next = qh->next;
105 qh->h->qh_list = qh->next;
112 static void add_qh(struct nfq_q_handle *qh)
114 qh->next = qh->h->qh_list;
118 static struct nfq_q_handle *find_qh(struct nfq_handle *h, u_int16_t id)
120 struct nfq_q_handle *qh;
122 for (qh = h->qh_list; qh; qh = qh->next) {
129 /* build a NFQNL_MSG_CONFIG message */
131 __build_send_cfg_msg(struct nfq_handle *h, u_int8_t command,
132 u_int16_t queuenum, u_int16_t pf)
135 char buf[NFNL_HEADER_LEN
136 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))];
139 struct nfqnl_msg_config_cmd cmd;
141 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, AF_UNSPEC, queuenum,
142 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
144 cmd.command = command;
146 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_CMD, &cmd, sizeof(cmd));
148 return nfnl_query(h->nfnlh, &u.nmh);
151 static int __nfq_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
154 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
155 struct nfq_handle *h = data;
156 u_int16_t queue_num = ntohs(nfmsg->res_id);
157 struct nfq_q_handle *qh = find_qh(h, queue_num);
158 struct nfq_data nfqa;
168 return qh->cb(qh, nfmsg, &nfqa, qh->data);
171 static struct nfnl_callback pkt_cb = {
172 .call = &__nfq_rcv_pkt,
173 .attr_count = NFQA_MAX,
176 /* public interface */
178 struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h)
185 * \defgroup Queue Queue handling
187 * Once libnetfilter_queue library has been initialised (See
188 * \link LibrarySetup \endlink), it is possible to bind the program to a
189 * specific queue. This can be done by using nfq_create_queue().
191 * The queue can then be tuned via nfq_set_mode() or nfq_set_queue_maxlen().
193 * Here's a little code snippet that create queue numbered 0:
195 printf("binding this socket to queue '0'\n");
196 qh = nfq_create_queue(h, 0, &cb, NULL);
198 fprintf(stderr, "error during nfq_create_queue()\n");
202 printf("setting copy_packet mode\n");
203 if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
204 fprintf(stderr, "can't set packet_copy mode\n");
209 * Next step is the handling of incoming packets which can be done via a loop:
214 while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
215 printf("pkt received\n");
216 nfq_handle_packet(h, buf, rv);
219 * When the decision on a packet has been choosed, the verdict has to be given
220 * by calling nfq_set_verdict() or nfq_set_verdict2(). The verdict
221 * determines the destiny of the packet as follows:
223 * - NF_DROP discarded the packet
224 * - NF_ACCEPT the packet passes, continue iterations
225 * - NF_STOLEN gone away
226 * - NF_QUEUE inject the packet into a different queue
227 * (the target queue number is in the high 16 bits of the verdict)
228 * - NF_REPEAT iterate the same cycle once more
229 * - NF_STOP accept, but don't continue iterations
231 * Data and information about the packet can be fetch by using message parsing
232 * functions (See \link Parsing \endlink).
237 * nfq_fd - get the file descriptor associated with the nfqueue handler
238 * \param h Netfilter queue connection handle obtained via call to nfq_open()
240 * \return a file descriptor for the netlink connection associated with the
241 * given queue connection handle. The file descriptor can then be used for
242 * receiving the queued packets for processing.
244 * This function returns a file descriptor that can be used for communication
245 * over the netlink connection associated with the given queue connection
248 int nfq_fd(struct nfq_handle *h)
250 return nfnl_fd(nfq_nfnlh(h));
258 * \defgroup LibrarySetup Library setup
260 * Library initialisation is made in two steps.
262 * First step is to call nfq_open() to open a NFQUEUE handler.
264 * Second step is to tell the kernel that userspace queueing is handle by
265 * NFQUEUE for the selected protocol. This is made by calling nfq_unbind_pf()
266 * and nfq_bind_pf() with protocol information. The idea behind this is to
267 * enable simultaneously loaded modules to be used for queuing.
269 * Here's a little code snippet that bind with AF_INET:
273 fprintf(stderr, "error during nfq_open()\n");
277 printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
278 if (nfq_unbind_pf(h, AF_INET) < 0) {
279 fprintf(stderr, "error during nfq_unbind_pf()\n");
283 printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
284 if (nfq_bind_pf(h, AF_INET) < 0) {
285 fprintf(stderr, "error during nfq_bind_pf()\n");
289 * Once this is done, you can setup and use a \link Queue \endlink.
294 * nfq_open - open a nfqueue handler
296 * This function obtains a netfilter queue connection handle. When you are
297 * finished with the handle returned by this function, you should destroy
298 * it by calling nfq_close(). A new netlink connection is obtained internally
299 * and associated with the queue connection handle returned.
301 * \return a pointer to a new queue handle or NULL on failure.
303 struct nfq_handle *nfq_open(void)
305 struct nfnl_handle *nfnlh = nfnl_open();
306 struct nfq_handle *qh;
311 /* unset netlink sequence tracking by default */
312 nfnl_unset_sequence_tracking(nfnlh);
314 qh = nfq_open_nfnl(nfnlh);
326 * nfq_open_nfnl - open a nfqueue handler from a existing nfnetlink handler
327 * \param nfnlh Netfilter netlink connection handle obtained by calling nfnl_open()
329 * This function obtains a netfilter queue connection handle using an existing
330 * netlink connection. This function is used internally to implement
331 * nfq_open(), and should typically not be called directly.
333 * \return a pointer to a new queue handle or NULL on failure.
335 struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh)
337 struct nfq_handle *h;
340 h = malloc(sizeof(*h));
344 memset(h, 0, sizeof(*h));
347 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE,
350 /* FIXME: nfq_errno */
355 err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
363 nfnl_subsys_close(h->nfnlssh);
370 * \addtogroup LibrarySetup
372 * When the program has finished with libnetfilter_queue, it has to call
373 * the nfq_close() function to free all associated resources.
379 * nfq_close - close a nfqueue handler
380 * \param h Netfilter queue connection handle obtained via call to nfq_open()
382 * This function closes the nfqueue handler and free associated resources.
384 * \return 0 on success, non-zero on failure.
386 int nfq_close(struct nfq_handle *h)
390 ret = nfnl_close(h->nfnlh);
397 * nfq_bind_pf - bind a nfqueue handler to a given protocol family
398 * \param h Netfilter queue connection handle obtained via call to nfq_open()
399 * \param pf protocol family to bind to nfqueue handler obtained from nfq_open()
401 * Binds the given queue connection handle to process packets belonging to
402 * the given protocol family (ie. PF_INET, PF_INET6, etc).
404 * \return integer inferior to 0 in case of failure
406 int nfq_bind_pf(struct nfq_handle *h, u_int16_t pf)
408 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
412 * nfq_unbind_pf - unbind nfqueue handler from a protocol family
413 * \param h Netfilter queue connection handle obtained via call to nfq_open()
414 * \param pf protocol family to unbind family from
416 * Unbinds the given queue connection handle from processing packets belonging
417 * to the given protocol family.
419 int nfq_unbind_pf(struct nfq_handle *h, u_int16_t pf)
421 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
436 * nfq_create_queue - create a new queue handle and return it.
438 * \param h Netfilter queue connection handle obtained via call to nfq_open()
439 * \param num the number of the queue to bind to
440 * \param cb callback function to call for each queued packet
441 * \param data custom data to pass to the callback function
443 * \return a nfq_q_handle pointing to the newly created queue
445 * Creates a new queue handle, and returns it. The new queue is identified by
446 * #num, and the callback specified by #cb will be called for each enqueued
447 * packet. The #data argument will be passed unchanged to the callback. If
448 * a queue entry with id #num already exists, this function will return failure
449 * and the existing entry is unchanged.
451 * The nfq_callback type is defined in libnetfilter_queue.h as:
453 typedef int nfq_callback(struct nfq_q_handle *qh,
454 struct nfgenmsg *nfmsg,
455 struct nfq_data *nfad, void *data);
459 * - qh The queue handle returned by nfq_create_queue
460 * - nfmsg message objetc that contains the packet
461 * - nfad Netlink packet data handle
462 * - data the value passed to the data parameter of nfq_create_queue
464 * The callback should return < 0 to stop processing.
467 struct nfq_q_handle *nfq_create_queue(struct nfq_handle *h,
473 struct nfq_q_handle *qh;
478 qh = malloc(sizeof(*qh));
480 memset(qh, 0, sizeof(*qh));
486 ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
507 * nfq_destroy_queue - destroy a queue handle
508 * \param qh queue handle that we want to destroy created via nfq_create_queue
510 * Removes the binding for the specified queue handle. This call also unbind
511 * from the nfqueue handler, so you don't have to call nfq_unbind_pf.
513 int nfq_destroy_queue(struct nfq_q_handle *qh)
515 int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
525 * nfq_handle_packet - handle a packet received from the nfqueue subsystem
526 * \param h Netfilter queue connection handle obtained via call to nfq_open()
527 * \param buf data to pass to the callback
528 * \param len length of packet data in buffer
530 * Triggers an associated callback for the given packet received from the
531 * queue. Packets can be read from the queue using nfq_fd() and recv(). See
532 * example code for nfq_fd().
534 * \return 0 on success, non-zero on failure.
536 int nfq_handle_packet(struct nfq_handle *h, char *buf, int len)
538 return nfnl_handle_packet(h->nfnlh, buf, len);
542 * nfq_set_mode - set the amount of packet data that nfqueue copies to userspace
543 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
544 * \param mode the part of the packet that we are interested in
545 * \param range size of the packet that we want to get
547 * Sets the amount of data to be copied to userspace for each packet queued
548 * to the given queue.
550 * - NFQNL_COPY_NONE - do not copy any data
551 * - NFQNL_COPY_META - copy only packet metadata
552 * - NFQNL_COPY_PACKET - copy entire packet
554 * \return -1 on error; >=0 otherwise.
556 int nfq_set_mode(struct nfq_q_handle *qh,
557 u_int8_t mode, u_int32_t range)
560 char buf[NFNL_HEADER_LEN
561 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
564 struct nfqnl_msg_config_params params;
566 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
567 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
569 params.copy_range = htonl(range);
570 params.copy_mode = mode;
571 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_PARAMS, ¶ms,
574 return nfnl_query(qh->h->nfnlh, &u.nmh);
578 * nfq_set_queue_maxlen - Set kernel queue maximum length parameter
579 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
580 * \param queuelen the length of the queue
582 * Sets the size of the queue in kernel. This fixes the maximum number
583 * of packets the kernel will store before internally before dropping
586 * \return -1 on error; >=0 otherwise.
588 int nfq_set_queue_maxlen(struct nfq_q_handle *qh,
592 char buf[NFNL_HEADER_LEN
593 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
596 u_int32_t queue_maxlen = htonl(queuelen);
598 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
599 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
601 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_QUEUE_MAXLEN, &queue_maxlen,
602 sizeof(queue_maxlen));
604 return nfnl_query(qh->h->nfnlh, &u.nmh);
611 static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id,
612 u_int32_t verdict, u_int32_t mark, int set_mark,
613 u_int32_t data_len, const unsigned char *data)
615 struct nfqnl_msg_verdict_hdr vh;
617 char buf[NFNL_HEADER_LEN
618 +NFA_LENGTH(sizeof(mark))
619 +NFA_LENGTH(sizeof(vh))];
626 /* This must be declared here (and not inside the data
627 * handling block) because the iovec points to this. */
628 struct nfattr data_attr;
630 memset(iov, 0, sizeof(iov));
632 vh.verdict = htonl(verdict);
635 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
636 NFQNL_MSG_VERDICT, NLM_F_REQUEST);
638 /* add verdict header */
639 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_VERDICT_HDR, &vh, sizeof(vh));
642 nfnl_addattr32(&u.nmh, sizeof(u), NFQA_MARK, mark);
644 iov[0].iov_base = &u.nmh;
645 iov[0].iov_len = NLMSG_TAIL(&u.nmh) - (void *)&u.nmh;
649 /* The typecast here is to cast away data's const-ness: */
650 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
651 data_len, (unsigned char *) data);
653 /* Add the length of the appended data to the message
654 * header. The size of the attribute is given in the
655 * nfa_len field and is set in the nfnl_build_nfa_iovec()
657 u.nmh.nlmsg_len += data_attr.nfa_len;
660 return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
669 * nfq_set_verdict - issue a verdict on a packet
670 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
671 * \param id ID assigned to packet by netfilter.
672 * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
673 * \param data_len number of bytes of data pointed to by #buf
674 * \param buf the buffer that contains the packet data
676 * Can be obtained by:
679 struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(tb);
681 id = ntohl(ph->packet_id);
684 * Notifies netfilter of the userspace verdict for the given packet. Every
685 * queued packet _must_ have a verdict specified by userspace, either by
686 * calling this function, or by calling the nfq_set_verdict2() function.
688 * \return -1 on error; >= 0 otherwise.
690 int nfq_set_verdict(struct nfq_q_handle *qh, u_int32_t id,
691 u_int32_t verdict, u_int32_t data_len,
692 const unsigned char *buf)
694 return __set_verdict(qh, id, verdict, 0, 0, data_len, buf);
698 * nfq_set_verdict2 - like nfq_set_verdict, but you can set the mark.
699 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
700 * \param id ID assigned to packet by netfilter.
701 * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
702 * \param mark mark to put on packet
703 * \param data_len number of bytes of data pointed to by #buf
704 * \param buf the buffer that contains the packet data
706 int nfq_set_verdict2(struct nfq_q_handle *qh, u_int32_t id,
707 u_int32_t verdict, u_int32_t mark,
708 u_int32_t data_len, const unsigned char *buf)
710 return __set_verdict(qh, id, verdict, htonl(mark), 1, data_len, buf);
714 * nfq_set_verdict_mark - like nfq_set_verdict, but you can set the mark.
715 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
716 * \param id ID assigned to packet by netfilter.
717 * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
718 * \param mark the mark to put on the packet, in network byte order.
719 * \param data_len number of bytes of data pointed to by #buf
720 * \param buf the buffer that contains the packet data
722 * \return -1 on error; >= 0 otherwise.
724 * This function is deprecated since it is broken, its use is highly
725 * discouraged. Please, use nfq_set_verdict2 instead.
727 int nfq_set_verdict_mark(struct nfq_q_handle *qh, u_int32_t id,
728 u_int32_t verdict, u_int32_t mark,
729 u_int32_t data_len, const unsigned char *buf)
731 return __set_verdict(qh, id, verdict, mark, 1, data_len, buf);
740 /*************************************************************
741 * Message parsing functions
742 *************************************************************/
745 * \defgroup Parsing Message parsing functions
750 * nfqnl_msg_packet_hdr - return the metaheader that wraps the packet
751 * \param nfad Netlink packet data handle passed to callback function
753 * \return the netfilter queue netlink packet header for the given
754 * nfq_data argument. Typically, the nfq_data value is passed as the 3rd
755 * parameter to the callback function set by a call to nfq_create_queue().
757 * The nfqnl_msg_packet_hdr structure is defined in libnetfilter_queue.h as:
760 struct nfqnl_msg_packet_hdr {
761 u_int32_t packet_id; // unique ID of packet in queue
762 u_int16_t hw_protocol; // hw protocol (network order)
763 u_int8_t hook; // netfilter hook
764 } __attribute__ ((packed));
767 struct nfqnl_msg_packet_hdr *nfq_get_msg_packet_hdr(struct nfq_data *nfad)
769 return nfnl_get_pointer_to_data(nfad->data, NFQA_PACKET_HDR,
770 struct nfqnl_msg_packet_hdr);
774 * nfq_get_nfmark - get the packet mark
775 * \param nfad Netlink packet data handle passed to callback function
777 * \return the netfilter mark currently assigned to the given queued packet.
779 uint32_t nfq_get_nfmark(struct nfq_data *nfad)
781 return ntohl(nfnl_get_data(nfad->data, NFQA_MARK, u_int32_t));
785 * nfq_get_timestamp - get the packet timestamp
786 * \param nfad Netlink packet data handle passed to callback function
787 * \param tv structure to fill with timestamp info
789 * Retrieves the received timestamp when the given queued packet.
791 * \return 0 on success, non-zero on failure.
793 int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv)
795 struct nfqnl_msg_packet_timestamp *qpt;
796 qpt = nfnl_get_pointer_to_data(nfad->data, NFQA_TIMESTAMP,
797 struct nfqnl_msg_packet_timestamp);
801 tv->tv_sec = __be64_to_cpu(qpt->sec);
802 tv->tv_usec = __be64_to_cpu(qpt->usec);
808 * nfq_get_indev - get the interface that the packet was received through
809 * \param nfad Netlink packet data handle passed to callback function
811 * \return The index of the device the queued packet was received via. If the
812 * returned index is 0, the packet was locally generated or the input
813 * interface is not known (ie. POSTROUTING?).
815 * \warning all nfq_get_dev() functions return 0 if not set, since linux
816 * only allows ifindex >= 1, see net/core/dev.c:2600 (in 2.6.13.1)
818 u_int32_t nfq_get_indev(struct nfq_data *nfad)
820 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_INDEV, u_int32_t));
824 * nfq_get_physindev - get the physical interface that the packet was received
825 * \param nfad Netlink packet data handle passed to callback function
827 * \return The index of the physical device the queued packet was received via.
828 * If the returned index is 0, the packet was locally generated or the
829 * physical input interface is no longer known (ie. POSTROUTING?).
831 u_int32_t nfq_get_physindev(struct nfq_data *nfad)
833 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSINDEV, u_int32_t));
837 * nfq_get_outdev - gets the interface that the packet will be routed out
838 * \param nfad Netlink packet data handle passed to callback function
840 * \return The index of the device the queued packet will be sent out. If the
841 * returned index is 0, the packet is destined for localhost or the output
842 * interface is not yet known (ie. PREROUTING?).
844 u_int32_t nfq_get_outdev(struct nfq_data *nfad)
846 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_OUTDEV, u_int32_t));
850 * nfq_get_physoutdev - get the physical interface that the packet output
851 * \param nfad Netlink packet data handle passed to callback function
853 * The index of the physical device the queued packet will be sent out.
854 * If the returned index is 0, the packet is destined for localhost or the
855 * physical output interface is not yet known (ie. PREROUTING?).
857 * \return The index of physical interface that the packet output will be routed out.
859 u_int32_t nfq_get_physoutdev(struct nfq_data *nfad)
861 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
865 * nfq_get_indev_name - get the name of the interface the packet
866 * was received through
867 * \param nlif_handle pointer to a nlif interface resolving handle
868 * \param nfad Netlink packet data handle passed to callback function
869 * \param name pointer to the buffer to receive the interface name;
870 * not more than \c IFNAMSIZ bytes will be copied to it.
871 * \return -1 in case of error, >0 if it succeed.
873 * To use a nlif_handle, You need first to call nlif_open() and to open
874 * an handler. Don't forget to store the result as it will be used
875 * during all your program life:
883 * Once the handler is open, you need to fetch the interface table at a
884 * whole via a call to nlif_query.
888 * libnfnetlink is able to update the interface mapping when a new interface
889 * appears. To do so, you need to call nlif_catch() on the handler after each
890 * interface related event. The simplest way to get and treat event is to run
891 * a select() or poll() against the nlif file descriptor. To get this file
892 * descriptor, you need to use nlif_fd:
896 * Don't forget to close the handler when you don't need the feature anymore:
902 int nfq_get_indev_name(struct nlif_handle *nlif_handle,
903 struct nfq_data *nfad, char *name)
905 u_int32_t ifindex = nfq_get_indev(nfad);
906 return nlif_index2name(nlif_handle, ifindex, name);
910 * nfq_get_physindev_name - get the name of the physical interface the
911 * packet was received through
912 * \param nlif_handle pointer to a nlif interface resolving handle
913 * \param nfad Netlink packet data handle passed to callback function
914 * \param name pointer to the buffer to receive the interface name;
915 * not more than \c IFNAMSIZ bytes will be copied to it.
917 * See nfq_get_indev_name() documentation for nlif_handle usage.
919 * \return -1 in case of error, > 0 if it succeed.
921 int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
922 struct nfq_data *nfad, char *name)
924 u_int32_t ifindex = nfq_get_physindev(nfad);
925 return nlif_index2name(nlif_handle, ifindex, name);
929 * nfq_get_outdev_name - get the name of the physical interface the
930 * packet will be sent to
931 * \param nlif_handle pointer to a nlif interface resolving handle
932 * \param nfad Netlink packet data handle passed to callback function
933 * \param name pointer to the buffer to receive the interface name;
934 * not more than \c IFNAMSIZ bytes will be copied to it.
936 * See nfq_get_indev_name() documentation for nlif_handle usage.
938 * \return -1 in case of error, > 0 if it succeed.
940 int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
941 struct nfq_data *nfad, char *name)
943 u_int32_t ifindex = nfq_get_outdev(nfad);
944 return nlif_index2name(nlif_handle, ifindex, name);
948 * nfq_get_physoutdev_name - get the name of the interface the
949 * packet will be sent to
950 * \param nlif_handle pointer to a nlif interface resolving handle
951 * \param nfad Netlink packet data handle passed to callback function
952 * \param name pointer to the buffer to receive the interface name;
953 * not more than \c IFNAMSIZ bytes will be copied to it.
955 * See nfq_get_indev_name() documentation for nlif_handle usage.
957 * \return -1 in case of error, > 0 if it succeed.
960 int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
961 struct nfq_data *nfad, char *name)
963 u_int32_t ifindex = nfq_get_physoutdev(nfad);
964 return nlif_index2name(nlif_handle, ifindex, name);
970 * get hardware address
972 * \param nfad Netlink packet data handle passed to callback function
974 * Retrieves the hardware address associated with the given queued packet.
975 * For ethernet packets, the hardware address returned (if any) will be the
976 * MAC address of the packet source host. The destination MAC address is not
977 * known until after POSTROUTING and a successful ARP request, so cannot
978 * currently be retrieved.
980 * The nfqnl_msg_packet_hw structure is defined in libnetfilter_queue.h as:
982 struct nfqnl_msg_packet_hw {
983 u_int16_t hw_addrlen;
986 } __attribute__ ((packed));
989 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
991 return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
992 struct nfqnl_msg_packet_hw);
996 * nfq_get_payload - get payload
997 * \param nfad Netlink packet data handle passed to callback function
998 * \param data Pointer of pointer that will be pointed to the payload
1000 * Retrieve the payload for a queued packet. The actual amount and type of
1001 * data retrieved by this function will depend on the mode set with the
1002 * nfq_set_mode() function.
1004 * \return -1 on error, otherwise > 0.
1006 int nfq_get_payload(struct nfq_data *nfad, unsigned char **data)
1008 *data = nfnl_get_pointer_to_data(nfad->data, NFQA_PAYLOAD, char);
1010 return NFA_PAYLOAD(nfad->data[NFQA_PAYLOAD-1]);
1015 #define SNPRINTF_FAILURE(size, len, offset) \
1017 if (size < 0 || (unsigned int) size >= len) \
1023 int nfq_snprintf_xml(char *buf, size_t len, struct nfq_data *tb, int flags)
1025 struct nfqnl_msg_packet_hdr *ph;
1026 struct nfqnl_msg_packet_hw *hwph;
1027 u_int32_t mark, ifi;
1028 int size, offset = 0, ret;
1029 unsigned char *data;
1031 size = snprintf(buf + offset, len, "<pkt>");
1032 SNPRINTF_FAILURE(size, len, offset);
1034 if (flags & NFQ_XML_TIME) {
1039 if (localtime_r(&t, &tm) == NULL)
1042 size = snprintf(buf + offset, len, "<when>");
1043 SNPRINTF_FAILURE(size, len, offset);
1045 size = snprintf(buf + offset, len,
1046 "<hour>%d</hour>", tm.tm_hour);
1047 SNPRINTF_FAILURE(size, len, offset);
1049 size = snprintf(buf + offset,
1050 len, "<min>%02d</min>", tm.tm_min);
1051 SNPRINTF_FAILURE(size, len, offset);
1053 size = snprintf(buf + offset,
1054 len, "<sec>%02d</sec>", tm.tm_sec);
1055 SNPRINTF_FAILURE(size, len, offset);
1057 size = snprintf(buf + offset, len, "<wday>%d</wday>",
1059 SNPRINTF_FAILURE(size, len, offset);
1061 size = snprintf(buf + offset, len, "<day>%d</day>", tm.tm_mday);
1062 SNPRINTF_FAILURE(size, len, offset);
1064 size = snprintf(buf + offset, len, "<month>%d</month>",
1066 SNPRINTF_FAILURE(size, len, offset);
1068 size = snprintf(buf + offset, len, "<year>%d</year>",
1070 SNPRINTF_FAILURE(size, len, offset);
1072 size = snprintf(buf + offset, len, "</when>");
1073 SNPRINTF_FAILURE(size, len, offset);
1076 ph = nfq_get_msg_packet_hdr(tb);
1078 size = snprintf(buf + offset, len,
1079 "<hook>%u</hook><id>%u</id>",
1080 ph->hook, ntohl(ph->packet_id));
1081 SNPRINTF_FAILURE(size, len, offset);
1083 hwph = nfq_get_packet_hw(tb);
1084 if (hwph && (flags & NFQ_XML_HW)) {
1085 int i, hlen = ntohs(hwph->hw_addrlen);
1087 size = snprintf(buf + offset, len, "<hw><proto>0x%04x"
1089 ntohs(ph->hw_protocol));
1090 SNPRINTF_FAILURE(size, len, offset);
1092 size = snprintf(buf + offset, len, "<src>");
1093 SNPRINTF_FAILURE(size, len, offset);
1095 for (i=0; i<hlen-1; i++) {
1096 size = snprintf(buf + offset, len, "%02x:",
1097 ntohs(ph->hw_protocol));
1098 SNPRINTF_FAILURE(size, len, offset);
1101 size = snprintf(buf + offset, len, "</src></hw>");
1102 SNPRINTF_FAILURE(size, len, offset);
1103 } else if (flags & NFQ_XML_HW) {
1104 size = snprintf(buf + offset, len, "<hw><proto>0x%04x"
1106 ntohs(ph->hw_protocol));
1107 SNPRINTF_FAILURE(size, len, offset);
1111 mark = nfq_get_nfmark(tb);
1112 if (mark && (flags & NFQ_XML_MARK)) {
1113 size = snprintf(buf + offset, len, "<mark>%u</mark>", mark);
1114 SNPRINTF_FAILURE(size, len, offset);
1117 ifi = nfq_get_indev(tb);
1118 if (ifi && (flags & NFQ_XML_DEV)) {
1119 size = snprintf(buf + offset, len, "<indev>%u</indev>", ifi);
1120 SNPRINTF_FAILURE(size, len, offset);
1123 ifi = nfq_get_outdev(tb);
1124 if (ifi && (flags & NFQ_XML_DEV)) {
1125 size = snprintf(buf + offset, len, "<outdev>%u</outdev>", ifi);
1126 SNPRINTF_FAILURE(size, len, offset);
1129 ifi = nfq_get_physindev(tb);
1130 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1131 size = snprintf(buf + offset, len,
1132 "<physindev>%u</physindev>", ifi);
1133 SNPRINTF_FAILURE(size, len, offset);
1136 ifi = nfq_get_physoutdev(tb);
1137 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1138 size = snprintf(buf + offset, len,
1139 "<physoutdev>%u</physoutdev>", ifi);
1140 SNPRINTF_FAILURE(size, len, offset);
1143 ret = nfq_get_payload(tb, &data);
1144 if (ret >= 0 && (flags & NFQ_XML_PAYLOAD)) {
1147 size = snprintf(buf + offset, len, "<payload>");
1148 SNPRINTF_FAILURE(size, len, offset);
1150 for (i=0; i<ret; i++) {
1151 size = snprintf(buf + offset, len, "%02x",
1153 SNPRINTF_FAILURE(size, len, offset);
1156 size = snprintf(buf + offset, len, "</payload>");
1157 SNPRINTF_FAILURE(size, len, offset);
1160 size = snprintf(buf + offset, len, "</pkt>");
1161 SNPRINTF_FAILURE(size, len, offset);