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