3 # - use $DESTDIR for prefix (Debian interest)
4 # - use libnetfilter_queue instead of deprecated libipq
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
16 +prefix=$(DESTDIR)/usr
18 # Set to "y" to build MT versions of sendd and cgatool
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
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
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
39 ifeq ($(USE_CONSOLE),y)
40 ifeq ($(USE_READLINE),y)
41 -LDLIBS += -lreadline -lncurses
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
52 ifeq ($(USE_CONSOLE),y)
53 ifeq ($(USE_READLINE),y)
54 -LDLIBS += -lreadline -lncurses
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
65 OBJS += os/addr.o os/ipq.o os/rand.o os/snd_linux.o
67 +OSLIBS= -lnetfilter_queue
69 -OSEXTRA= os/sendd os/snd_upd_fw
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
80 - sed "s/@etcinit@/\/etc\/init.d/g" $< > $@
83 - @./os/find_ip6tables.sh
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
94 #include <sys/select.h>
95 #include <netinet/in.h>
96 #include <linux/netfilter.h>
98 +#include <libnetfilter_queue.h>
102 @@ -42,122 +42,170 @@
103 #include "../sendd_local.h"
104 #include "snd_linux.h"
106 -static struct ipq_handle *qh;
108 extern unsigned if_nametoindex(const char *);
111 -process_pkt(ipq_packet_msg_t *pkt, struct sbuff *b)
113 +struct nfq_handle *h = NULL;
114 +struct nfq_q_handle *qh = NULL;
116 +/* This is the default queue number used in our init script */
117 +#define SND_DEFAULT_NFQUEUE_NUMBER 13
119 +/* The sbuff is must be made available to the callback function that will
120 + handle the packet */
121 +struct callback_data {
125 +struct callback_data process_pkt_data;
127 +/* nfqueue callback */
128 +static int process_pkt(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
129 + struct nfq_data *nfa, void *data)
131 + struct callback_data * d = (struct callback_data *)data;
132 + struct nfqnl_msg_packet_hdr *ph;
133 + struct sbuff *b = d->b;
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__);
144 + b->data = (unsigned char *)pkt_data;
146 - if (*(pkt->indev_name)) {
147 + if ((ifidx = nfq_get_indev(nfa)) && ifidx != 0)
149 - ifidx = if_nametoindex(pkt->indev_name);
150 - } else if (*(pkt->outdev_name)) {
151 + else if ((ifidx = nfq_get_outdev(nfa)) && ifidx != 0)
153 - ifidx = if_nametoindex(pkt->outdev_name);
156 applog(LOG_ERR, "%s: pkt has neither indev nor outdev",
163 - snd_recv_pkt(b, ifidx, in, pkt);
165 + /* Grab packet header to get its id later */
166 + ph = nfq_get_msg_packet_hdr(nfa); /* FIXME Check return value */
172 - struct sbuff *b = snd_get_buf();
173 + snd_recv_pkt(b, ifidx, in, (void *)ph);
178 - if ((r = ipq_read(qh, b->head, b->rem, -1)) < 0) {
179 - applog(LOG_ERR, "%s: ipq_read(): %s", __FUNCTION__,
182 - } else if (r == 0) {
187 - switch ((r = ipq_message_type(b->head))) {
189 - applog(LOG_ERR, "%s: nlmsg error: %s", __FUNCTION__,
190 - strerror(ipq_get_msgerr(b->head)));
193 - process_pkt(ipq_get_packet(b->head), b);
205 -linux_ipq_add_fds(fd_set *fds, int *maxfd)
206 +linux_nfq_add_fds(fd_set *fds, int *maxfd)
208 - FD_SET(qh->fd, fds);
209 - *maxfd = sendd_max(*maxfd, qh->fd);
210 + int fd = nfnl_fd(nfq_nfnlh(h));
213 + *maxfd = sendd_max(*maxfd, fd);
217 -linux_ipq_dispatch_fds(fd_set *fds)
218 +linux_nfq_dispatch_fds(fd_set *fds)
220 - if (FD_ISSET(qh->fd, fds)) {
222 + int fd = nfnl_fd(nfq_nfnlh(h));
225 + if (FD_ISSET(fd, fds)) {
226 + struct sbuff *b = snd_get_buf();
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.",
240 + process_pkt_data.b = b; /* make sbuff available to
241 + callback function */
242 + nfq_handle_packet(h, (char *)b->head, r);
247 os_specific_deliver_pkt(void *p, struct sbuff *b, int drop, int changed)
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;
257 + id = ntohl(ph->packet_id);
259 if (changed && !drop) {
260 - newpkt = sbuff_data(b);
261 + newpkt = (unsigned char *)b->data;
265 - ipq_set_verdict(qh, pkt->packet_id, drop ? NF_DROP : NF_ACCEPT,
267 + nfq_set_verdict(qh, id, drop ? NF_DROP : NF_ACCEPT, plen, newpkt);
272 -linux_ipq_init(void)
273 +linux_nfq_init(void)
275 - if ((qh = ipq_create_handle(0, PF_INET6)) == NULL) {
276 - applog(LOG_ERR, "%s: ipq_create_handle() failed: %s",
277 - __FUNCTION__, ipq_errstr());
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__);
288 + struct nfnl_handle *nh;
289 + u_int16_t nfqueue_num = SND_DEFAULT_NFQUEUE_NUMBER;
291 + /* Get netfilter queue connection handle */
294 + applog(LOG_ERR, "%s: nfq_open() failed.", __FUNCTION__);
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);
303 + if (nfq_bind_pf(h, PF_INET6) < 0) {
304 + applog(LOG_ERR, "%s: nfq_bind_pf failed.\n", __FUNCTION__);
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);
314 + applog(LOG_ERR, "%s: nfq_create_queue() failed.\n",
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");
326 + /* XXX - Check if we have an interest in setting queue length */
328 + /* The netlink handle associated with our queue connection handle */
335 -linux_ipq_fini(void)
336 +linux_nfq_fini(void)
338 - ipq_destroy_handle(qh);
339 + /* Remove the binding for our queue handler*/
341 + nfq_destroy_queue(qh);
343 + /* Close connection associated with our connection handler */
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
353 os_specific_add_fds(fd_set *fds, int *maxfd)
355 - linux_ipq_add_fds(fds, maxfd);
356 + linux_nfq_add_fds(fds, maxfd);
360 os_specific_dispatch_fds(fd_set *fds)
362 - linux_ipq_dispatch_fds(fds);
363 + linux_nfq_dispatch_fds(fds);
368 os_specific_init(void)
370 if (linux_rand_init() < 0 ||
371 - linux_ipq_init() < 0) {
372 + linux_nfq_init() < 0) {
378 os_specific_fini(void)
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
389 #ifndef _SEND_LINUX_H
390 #define _SEND_LINUX_H
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);
401 extern void linux_rand_fini(void);
402 extern int linux_rand_init(void);