Switch documentation style to doxygen.
[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 Using libnetfilter_queue
59  * 
60  * To write your own program using libnetfilter_queue, you should start by reading
61  * the doxygen documentation (start by \link LibrarySetup \endlink page) and nfqnl_test.c source file.
62  * 
63  */
64
65 struct nfq_handle
66 {
67         struct nfnl_handle *nfnlh;
68         struct nfnl_subsys_handle *nfnlssh;
69         struct nfq_q_handle *qh_list;
70 };
71
72 struct nfq_q_handle
73 {
74         struct nfq_q_handle *next;
75         struct nfq_handle *h;
76         u_int16_t id;
77
78         nfq_callback *cb;
79         void *data;
80 };
81
82 struct nfq_data {
83         struct nfattr **data;
84 };
85
86 int nfq_errno;
87
88 /***********************************************************************
89  * low level stuff 
90  ***********************************************************************/
91
92 static void del_qh(struct nfq_q_handle *qh)
93 {
94         struct nfq_q_handle *cur_qh, *prev_qh = NULL;
95
96         for (cur_qh = qh->h->qh_list; cur_qh; cur_qh = cur_qh->next) {
97                 if (cur_qh == qh) {
98                         if (prev_qh)
99                                 prev_qh->next = qh->next;
100                         else
101                                 qh->h->qh_list = qh->next;
102                         return;
103                 }
104                 prev_qh = cur_qh;
105         }
106 }
107
108 static void add_qh(struct nfq_q_handle *qh)
109 {
110         qh->next = qh->h->qh_list;
111         qh->h->qh_list = qh;
112 }
113
114 static struct nfq_q_handle *find_qh(struct nfq_handle *h, u_int16_t id)
115 {
116         struct nfq_q_handle *qh;
117
118         for (qh = h->qh_list; qh; qh = qh->next) {
119                 if (qh->id == id)
120                         return qh;
121         }
122         return NULL;
123 }
124
125 /* build a NFQNL_MSG_CONFIG message */
126         static int
127 __build_send_cfg_msg(struct nfq_handle *h, u_int8_t command,
128                 u_int16_t queuenum, u_int16_t pf)
129 {
130         union {
131                 char buf[NFNL_HEADER_LEN
132                         +NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))];
133                 struct nlmsghdr nmh;
134         } u;
135         struct nfqnl_msg_config_cmd cmd;
136
137         nfnl_fill_hdr(h->nfnlssh, &u.nmh, 0, AF_UNSPEC, queuenum,
138                         NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
139
140         cmd.command = command;
141         cmd.pf = htons(pf);
142         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_CMD, &cmd, sizeof(cmd));
143
144         return nfnl_talk(h->nfnlh, &u.nmh, 0, 0, NULL, NULL, NULL);
145 }
146
147 static int __nfq_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
148                 void *data)
149 {
150         struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
151         struct nfq_handle *h = data;
152         u_int16_t queue_num = ntohs(nfmsg->res_id);
153         struct nfq_q_handle *qh = find_qh(h, queue_num);
154         struct nfq_data nfqa;
155
156         if (!qh)
157                 return -ENODEV;
158
159         if (!qh->cb)
160                 return -ENODEV;
161
162         nfqa.data = nfa;
163
164         return qh->cb(qh, nfmsg, &nfqa, qh->data);
165 }
166
167 static struct nfnl_callback pkt_cb = {
168         .call           = &__nfq_rcv_pkt,
169         .attr_count     = NFQA_MAX,
170 };
171
172 /* public interface */
173
174 struct nfnl_handle *nfq_nfnlh(struct nfq_handle *h)
175 {
176         return h->nfnlh;
177 }
178
179 /**
180  *
181  * \defgroup Queue Queue handling
182  *
183  * Once libnetfilter_queue library has been initialised (See 
184  * \link LibrarySetup \endlink), it is possible to bind the program to a
185  * specific queue. This can be done by using nfq_create_queue().
186  *
187  * The queue can then be tuned via nfq_set_mode() or nfq_set_queue_maxlen().
188  * 
189  * Here's a little code snippet that create queue numbered 0:
190  * \verbatim
191         printf("binding this socket to queue '0'\n");
192         qh = nfq_create_queue(h,  0, &cb, NULL);
193         if (!qh) {
194                 fprintf(stderr, "error during nfq_create_queue()\n");
195                 exit(1);
196         }
197
198         printf("setting copy_packet mode\n");
199         if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
200                 fprintf(stderr, "can't set packet_copy mode\n");
201                 exit(1);
202         }
203 \endverbatim
204  *
205  * Next step is the handling of incoming packets which can be done via a loop:
206  *
207  * \verbatim
208         fd = nfq_fd(h);
209
210         while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
211                 printf("pkt received\n");
212                 nfq_handle_packet(h, buf, rv);
213         }
214 \endverbatim
215  * When the decision on a packet has been choosed, the verdict has to be given
216  * by calling nfq_set_verdict() or nfq_set_verdict_mark().
217  *
218  * Data and information about the packet can be fetch by using message parsing
219  * functions (See \link Parsing \endlink).
220  * @{
221  */
222
223 /**
224  * nfq_fd - get the file descriptor associated with the nfqueue handler
225  * \param h Netfilter queue connection handle obtained via call to nfq_open()
226  *
227  * \return a file descriptor for the netlink connection associated with the
228  * given queue connection handle. The file descriptor can then be used for
229  * receiving the queued packets for processing.
230  *
231   * This function returns a file descriptor that can be used for communication
232  * over the netlink connection associated with the given queue connection
233  * handle.
234  */
235 int nfq_fd(struct nfq_handle *h)
236 {
237         return nfnl_fd(nfq_nfnlh(h));
238 }
239
240 /**
241  * @}
242  */
243
244 /**
245  * \defgroup LibrarySetup Library setup
246  *
247  * Library initialisation is made in two steps.
248  *
249  * First step is to call nfq_open() to open a NFQUEUE handler. 
250  *
251  * Second step is to tell the kernel that userspace queueing is handle by
252  * NFQUEUE for the selected protocol. This is made by calling nfq_unbind_pf()
253  * and nfq_bind_pf() with protocol information. The idea behind this is to
254  * enable simultaneously loaded modules to be used for queuing.
255  *
256  * Here's a little code snippet that bind with AF_INET:
257  * \verbatim
258         h = nfq_open();
259         if (!h) {
260                 fprintf(stderr, "error during nfq_open()\n");
261                 exit(1);
262         }
263
264         printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
265         if (nfq_unbind_pf(h, AF_INET) < 0) {
266                 fprintf(stderr, "error during nfq_unbind_pf()\n");
267                 exit(1);
268         }
269
270         printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
271         if (nfq_bind_pf(h, AF_INET) < 0) {
272                 fprintf(stderr, "error during nfq_bind_pf()\n");
273                 exit(1);
274         }
275 \endverbatim
276  * Once this is done, you can setup and use a \link Queue \endlink.
277  * @{
278  */
279
280 /**
281  * nfq_open - open a nfqueue handler
282  *
283  * This function obtains a netfilter queue connection handle. When you are
284  * finished with the handle returned by this function, you should destroy
285  * it by calling nfq_close(). A new netlink connection is obtained internally
286  * and associated with the queue connection handle returned.
287  *
288  * \return a pointer to a new queue handle or NULL on failure.
289  */
290 struct nfq_handle *nfq_open(void)
291 {
292         struct nfnl_handle *nfnlh = nfnl_open();
293         struct nfq_handle *qh;
294
295         if (!nfnlh)
296                 return NULL;
297
298         qh = nfq_open_nfnl(nfnlh);
299         if (!qh)
300                 nfnl_close(nfnlh);
301
302         return qh;
303 }
304
305 /**
306  * @}
307  */
308
309 /**
310  * nfq_open_nfnl - open a nfqueue handler from a existing nfnetlink handler
311  * \param nfnlh Netfilter netlink connection handle obtained by calling nfnl_open()
312  *
313  * This function obtains a netfilter queue connection handle using an existing
314  * netlink connection. This function is used internally to implement 
315  * nfq_open(), and should typically not be called directly.
316  *
317  * \return a pointer to a new queue handle or NULL on failure.
318  */
319 struct nfq_handle *nfq_open_nfnl(struct nfnl_handle *nfnlh)
320 {
321         struct nfq_handle *h;
322         int err;
323
324         h = malloc(sizeof(*h));
325         if (!h)
326                 return NULL;
327
328         memset(h, 0, sizeof(*h));
329         h->nfnlh = nfnlh;
330
331         h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_QUEUE, 
332                                       NFQNL_MSG_MAX, 0);
333         if (!h->nfnlssh) {
334                 /* FIXME: nfq_errno */
335                 goto out_free;
336         }
337
338         pkt_cb.data = h;
339         err = nfnl_callback_register(h->nfnlssh, NFQNL_MSG_PACKET, &pkt_cb);
340         if (err < 0) {
341                 nfq_errno = err;
342                 goto out_close;
343         }
344
345         return h;
346 out_close:
347         nfnl_subsys_close(h->nfnlssh);
348 out_free:
349         free(h);
350         return NULL;
351 }
352
353 /**
354  * \addtogroup LibrarySetup
355  *
356  * When the program has finished with libnetfilter_queue, it has to call
357  * the nfq_close() function to free all associated resources.
358  *
359  * @{
360  */
361
362 /**
363  * nfq_close - close a nfqueue handler
364  * \param h Netfilter queue connection handle obtained via call to nfq_open()
365  *
366  * This function closes the nfqueue handler and free associated resources.
367  *
368  * \return 0 on success, non-zero on failure. 
369  */
370 int nfq_close(struct nfq_handle *h)
371 {
372         int ret;
373         
374         ret = nfnl_close(h->nfnlh);
375         if (ret == 0)
376                 free(h);
377         return ret;
378 }
379
380 /**
381  * nfq_bind_pf - bind a nfqueue handler to a given protocol family
382  * \param h Netfilter queue connection handle obtained via call to nfq_open()
383  * \param pf protocol family to bind to nfqueue handler obtained from nfq_open()
384  *
385  * Binds the given queue connection handle to process packets belonging to 
386  * the given protocol family (ie. PF_INET, PF_INET6, etc).
387  *
388  * \return integer inferior to 0 in case of failure
389  */
390 int nfq_bind_pf(struct nfq_handle *h, u_int16_t pf)
391 {
392         return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_BIND, 0, pf);
393 }
394
395 /**
396  * nfq_unbind_pf - unbind nfqueue handler from a protocol family
397  * \param h Netfilter queue connection handle obtained via call to nfq_open()
398  * \param pf protocol family to unbind family from
399  *
400  * Unbinds the given queue connection handle from processing packets belonging
401  * to the given protocol family.
402  */
403 int nfq_unbind_pf(struct nfq_handle *h, u_int16_t pf)
404 {
405         return __build_send_cfg_msg(h, NFQNL_CFG_CMD_PF_UNBIND, 0, pf);
406 }
407
408
409
410 /**
411  * @}
412  */
413
414 /**
415  * \addtogroup Queue
416  * @{
417  */
418
419 /**
420  * nfq_create_queue - create a new queue handle and return it.
421  *
422  * \param h Netfilter queue connection handle obtained via call to nfq_open()
423  * \param num the number of the queue to bind to
424  * \param cb callback function to call for each queued packet
425  * \param data custom data to pass to the callback function
426  *
427  * \return a nfq_q_handle pointing to the newly created queue
428  *
429  * Creates a new queue handle, and returns it.  The new queue is identified by
430  * #num, and the callback specified by #cb will be called for each enqueued
431  * packet.  The #data argument will be passed unchanged to the callback.  If
432  * a queue entry with id #num already exists, this function will return failure
433  * and the existing entry is unchanged.
434  *
435  * The nfq_callback type is defined in libnetfilter_queue.h as:
436  * \verbatim
437 typedef int nfq_callback(struct nfq_q_handle *qh,
438                          struct nfgenmsg *nfmsg,
439                          struct nfq_data *nfad, void *data);
440 \endverbatim
441  *
442  * Parameters:
443  *  - qh The queue handle returned by nfq_create_queue
444  *  - nfmsg message objetc that contains the packet
445  *  - nfad Netlink packet data handle
446  *  - data the value passed to the data parameter of nfq_create_queue
447  *
448  * The callback should return < 0 to stop processing.
449  */
450
451 struct nfq_q_handle *nfq_create_queue(struct nfq_handle *h, 
452                 u_int16_t num,
453                 nfq_callback *cb,
454                 void *data)
455 {
456         int ret;
457         struct nfq_q_handle *qh;
458
459         if (find_qh(h, num))
460                 return NULL;
461
462         qh = malloc(sizeof(*qh));
463
464         memset(qh, 0, sizeof(*qh));
465         qh->h = h;
466         qh->id = num;
467         qh->cb = cb;
468         qh->data = data;
469
470         ret = __build_send_cfg_msg(h, NFQNL_CFG_CMD_BIND, num, 0);
471         if (ret < 0) {
472                 nfq_errno = ret;
473                 free(qh);
474                 return NULL;
475         }
476
477         add_qh(qh);
478         return qh;
479 }
480
481 /**
482  * @}
483  */
484
485 /**
486  * \addtogroup Queue
487  * @{
488  */
489
490 /**
491  * nfq_destroy_queue - destroy a queue handle
492  * \param qh queue handle that we want to destroy created via nfq_create_queue
493  *
494  * Removes the binding for the specified queue handle. This call also unbind
495  * from the nfqueue handler, so you don't have to call nfq_unbind_pf.
496  */
497 int nfq_destroy_queue(struct nfq_q_handle *qh)
498 {
499         int ret = __build_send_cfg_msg(qh->h, NFQNL_CFG_CMD_UNBIND, qh->id, 0);
500         if (ret == 0) {
501                 del_qh(qh);
502                 free(qh);
503         }
504
505         return ret;
506 }
507
508 /**
509  * nfq_handle_packet - handle a packet received from the nfqueue subsystem
510  * \param h Netfilter queue connection handle obtained via call to nfq_open()
511  * \param buf data to pass to the callback
512  * \param len length of packet data in buffer
513  *
514  * Triggers an associated callback for the given packet received from the
515  * queue. Packets can be read from the queue using nfq_fd() and recv(). See
516  * example code for nfq_fd().
517  *
518  * \return 0 on success, non-zero on failure.
519  */
520 int nfq_handle_packet(struct nfq_handle *h, char *buf, int len)
521 {
522         return nfnl_handle_packet(h->nfnlh, buf, len);
523 }
524
525 /**
526  * nfq_set_mode - set the amount of packet data that nfqueue copies to userspace
527  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
528  * \param mode the part of the packet that we are interested in
529  * \param range size of the packet that we want to get
530  *
531  * Sets the amount of data to be copied to userspace for each packet queued
532  * to the given queue.
533  *
534  * - NFQNL_COPY_NONE - do not copy any data
535  * - NFQNL_COPY_META - copy only packet metadata
536  * - NFQNL_COPY_PACKET - copy entire packet
537  */
538 int nfq_set_mode(struct nfq_q_handle *qh,
539                 u_int8_t mode, u_int32_t range)
540 {
541         union {
542                 char buf[NFNL_HEADER_LEN
543                         +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
544                 struct nlmsghdr nmh;
545         } u;
546         struct nfqnl_msg_config_params params;
547
548         nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
549                         NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
550
551         params.copy_range = htonl(range);
552         params.copy_mode = mode;
553         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_PARAMS, &params,
554                         sizeof(params));
555
556         return nfnl_talk(qh->h->nfnlh, &u.nmh, 0, 0, NULL, NULL, NULL);
557 }
558
559 /**
560  * nfq_set_queue_maxlen - Set kernel queue maximum length parameter
561  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
562  * \param queuelen the length of the queue
563  *
564  * Sets the size of the queue in kernel. This fixes the maximum number
565  * of packets the kernel will store before internally before dropping
566  * upcoming packets.
567  */
568 int nfq_set_queue_maxlen(struct nfq_q_handle *qh,
569                                 u_int32_t queuelen)
570 {
571         union {
572                 char buf[NFNL_HEADER_LEN
573                         +NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
574                 struct nlmsghdr nmh;
575         } u;
576         u_int32_t queue_maxlen = htonl(queuelen);
577
578         nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
579                         NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
580
581         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_CFG_QUEUE_MAXLEN, &queue_maxlen,
582                         sizeof(queue_maxlen));
583
584         return nfnl_talk(qh->h->nfnlh, &u.nmh, 0, 0, NULL, NULL, NULL);
585 }
586
587 /**
588  * @}
589  */
590
591 static int __set_verdict(struct nfq_q_handle *qh, u_int32_t id,
592                 u_int32_t verdict, u_int32_t mark, int set_mark,
593                 u_int32_t data_len, unsigned char *data)
594 {
595         struct nfqnl_msg_verdict_hdr vh;
596         union {
597                 char buf[NFNL_HEADER_LEN
598                         +NFA_LENGTH(sizeof(mark))
599                         +NFA_LENGTH(sizeof(vh))];
600                 struct nlmsghdr nmh;
601         } u;
602
603         struct iovec iov[3];
604         int nvecs;
605
606         /* This must be declared here (and not inside the data
607          * handling block) because the iovec points to this. */
608         struct nfattr data_attr;
609
610         memset(iov, 0, sizeof(iov));
611
612         vh.verdict = htonl(verdict);
613         vh.id = htonl(id);
614
615         nfnl_fill_hdr(qh->h->nfnlssh, &u.nmh, 0, AF_UNSPEC, qh->id,
616                         NFQNL_MSG_VERDICT, NLM_F_REQUEST);
617
618         /* add verdict header */
619         nfnl_addattr_l(&u.nmh, sizeof(u), NFQA_VERDICT_HDR, &vh, sizeof(vh));
620
621         if (set_mark)
622                 nfnl_addattr32(&u.nmh, sizeof(u), NFQA_MARK, mark);
623
624         iov[0].iov_base = &u.nmh;
625         iov[0].iov_len = NLMSG_TAIL(&u.nmh) - (void *)&u.nmh;
626         nvecs = 1;
627
628         if (data_len) {
629                 nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
630                                 data_len, data);
631                 nvecs += 2;
632                 /* Add the length of the appended data to the message
633                  * header.  The size of the attribute is given in the
634                  * nfa_len field and is set in the nfnl_build_nfa_iovec()
635                  * function. */
636                 u.nmh.nlmsg_len += data_attr.nfa_len;
637         }
638
639         return nfnl_sendiov(qh->h->nfnlh, iov, nvecs, 0);
640 }
641
642 /**
643  * \addtogroup Queue
644  * @{
645  */
646
647 /**
648  * nfq_set_verdict - issue a verdict on a packet 
649  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
650  * \param id    ID assigned to packet by netfilter.
651  * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
652  * \param data_len number of bytes of data pointed to by #buf
653  * \param buf the buffer that contains the packet data
654  *
655  * Can be obtained by: 
656  * \verbatim
657         int id;
658         struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(tb);
659         if (ph)
660                 id = ntohl(ph->packet_id);
661 \endverbatim
662  *
663  * Notifies netfilter of the userspace verdict for the given packet.  Every
664  * queued packet _must_ have a verdict specified by userspace, either by
665  * calling this function, or by calling the nfq_set_verdict_mark() function.
666  */
667 int nfq_set_verdict(struct nfq_q_handle *qh, u_int32_t id,
668                 u_int32_t verdict, u_int32_t data_len, 
669                 unsigned char *buf)
670 {
671         return __set_verdict(qh, id, verdict, 0, 0, data_len, buf);
672 }       
673
674 /**
675  * nfq_set_verdict_mark - like nfq_set_verdict, but you can set the mark.
676  * \param qh Netfilter queue handle obtained by call to nfq_create_queue().
677  * \param id    ID assigned to packet by netfilter.
678  * \param verdict verdict to return to netfilter (NF_ACCEPT, NF_DROP)
679  * \param mark mark to put on packet
680  * \param data_len number of bytes of data pointed to by #buf
681  * \param buf the buffer that contains the packet data
682  */
683 int nfq_set_verdict_mark(struct nfq_q_handle *qh, u_int32_t id,
684                 u_int32_t verdict, u_int32_t mark,
685                 u_int32_t data_len, unsigned char *buf)
686 {
687         return __set_verdict(qh, id, verdict, mark, 1, data_len, buf);
688 }
689
690 /**
691  * @}
692  */
693
694
695
696 /*************************************************************
697  * Message parsing functions 
698  *************************************************************/
699
700 /**
701  * \defgroup Parsing Message parsing functions
702  * @{
703  */
704
705 /**
706  * nfqnl_msg_packet_hdr - return the metaheader that wraps the packet
707  * \param nfad Netlink packet data handle passed to callback function
708  *
709  * \return the netfilter queue netlink packet header for the given
710  * nfq_data argument.  Typically, the nfq_data value is passed as the 3rd
711  * parameter to the callback function set by a call to nfq_create_queue().
712  *
713  * The nfqnl_msg_packet_hdr structure is defined in libnetfilter_queue.h as:
714  *
715  * \verbatim
716         struct nfqnl_msg_packet_hdr {
717                 u_int32_t       packet_id;      // unique ID of packet in queue
718                 u_int16_t       hw_protocol;    // hw protocol (network order)
719                 u_int8_t        hook;           // netfilter hook
720         } __attribute__ ((packed));
721 \endverbatim
722  */
723 struct nfqnl_msg_packet_hdr *nfq_get_msg_packet_hdr(struct nfq_data *nfad)
724 {
725         return nfnl_get_pointer_to_data(nfad->data, NFQA_PACKET_HDR,
726                                         struct nfqnl_msg_packet_hdr);
727 }
728
729 /**
730  * nfq_get_nfmark - get the packet mark
731  * \param nfad Netlink packet data handle passed to callback function
732  *
733  * \return the netfilter mark currently assigned to the given queued packet.
734  */
735 uint32_t nfq_get_nfmark(struct nfq_data *nfad)
736 {
737         return ntohl(nfnl_get_data(nfad->data, NFQA_MARK, u_int32_t));
738 }
739
740 /**
741  * nfq_get_timestamp - get the packet timestamp
742  * \param nfad Netlink packet data handle passed to callback function
743  * \param tv structure to fill with timestamp info
744  *
745  * Retrieves the received timestamp when the given queued packet.
746  *
747  * \return 0 on success, non-zero on failure.
748  */
749 int nfq_get_timestamp(struct nfq_data *nfad, struct timeval *tv)
750 {
751         struct nfqnl_msg_packet_timestamp *qpt;
752         qpt = nfnl_get_pointer_to_data(nfad->data, NFQA_TIMESTAMP,
753                                         struct nfqnl_msg_packet_timestamp);
754         if (!qpt)
755                 return -1;
756
757         tv->tv_sec = __be64_to_cpu(qpt->sec);
758         tv->tv_usec = __be64_to_cpu(qpt->usec);
759
760         return 0;
761 }
762
763 /**
764  * nfq_get_indev - get the interface that the packet was received through
765  * \param nfad Netlink packet data handle passed to callback function
766  *
767  * \return The index of the device the queued packet was received via.  If the
768  * returned index is 0, the packet was locally generated or the input
769  * interface is not known (ie. POSTROUTING?).
770  *
771  * \warning all nfq_get_dev() functions return 0 if not set, since linux
772  * only allows ifindex >= 1, see net/core/dev.c:2600  (in 2.6.13.1)
773  */
774 u_int32_t nfq_get_indev(struct nfq_data *nfad)
775 {
776         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_INDEV, u_int32_t));
777 }
778
779 /**
780  * nfq_get_physindev - get the physical interface that the packet was received
781  * \param nfad Netlink packet data handle passed to callback function
782  *
783  * \return The index of the physical device the queued packet was received via.
784  * If the returned index is 0, the packet was locally generated or the
785  * physical input interface is no longer known (ie. POSTROUTING?).
786  */
787 u_int32_t nfq_get_physindev(struct nfq_data *nfad)
788 {
789         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSINDEV, u_int32_t));
790 }
791
792 /**
793  * nfq_get_outdev - gets the interface that the packet will be routed out
794  * \param nfad Netlink packet data handle passed to callback function
795  *
796  * \return The index of the device the queued packet will be sent out.  If the
797  * returned index is 0, the packet is destined for localhost or the output
798  * interface is not yet known (ie. PREROUTING?).
799  */
800 u_int32_t nfq_get_outdev(struct nfq_data *nfad)
801 {
802         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_OUTDEV, u_int32_t));
803 }
804
805 /**
806  * nfq_get_physoutdev - get the physical interface that the packet output
807  * \param nfad Netlink packet data handle passed to callback function
808  *
809  * The index of the physical device the queued packet will be sent out.
810  * If the returned index is 0, the packet is destined for localhost or the
811  * physical output interface is not yet known (ie. PREROUTING?).
812  * 
813  * \return The index of physical interface that the packet output will be routed out.
814  */
815 u_int32_t nfq_get_physoutdev(struct nfq_data *nfad)
816 {
817         return ntohl(nfnl_get_data(nfad->data, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t));
818 }
819
820 /**
821  * nfq_get_indev_name - get the name of the interface the packet
822  * was received through
823  * \param nlif_handle pointer to a nlif interface resolving handle
824  * \param nfad Netlink packet data handle passed to callback function
825  * \param name pointer that will be set to the interface name string 
826  * \return -1 in case of error, >0 if it succeed. 
827  *
828  * The #name variable will point to the name of the input interface.
829  *
830  * To use a nlif_handle, You need first to call nlif_open() and to open
831  * an handler. Don't forget to store the result as it will be used 
832  * during all your program life:
833  * \verbatim
834         h = nlif_open();
835         if (h == NULL) {
836                 perror("nlif_open");
837                 exit(EXIT_FAILURE);
838         }
839 \endverbatim
840  * Once the handler is open, you need to fetch the interface table at a
841  * whole via a call to nlif_query.
842  * \verbatim
843         nlif_query(h);
844 \endverbatim
845  * libnfnetlink is able to update the interface mapping when a new interface
846  * appears. To do so, you need to call nlif_catch() on the handler after each
847  * interface related event. The simplest way to get and treat event is to run
848  * a select() or poll() against the nlif file descriptor. To get this file 
849  * descriptor, you need to use nlif_fd:
850  * \verbatim
851         if_fd = nlif_fd(h);
852 \endverbatim
853  * Don't forget to close the handler when you don't need the feature anymore:
854  * \verbatim
855         nlif_close(h);
856 \endverbatim
857  *
858  */
859 int nfq_get_indev_name(struct nlif_handle *nlif_handle,
860                         struct nfq_data *nfad, char *name)
861 {
862         u_int32_t ifindex = nfq_get_indev(nfad);
863         return nlif_index2name(nlif_handle, ifindex, name);
864 }
865
866 /**
867  * nfq_get_physindev_name - get the name of the physical interface the
868  * packet was received through
869  * \param nlif_handle pointer to a nlif interface resolving handle
870  * \param nfad Netlink packet data handle passed to callback function
871  * \param name pointer that will be set to the interface name string 
872  *
873  * The #name variable will point to the name of the input physical
874  * interface.
875  *
876  * See nfq_get_indev_name() documentation for nlif_handle usage.
877  *
878  * \return  -1 in case of error, > 0 if it succeed. 
879  */
880 int nfq_get_physindev_name(struct nlif_handle *nlif_handle,
881                            struct nfq_data *nfad, char *name)
882 {
883         u_int32_t ifindex = nfq_get_physindev(nfad);
884         return nlif_index2name(nlif_handle, ifindex, name);
885 }
886
887 /**
888  * nfq_get_outdev_name - get the name of the physical interface the
889  * packet will be sent to
890  * \param nlif_handle pointer to a nlif interface resolving handle
891  * \param nfad Netlink packet data handle passed to callback function
892  * \param name pointer that will be set to the interface name string 
893  *
894  * The #name variable will point to the name of the output interface.
895  *
896  * See nfq_get_indev_name() documentation for nlif_handle usage.
897  *
898  * \return  -1 in case of error, > 0 if it succeed. 
899  */
900 int nfq_get_outdev_name(struct nlif_handle *nlif_handle,
901                         struct nfq_data *nfad, char *name)
902 {
903         u_int32_t ifindex = nfq_get_outdev(nfad);
904         return nlif_index2name(nlif_handle, ifindex, name);
905 }
906
907 /**
908  * nfq_get_physoutdev_name - get the name of the interface the
909  * packet will be sent to
910  * \param nlif_handle pointer to a nlif interface resolving handle
911  * \param nfad Netlink packet data handle passed to callback function
912  * \param name pointer that will be set to the interface name string 
913  * The #name variable will point to the name of the physical
914  * output interface.
915  *
916  * See nfq_get_indev_name() documentation for nlif_handle usage.
917  *
918  * \return  -1 in case of error, > 0 if it succeed. 
919  */
920
921 int nfq_get_physoutdev_name(struct nlif_handle *nlif_handle,
922                             struct nfq_data *nfad, char *name)
923 {
924         u_int32_t ifindex = nfq_get_physoutdev(nfad);
925         return nlif_index2name(nlif_handle, ifindex, name);
926 }
927
928 /**
929  * nfq_get_packet_hw
930  *
931  * get hardware address 
932  *
933  * \param nfad Netlink packet data handle passed to callback function
934  *
935  * Retrieves the hardware address associated with the given queued packet.
936  * For ethernet packets, the hardware address returned (if any) will be the
937  * MAC address of the packet source host.  The destination MAC address is not
938  * known until after POSTROUTING and a successful ARP request, so cannot
939  * currently be retrieved.
940  *
941  * The nfqnl_msg_packet_hw structure is defined in libnetfilter_queue.h as:
942  * \verbatim
943         struct nfqnl_msg_packet_hw {
944                 u_int16_t       hw_addrlen;
945                 u_int16_t       _pad;
946                 u_int8_t        hw_addr[8];
947         } __attribute__ ((packed));
948 \endverbatim
949  */
950 struct nfqnl_msg_packet_hw *nfq_get_packet_hw(struct nfq_data *nfad)
951 {
952         return nfnl_get_pointer_to_data(nfad->data, NFQA_HWADDR,
953                                         struct nfqnl_msg_packet_hw);
954 }
955
956 /**
957  * nfq_get_payload - get payload 
958  * \param nfad Netlink packet data handle passed to callback function
959  * \param data Pointer of pointer that will be pointed to the payload
960  *
961  * Retrieve the payload for a queued packet. The actual amount and type of
962  * data retrieved by this function will depend on the mode set with the
963  * nfq_set_mode() function.
964  *
965  * \return -1 on error, otherwise > 0.
966  */
967 int nfq_get_payload(struct nfq_data *nfad, char **data)
968 {
969         *data = nfnl_get_pointer_to_data(nfad->data, NFQA_PAYLOAD, char);
970         if (*data)
971                 return NFA_PAYLOAD(nfad->data[NFQA_PAYLOAD-1]);
972
973         return -1;
974 }
975
976 /**
977  * @}
978  */