Add send (rfc3971 implementation)
[packages.git] / ipv6 / send / patches / 001-libnetfilter_queue_update.patch
1 Index: sendd-0.2/Makefile.config
2 ===================================================================
3 --- sendd-0.2.orig/Makefile.config      2008-05-27 16:53:49.238160776 +0200
4 +++ sendd-0.2/Makefile.config   2008-05-27 16:53:52.866156255 +0200
5 @@ -19,7 +19,7 @@
6  #CC=gcc-4.0
7  
8  # Where to install
9 -prefix=/usr
10 +prefix=$(DESTDIR)/usr
11  
12  # Set to "y" to build MT versions of sendd and cgatool
13  USE_THREADS=n
14 Index: sendd-0.2/README
15 ===================================================================
16 --- sendd-0.2.orig/README       2008-05-27 16:53:49.246168775 +0200
17 +++ sendd-0.2/README    2008-05-27 16:53:52.866156255 +0200
18 @@ -20,7 +20,7 @@
19    o CONFIG_NETFILTER, CONFIG_IPV6, CONFIG_IP6_NF_QUEUE, CONFIG_IP6_NF_IPTABLES,
20      CONFIG_IP6_NF_FILTER enabled in your kernel config.
21    o netfilter ip6tables command
22 -  o netfilter libipq development library and headers
23 +  o netfilter libnetfilter_queue development library and headers
24  
25  FreeBSD:
26    o NETGRAPH, NETGRAPH_BPF, NETGRAPH_ETHER, NETGRAPH_SOCKET enabled in
27 Index: sendd-0.2/cgatool/Makefile
28 ===================================================================
29 --- sendd-0.2.orig/cgatool/Makefile     2008-05-27 16:53:49.278164104 +0200
30 +++ sendd-0.2/cgatool/Makefile  2008-05-27 16:53:52.866156255 +0200
31 @@ -25,7 +25,7 @@
32  
33  ifeq ($(USE_CONSOLE),y)
34  ifeq ($(USE_READLINE),y)
35 -LDLIBS += -lreadline -lncurses
36 +LDLIBS += -lreadline
37  endif
38  endif
39  
40 Index: sendd-0.2/sendd/Makefile
41 ===================================================================
42 --- sendd-0.2.orig/sendd/Makefile       2008-05-27 16:53:49.286173430 +0200
43 +++ sendd-0.2/sendd/Makefile    2008-05-27 16:53:52.878156241 +0200
44 @@ -37,7 +37,7 @@
45  
46  ifeq ($(USE_CONSOLE),y)
47  ifeq ($(USE_READLINE),y)
48 -LDLIBS += -lreadline -lncurses
49 +LDLIBS += -lreadline
50  endif
51  endif
52  
53 Index: sendd-0.2/sendd/os-linux/Makefile
54 ===================================================================
55 --- sendd-0.2.orig/sendd/os-linux/Makefile      2008-05-27 16:53:49.294197424 +0200
56 +++ sendd-0.2/sendd/os-linux/Makefile   2008-05-27 16:53:52.910156597 +0200
57 @@ -1,23 +1,5 @@
58  
59  OBJS += os/addr.o os/ipq.o os/rand.o os/snd_linux.o
60 -OSLIBS= -ldl -lipq
61 +OSLIBS= -lnetfilter_queue
62  
63 -OSEXTRA= os/sendd os/snd_upd_fw
64 -
65 -ETCINIT= /etc/init.d
66 -EXTRAINSTALL= $(ETCINIT)/sendd $(ETCINIT)/snd_upd_fw $(ETCINIT)/snd_fw_functions.sh
67 -EXTRAUNINSTALL=$(EXTRAINSTALL)
68 -EXTRACLEAN= os/sendd os/snd_upd_fw os/snd_fw_functions.sh
69 -
70 -$(ETCINIT)/%: os/%
71 -       install $< $@
72 -
73 -os/%: os/%.in
74 -       sed "s/@etcinit@/\/etc\/init.d/g" $< > $@
75 -
76 -os/%: os/%.in2
77 -       @./os/find_ip6tables.sh
78 -
79 -# Sometimes libipq.h is installed in include/libipq.h, other times it is
80 -# installed in include/libipq/libipq.h. This rule helps cpp to find it.
81 -os/ipq.o: CPPFLAGS += -I/usr/include/libipq -I/usr/local/include/libipq
82 +os/ipq.o: CPPFLAGS += -I/usr/include/libnetfilter_queue
83 Index: sendd-0.2/sendd/os-linux/ipq.c
84 ===================================================================
85 --- sendd-0.2.orig/sendd/os-linux/ipq.c 2008-05-27 16:53:49.306181136 +0200
86 +++ sendd-0.2/sendd/os-linux/ipq.c      2008-05-27 16:55:57.602168158 +0200
87 @@ -33,7 +33,7 @@
88  #include <sys/select.h>
89  #include <netinet/in.h>
90  #include <linux/netfilter.h>
91 -#include <libipq.h>
92 +#include <libnetfilter_queue.h>
93  
94  #include "config.h"
95  #include <applog.h>
96 @@ -42,122 +42,170 @@
97  #include "../sendd_local.h"
98  #include "snd_linux.h"
99  
100 -static struct ipq_handle *qh;
101 -
102  extern unsigned if_nametoindex(const char *);
103  
104 -static inline void
105 -process_pkt(ipq_packet_msg_t *pkt, struct sbuff *b)
106 -{
107 +struct nfq_handle *h = NULL;
108 +struct nfq_q_handle *qh = NULL;
109 +
110 +/* This is the default queue number used in our init script */
111 +#define SND_DEFAULT_NFQUEUE_NUMBER 13
112 +
113 +/* The sbuff is must be made available to the callback function that will
114 +   handle the packet */
115 +struct callback_data {
116 +       struct sbuff *b;
117 +};
118 +
119 +struct callback_data process_pkt_data;
120 +
121 +/* nfqueue callback */
122 +static int process_pkt(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
123 +                      struct nfq_data *nfa, void *data)
124 +{
125 +       struct callback_data * d = (struct callback_data *)data;
126 +       struct nfqnl_msg_packet_hdr *ph;
127 +       struct sbuff *b = d->b;
128 +       char *pkt_data;
129         int in, ifidx;
130  
131 -       b->data = pkt->payload;
132 -       b->len = pkt->data_len;
133 +       b->len = nfq_get_payload(nfa, &pkt_data);
134 +       if (b->len == -1) {
135 +               applog(LOG_ERR, "%s: nfq_get_payload() failed.", __FUNCTION__);
136 +               return 0;
137 +       }
138 +       b->data = (unsigned char *)pkt_data;
139  
140 -       if (*(pkt->indev_name)) {
141 +       if ((ifidx = nfq_get_indev(nfa)) && ifidx != 0)
142                 in = 1;
143 -               ifidx = if_nametoindex(pkt->indev_name);
144 -       } else if (*(pkt->outdev_name)) {
145 +       else if ((ifidx = nfq_get_outdev(nfa)) && ifidx != 0)
146                 in = 0;
147 -               ifidx = if_nametoindex(pkt->outdev_name);
148 -       } else {
149 +       else {
150                 applog(LOG_ERR, "%s: pkt has neither indev nor outdev",
151                        __FUNCTION__);
152                 snd_put_buf(b);
153 -               return;
154 +               return 0;
155         }
156  
157 -       snd_recv_pkt(b, ifidx, in, pkt);
158 -}
159 +       /* Grab packet header to get its id later */
160 +       ph = nfq_get_msg_packet_hdr(nfa); /* FIXME Check return value */
161  
162 -static void
163 -ipq_recv_pkt(void)
164 -{
165 -       int r;
166 -       struct sbuff *b = snd_get_buf();
167 +       snd_recv_pkt(b, ifidx, in, (void *)ph);
168  
169 -       if (b == NULL) {
170 -               return;
171 -       }
172 -       if ((r = ipq_read(qh, b->head, b->rem, -1)) < 0) {
173 -               applog(LOG_ERR, "%s: ipq_read(): %s", __FUNCTION__,
174 -                      ipq_errstr());
175 -               goto fail;
176 -       } else if (r == 0) {
177 -               /* timeout */
178 -               goto fail;
179 -       }
180 -
181 -       switch ((r = ipq_message_type(b->head))) {
182 -       case NLMSG_ERROR:
183 -               applog(LOG_ERR, "%s: nlmsg error: %s", __FUNCTION__,
184 -                      strerror(ipq_get_msgerr(b->head)));
185 -               goto fail;
186 -       case IPQM_PACKET:
187 -               process_pkt(ipq_get_packet(b->head), b);
188 -               return;
189 -       default:
190 -               break;
191 -       }
192 -
193 -fail:
194 -       snd_put_buf(b);
195 +       return 1;
196  }
197  
198  void
199 -linux_ipq_add_fds(fd_set *fds, int *maxfd)
200 +linux_nfq_add_fds(fd_set *fds, int *maxfd)
201  {
202 -       FD_SET(qh->fd, fds);
203 -       *maxfd = sendd_max(*maxfd, qh->fd);
204 +       int fd = nfnl_fd(nfq_nfnlh(h));
205 +
206 +       FD_SET(fd, fds);
207 +       *maxfd = sendd_max(*maxfd, fd);
208  }
209  
210  void
211 -linux_ipq_dispatch_fds(fd_set *fds)
212 +linux_nfq_dispatch_fds(fd_set *fds)
213  {
214 -       if (FD_ISSET(qh->fd, fds)) {
215 -               ipq_recv_pkt();
216 +       int fd = nfnl_fd(nfq_nfnlh(h));
217 +       int r;
218 +
219 +       if (FD_ISSET(fd, fds)) {
220 +               struct sbuff *b = snd_get_buf();
221 +
222 +               if (b == NULL) {
223 +                       return;
224 +               }
225 +
226 +               if ((r = recv(fd, b->head, b->rem, 0)) && r <= 0) {
227 +                       if (r < 0) /* not a timeout */
228 +                               applog(LOG_ERR, "%s: recv failed.",
229 +                                      __FUNCTION__);
230 +                       snd_put_buf(b);
231 +                       return;
232 +               }
233 +
234 +               process_pkt_data.b = b; /* make sbuff available to
235 +                                          callback function */
236 +               nfq_handle_packet(h, (char *)b->head, r);
237         }
238  }
239  
240  void
241  os_specific_deliver_pkt(void *p, struct sbuff *b, int drop, int changed)
242  {
243 -       ipq_packet_msg_t *pkt = p;
244 -       void *newpkt = NULL;
245 +       struct nfqnl_msg_packet_hdr *ph = (struct nfqnl_msg_packet_hdr *)p;
246 +       unsigned char *newpkt = NULL;
247         int plen = 0;
248 +       uint32_t id = 0;
249 +
250 +       if (ph)
251 +               id = ntohl(ph->packet_id);
252  
253         if (changed && !drop) {
254 -               newpkt = sbuff_data(b);
255 +               newpkt = (unsigned char *)b->data;
256                 plen = b->len;
257         }
258  
259 -       ipq_set_verdict(qh, pkt->packet_id, drop ? NF_DROP : NF_ACCEPT,
260 -                       plen, newpkt);
261 +       nfq_set_verdict(qh, id, drop ? NF_DROP : NF_ACCEPT, plen, newpkt);
262         snd_put_buf(b);
263  }
264  
265  int
266 -linux_ipq_init(void)
267 +linux_nfq_init(void)
268  {
269 -       if ((qh = ipq_create_handle(0, PF_INET6)) == NULL) {
270 -               applog(LOG_ERR, "%s: ipq_create_handle() failed: %s",
271 -                      __FUNCTION__, ipq_errstr());
272 -               return (-1);
273 -       }
274 -       if (ipq_set_mode(qh, IPQ_COPY_PACKET, SND_MAX_PKT) < 0) {
275 -               applog(LOG_ERR, "%s: ipq_set_mode() failed: %s",
276 -                      __FUNCTION__, ipq_errstr());
277 -               if (errno == ECONNREFUSED) {
278 -                       applog(LOG_ERR, "%s: perhaps you need to modprobe "
279 -                              "ip6_queue?", __FUNCTION__);
280 -               }
281 -               return (-1);
282 +       struct nfnl_handle *nh;
283 +       u_int16_t nfqueue_num = SND_DEFAULT_NFQUEUE_NUMBER;
284 +
285 +       /* Get netfilter queue connection handle */
286 +       h = nfq_open();
287 +       if (!h) {
288 +               applog(LOG_ERR, "%s: nfq_open() failed.", __FUNCTION__);
289 +               return -1;
290 +       }
291 +
292 +       /* Unbinding existing nfqueue handlers for AF_INET6. We ignore the
293 +          return value: http://www.spinics.net/lists/netfilter/msg42063.html.
294 +          Note that this call is required, otherwise, nfq_bind_pf() fails. */
295 +       nfq_unbind_pf(h, PF_INET6);
296 +
297 +       if (nfq_bind_pf(h, PF_INET6) < 0) {
298 +               applog(LOG_ERR, "%s: nfq_bind_pf failed.\n", __FUNCTION__);
299 +               return -1;
300 +       }
301 +
302 +       /* Binding this socket to queue number nfqueue_num and installing
303 +          our packet handler */
304 +       qh = nfq_create_queue(h, nfqueue_num,
305 +                             (nfq_callback *) &process_pkt,
306 +                             (void *)&process_pkt_data);
307 +       if (!qh) {
308 +               applog(LOG_ERR, "%s: nfq_create_queue() failed.\n",
309 +                      __FUNCTION__);
310 +               return -1;
311 +       }
312 +
313 +       /* Asking for entire copy of queued packets */
314 +       if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { /* XXX was SND_MAX_PKT */
315 +               fprintf(stderr, "nfq_set_mode() failed.\n");
316 +               return -1;
317         }
318 -       return (0);
319 +
320 +       /* XXX - Check if we have an interest in setting queue length */
321 +
322 +       /* The netlink handle associated with our queue connection handle */
323 +       nh = nfq_nfnlh(h);
324 +
325 +       return 0;
326  }
327  
328  void
329 -linux_ipq_fini(void)
330 +linux_nfq_fini(void)
331  {
332 -       ipq_destroy_handle(qh);
333 +       /* Remove the binding for our queue handler*/
334 +       if (qh != NULL)
335 +               nfq_destroy_queue(qh);
336 +
337 +       /* Close connection associated with our connection handler */
338 +       if (h != NULL)
339 +               nfq_close(h);
340  }
341 Index: sendd-0.2/sendd/os-linux/snd_linux.c
342 ===================================================================
343 --- sendd-0.2.orig/sendd/os-linux/snd_linux.c   2008-05-27 16:53:49.314164060 +0200
344 +++ sendd-0.2/sendd/os-linux/snd_linux.c        2008-05-27 16:53:52.914160667 +0200
345 @@ -40,13 +40,13 @@
346  void
347  os_specific_add_fds(fd_set *fds, int *maxfd)
348  {
349 -       linux_ipq_add_fds(fds, maxfd);
350 +       linux_nfq_add_fds(fds, maxfd);
351  }
352  
353  void
354  os_specific_dispatch_fds(fd_set *fds)
355  {
356 -       linux_ipq_dispatch_fds(fds);
357 +       linux_nfq_dispatch_fds(fds);
358  }
359  
360  int
361 @@ -59,7 +59,7 @@
362  os_specific_init(void)
363  {
364         if (linux_rand_init() < 0 ||
365 -           linux_ipq_init() < 0) {
366 +           linux_nfq_init() < 0) {
367                 return (-1);
368         }
369         return (0);
370 @@ -68,6 +68,6 @@
371  void
372  os_specific_fini(void)
373  {
374 -       linux_ipq_fini();
375 +       linux_nfq_fini();
376         linux_rand_fini();
377  }
378 Index: sendd-0.2/sendd/os-linux/snd_linux.h
379 ===================================================================
380 --- sendd-0.2.orig/sendd/os-linux/snd_linux.h   2008-05-27 16:53:49.330169232 +0200
381 +++ sendd-0.2/sendd/os-linux/snd_linux.h        2008-05-27 16:53:52.914160667 +0200
382 @@ -33,10 +33,10 @@
383  #ifndef        _SEND_LINUX_H
384  #define        _SEND_LINUX_H
385  
386 -extern void linux_ipq_add_fds(fd_set *, int *);
387 -extern void linux_ipq_dispatch_fds(fd_set *);
388 -extern int linux_ipq_init(void);
389 -extern void linux_ipq_fini(void);
390 +extern void linux_nfq_add_fds(fd_set *, int *);
391 +extern void linux_nfq_dispatch_fds(fd_set *);
392 +extern int linux_nfq_init(void);
393 +extern void linux_nfq_fini(void);
394  
395  extern void linux_rand_fini(void);
396  extern int linux_rand_init(void);