1 /* libnetfilter_queue.c: generic library for access to nf_queue
3 * (C) 2005 by Harald Welte <laforge@gnumonks.org>
4 * (C) 2005, 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation (or any later at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 2006-01-23 Andreas Florath <andreas@florath.net>
20 * Fix __set_verdict() that it can now handle payload.
30 #include <netinet/in.h>
31 #include <sys/socket.h>
33 #include <libnfnetlink/libnfnetlink.h>
34 #include <libnetfilter_queue/libnetfilter_queue.h>
39 * libnetfilter_queue is a userspace library providing an API to packets that
40 * have been queued by the kernel packet filter. It is is part of a system that
41 * deprecates the old ip_queue / libipq mechanism.
43 * libnetfilter_queue homepage is:
44 * http://netfilter.org/projects/libnetfilter_queue/
46 * \section Dependencies
47 * libnetfilter_queue requires libnfnetlink and a kernel that includes the
48 * nfnetlink_queue subsystem (i.e. 2.6.14 or later).
50 * \section Main Features
51 * - receiving queued packets from the kernel nfnetlink_queue subsystem
52 * - issuing verdicts and/or reinjecting altered packets to the kernel
53 * nfnetlink_queue subsystem
56 * The current development version of libnetfilter_queue can be accessed
57 * at https://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnetfilter_queue.git;a=summary.
60 * You need the CAP_NET_ADMIN capability in order to allow your application
61 * to receive from and to send packets to kernel-space.
63 * \section Using libnetfilter_queue
65 * To write your own program using libnetfilter_queue, you should start by reading
66 * the doxygen documentation (start by \link LibrarySetup \endlink page) and nfqnl_test.c source file.
68 * \section errors ENOBUFS errors in recv()
70 * recv() may return -1 and errno is set to ENOBUFS in case that your
71 * application is not fast enough to retrieve the packets from the kernel.
72 * In that case, you can increase the socket buffer size by means of
73 * nfnl_rcvbufsiz(). Although this delays the appearance of ENOBUFS errors,
74 * you may hit it again sooner or later. The next section provides some hints
75 * on how to obtain the best performance for your application.
77 * \section perf Performance
78 * To improve your libnetfilter_queue application in terms of performance,
79 * you may consider the following tweaks:
81 * - increase the default socket buffer size by means of nfnl_rcvbufsiz().
82 * - set nice value of your process to -20 (maximum priority).
83 * - set the CPU affinity of your process to a spare core that is not used
84 * to handle NIC interruptions.
85 * - set NETLINK_NO_ENOBUFS socket option to avoid receiving ENOBUFS errors
86 * (requires Linux kernel >= 2.6.30).
87 * - see --queue-balance option in NFQUEUE target for multi-threaded apps
88 * (it requires Linux kernel >= 2.6.31).
93 struct nfnl_handle *nfnlh;
94 struct nfnl_subsys_handle *nfnlssh;
95 struct nfq_q_handle *qh_list;
100 struct nfq_q_handle *next;
101 struct nfq_handle *h;
109 struct nfattr **data;
114 /***********************************************************************
116 ***********************************************************************/
118 static void del_qh(struct nfq_q_handle *qh)
120 struct nfq_q_handle *cur_qh, *prev_qh = NULL;
122 for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) {
125 prev_qh->next = qh->next;
127 qh->h->qh_list = qh->next;
134 static void add_qh(struct nfq_q_handle *qh)
136 qh->next = qh->h->qh_list;
140 static struct nfq_q_handle *find_qh(struct nfq_handle *h, u_int16_t id)
142 struct nfq_q_handle *qh;
144 for (qh = h->qh_list; qh; qh = qh->next) {
151 /* build a NFQNL_MSG_CONFIG message */
153 __build_send_cfg_msg(struct nfq_handle *h, u_int8_t command,
154 u_int16_t queuenum, u_int16_t pf)
157 char buf[NFNL_HEADER_LEN
158 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))];
161 struct nfqnl_msg_config_cmd cmd;
163 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, AF_UNSPEC, queuenum,
164 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
166 cmd.command = command;
168 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_CMD, &cmd, sizeof(cmd));
170 return nfnl_query(h->nfnlh, &u.nmh);
173 static int __nfq_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
176 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
177 struct nfq_handle *h = data;
178 u_int16_t queue_num = ntohs(nfmsg->res_id);
179 struct nfq_q_handle *qh = find_qh(h, queue_num);
180 struct nfq_data nfqa;
190 return qh->cb(qh, nfmsg, &nfqa, qh->data);
193 static struct nfnl_callback pkt_cb = {
194 .call = &__nfq_rcv_pkt,
195 .attr_count = NFQA_MAX,
198 /* public interface */
200 struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h)
207 * \defgroup Queue Queue handling
209 * Once libnetfilter_queue library has been initialised (See
210 * \link LibrarySetup \endlink), it is possible to bind the program to a
211 * specific queue. This can be done by using nfq_create_queue().
213 * The queue can then be tuned via nfq_set_mode() or nfq_set_queue_maxlen().
215 * Here's a little code snippet that create queue numbered 0:
217 printf("binding this socket to queue '0'\n");
218 qh = nfq_create_queue(h, 0, &cb, NULL);
220 fprintf(stderr, "error during nfq_create_queue()\n");
224 printf("setting copy_packet mode\n");
225 if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
226 fprintf(stderr, "can't set packet_copy mode\n");
231 * Next step is the handling of incoming packets which can be done via a loop:
236 while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
237 printf("pkt received\n");
238 nfq_handle_packet(h, buf, rv);
241 * When the decision on a packet has been choosed, the verdict has to be given
242 * by calling nfq_set_verdict() or nfq_set_verdict2(). The verdict
243 * determines the destiny of the packet as follows:
245 * - NF_DROP discarded the packet
246 * - NF_ACCEPT the packet passes, continue iterations
247 * - NF_STOLEN gone away
248 * - NF_QUEUE inject the packet into a different queue
249 * (the target queue number is in the high 16 bits of the verdict)
250 * - NF_REPEAT iterate the same cycle once more
251 * - NF_STOP accept, but don't continue iterations
253 * Data and information about the packet can be fetch by using message parsing
254 * functions (See \link Parsing \endlink).
259 * nfq_fd - get the file descriptor associated with the nfqueue handler
260 * \param h Netfilter queue connection handle obtained via call to nfq_open()
262 * \return a file descriptor for the netlink connection associated with the
263 * given queue connection handle. The file descriptor can then be used for
264 * receiving the queued packets for processing.
266 * This function returns a file descriptor that can be used for communication
267 * over the netlink connection associated with the given queue connection
270 int nfq_fd(struct nfq_handle *h)
272 return nfnl_fd(nfq_nfnlh(h));
280 * \defgroup LibrarySetup Library setup
282 * Library initialisation is made in two steps.
284 * First step is to call nfq_open() to open a NFQUEUE handler.
286 * Second step is to tell the kernel that userspace queueing is handle by
287 * NFQUEUE for the selected protocol. This is made by calling nfq_unbind_pf()
288 * and nfq_bind_pf() with protocol information. The idea behind this is to
289 * enable simultaneously loaded modules to be used for queuing.
291 * Here's a little code snippet that bind with AF_INET:
295 fprintf(stderr, "error during nfq_open()\n");
299 printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
300 if (nfq_unbind_pf(h, AF_INET) < 0) {
301 fprintf(stderr, "error during nfq_unbind_pf()\n");
305 printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
306 if (nfq_bind_pf(h, AF_INET) < 0) {
307 fprintf(stderr, "error during nfq_bind_pf()\n");
311 * Once this is done, you can setup and use a \link Queue \endlink.
316 * nfq_open - open a nfqueue handler
318 * This function obtains a netfilter queue connection handle. When you are
319 * finished with the handle returned by this function, you should destroy
320 * it by calling nfq_close(). A new netlink connection is obtained internally
321 * and associated with the queue connection handle returned.
323 * \return a pointer to a new queue handle or NULL on failure.
325 struct nfq_handle *nfq_open(void)
327 struct nfnl_handle *nfnlh = nfnl_open();
328 struct nfq_handle *qh;
333 /* unset netlink sequence tracking by default */
334 nfnl_unset_sequence_tracking(nfnlh);
336 qh = nfq_open_nfnl(nfnlh);
348 * nfq_open_nfnl - open a nfqueue handler from a existing nfnetlink handler
349 * \param nfnlh Netfilter netlink connection handle obtained by calling nfnl_open()
351 * This function obtains a netfilter queue connection handle using an existing
352 * netlink connection. This function is used internally to implement
353 * nfq_open(), and should typically not be called directly.
355 * \return a pointer to a new queue handle or NULL on failure.
357 struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh)
359 struct nfq_handle *h;
362 h = malloc(sizeof(*h));
366 memset(h, 0, sizeof(*h));
369 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE,
372 /* FIXME: nfq_errno */
377 err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
385 nfnl_subsys_close(h->nfnlssh);
392 * \addtogroup LibrarySetup
394 * When the program has finished with libnetfilter_queue, it has to call
395 * the nfq_close() function to free all associated resources.
401 * nfq_close - close a nfqueue handler
402 * \param h Netfilter queue connection handle obtained via call to nfq_open()
404 * This function closes the nfqueue handler and free associated resources.
406 * \return 0 on success, non-zero on failure.
408 int nfq_close(struct nfq_handle *h)
412 ret = nfnl_close(h->nfnlh);
419 * nfq_bind_pf - bind a nfqueue handler to a given protocol family
420 * \param h Netfilter queue connection handle obtained via call to nfq_open()
421 * \param pf protocol family to bind to nfqueue handler obtained from nfq_open()
423 * Binds the given queue connection handle to process packets belonging to
424 * the given protocol family (ie. PF_INET, PF_INET6, etc).
426 * \return integer inferior to 0 in case of failure
428 int nfq_bind_pf(struct nfq_handle *h, u_int16_t pf)
430 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
434 * nfq_unbind_pf - unbind nfqueue handler from a protocol family
435 * \param h Netfilter queue connection handle obtained via call to nfq_open()
436 * \param pf protocol family to unbind family from
438 * Unbinds the given queue connection handle from processing packets belonging
439 * to the given protocol family.
441 int nfq_unbind_pf(struct nfq_handle *h, u_int16_t pf)
443 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
458 * nfq_create_queue - create a new queue handle and return it.
460 * \param h Netfilter queue connection handle obtained via call to nfq_open()
461 * \param num the number of the queue to bind to
462 * \param cb callback function to call for each queued packet
463 * \param data custom data to pass to the callback function
465 * \return a nfq_q_handle pointing to the newly created queue
467 * Creates a new queue handle, and returns it. The new queue is identified by
468 * #num, and the callback specified by #cb will be called for each enqueued
469 * packet. The #data argument will be passed unchanged to the callback. If
470 * a queue entry with id #num already exists, this function will return failure
471 * and the existing entry is unchanged.
473 * The nfq_callback type is defined in libnetfilter_queue.h as:
475 typedef int nfq_callback(struct nfq_q_handle *qh,
476 struct nfgenmsg *nfmsg,
477 struct nfq_data *nfad, void *data);
481 * - qh The queue handle returned by nfq_create_queue
482 * - nfmsg message objetc that contains the packet
483 * - nfad Netlink packet data handle
484 * - data the value passed to the data parameter of nfq_create_queue
486 * The callback should return < 0 to stop processing.
489 struct nfq_q_handle *nfq_create_queue(struct nfq_handle *h,
495 struct nfq_q_handle *qh;
500 qh = malloc(sizeof(*qh));
502 memset(qh, 0, sizeof(*qh));
508 ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
529 * nfq_destroy_queue - destroy a queue handle
530 * \param qh queue handle that we want to destroy created via nfq_create_queue
532 * Removes the binding for the specified queue handle. This call also unbind
533 * from the nfqueue handler, so you don't have to call nfq_unbind_pf.
535 int nfq_destroy_queue(struct nfq_q_handle *qh)
537 int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
547 * nfq_handle_packet - handle a packet received from the nfqueue subsystem
548 * \param h Netfilter queue connection handle obtained via call to nfq_open()
549 * \param buf data to pass to the callback
550 * \param len length of packet data in buffer
552 * Triggers an associated callback for the given packet received from the
553 * queue. Packets can be read from the queue using nfq_fd() and recv(). See
554 * example code for nfq_fd().
556 * \return 0 on success, non-zero on failure.
558 int nfq_handle_packet(struct nfq_handle *h, char *buf, int len)
560 return nfnl_handle_packet(h->nfnlh, buf, len);
564 * nfq_set_mode - set the amount of packet data that nfqueue copies to userspace
565 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
566 * \param mode the part of the packet that we are interested in
567 * \param range size of the packet that we want to get
569 * Sets the amount of data to be copied to userspace for each packet queued
570 * to the given queue.
572 * - NFQNL_COPY_NONE - do not copy any data
573 * - NFQNL_COPY_META - copy only packet metadata
574 * - NFQNL_COPY_PACKET - copy entire packet
576 * \return -1 on error; >=0 otherwise.
578 int nfq_set_mode(struct nfq_q_handle *qh,
579 u_int8_t mode, u_int32_t range)
582 char buf[NFNL_HEADER_LEN
583 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
586 struct nfqnl_msg_config_params params;
588 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
589 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
591 params.copy_range = htonl(range);
592 params.copy_mode = mode;
593 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_PARAMS, ¶ms,
596 return nfnl_query(qh->h->nfnlh, &u.nmh);
600 * nfq_set_queue_maxlen - Set kernel queue maximum length parameter
601 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
602 * \param queuelen the length of the queue
604 * Sets the size of the queue in kernel. This fixes the maximum number
605 * of packets the kernel will store before internally before dropping
608 * \return -1 on error; >=0 otherwise.
610 int nfq_set_queue_maxlen(struct nfq_q_handle *qh,
614 char buf[NFNL_HEADER_LEN
615 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
618 u_int32_t queue_maxlen = htonl(queuelen);
620 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
621 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
623 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_QUEUE_MAXLEN, &queue_maxlen,
624 sizeof(queue_maxlen));
626 return nfnl_query(qh->h->nfnlh, &u.nmh);
633 static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id,
634 u_int32_t verdict, u_int32_t mark, int set_mark,
635 u_int32_t data_len, const unsigned char *data)
637 struct nfqnl_msg_verdict_hdr vh;
639 char buf[NFNL_HEADER_LEN
640 +NFA_LENGTH(sizeof(mark))
641 +NFA_LENGTH(sizeof(vh))];
648 /* This must be declared here (and not inside the data
649 * handling block) because the iovec points to this. */
650 struct nfattr data_attr;
652 memset(iov, 0, sizeof(iov));
654 vh.verdict = htonl(verdict);
657 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
658 NFQNL_MSG_VERDICT, NLM_F_REQUEST);
660 /* add verdict header */
661 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_VERDICT_HDR, &vh, sizeof(vh));
664 nfnl_addattr32(&u.nmh, sizeof(u), NFQA_MARK, mark);
666 iov[0].iov_base = &u.nmh;
667 iov[0].iov_len = NLMSG_TAIL(&u.nmh) - (void *)&u.nmh;
671 /* The typecast here is to cast away data's const-ness: */
672 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
673 data_len, (unsigned char *) data);
675 /* Add the length of the appended data to the message
676 * header. The size of the attribute is given in the
677 * nfa_len field and is set in the nfnl_build_nfa_iovec()
679 u.nmh.nlmsg_len += data_attr.nfa_len;
682 return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
691 * nfq_set_verdict - issue a verdict on a packet
692 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
693 * \param id ID assigned to packet by netfilter.
694 * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
695 * \param data_len number of bytes of data pointed to by #buf
696 * \param buf the buffer that contains the packet data
698 * Can be obtained by:
701 struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(tb);
703 id = ntohl(ph->packet_id);
706 * Notifies netfilter of the userspace verdict for the given packet. Every
707 * queued packet _must_ have a verdict specified by userspace, either by
708 * calling this function, or by calling the nfq_set_verdict2() function.
710 * \return -1 on error; >= 0 otherwise.
712 int nfq_set_verdict(struct nfq_q_handle *qh, u_int32_t id,
713 u_int32_t verdict, u_int32_t data_len,
714 const unsigned char *buf)
716 return __set_verdict(qh, id, verdict, 0, 0, data_len, buf);
720 * nfq_set_verdict2 - like nfq_set_verdict, but you can set the mark.
721 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
722 * \param id ID assigned to packet by netfilter.
723 * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
724 * \param mark mark to put on packet
725 * \param data_len number of bytes of data pointed to by #buf
726 * \param buf the buffer that contains the packet data
728 int nfq_set_verdict2(struct nfq_q_handle *qh, u_int32_t id,
729 u_int32_t verdict, u_int32_t mark,
730 u_int32_t data_len, const unsigned char *buf)
732 return __set_verdict(qh, id, verdict, htonl(mark), 1, data_len, buf);
736 * nfq_set_verdict_mark - like nfq_set_verdict, but you can set the mark.
737 * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
738 * \param id ID assigned to packet by netfilter.
739 * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
740 * \param mark the mark to put on the packet, in network byte order.
741 * \param data_len number of bytes of data pointed to by #buf
742 * \param buf the buffer that contains the packet data
744 * \return -1 on error; >= 0 otherwise.
746 * This function is deprecated since it is broken, its use is highly
747 * discouraged. Please, use nfq_set_verdict2 instead.
749 int nfq_set_verdict_mark(struct nfq_q_handle *qh, u_int32_t id,
750 u_int32_t verdict, u_int32_t mark,
751 u_int32_t data_len, const unsigned char *buf)
753 return __set_verdict(qh, id, verdict, mark, 1, data_len, buf);
762 /*************************************************************
763 * Message parsing functions
764 *************************************************************/
767 * \defgroup Parsing Message parsing functions
772 * nfqnl_msg_packet_hdr - return the metaheader that wraps the packet
773 * \param nfad Netlink packet data handle passed to callback function
775 * \return the netfilter queue netlink packet header for the given
776 * nfq_data argument. Typically, the nfq_data value is passed as the 3rd
777 * parameter to the callback function set by a call to nfq_create_queue().
779 * The nfqnl_msg_packet_hdr structure is defined in libnetfilter_queue.h as:
782 struct nfqnl_msg_packet_hdr {
783 u_int32_t packet_id; // unique ID of packet in queue
784 u_int16_t hw_protocol; // hw protocol (network order)
785 u_int8_t hook; // netfilter hook
786 } __attribute__ ((packed));
789 struct nfqnl_msg_packet_hdr *nfq_get_msg_packet_hdr(struct nfq_data *nfad)
791 return nfnl_get_pointer_to_data(nfad->data, NFQA_PACKET_HDR,
792 struct nfqnl_msg_packet_hdr);
796 * nfq_get_nfmark - get the packet mark
797 * \param nfad Netlink packet data handle passed to callback function
799 * \return the netfilter mark currently assigned to the given queued packet.
801 uint32_t nfq_get_nfmark(struct nfq_data *nfad)
803 return ntohl(nfnl_get_data(nfad->data, NFQA_MARK, u_int32_t));
807 * nfq_get_timestamp - get the packet timestamp
808 * \param nfad Netlink packet data handle passed to callback function
809 * \param tv structure to fill with timestamp info
811 * Retrieves the received timestamp when the given queued packet.
813 * \return 0 on success, non-zero on failure.
815 int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv)
817 struct nfqnl_msg_packet_timestamp *qpt;
818 qpt = nfnl_get_pointer_to_data(nfad->data, NFQA_TIMESTAMP,
819 struct nfqnl_msg_packet_timestamp);
823 tv->tv_sec = __be64_to_cpu(qpt->sec);
824 tv->tv_usec = __be64_to_cpu(qpt->usec);
830 * nfq_get_indev - get the interface that the packet was received through
831 * \param nfad Netlink packet data handle passed to callback function
833 * \return The index of the device the queued packet was received via. If the
834 * returned index is 0, the packet was locally generated or the input
835 * interface is not known (ie. POSTROUTING?).
837 * \warning all nfq_get_dev() functions return 0 if not set, since linux
838 * only allows ifindex >= 1, see net/core/dev.c:2600 (in 2.6.13.1)
840 u_int32_t nfq_get_indev(struct nfq_data *nfad)
842 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_INDEV, u_int32_t));
846 * nfq_get_physindev - get the physical interface that the packet was received
847 * \param nfad Netlink packet data handle passed to callback function
849 * \return The index of the physical device the queued packet was received via.
850 * If the returned index is 0, the packet was locally generated or the
851 * physical input interface is no longer known (ie. POSTROUTING?).
853 u_int32_t nfq_get_physindev(struct nfq_data *nfad)
855 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSINDEV, u_int32_t));
859 * nfq_get_outdev - gets the interface that the packet will be routed out
860 * \param nfad Netlink packet data handle passed to callback function
862 * \return The index of the device the queued packet will be sent out. If the
863 * returned index is 0, the packet is destined for localhost or the output
864 * interface is not yet known (ie. PREROUTING?).
866 u_int32_t nfq_get_outdev(struct nfq_data *nfad)
868 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_OUTDEV, u_int32_t));
872 * nfq_get_physoutdev - get the physical interface that the packet output
873 * \param nfad Netlink packet data handle passed to callback function
875 * The index of the physical device the queued packet will be sent out.
876 * If the returned index is 0, the packet is destined for localhost or the
877 * physical output interface is not yet known (ie. PREROUTING?).
879 * \return The index of physical interface that the packet output will be routed out.
881 u_int32_t nfq_get_physoutdev(struct nfq_data *nfad)
883 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
887 * nfq_get_indev_name - get the name of the interface the packet
888 * was received through
889 * \param nlif_handle pointer to a nlif interface resolving handle
890 * \param nfad Netlink packet data handle passed to callback function
891 * \param name pointer to the buffer to receive the interface name;
892 * not more than \c IFNAMSIZ bytes will be copied to it.
893 * \return -1 in case of error, >0 if it succeed.
895 * To use a nlif_handle, You need first to call nlif_open() and to open
896 * an handler. Don't forget to store the result as it will be used
897 * during all your program life:
905 * Once the handler is open, you need to fetch the interface table at a
906 * whole via a call to nlif_query.
910 * libnfnetlink is able to update the interface mapping when a new interface
911 * appears. To do so, you need to call nlif_catch() on the handler after each
912 * interface related event. The simplest way to get and treat event is to run
913 * a select() or poll() against the nlif file descriptor. To get this file
914 * descriptor, you need to use nlif_fd:
918 * Don't forget to close the handler when you don't need the feature anymore:
924 int nfq_get_indev_name(struct nlif_handle *nlif_handle,
925 struct nfq_data *nfad, char *name)
927 u_int32_t ifindex = nfq_get_indev(nfad);
928 return nlif_index2name(nlif_handle, ifindex, name);
932 * nfq_get_physindev_name - get the name of the physical interface the
933 * packet was received through
934 * \param nlif_handle pointer to a nlif interface resolving handle
935 * \param nfad Netlink packet data handle passed to callback function
936 * \param name pointer to the buffer to receive the interface name;
937 * not more than \c IFNAMSIZ bytes will be copied to it.
939 * See nfq_get_indev_name() documentation for nlif_handle usage.
941 * \return -1 in case of error, > 0 if it succeed.
943 int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
944 struct nfq_data *nfad, char *name)
946 u_int32_t ifindex = nfq_get_physindev(nfad);
947 return nlif_index2name(nlif_handle, ifindex, name);
951 * nfq_get_outdev_name - get the name of the physical interface the
952 * packet will be sent to
953 * \param nlif_handle pointer to a nlif interface resolving handle
954 * \param nfad Netlink packet data handle passed to callback function
955 * \param name pointer to the buffer to receive the interface name;
956 * not more than \c IFNAMSIZ bytes will be copied to it.
958 * See nfq_get_indev_name() documentation for nlif_handle usage.
960 * \return -1 in case of error, > 0 if it succeed.
962 int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
963 struct nfq_data *nfad, char *name)
965 u_int32_t ifindex = nfq_get_outdev(nfad);
966 return nlif_index2name(nlif_handle, ifindex, name);
970 * nfq_get_physoutdev_name - get the name of the interface the
971 * packet will be sent to
972 * \param nlif_handle pointer to a nlif interface resolving handle
973 * \param nfad Netlink packet data handle passed to callback function
974 * \param name pointer to the buffer to receive the interface name;
975 * not more than \c IFNAMSIZ bytes will be copied to it.
977 * See nfq_get_indev_name() documentation for nlif_handle usage.
979 * \return -1 in case of error, > 0 if it succeed.
982 int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
983 struct nfq_data *nfad, char *name)
985 u_int32_t ifindex = nfq_get_physoutdev(nfad);
986 return nlif_index2name(nlif_handle, ifindex, name);
992 * get hardware address
994 * \param nfad Netlink packet data handle passed to callback function
996 * Retrieves the hardware address associated with the given queued packet.
997 * For ethernet packets, the hardware address returned (if any) will be the
998 * MAC address of the packet source host. The destination MAC address is not
999 * known until after POSTROUTING and a successful ARP request, so cannot
1000 * currently be retrieved.
1002 * The nfqnl_msg_packet_hw structure is defined in libnetfilter_queue.h as:
1004 struct nfqnl_msg_packet_hw {
1005 u_int16_t hw_addrlen;
1007 u_int8_t hw_addr[8];
1008 } __attribute__ ((packed));
1011 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
1013 return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
1014 struct nfqnl_msg_packet_hw);
1018 * nfq_get_payload - get payload
1019 * \param nfad Netlink packet data handle passed to callback function
1020 * \param data Pointer of pointer that will be pointed to the payload
1022 * Retrieve the payload for a queued packet. The actual amount and type of
1023 * data retrieved by this function will depend on the mode set with the
1024 * nfq_set_mode() function.
1026 * \return -1 on error, otherwise > 0.
1028 int nfq_get_payload(struct nfq_data *nfad, unsigned char **data)
1030 *data = nfnl_get_pointer_to_data(nfad->data, NFQA_PAYLOAD, char);
1032 return NFA_PAYLOAD(nfad->data[NFQA_PAYLOAD-1]);
1041 #define SNPRINTF_FAILURE(ret, rem, offset, len) \
1053 * \defgroup Printing
1058 * nfq_snprintf_xml - print the enqueued packet in XML format into a buffer
1059 * \param buf The buffer that you want to use to print the logged packet
1060 * \param rem The size of the buffer that you have passed
1061 * \param tb Netlink packet data handle passed to callback function
1062 * \param flags The flag that tell what to print into the buffer
1064 * This function supports the following flags:
1066 * - NFQ_XML_HW: include the hardware link layer address
1067 * - NFQ_XML_MARK: include the packet mark
1068 * - NFQ_XML_DEV: include the device information
1069 * - NFQ_XML_PHYSDEV: include the physical device information
1070 * - NFQ_XML_PAYLOAD: include the payload (in hexadecimal)
1071 * - NFQ_XML_TIME: include the timestamp
1072 * - NFQ_XML_ALL: include all the logging information (all flags set)
1074 * You can combine this flags with an binary OR.
1076 * \return -1 in case of failure, otherwise the length of the string that
1077 * would have been printed into the buffer (in case that there is enough
1078 * room in it). See snprintf() return value for more information.
1080 int nfq_snprintf_xml(char *buf, size_t rem, struct nfq_data *tb, int flags)
1082 struct nfqnl_msg_packet_hdr *ph;
1083 struct nfqnl_msg_packet_hw *hwph;
1084 u_int32_t mark, ifi;
1085 int size, offset = 0, len = 0, ret;
1086 unsigned char *data;
1088 size = snprintf(buf + offset, rem, "<pkt>");
1089 SNPRINTF_FAILURE(size, rem, offset, len);
1091 if (flags & NFQ_XML_TIME) {
1096 if (localtime_r(&t, &tm) == NULL)
1099 size = snprintf(buf + offset, rem, "<when>");
1100 SNPRINTF_FAILURE(size, rem, offset, len);
1102 size = snprintf(buf + offset, rem,
1103 "<hour>%d</hour>", tm.tm_hour);
1104 SNPRINTF_FAILURE(size, rem, offset, len);
1106 size = snprintf(buf + offset,
1107 rem, "<min>%02d</min>", tm.tm_min);
1108 SNPRINTF_FAILURE(size, rem, offset, len);
1110 size = snprintf(buf + offset,
1111 rem, "<sec>%02d</sec>", tm.tm_sec);
1112 SNPRINTF_FAILURE(size, rem, offset, len);
1114 size = snprintf(buf + offset, rem, "<wday>%d</wday>",
1116 SNPRINTF_FAILURE(size, rem, offset, len);
1118 size = snprintf(buf + offset, rem, "<day>%d</day>", tm.tm_mday);
1119 SNPRINTF_FAILURE(size, rem, offset, len);
1121 size = snprintf(buf + offset, rem, "<month>%d</month>",
1123 SNPRINTF_FAILURE(size, rem, offset, len);
1125 size = snprintf(buf + offset, rem, "<year>%d</year>",
1127 SNPRINTF_FAILURE(size, rem, offset, len);
1129 size = snprintf(buf + offset, rem, "</when>");
1130 SNPRINTF_FAILURE(size, rem, offset, len);
1133 ph = nfq_get_msg_packet_hdr(tb);
1135 size = snprintf(buf + offset, rem,
1136 "<hook>%u</hook><id>%u</id>",
1137 ph->hook, ntohl(ph->packet_id));
1138 SNPRINTF_FAILURE(size, rem, offset, len);
1140 hwph = nfq_get_packet_hw(tb);
1141 if (hwph && (flags & NFQ_XML_HW)) {
1142 int i, hlen = ntohs(hwph->hw_addrlen);
1144 size = snprintf(buf + offset, rem, "<hw><proto>%04x"
1146 ntohs(ph->hw_protocol));
1147 SNPRINTF_FAILURE(size, rem, offset, len);
1149 size = snprintf(buf + offset, rem, "<src>");
1150 SNPRINTF_FAILURE(size, rem, offset, len);
1152 for (i=0; i<hlen; i++) {
1153 size = snprintf(buf + offset, rem, "%02x",
1155 SNPRINTF_FAILURE(size, rem, offset, len);
1158 size = snprintf(buf + offset, rem, "</src></hw>");
1159 SNPRINTF_FAILURE(size, rem, offset, len);
1160 } else if (flags & NFQ_XML_HW) {
1161 size = snprintf(buf + offset, rem, "<hw><proto>%04x"
1163 ntohs(ph->hw_protocol));
1164 SNPRINTF_FAILURE(size, rem, offset, len);
1168 mark = nfq_get_nfmark(tb);
1169 if (mark && (flags & NFQ_XML_MARK)) {
1170 size = snprintf(buf + offset, rem, "<mark>%u</mark>", mark);
1171 SNPRINTF_FAILURE(size, rem, offset, len);
1174 ifi = nfq_get_indev(tb);
1175 if (ifi && (flags & NFQ_XML_DEV)) {
1176 size = snprintf(buf + offset, rem, "<indev>%u</indev>", ifi);
1177 SNPRINTF_FAILURE(size, rem, offset, len);
1180 ifi = nfq_get_outdev(tb);
1181 if (ifi && (flags & NFQ_XML_DEV)) {
1182 size = snprintf(buf + offset, rem, "<outdev>%u</outdev>", ifi);
1183 SNPRINTF_FAILURE(size, rem, offset, len);
1186 ifi = nfq_get_physindev(tb);
1187 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1188 size = snprintf(buf + offset, rem,
1189 "<physindev>%u</physindev>", ifi);
1190 SNPRINTF_FAILURE(size, rem, offset, len);
1193 ifi = nfq_get_physoutdev(tb);
1194 if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1195 size = snprintf(buf + offset, rem,
1196 "<physoutdev>%u</physoutdev>", ifi);
1197 SNPRINTF_FAILURE(size, rem, offset, len);
1200 ret = nfq_get_payload(tb, &data);
1201 if (ret >= 0 && (flags & NFQ_XML_PAYLOAD)) {
1204 size = snprintf(buf + offset, rem, "<payload>");
1205 SNPRINTF_FAILURE(size, rem, offset, len);
1207 for (i=0; i<ret; i++) {
1208 size = snprintf(buf + offset, rem, "%02x",
1210 SNPRINTF_FAILURE(size, rem, offset, len);
1213 size = snprintf(buf + offset, rem, "</payload>");
1214 SNPRINTF_FAILURE(size, rem, offset, len);
1217 size = snprintf(buf + offset, rem, "</pkt>");
1218 SNPRINTF_FAILURE(size, rem, offset, len);