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