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