src: add NFQNL_MSG_VERDICT_BATCH support
[platform/upstream/libnetfilter_queue.git] / src / libnetfilter_queue.c
1 /* libnetfilter_queue.c: generic library for access to nf_queue
2  *
3  * (C) 2005 by Harald Welte <laforge@gnumonks.org>
4  * (C) 2005, 2008-2010 by Pablo Neira Ayuso <pablo@netfilter.org>
5  *
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)
9  *
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.
14  *
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
18  *
19  *  2006-01-23 Andreas Florath <andreas@florath.net>
20  *      Fix __set_verdict() that it can now handle payload.
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <time.h>
29 #include <errno.h>
30 #include <netinet/in.h>
31 #include <sys/socket.h>
32
33 #include <libnfnetlink/libnfnetlink.h>
34 #include <libnetfilter_queue/libnetfilter_queue.h>
35
36 /**
37  * \mainpage
38  *
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.
42  *
43  * libnetfilter_queue homepage is:
44  *      http://netfilter.org/projects/libnetfilter_queue/
45  *
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).
49  *
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
54  * 
55  * \section Git Tree
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.
58  *
59  * \section Privileges
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.
62  *
63  * \section Using libnetfilter_queue
64  * 
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.
67  *
68  * \section errors ENOBUFS errors in recv()
69  *
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.
76  *
77  * \section perf Performance
78  * To improve your libnetfilter_queue application in terms of performance,
79  * you may consider the following tweaks:
80  *
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).
89  */
90
91 struct nfq_handle
92 {
93         struct nfnl_handle *nfnlh;
94         struct nfnl_subsys_handle *nfnlssh;
95         struct nfq_q_handle *qh_list;
96 };
97
98 struct nfq_q_handle
99 {
100         struct nfq_q_handle *next;
101         struct nfq_handle *h;
102         u_int16_t id;
103
104         nfq_callback *cb;
105         void *data;
106 };
107
108 struct nfq_data {
109         struct nfattr **data;
110 };
111
112 int nfq_errno;
113
114 /***********************************************************************
115  * low level stuff 
116  ***********************************************************************/
117
118 static void del_qh(struct nfq_q_handle *qh)
119 {
120         struct nfq_q_handle *cur_qh, *prev_qh = NULL;
121
122         for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) {
123                 if (cur_qh == qh) {
124                         if (prev_qh)
125                                 prev_qh->next = qh->next;
126                         else
127                                 qh->h->qh_list = qh->next;
128                         return;
129                 }
130                 prev_qh = cur_qh;
131         }
132 }
133
134 static void add_qh(struct nfq_q_handle *qh)
135 {
136         qh->next = qh->h->qh_list;
137         qh->h->qh_list = qh;
138 }
139
140 static struct nfq_q_handle *find_qh(struct nfq_handle *h, u_int16_t id)
141 {
142         struct nfq_q_handle *qh;
143
144         for (qh = h->qh_list; qh; qh = qh->next) {
145                 if (qh->id == id)
146                         return qh;
147         }
148         return NULL;
149 }
150
151 /* build a NFQNL_MSG_CONFIG message */
152         static int
153 __build_send_cfg_msg(struct nfq_handle *h, u_int8_t command,
154                 u_int16_t queuenum, u_int16_t pf)
155 {
156         union {
157                 char buf[NFNL_HEADER_LEN
158                         +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))];
159                 struct nlmsghdr nmh;
160         } u;
161         struct nfqnl_msg_config_cmd cmd;
162
163         nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, AF_UNSPEC, queuenum,
164                         NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
165
166         cmd.command = command;
167         cmd.pf = htons(pf);
168         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_CMD, &cmd, sizeof(cmd));
169
170         return nfnl_query(h->nfnlh, &u.nmh);
171 }
172
173 static int __nfq_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
174                 void *data)
175 {
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;
181
182         if (!qh)
183                 return -ENODEV;
184
185         if (!qh->cb)
186                 return -ENODEV;
187
188         nfqa.data = nfa;
189
190         return qh->cb(qh, nfmsg, &nfqa, qh->data);
191 }
192
193 static struct nfnl_callback pkt_cb = {
194         .call           = &__nfq_rcv_pkt,
195         .attr_count     = NFQA_MAX,
196 };
197
198 /* public interface */
199
200 struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h)
201 {
202         return h->nfnlh;
203 }
204
205 /**
206  *
207  * \defgroup Queue Queue handling
208  *
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().
212  *
213  * The queue can then be tuned via nfq_set_mode() or nfq_set_queue_maxlen().
214  * 
215  * Here's a little code snippet that create queue numbered 0:
216  * \verbatim
217         printf("binding this socket to queue '0'\n");
218         qh = nfq_create_queue(h,  0, &cb, NULL);
219         if (!qh) {
220                 fprintf(stderr, "error during nfq_create_queue()\n");
221                 exit(1);
222         }
223
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");
227                 exit(1);
228         }
229 \endverbatim
230  *
231  * Next step is the handling of incoming packets which can be done via a loop:
232  *
233  * \verbatim
234         fd = nfq_fd(h);
235
236         while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
237                 printf("pkt received\n");
238                 nfq_handle_packet(h, buf, rv);
239         }
240 \endverbatim
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:
244  *
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
252  *
253  * Data and information about the packet can be fetch by using message parsing
254  * functions (See \link Parsing \endlink).
255  * @{
256  */
257
258 /**
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()
261  *
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.
265  *
266   * This function returns a file descriptor that can be used for communication
267  * over the netlink connection associated with the given queue connection
268  * handle.
269  */
270 int nfq_fd(struct nfq_handle *h)
271 {
272         return nfnl_fd(nfq_nfnlh(h));
273 }
274
275 /**
276  * @}
277  */
278
279 /**
280  * \defgroup LibrarySetup Library setup
281  *
282  * Library initialisation is made in two steps.
283  *
284  * First step is to call nfq_open() to open a NFQUEUE handler. 
285  *
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.
290  *
291  * Here's a little code snippet that bind with AF_INET:
292  * \verbatim
293         h = nfq_open();
294         if (!h) {
295                 fprintf(stderr, "error during nfq_open()\n");
296                 exit(1);
297         }
298
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");
302                 exit(1);
303         }
304
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");
308                 exit(1);
309         }
310 \endverbatim
311  * Once this is done, you can setup and use a \link Queue \endlink.
312  * @{
313  */
314
315 /**
316  * nfq_open - open a nfqueue handler
317  *
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.
322  *
323  * \return a pointer to a new queue handle or NULL on failure.
324  */
325 struct nfq_handle *nfq_open(void)
326 {
327         struct nfnl_handle *nfnlh = nfnl_open();
328         struct nfq_handle *qh;
329
330         if (!nfnlh)
331                 return NULL;
332
333         /* unset netlink sequence tracking by default */
334         nfnl_unset_sequence_tracking(nfnlh);
335
336         qh = nfq_open_nfnl(nfnlh);
337         if (!qh)
338                 nfnl_close(nfnlh);
339
340         return qh;
341 }
342
343 /**
344  * @}
345  */
346
347 /**
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()
350  *
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.
354  *
355  * \return a pointer to a new queue handle or NULL on failure.
356  */
357 struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh)
358 {
359         struct nfq_handle *h;
360         int err;
361
362         h = malloc(sizeof(*h));
363         if (!h)
364                 return NULL;
365
366         memset(h, 0, sizeof(*h));
367         h->nfnlh = nfnlh;
368
369         h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE, 
370                                       NFQNL_MSG_MAX, 0);
371         if (!h->nfnlssh) {
372                 /* FIXME: nfq_errno */
373                 goto out_free;
374         }
375
376         pkt_cb.data = h;
377         err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
378         if (err < 0) {
379                 nfq_errno = err;
380                 goto out_close;
381         }
382
383         return h;
384 out_close:
385         nfnl_subsys_close(h->nfnlssh);
386 out_free:
387         free(h);
388         return NULL;
389 }
390
391 /**
392  * \addtogroup LibrarySetup
393  *
394  * When the program has finished with libnetfilter_queue, it has to call
395  * the nfq_close() function to free all associated resources.
396  *
397  * @{
398  */
399
400 /**
401  * nfq_close - close a nfqueue handler
402  * \param h Netfilter queue connection handle obtained via call to nfq_open()
403  *
404  * This function closes the nfqueue handler and free associated resources.
405  *
406  * \return 0 on success, non-zero on failure. 
407  */
408 int nfq_close(struct nfq_handle *h)
409 {
410         int ret;
411         
412         ret = nfnl_close(h->nfnlh);
413         if (ret == 0)
414                 free(h);
415         return ret;
416 }
417
418 /**
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()
422  *
423  * Binds the given queue connection handle to process packets belonging to 
424  * the given protocol family (ie. PF_INET, PF_INET6, etc).
425  *
426  * \return integer inferior to 0 in case of failure
427  */
428 int nfq_bind_pf(struct nfq_handle *h, u_int16_t pf)
429 {
430         return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
431 }
432
433 /**
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
437  *
438  * Unbinds the given queue connection handle from processing packets belonging
439  * to the given protocol family.
440  */
441 int nfq_unbind_pf(struct nfq_handle *h, u_int16_t pf)
442 {
443         return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
444 }
445
446
447
448 /**
449  * @}
450  */
451
452 /**
453  * \addtogroup Queue
454  * @{
455  */
456
457 /**
458  * nfq_create_queue - create a new queue handle and return it.
459  *
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
464  *
465  * \return a nfq_q_handle pointing to the newly created queue
466  *
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.
472  *
473  * The nfq_callback type is defined in libnetfilter_queue.h as:
474  * \verbatim
475 typedef int nfq_callback(struct nfq_q_handle *qh,
476                          struct nfgenmsg *nfmsg,
477                          struct nfq_data *nfad, void *data);
478 \endverbatim
479  *
480  * Parameters:
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
485  *
486  * The callback should return < 0 to stop processing.
487  */
488
489 struct nfq_q_handle *nfq_create_queue(struct nfq_handle *h, 
490                 u_int16_t num,
491                 nfq_callback *cb,
492                 void *data)
493 {
494         int ret;
495         struct nfq_q_handle *qh;
496
497         if (find_qh(h, num))
498                 return NULL;
499
500         qh = malloc(sizeof(*qh));
501
502         memset(qh, 0, sizeof(*qh));
503         qh->h = h;
504         qh->id = num;
505         qh->cb = cb;
506         qh->data = data;
507
508         ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
509         if (ret < 0) {
510                 nfq_errno = ret;
511                 free(qh);
512                 return NULL;
513         }
514
515         add_qh(qh);
516         return qh;
517 }
518
519 /**
520  * @}
521  */
522
523 /**
524  * \addtogroup Queue
525  * @{
526  */
527
528 /**
529  * nfq_destroy_queue - destroy a queue handle
530  * \param qh queue handle that we want to destroy created via nfq_create_queue
531  *
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.
534  */
535 int nfq_destroy_queue(struct nfq_q_handle *qh)
536 {
537         int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
538         if (ret == 0) {
539                 del_qh(qh);
540                 free(qh);
541         }
542
543         return ret;
544 }
545
546 /**
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
551  *
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().
555  *
556  * \return 0 on success, non-zero on failure.
557  */
558 int nfq_handle_packet(struct nfq_handle *h, char *buf, int len)
559 {
560         return nfnl_handle_packet(h->nfnlh, buf, len);
561 }
562
563 /**
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
568  *
569  * Sets the amount of data to be copied to userspace for each packet queued
570  * to the given queue.
571  *
572  * - NFQNL_COPY_NONE - noop, do not use it
573  * - NFQNL_COPY_META - copy only packet metadata
574  * - NFQNL_COPY_PACKET - copy entire packet
575  *
576  * \return -1 on error; >=0 otherwise.
577  */
578 int nfq_set_mode(struct nfq_q_handle *qh,
579                 u_int8_t mode, u_int32_t range)
580 {
581         union {
582                 char buf[NFNL_HEADER_LEN
583                         +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
584                 struct nlmsghdr nmh;
585         } u;
586         struct nfqnl_msg_config_params params;
587
588         nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
589                         NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
590
591         params.copy_range = htonl(range);
592         params.copy_mode = mode;
593         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_PARAMS, &params,
594                         sizeof(params));
595
596         return nfnl_query(qh->h->nfnlh, &u.nmh);
597 }
598
599 /**
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
603  *
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
606  * upcoming packets.
607  *
608  * \return -1 on error; >=0 otherwise.
609  */
610 int nfq_set_queue_maxlen(struct nfq_q_handle *qh,
611                                 u_int32_t queuelen)
612 {
613         union {
614                 char buf[NFNL_HEADER_LEN
615                         +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
616                 struct nlmsghdr nmh;
617         } u;
618         u_int32_t queue_maxlen = htonl(queuelen);
619
620         nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
621                         NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
622
623         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_QUEUE_MAXLEN, &queue_maxlen,
624                         sizeof(queue_maxlen));
625
626         return nfnl_query(qh->h->nfnlh, &u.nmh);
627 }
628
629 /**
630  * @}
631  */
632
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,
636                 enum nfqnl_msg_types type)
637 {
638         struct nfqnl_msg_verdict_hdr vh;
639         union {
640                 char buf[NFNL_HEADER_LEN
641                         +NFA_LENGTH(sizeof(mark))
642                         +NFA_LENGTH(sizeof(vh))];
643                 struct nlmsghdr nmh;
644         } u;
645
646         struct iovec iov[3];
647         int nvecs;
648
649         /* This must be declared here (and not inside the data
650          * handling block) because the iovec points to this. */
651         struct nfattr data_attr;
652
653         memset(iov, 0, sizeof(iov));
654
655         vh.verdict = htonl(verdict);
656         vh.id = htonl(id);
657
658         nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
659                                 type, NLM_F_REQUEST);
660
661         /* add verdict header */
662         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_VERDICT_HDR, &vh, sizeof(vh));
663
664         if (set_mark)
665                 nfnl_addattr32(&u.nmh, sizeof(u), NFQA_MARK, mark);
666
667         iov[0].iov_base = &u.nmh;
668         iov[0].iov_len = NLMSG_TAIL(&u.nmh) - (void *)&u.nmh;
669         nvecs = 1;
670
671         if (data_len) {
672                 /* The typecast here is to cast away data's const-ness: */
673                 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
674                                 data_len, (unsigned char *) data);
675                 nvecs += 2;
676                 /* Add the length of the appended data to the message
677                  * header.  The size of the attribute is given in the
678                  * nfa_len field and is set in the nfnl_build_nfa_iovec()
679                  * function. */
680                 u.nmh.nlmsg_len += data_attr.nfa_len;
681         }
682
683         return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
684 }
685
686 /**
687  * \addtogroup Queue
688  * @{
689  */
690
691 /**
692  * nfq_set_verdict - issue a verdict on a packet 
693  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
694  * \param id    ID assigned to packet by netfilter.
695  * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
696  * \param data_len number of bytes of data pointed to by #buf
697  * \param buf the buffer that contains the packet data
698  *
699  * Can be obtained by: 
700  * \verbatim
701         int id;
702         struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(tb);
703         if (ph)
704                 id = ntohl(ph->packet_id);
705 \endverbatim
706  *
707  * Notifies netfilter of the userspace verdict for the given packet.  Every
708  * queued packet _must_ have a verdict specified by userspace, either by
709  * calling this function, the nfq_set_verdict2() function, or the _batch
710  * versions of these functions.
711  *
712  * \return -1 on error; >= 0 otherwise.
713  */
714 int nfq_set_verdict(struct nfq_q_handle *qh, u_int32_t id,
715                 u_int32_t verdict, u_int32_t data_len, 
716                 const unsigned char *buf)
717 {
718         return __set_verdict(qh, id, verdict, 0, 0, data_len, buf,
719                                                 NFQNL_MSG_VERDICT);
720 }       
721
722 /**
723  * nfq_set_verdict2 - like nfq_set_verdict, but you can set the mark.
724  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
725  * \param id    ID assigned to packet by netfilter.
726  * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
727  * \param mark mark to put on packet
728  * \param data_len number of bytes of data pointed to by #buf
729  * \param buf the buffer that contains the packet data
730  */
731 int nfq_set_verdict2(struct nfq_q_handle *qh, u_int32_t id,
732                      u_int32_t verdict, u_int32_t mark,
733                      u_int32_t data_len, const unsigned char *buf)
734 {
735         return __set_verdict(qh, id, verdict, htonl(mark), 1, data_len,
736                                                 buf, NFQNL_MSG_VERDICT);
737 }
738
739 /**
740  * nfq_set_verdict_batch - issue verdicts on several packets at once
741  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
742  * \param id maximum ID of the packets that the verdict should be applied to.
743  * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
744  *
745  * Unlike nfq_set_verdict, the verdict is applied to all queued packets
746  * whose packet id is smaller or equal to #id.
747  *
748  * batch support was added in Linux 3.1.
749  * These functions will fail silently on older kernels.
750  */
751 int nfq_set_verdict_batch(struct nfq_q_handle *qh, u_int32_t id,
752                                           u_int32_t verdict)
753 {
754         return __set_verdict(qh, id, verdict, 0, 0, 0, NULL,
755                                         NFQNL_MSG_VERDICT_BATCH);
756 }
757
758 /**
759  * nfq_set_verdict_batch2 - like nfq_set_verdict_batch, but you can set a mark.
760  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
761  * \param id maximum ID of the packets that the verdict should be applied to.
762  * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
763  * \param mark mark to put on packet
764  */
765 int nfq_set_verdict_batch2(struct nfq_q_handle *qh, u_int32_t id,
766                      u_int32_t verdict, u_int32_t mark)
767 {
768         return __set_verdict(qh, id, verdict, htonl(mark), 1, 0,
769                                 NULL, NFQNL_MSG_VERDICT_BATCH);
770 }
771
772 /**
773  * nfq_set_verdict_mark - like nfq_set_verdict, but you can set the mark.
774  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
775  * \param id    ID assigned to packet by netfilter.
776  * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
777  * \param mark the mark to put on the packet, in network byte order.
778  * \param data_len number of bytes of data pointed to by #buf
779  * \param buf the buffer that contains the packet data
780  *
781  * \return -1 on error; >= 0 otherwise.
782  *
783  * This function is deprecated since it is broken, its use is highly
784  * discouraged. Please, use nfq_set_verdict2 instead.
785  */
786 int nfq_set_verdict_mark(struct nfq_q_handle *qh, u_int32_t id,
787                 u_int32_t verdict, u_int32_t mark,
788                 u_int32_t data_len, const unsigned char *buf)
789 {
790         return __set_verdict(qh, id, verdict, mark, 1, data_len, buf,
791                                                 NFQNL_MSG_VERDICT);
792 }
793
794 /**
795  * @}
796  */
797
798
799
800 /*************************************************************
801  * Message parsing functions 
802  *************************************************************/
803
804 /**
805  * \defgroup Parsing Message parsing functions
806  * @{
807  */
808
809 /**
810  * nfqnl_msg_packet_hdr - return the metaheader that wraps the packet
811  * \param nfad Netlink packet data handle passed to callback function
812  *
813  * \return the netfilter queue netlink packet header for the given
814  * nfq_data argument.  Typically, the nfq_data value is passed as the 3rd
815  * parameter to the callback function set by a call to nfq_create_queue().
816  *
817  * The nfqnl_msg_packet_hdr structure is defined in libnetfilter_queue.h as:
818  *
819  * \verbatim
820         struct nfqnl_msg_packet_hdr {
821                 u_int32_t       packet_id;      // unique ID of packet in queue
822                 u_int16_t       hw_protocol;    // hw protocol (network order)
823                 u_int8_t        hook;           // netfilter hook
824         } __attribute__ ((packed));
825 \endverbatim
826  */
827 struct nfqnl_msg_packet_hdr *nfq_get_msg_packet_hdr(struct nfq_data *nfad)
828 {
829         return nfnl_get_pointer_to_data(nfad->data, NFQA_PACKET_HDR,
830                                         struct nfqnl_msg_packet_hdr);
831 }
832
833 /**
834  * nfq_get_nfmark - get the packet mark
835  * \param nfad Netlink packet data handle passed to callback function
836  *
837  * \return the netfilter mark currently assigned to the given queued packet.
838  */
839 uint32_t nfq_get_nfmark(struct nfq_data *nfad)
840 {
841         return ntohl(nfnl_get_data(nfad->data, NFQA_MARK, u_int32_t));
842 }
843
844 /**
845  * nfq_get_timestamp - get the packet timestamp
846  * \param nfad Netlink packet data handle passed to callback function
847  * \param tv structure to fill with timestamp info
848  *
849  * Retrieves the received timestamp when the given queued packet.
850  *
851  * \return 0 on success, non-zero on failure.
852  */
853 int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv)
854 {
855         struct nfqnl_msg_packet_timestamp *qpt;
856         qpt = nfnl_get_pointer_to_data(nfad->data, NFQA_TIMESTAMP,
857                                         struct nfqnl_msg_packet_timestamp);
858         if (!qpt)
859                 return -1;
860
861         tv->tv_sec = __be64_to_cpu(qpt->sec);
862         tv->tv_usec = __be64_to_cpu(qpt->usec);
863
864         return 0;
865 }
866
867 /**
868  * nfq_get_indev - get the interface that the packet was received through
869  * \param nfad Netlink packet data handle passed to callback function
870  *
871  * \return The index of the device the queued packet was received via.  If the
872  * returned index is 0, the packet was locally generated or the input
873  * interface is not known (ie. POSTROUTING?).
874  *
875  * \warning all nfq_get_dev() functions return 0 if not set, since linux
876  * only allows ifindex >= 1, see net/core/dev.c:2600  (in 2.6.13.1)
877  */
878 u_int32_t nfq_get_indev(struct nfq_data *nfad)
879 {
880         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_INDEV, u_int32_t));
881 }
882
883 /**
884  * nfq_get_physindev - get the physical interface that the packet was received
885  * \param nfad Netlink packet data handle passed to callback function
886  *
887  * \return The index of the physical device the queued packet was received via.
888  * If the returned index is 0, the packet was locally generated or the
889  * physical input interface is no longer known (ie. POSTROUTING?).
890  */
891 u_int32_t nfq_get_physindev(struct nfq_data *nfad)
892 {
893         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSINDEV, u_int32_t));
894 }
895
896 /**
897  * nfq_get_outdev - gets the interface that the packet will be routed out
898  * \param nfad Netlink packet data handle passed to callback function
899  *
900  * \return The index of the device the queued packet will be sent out.  If the
901  * returned index is 0, the packet is destined for localhost or the output
902  * interface is not yet known (ie. PREROUTING?).
903  */
904 u_int32_t nfq_get_outdev(struct nfq_data *nfad)
905 {
906         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_OUTDEV, u_int32_t));
907 }
908
909 /**
910  * nfq_get_physoutdev - get the physical interface that the packet output
911  * \param nfad Netlink packet data handle passed to callback function
912  *
913  * The index of the physical device the queued packet will be sent out.
914  * If the returned index is 0, the packet is destined for localhost or the
915  * physical output interface is not yet known (ie. PREROUTING?).
916  * 
917  * \return The index of physical interface that the packet output will be routed out.
918  */
919 u_int32_t nfq_get_physoutdev(struct nfq_data *nfad)
920 {
921         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
922 }
923
924 /**
925  * nfq_get_indev_name - get the name of the interface the packet
926  * was received through
927  * \param nlif_handle pointer to a nlif interface resolving handle
928  * \param nfad Netlink packet data handle passed to callback function
929  * \param name pointer to the buffer to receive the interface name;
930  *  not more than \c IFNAMSIZ bytes will be copied to it.
931  * \return -1 in case of error, >0 if it succeed. 
932  *
933  * To use a nlif_handle, You need first to call nlif_open() and to open
934  * an handler. Don't forget to store the result as it will be used 
935  * during all your program life:
936  * \verbatim
937         h = nlif_open();
938         if (h == NULL) {
939                 perror("nlif_open");
940                 exit(EXIT_FAILURE);
941         }
942 \endverbatim
943  * Once the handler is open, you need to fetch the interface table at a
944  * whole via a call to nlif_query.
945  * \verbatim
946         nlif_query(h);
947 \endverbatim
948  * libnfnetlink is able to update the interface mapping when a new interface
949  * appears. To do so, you need to call nlif_catch() on the handler after each
950  * interface related event. The simplest way to get and treat event is to run
951  * a select() or poll() against the nlif file descriptor. To get this file 
952  * descriptor, you need to use nlif_fd:
953  * \verbatim
954         if_fd = nlif_fd(h);
955 \endverbatim
956  * Don't forget to close the handler when you don't need the feature anymore:
957  * \verbatim
958         nlif_close(h);
959 \endverbatim
960  *
961  */
962 int nfq_get_indev_name(struct nlif_handle *nlif_handle,
963                         struct nfq_data *nfad, char *name)
964 {
965         u_int32_t ifindex = nfq_get_indev(nfad);
966         return nlif_index2name(nlif_handle, ifindex, name);
967 }
968
969 /**
970  * nfq_get_physindev_name - get the name of the physical interface the
971  * packet was received through
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.
976  *
977  * See nfq_get_indev_name() documentation for nlif_handle usage.
978  *
979  * \return  -1 in case of error, > 0 if it succeed. 
980  */
981 int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
982                            struct nfq_data *nfad, char *name)
983 {
984         u_int32_t ifindex = nfq_get_physindev(nfad);
985         return nlif_index2name(nlif_handle, ifindex, name);
986 }
987
988 /**
989  * nfq_get_outdev_name - get the name of the physical interface the
990  * packet will be sent to
991  * \param nlif_handle pointer to a nlif interface resolving handle
992  * \param nfad Netlink packet data handle passed to callback function
993  * \param name pointer to the buffer to receive the interface name;
994  *  not more than \c IFNAMSIZ bytes will be copied to it.
995  *
996  * See nfq_get_indev_name() documentation for nlif_handle usage.
997  *
998  * \return  -1 in case of error, > 0 if it succeed. 
999  */
1000 int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
1001                         struct nfq_data *nfad, char *name)
1002 {
1003         u_int32_t ifindex = nfq_get_outdev(nfad);
1004         return nlif_index2name(nlif_handle, ifindex, name);
1005 }
1006
1007 /**
1008  * nfq_get_physoutdev_name - get the name of the interface the
1009  * packet will be sent to
1010  * \param nlif_handle pointer to a nlif interface resolving handle
1011  * \param nfad Netlink packet data handle passed to callback function
1012  * \param name pointer to the buffer to receive the interface name;
1013  *  not more than \c IFNAMSIZ bytes will be copied to it.
1014  *
1015  * See nfq_get_indev_name() documentation for nlif_handle usage.
1016  *
1017  * \return  -1 in case of error, > 0 if it succeed. 
1018  */
1019
1020 int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
1021                             struct nfq_data *nfad, char *name)
1022 {
1023         u_int32_t ifindex = nfq_get_physoutdev(nfad);
1024         return nlif_index2name(nlif_handle, ifindex, name);
1025 }
1026
1027 /**
1028  * nfq_get_packet_hw
1029  *
1030  * get hardware address 
1031  *
1032  * \param nfad Netlink packet data handle passed to callback function
1033  *
1034  * Retrieves the hardware address associated with the given queued packet.
1035  * For ethernet packets, the hardware address returned (if any) will be the
1036  * MAC address of the packet source host.  The destination MAC address is not
1037  * known until after POSTROUTING and a successful ARP request, so cannot
1038  * currently be retrieved.
1039  *
1040  * The nfqnl_msg_packet_hw structure is defined in libnetfilter_queue.h as:
1041  * \verbatim
1042         struct nfqnl_msg_packet_hw {
1043                 u_int16_t       hw_addrlen;
1044                 u_int16_t       _pad;
1045                 u_int8_t        hw_addr[8];
1046         } __attribute__ ((packed));
1047 \endverbatim
1048  */
1049 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
1050 {
1051         return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
1052                                         struct nfqnl_msg_packet_hw);
1053 }
1054
1055 /**
1056  * nfq_get_payload - get payload 
1057  * \param nfad Netlink packet data handle passed to callback function
1058  * \param data Pointer of pointer that will be pointed to the payload
1059  *
1060  * Retrieve the payload for a queued packet. The actual amount and type of
1061  * data retrieved by this function will depend on the mode set with the
1062  * nfq_set_mode() function.
1063  *
1064  * \return -1 on error, otherwise > 0.
1065  */
1066 int nfq_get_payload(struct nfq_data *nfad, unsigned char **data)
1067 {
1068         *data = nfnl_get_pointer_to_data(nfad->data, NFQA_PAYLOAD, char);
1069         if (*data)
1070                 return NFA_PAYLOAD(nfad->data[NFQA_PAYLOAD-1]);
1071
1072         return -1;
1073 }
1074
1075 /**
1076  * @}
1077  */
1078
1079 #define SNPRINTF_FAILURE(ret, rem, offset, len)                 \
1080 do {                                                            \
1081         if (ret < 0)                                            \
1082                 return ret;                                     \
1083         len += ret;                                             \
1084         if (ret > rem)                                          \
1085                 ret = rem;                                      \
1086         offset += ret;                                          \
1087         rem -= ret;                                             \
1088 } while (0)
1089
1090 /**
1091  * \defgroup Printing
1092  * @{
1093  */
1094
1095 /**
1096  * nfq_snprintf_xml - print the enqueued packet in XML format into a buffer
1097  * \param buf The buffer that you want to use to print the logged packet
1098  * \param rem The size of the buffer that you have passed
1099  * \param tb Netlink packet data handle passed to callback function
1100  * \param flags The flag that tell what to print into the buffer
1101  *
1102  * This function supports the following flags:
1103  *
1104  *      - NFQ_XML_HW: include the hardware link layer address
1105  *      - NFQ_XML_MARK: include the packet mark
1106  *      - NFQ_XML_DEV: include the device information
1107  *      - NFQ_XML_PHYSDEV: include the physical device information
1108  *      - NFQ_XML_PAYLOAD: include the payload (in hexadecimal)
1109  *      - NFQ_XML_TIME: include the timestamp
1110  *      - NFQ_XML_ALL: include all the logging information (all flags set)
1111  *
1112  * You can combine this flags with an binary OR.
1113  *
1114  * \return -1 in case of failure, otherwise the length of the string that
1115  * would have been printed into the buffer (in case that there is enough
1116  * room in it). See snprintf() return value for more information.
1117  */
1118 int nfq_snprintf_xml(char *buf, size_t rem, struct nfq_data *tb, int flags)
1119 {
1120         struct nfqnl_msg_packet_hdr *ph;
1121         struct nfqnl_msg_packet_hw *hwph;
1122         u_int32_t mark, ifi;
1123         int size, offset = 0, len = 0, ret;
1124         unsigned char *data;
1125
1126         size = snprintf(buf + offset, rem, "<pkt>");
1127         SNPRINTF_FAILURE(size, rem, offset, len);
1128
1129         if (flags & NFQ_XML_TIME) {
1130                 time_t t;
1131                 struct tm tm;
1132
1133                 t = time(NULL);
1134                 if (localtime_r(&t, &tm) == NULL)
1135                         return -1;
1136
1137                 size = snprintf(buf + offset, rem, "<when>");
1138                 SNPRINTF_FAILURE(size, rem, offset, len);
1139
1140                 size = snprintf(buf + offset, rem,
1141                                 "<hour>%d</hour>", tm.tm_hour);
1142                 SNPRINTF_FAILURE(size, rem, offset, len);
1143
1144                 size = snprintf(buf + offset,
1145                                 rem, "<min>%02d</min>", tm.tm_min);
1146                 SNPRINTF_FAILURE(size, rem, offset, len);
1147
1148                 size = snprintf(buf + offset,
1149                                 rem, "<sec>%02d</sec>", tm.tm_sec);
1150                 SNPRINTF_FAILURE(size, rem, offset, len);
1151
1152                 size = snprintf(buf + offset, rem, "<wday>%d</wday>",
1153                                 tm.tm_wday + 1);
1154                 SNPRINTF_FAILURE(size, rem, offset, len);
1155
1156                 size = snprintf(buf + offset, rem, "<day>%d</day>", tm.tm_mday);
1157                 SNPRINTF_FAILURE(size, rem, offset, len);
1158
1159                 size = snprintf(buf + offset, rem, "<month>%d</month>",
1160                                 tm.tm_mon + 1);
1161                 SNPRINTF_FAILURE(size, rem, offset, len);
1162
1163                 size = snprintf(buf + offset, rem, "<year>%d</year>",
1164                                 1900 + tm.tm_year);
1165                 SNPRINTF_FAILURE(size, rem, offset, len);
1166
1167                 size = snprintf(buf + offset, rem, "</when>");
1168                 SNPRINTF_FAILURE(size, rem, offset, len);
1169         }
1170
1171         ph = nfq_get_msg_packet_hdr(tb);
1172         if (ph) {
1173                 size = snprintf(buf + offset, rem,
1174                                 "<hook>%u</hook><id>%u</id>",
1175                                 ph->hook, ntohl(ph->packet_id));
1176                 SNPRINTF_FAILURE(size, rem, offset, len);
1177
1178                 hwph = nfq_get_packet_hw(tb);
1179                 if (hwph && (flags & NFQ_XML_HW)) {
1180                         int i, hlen = ntohs(hwph->hw_addrlen);
1181
1182                         size = snprintf(buf + offset, rem, "<hw><proto>%04x"
1183                                                            "</proto>",
1184                                         ntohs(ph->hw_protocol));
1185                         SNPRINTF_FAILURE(size, rem, offset, len);
1186
1187                         size = snprintf(buf + offset, rem, "<src>");
1188                         SNPRINTF_FAILURE(size, rem, offset, len);
1189
1190                         for (i=0; i<hlen; i++) {
1191                                 size = snprintf(buf + offset, rem, "%02x",
1192                                                 hwph->hw_addr[i]);
1193                                 SNPRINTF_FAILURE(size, rem, offset, len);
1194                         }
1195
1196                         size = snprintf(buf + offset, rem, "</src></hw>");
1197                         SNPRINTF_FAILURE(size, rem, offset, len);
1198                 } else if (flags & NFQ_XML_HW) {
1199                         size = snprintf(buf + offset, rem, "<hw><proto>%04x"
1200                                                     "</proto></hw>",
1201                                  ntohs(ph->hw_protocol));
1202                         SNPRINTF_FAILURE(size, rem, offset, len);
1203                 }
1204         }
1205
1206         mark = nfq_get_nfmark(tb);
1207         if (mark && (flags & NFQ_XML_MARK)) {
1208                 size = snprintf(buf + offset, rem, "<mark>%u</mark>", mark);
1209                 SNPRINTF_FAILURE(size, rem, offset, len);
1210         }
1211
1212         ifi = nfq_get_indev(tb);
1213         if (ifi && (flags & NFQ_XML_DEV)) {
1214                 size = snprintf(buf + offset, rem, "<indev>%u</indev>", ifi);
1215                 SNPRINTF_FAILURE(size, rem, offset, len);
1216         }
1217
1218         ifi = nfq_get_outdev(tb);
1219         if (ifi && (flags & NFQ_XML_DEV)) {
1220                 size = snprintf(buf + offset, rem, "<outdev>%u</outdev>", ifi);
1221                 SNPRINTF_FAILURE(size, rem, offset, len);
1222         }
1223
1224         ifi = nfq_get_physindev(tb);
1225         if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1226                 size = snprintf(buf + offset, rem,
1227                                 "<physindev>%u</physindev>", ifi);
1228                 SNPRINTF_FAILURE(size, rem, offset, len);
1229         }
1230
1231         ifi = nfq_get_physoutdev(tb);
1232         if (ifi && (flags & NFQ_XML_PHYSDEV)) {
1233                 size = snprintf(buf + offset, rem,
1234                                 "<physoutdev>%u</physoutdev>", ifi);
1235                 SNPRINTF_FAILURE(size, rem, offset, len);
1236         }
1237
1238         ret = nfq_get_payload(tb, &data);
1239         if (ret >= 0 && (flags & NFQ_XML_PAYLOAD)) {
1240                 int i;
1241
1242                 size = snprintf(buf + offset, rem, "<payload>");
1243                 SNPRINTF_FAILURE(size, rem, offset, len);
1244
1245                 for (i=0; i<ret; i++) {
1246                         size = snprintf(buf + offset, rem, "%02x",
1247                                         data[i] & 0xff);
1248                         SNPRINTF_FAILURE(size, rem, offset, len);
1249                 }
1250
1251                 size = snprintf(buf + offset, rem, "</payload>");
1252                 SNPRINTF_FAILURE(size, rem, offset, len);
1253         }
1254
1255         size = snprintf(buf + offset, rem, "</pkt>");
1256         SNPRINTF_FAILURE(size, rem, offset, len);
1257
1258         return len;
1259 }
1260
1261 /**
1262  * @}
1263  */