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