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