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