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