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>
37 struct nfnl_handle *nfnlh;
38 struct nfnl_subsys_handle *nfnlssh;
39 struct nfq_q_handle *qh_list;
44 struct nfq_q_handle *next;
58 /***********************************************************************
60 ***********************************************************************/
62 static void del_qh(struct nfq_q_handle *qh)
64 struct nfq_q_handle *cur_qh, *prev_qh = NULL;
66 for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) {
69 prev_qh->next = qh->next;
71 qh->h->qh_list = qh->next;
78 static void add_qh(struct nfq_q_handle *qh)
80 qh->next = qh->h->qh_list;
84 static struct nfq_q_handle *find_qh(struct nfq_handle *h, u_int16_t id)
86 struct nfq_q_handle *qh;
88 for (qh = h->qh_list; qh; qh = qh->next) {
95 /* build a NFQNL_MSG_CONFIG message */
97 __build_send_cfg_msg(struct nfq_handle *h, u_int8_t command,
98 u_int16_t queuenum, u_int16_t pf)
101 char buf[NFNL_HEADER_LEN
102 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))];
105 struct nfqnl_msg_config_cmd cmd;
107 nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, AF_UNSPEC, queuenum,
108 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
110 cmd.command = command;
112 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_CMD, &cmd, sizeof(cmd));
114 return nfnl_talk(h->nfnlh, &u.nmh, 0, 0, NULL, NULL, NULL);
117 static int __nfq_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
120 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
121 struct nfq_handle *h = data;
122 u_int16_t queue_num = ntohs(nfmsg->res_id);
123 struct nfq_q_handle *qh = find_qh(h, queue_num);
124 struct nfq_data nfqa;
134 return qh->cb(qh, nfmsg, &nfqa, qh->data);
137 static struct nfnl_callback pkt_cb = {
138 .call = &__nfq_rcv_pkt,
139 .attr_count = NFQA_MAX,
142 /* public interface */
144 struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h)
150 * nfq_fd - get the file descriptor associated with the nfqueue handler
151 * @h: Netfilter queue connection handle obtained via call to nfq_open()
153 * Returns a file descriptor for the netlink connection associated with the
154 * given queue connection handle. The file descriptor can then be used for
155 * receiving the queued packets for processing.
160 * while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
161 * printf("pkt received\n");
162 * nfq_handle_packet(h, buf, rv);
165 * This function returns a file descriptor that can be used for communication
166 * over the netlink connection associated with the given queue connection
169 int nfq_fd(struct nfq_handle *h)
171 return nfnl_fd(nfq_nfnlh(h));
175 * nfq_open - open a nfqueue handler
177 * This function obtains a netfilter queue connection handle. When you are
178 * finished with the handle returned by this function, you should destroy
179 * it by calling nfq_close(). A new netlink connection is obtained internally
180 * and associated with the queue connection handle returned.
182 * This function returns a pointer to a new queue handle or NULL on failure.
184 struct nfq_handle *nfq_open(void)
186 struct nfnl_handle *nfnlh = nfnl_open();
187 struct nfq_handle *qh;
192 qh = nfq_open_nfnl(nfnlh);
200 * nfq_open_nfnl - open a nfqueue handler from a existing nfnetlink handler
201 * @nfnlh: Netfilter netlink connection handle obtained by calling nfnl_open()
203 * This function obtains a netfilter queue connection handle using an existing
204 * netlink connection. This function is used internally to implement
205 * nfq_open(), and should typically not be called directly.
207 * This function returns a pointer to a new queue handle or NULL on failure.
209 struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh)
211 struct nfq_handle *h;
214 h = malloc(sizeof(*h));
218 memset(h, 0, sizeof(*h));
221 h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE,
224 /* FIXME: nfq_errno */
229 err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
237 nfnl_subsys_close(h->nfnlssh);
244 * nfq_close - close a nfqueue handler
245 * @h: Netfilter queue connection handle obtained via call to nfq_open()
247 * This function closes the nfqueue handler and free associated resources.
249 * This function returns 0 on success, non-zero on failure.
251 int nfq_close(struct nfq_handle *h)
255 nfnl_subsys_close(h->nfnlssh);
256 ret = nfnl_close(h->nfnlh);
263 * nfq_bind_pf - bind a nfqueue handler to a given protocol family
264 * @h: Netfilter queue connection handle obtained via call to nfq_open()
265 * @pf: protocol family to bind to nfqueue handler obtained from nfq_open()
267 * Binds the given queue connection handle to process packets belonging to
268 * the given protocol family (ie. PF_INET, PF_INET6, etc).
270 int nfq_bind_pf(struct nfq_handle *h, u_int16_t pf)
272 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
276 * nfq_unbind_pf - unbind nfqueue handler from a protocol family
277 * @h: Netfilter queue connection handle obtained via call to nfq_open()
278 * @pf: protocol family to unbind family from
280 * Unbinds the given queue connection handle from processing packets belonging
281 * to the given protocol family.
283 int nfq_unbind_pf(struct nfq_handle *h, u_int16_t pf)
285 return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
289 * nfq_create_queue - create a new queue handle and return it.
290 * @h: Netfilter queue connection handle obtained via call to nfq_open()
291 * @num: the number of the queue to bind to
292 * @cb: callback function to call for each queued packet
293 * @data: custom data to pass to the callback function
295 * Creates a new queue handle, and returns it. The new queue is identified by
296 * <num>, and the callback specified by <cb> will be called for each enqueued
297 * packet. The <data> argument will be passed unchanged to the callback. If
298 * a queue entry with id <num> already exists, this function will return failure
299 * and the existing entry is unchanged.
301 * The nfq_callback type is defined in libnetfilter_queue.h as:
303 * typedef int nfq_callback(struct nfq_q_handle *qh,
304 * struct nfgenmsg *nfmsg,
305 * struct nfq_data *nfad, void *data);
308 * @qh: The queue handle returned by nfq_create_queue
309 * @nfmsg: message objetc that contains the packet
310 * @nfq_data: Netlink packet data handle
311 * @data: the value passed to the data parameter of nfq_create_queue
313 * The callback should return < 0 to stop processing.
315 struct nfq_q_handle *nfq_create_queue(struct nfq_handle *h,
321 struct nfq_q_handle *qh;
326 qh = malloc(sizeof(*qh));
328 memset(qh, 0, sizeof(*qh));
334 ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
346 * nfq_destroy_queue - destroy a queue handle
347 * @qh: queue handle that we want to destroy created via nfq_create_queue
349 * Removes the binding for the specified queue handle. This call also unbind
350 * from the nfqueue handler, so you don't have to call nfq_unbind_pf.
352 int nfq_destroy_queue(struct nfq_q_handle *qh)
354 int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
364 * nfq_handle_packet - handle a packet received from the nfqueue subsystem
365 * @h: Netfilter queue connection handle obtained via call to nfq_open()
366 * @buf: data to pass to the callback
367 * @len: length of packet data in buffer
369 * Triggers an associated callback for the given packet received from the
370 * queue. Packets can be read from the queue using nfq_fd() and recv(). See
371 * example code for nfq_fd().
373 * Returns 0 on success, non-zero on failure.
375 int nfq_handle_packet(struct nfq_handle *h, char *buf, int len)
377 return nfnl_handle_packet(h->nfnlh, buf, len);
381 * nfq_set_mode - set the amount of packet data that nfqueue copies to userspace
382 * @qh: Netfilter queue handle obtained by call to nfq_create_queue().
383 * @mode: the part of the packet that we are interested in
384 * @range: size of the packet that we want to get
386 * Sets the amount of data to be copied to userspace for each packet queued
387 * to the given queue.
389 * - NFQNL_COPY_NONE - do not copy any data
390 * - NFQNL_COPY_META - copy only packet metadata
391 * - NFQNL_COPY_PACKET - copy entire packet
393 int nfq_set_mode(struct nfq_q_handle *qh,
394 u_int8_t mode, u_int32_t range)
397 char buf[NFNL_HEADER_LEN
398 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
401 struct nfqnl_msg_config_params params;
403 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
404 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
406 params.copy_range = htonl(range);
407 params.copy_mode = mode;
408 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_PARAMS, ¶ms,
411 return nfnl_talk(qh->h->nfnlh, &u.nmh, 0, 0, NULL, NULL, NULL);
415 * nfq_set_queue_maxlen - Set kernel queue maximum length parameter
416 * @qh: Netfilter queue handle obtained by call to nfq_create_queue().
417 * @queuelen: the length of the queue
419 * Sets the size of the queue in kernel. This fixes the maximum number
420 * of packets the kernel will store before internally before dropping
423 int nfq_set_queue_maxlen(struct nfq_q_handle *qh,
427 char buf[NFNL_HEADER_LEN
428 +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
431 u_int32_t queue_maxlen = htonl(queuelen);
433 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
434 NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
436 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_QUEUE_MAXLEN, &queue_maxlen,
437 sizeof(queue_maxlen));
439 return nfnl_talk(qh->h->nfnlh, &u.nmh, 0, 0, NULL, NULL, NULL);
442 static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id,
443 u_int32_t verdict, u_int32_t mark, int set_mark,
444 u_int32_t data_len, unsigned char *data)
446 struct nfqnl_msg_verdict_hdr vh;
448 char buf[NFNL_HEADER_LEN
449 +NFA_LENGTH(sizeof(mark))
450 +NFA_LENGTH(sizeof(vh))];
457 /* This must be declared here (and not inside the data
458 * handling block) because the iovec points to this. */
459 struct nfattr data_attr;
461 memset(iov, 0, sizeof(iov));
463 vh.verdict = htonl(verdict);
466 nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
467 NFQNL_MSG_VERDICT, NLM_F_REQUEST);
469 /* add verdict header */
470 nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_VERDICT_HDR, &vh, sizeof(vh));
473 nfnl_addattr32(&u.nmh, sizeof(u), NFQA_MARK, mark);
475 iov[0].iov_base = &u.nmh;
476 iov[0].iov_len = NLMSG_TAIL(&u.nmh) - (void *)&u.nmh;
480 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
483 /* Add the length of the appended data to the message
484 * header. The size of the attribute is given in the
485 * nfa_len field and is set in the nfnl_build_nfa_iovec()
487 u.nmh.nlmsg_len += data_attr.nfa_len;
490 return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
494 * nfq_set_verdict - issue a verdict on a packet
495 * @qh: Netfilter queue handle obtained by call to nfq_create_queue().
496 * @id: ID assigned to packet by netfilter.
497 * @verdict: verdict to return to netfilter (NF_ACCEPT, NF_DROP)
498 * @data_len: number of bytes of data pointed to by <buf>
499 * @buf: the buffer that contains the packet data
501 * Can be obtained by:
504 * struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(tb);
507 * id = ntohl(ph->packet_id);
509 * Notifies netfilter of the userspace verdict for the given packet. Every
510 * queued packet _must_ have a verdict specified by userspace, either by
511 * calling this function, or by calling the nfq_set_verdict_mark() function.
513 int nfq_set_verdict(struct nfq_q_handle *qh, u_int32_t id,
514 u_int32_t verdict, u_int32_t data_len,
517 return __set_verdict(qh, id, verdict, 0, 0, data_len, buf);
521 * nfq_set_verdict_mark - like nfq_set_verdict, but you can set the mark.
522 * @qh: Netfilter queue handle obtained by call to nfq_create_queue().
523 * @id: ID assigned to packet by netfilter.
524 * @verdict: verdict to return to netfilter (NF_ACCEPT, NF_DROP)
525 * @mark: mark to put on packet
526 * @data_len: number of bytes of data pointed to by <buf>
527 * @buf: the buffer that contains the packet data
530 int nfq_set_verdict_mark(struct nfq_q_handle *qh, u_int32_t id,
531 u_int32_t verdict, u_int32_t mark,
532 u_int32_t datalen, unsigned char *buf)
534 return __set_verdict(qh, id, verdict, mark, 1, datalen, buf);
537 /*************************************************************
538 * Message parsing functions
539 *************************************************************/
542 * nfqnl_msg_packet_hdr - return the metaheader that wraps the packet
543 * @nfad: Netlink packet data handle passed to callback function
545 * Returns the netfilter queue netlink packet header for the given
546 * nfq_data argument. Typically, the nfq_data value is passed as the 3rd
547 * parameter to the callback function set by a call to nfq_create_queue().
549 * The nfqnl_msg_packet_hdr structure is defined in libnetfilter_queue.h as:
551 * struct nfqnl_msg_packet_hdr {
552 * u_int32_t packet_id; // unique ID of packet in queue
553 * u_int16_t hw_protocol; // hw protocol (network order)
554 * u_int8_t hook; // netfilter hook
555 * } __attribute__ ((packed));
557 struct nfqnl_msg_packet_hdr *nfq_get_msg_packet_hdr(struct nfq_data *nfad)
559 return nfnl_get_pointer_to_data(nfad->data, NFQA_PACKET_HDR,
560 struct nfqnl_msg_packet_hdr);
564 * nfq_get_nfmark - get the packet mark
565 * @nfad: Netlink packet data handle passed to callback function
567 * Returns the netfilter mark currently assigned to the given queued packet.
569 uint32_t nfq_get_nfmark(struct nfq_data *nfad)
571 return ntohl(nfnl_get_data(nfad->data, NFQA_MARK, u_int32_t));
575 * nfq_get_timestamp - get the packet timestamp
576 * @nfad: Netlink packet data handle passed to callback function
577 * @tv: structure to fill with timestamp info
579 * Retrieves the received timestamp when the given queued packet.
581 * Returns 0 on success, non-zero on failure.
583 int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv)
585 struct nfqnl_msg_packet_timestamp *qpt;
586 qpt = nfnl_get_pointer_to_data(nfad->data, NFQA_TIMESTAMP,
587 struct nfqnl_msg_packet_timestamp);
591 tv->tv_sec = __be64_to_cpu(qpt->sec);
592 tv->tv_usec = __be64_to_cpu(qpt->usec);
598 * nfq_get_indev - get the interface that the packet was received through
599 * @nfad: Netlink packet data handle passed to callback function
601 * The index of the device the queued packet was received via. If the
602 * returned index is 0, the packet was locally generated or the input
603 * interface is not known (ie. POSTROUTING?).
605 * WARNING: all nfq_get_dev() functions return 0 if not set, since linux
606 * only allows ifindex >= 1, see net/core/dev.c:2600 (in 2.6.13.1)
608 u_int32_t nfq_get_indev(struct nfq_data *nfad)
610 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_INDEV, u_int32_t));
614 * nfq_get_physindev - get the physical interface that the packet was received
615 * @nfad: Netlink packet data handle passed to callback function
617 * The index of the physical device the queued packet was received via.
618 * If the returned index is 0, the packet was locally generated or the
619 * physical input interface is no longer known (ie. POSTROUTING?).
621 u_int32_t nfq_get_physindev(struct nfq_data *nfad)
623 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSINDEV, u_int32_t));
627 * nfq_get_outdev - gets the interface that the packet will be routed out
628 * @nfad: Netlink packet data handle passed to callback function
630 * The index of the device the queued packet will be sent out. If the
631 * returned index is 0, the packet is destined for localhost or the output
632 * interface is not yet known (ie. PREROUTING?).
634 u_int32_t nfq_get_outdev(struct nfq_data *nfad)
636 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_OUTDEV, u_int32_t));
640 * nfq_get_physoutdev - get the physical interface that the packet output
641 * @nfad: Netlink packet data handle passed to callback function
643 * The index of the physical device the queued packet will be sent out.
644 * If the returned index is 0, the packet is destined for localhost or the
645 * physical output interface is not yet known (ie. PREROUTING?).
647 * Retrieves the physical interface that the packet output will be routed out.
649 u_int32_t nfq_get_physoutdev(struct nfq_data *nfad)
651 return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
655 * nfq_get_indev_name - get the name of the interface the packet
656 * was received through
657 * @nlif_handle: pointer to a nlif interface resolving handle
658 * @nfad: Netlink packet data handle passed to callback function
659 * @name: pointer that will be set to the interface name string
661 * The <name> variable will point to the name of the input interface.
663 * To use a nlif_handle, You need first to call nlif_open() and to open
664 * an handler. Don't forget to store the result as it will be used
665 * during all your program life:
668 * perror("nlif_open");
669 * exit(EXIT_FAILURE);
671 * Once the handler is open, you need to fetch the interface table at a
672 * whole via a call to nlif_query.
674 * libnfnetlink is able to update the interface mapping when a new interface
675 * appears. To do so, you need to call nlif_catch() on the handler after each
676 * interface related event. The simplest way to get and treat event is to run
677 * a select() or poll() against the nlif file descriptor. To get this file
678 * descriptor, you need to use nlif_fd:
679 * if_fd = nlif_fd(h);
680 * Don't forget to close the handler when you don't need the feature anymore:
683 * Return -1 in case of error, >0 if it succeed.
685 int nfq_get_indev_name(struct nlif_handle *nlif_handle,
686 struct nfq_data *nfad, char *name)
688 u_int32_t ifindex = nfq_get_indev(nfad);
689 return nlif_index2name(nlif_handle, ifindex, name);
693 * nfq_get_physindev_name - get the name of the physical interface the
694 * packet was received through
695 * @nlif_handle: pointer to a nlif interface resolving handle
696 * @nfad: Netlink packet data handle passed to callback function
697 * @name: pointer that will be set to the interface name string
699 * The <name> variable will point to the name of the input physical
702 * See nfq_get_indev_name() documentation for nlif_handle usage.
704 * Return -1 in case of error, >0 if it succeed.
706 int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
707 struct nfq_data *nfad, char *name)
709 u_int32_t ifindex = nfq_get_physindev(nfad);
710 return nlif_index2name(nlif_handle, ifindex, name);
714 * nfq_get_outdev_name - get the name of the physical interface the
715 * packet will be sent to
716 * @nlif_handle: pointer to a nlif interface resolving handle
717 * @nfad: Netlink packet data handle passed to callback function
718 * @name: pointer that will be set to the interface name string
720 * The <name> variable will point to the name of the output interface.
722 * See nfq_get_indev_name() documentation for nlif_handle usage.
724 * Return -1 in case of error, >0 if it succeed.
726 int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
727 struct nfq_data *nfad, char *name)
729 u_int32_t ifindex = nfq_get_outdev(nfad);
730 return nlif_index2name(nlif_handle, ifindex, name);
734 * nfq_get_physoutdev_name - get the name of the interface the
735 * packet will be sent to
736 * @nlif_handle: pointer to a nlif interface resolving handle
737 * @nfad: Netlink packet data handle passed to callback function
738 * @name: pointer that will be set to the interface name string
740 * The <name> variable will point to the name of the physical
743 * See nfq_get_indev_name() documentation for nlif_handle usage.
745 * Return -1 in case of error, >0 if it succeed.
748 int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
749 struct nfq_data *nfad, char *name)
751 u_int32_t ifindex = nfq_get_physoutdev(nfad);
752 return nlif_index2name(nlif_handle, ifindex, name);
756 * nfq_get_packet_hw - get hardware address
757 * @nfad: Netlink packet data handle passed to callback function
759 * Retrieves the hardware address associated with the given queued packet.
760 * For ethernet packets, the hardware address returned (if any) will be the
761 * MAC address of the packet source host. The destination MAC address is not
762 * known until after POSTROUTING and a successful ARP request, so cannot
763 * currently be retrieved.
765 * The nfqnl_msg_packet_hw structure is defined in libnetfilter_queue.h as:
767 * struct nfqnl_msg_packet_hw {
768 * u_int16_t hw_addrlen;
770 * u_int8_t hw_addr[8];
771 * } __attribute__ ((packed));
773 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
775 return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
776 struct nfqnl_msg_packet_hw);
780 * nfq_get_payload - get payload
781 * @nfad: Netlink packet data handle passed to callback function
782 * @data: Pointer of pointer that will be pointed to the payload
784 * Retrieve the payload for a queued packet. The actual amount and type of
785 * data retrieved by this function will depend on the mode set with the
786 * nfq_set_mode() function.
788 * Returns -1 on error, otherwise > 0.
790 int nfq_get_payload(struct nfq_data *nfad, char **data)
792 *data = nfnl_get_pointer_to_data(nfad->data, NFQA_PAYLOAD, char);
794 return NFA_PAYLOAD(nfad->data[NFQA_PAYLOAD-1]);