Issue #5, Describe routable prefix, the -R option
[6bed4] / src / 6bed4router.c
1 /* 6bed4/router.c -- traffic forwarding daemon for public TSP service
2  *
3  * This is an implementation of the profile that makes TSP service publicly
4  * usable, that is without authentication.  However to avoid abuse of such
5  * a service, it is not anonymous -- IPv6 addresses contain the IPv4 address
6  * and port.
7  *
8  * This is an implementation of neighbour and router discovery over a
9  * tunnel that packs IPv6 inside UDP/IPv4.  This tunnel mechanism is
10  * targeted specifically at embedded devices that are to function on
11  * any network, including IPv4-only, while being designed as IPv6-only
12  * devices with a fallback to this tunnel.
13  *
14  * Interestingly, as a side-effect of this design the router daemon can be
15  * stateless.  Any further requirements that are stateful are most likely
16  * filtering, and that can be solved in stateful firewall configuration.
17  *
18  * The intention of TSP is to enable IPv4-only hosts to connecto to
19  * IPv6 services; the public TSP profile adds to that the ability to
20  * do it in a temporary manner.
21  *
22  * TODO: Should we translate ICMPv4 --> ICMPv6?
23  *
24  * From: Rick van Rein <rick@openfortress.nl>
25  */
26
27
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <stdbool.h>
33
34 #include <errno.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include <getopt.h>
38 #include <fcntl.h>
39
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <sys/time.h>
43 #include <sys/select.h>
44 #include <sys/ioctl.h>
45
46 #include <netinet/in.h>
47 #include <netinet/ip.h>
48 #include <netinet/ip6.h>
49 #include <netinet/tcp.h>
50 #include <netinet/udp.h>
51 #include <netinet/icmp6.h>
52 #include <arpa/inet.h>
53
54 #include <linux/if.h>
55 #include <linux/if_tun.h>
56 #include <linux/if_ether.h>
57
58
59 /* The following will initially fail, due to an IANA obligation to avoid
60  * default builds with non-standard options.
61  */
62 #include "nonstd.h"
63
64
65 #define MTU 1280
66
67
68 #ifndef MAX_ROUTABLE_PREFIXES
69 #define MAX_ROUTABLE_PREFIXES 10
70 #endif
71
72
73 /*
74  * The HAVE_SETUP_TUNNEL variable is used to determine whether absense of
75  * the -d option leads to an error, or to an attempt to setup the tunnel.
76  * The setup_tunnel() function used for that is defined per platform, such
77  * as for LINUX.  Remember to maintain the manpage's optionality for -d.
78  */
79 #undef HAVE_SETUP_TUNNEL
80
81
82 /* Global variables */
83
84 /* SCTP structures are far from standardised, so we define our own header */
85 struct my_sctphdr {
86         uint16_t source, dest;
87         uint32_t vtag;
88         uint32_t cksum;
89 };
90
91 char *program;
92
93 int v4sox = -1;
94 int v6sox = -1;
95
96 char *v4server = NULL;
97 char *v6server = NULL;
98 char *v6prefix = NULL;
99
100 const uint8_t v6listen_linklocal [16] = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
101 uint8_t v6listen_linklocal_complete [16] = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
102
103 uint8_t lladdr_6bed4 [6];
104
105 struct sockaddr_in6 v6name;
106 struct sockaddr_in  v4name;
107 struct sockaddr_in  v4name_xlate;
108
109 struct in6_addr v6listen;
110 struct in6_addr v6listen_complete;
111 struct in_addr  v4listen;
112
113 struct in6_addr v6routable_prefix    [MAX_ROUTABLE_PREFIXES];
114 uint8_t         v6routable_prefixlen [MAX_ROUTABLE_PREFIXES];
115 int             v6routable_prefixcount = 0;
116
117
118 struct {
119         struct tun_pi tun;
120         union {
121                 struct {
122                         struct ip6_hdr v6hdr;
123                         uint8_t data [MTU - sizeof (struct ip6_hdr)];
124                 } idata;
125                 struct v4frame {
126                         struct ip6_hdr v6hdr;
127                         union {
128                                 struct icmp6_hdr  v6icmphdr;
129                                 struct my_sctphdr v6sctphdr;
130                                 struct tcphdr     v6tcphdr ;
131                                 struct udphdr     v6udphdr ;
132                                 struct {
133                                         struct udphdr     v6udphdr;
134                                         struct my_sctphdr v6sctphdr;
135                                 } tdata;
136                         } adata;
137                 } ndata;
138         } udata;
139 } v4data6;
140
141 #define v4tunpi6        ( v4data6.tun)
142 #define v4data          ((uint8_t *) &v4data6.udata)
143 #define v4hdr6          (&v4data6.udata.idata.v6hdr)
144 #define v4src6          (&v4data6.udata.idata.v6hdr.ip6_src)
145 #define v4dst6          (&v4data6.udata.idata.v6hdr.ip6_dst)
146
147 #define v4v6payload     ((uint16_t *) &v4data6.udata.ndata.adata)
148 #define v4v6plen        ( v4data6.udata.ndata.v6hdr.ip6_plen)
149 #define v4v6nexthdr     ( v4data6.udata.ndata.v6hdr.ip6_nxt)
150 #define v4v6hoplimit    ( v4data6.udata.ndata.v6hdr.ip6_hops)
151
152 #define v4v6icmpdata    ( v4data6.udata.ndata.adata.v6icmphdr.icmp6_data8)
153 #define v4v6icmptype    ( v4data6.udata.ndata.adata.v6icmphdr.icmp6_type)
154 #define v4v6icmpcode    ( v4data6.udata.ndata.adata.v6icmphdr.icmp6_code)
155 #define v4v6icmpcksum   ( v4data6.udata.ndata.adata.v6icmphdr.icmp6_cksum)
156
157 #define v4v6sctpofs     (offsetof (struct v4frame,adata.v6sctphdr))
158 #define v4v6sctpsrcport ( v4data6.udata.ndata.adata.v6sctphdr.source)
159 #define v4v6sctpdstport ( v4data6.udata.ndata.adata.v6sctphdr.dest)
160 #define v4v6sctpcksum   ( v4data6.udata.ndata.adata.v6sctphdr.cksum)
161
162 #define v4v6tunsctpofs  (offsetof (struct v4frame,adata.tdata.v6sctphdr))
163 #define v4v6tunsctpsrcport ( v4data6.udata.ndata.adata.tdata.v6sctphdr.source)
164 #define v4v6tunsctpdstport ( v4data6.udata.ndata.adata.tdata.v6sctphdr.dest)
165 #define v4v6tunsctpcksum   ( v4data6.udata.ndata.adata.tdata.v6sctphdr.cksum)
166
167 #define v4v6tcpsrcport  ( v4data6.udata.ndata.adata.v6tcphdr.source)
168 #define v4v6tcpdstport  ( v4data6.udata.ndata.adata.v6tcphdr.dest)
169 #define v4v6tcpcksum    ( v4data6.udata.ndata.adata.v6tcphdr.check)
170
171 #define v4v6udpsrcport  ( v4data6.udata.ndata.adata.v6udphdr.source)
172 #define v4v6udpdstport  ( v4data6.udata.ndata.adata.v6udphdr.dest)
173 #define v4v6udpcksum    ( v4data6.udata.ndata.adata.v6udphdr.check)
174
175 #define v4ngbsoltarget  (&v4data6.udata.ndata.adata.v6icmphdr.icmp6_data8 [4])
176
177
178 struct {
179         struct tun_pi tun;
180         union {
181                 uint8_t data [MTU];
182                 struct v6frame {
183                         struct ip6_hdr v6hdr;
184                         union {
185                                 struct icmp6_hdr  v6icmphdr;
186                                 struct my_sctphdr v6sctphdr;
187                                 struct tcphdr     v6tcphdr ;
188                                 struct udphdr     v6udphdr ;
189                                 struct {
190                                         struct udphdr     v6udphdr;
191                                         struct my_sctphdr v6sctphdr;
192                                 } tdata;
193                         } adata;
194                 } ndata;
195         } udata;
196         uint8_t zero;
197 } v6data6;
198
199 #define v6tuncmd        ( v6data6.tun)
200 #define v6data          ( v6data6.udata.data)
201 #define v6hdr6          (&v6data6.udata.ndata.v6hdr)
202 #define v6src6          (&v6data6.udata.ndata.v6hdr.ip6_src)
203 #define v6dst6          (&v6data6.udata.ndata.v6hdr.ip6_dst)
204 #define v6hoplimit      ( v6data6.udata.ndata.v6hdr.ip6_hops)
205 #define v6nexthdr       ( v6data6.udata.ndata.v6hdr.ip6_nxt)
206
207 #define v6icmptype      ( v6data6.udata.ndata.adata.v6icmphdr.icmp6_type)
208 #define v6icmpcksum     ( v6data6.udata.ndata.adata.v6icmphdr.icmp6_cksum)
209
210 #define v6sctpcksum     ( v6data6.udata.ndata.adata.v6sctphdr.cksum)
211 #define v6tunsctpcksum  ( v6data6.udata.ndata.adata.tdata.v6sctphdr.cksum)
212
213 #define v6sctpofs       (offsetof(struct v6frame,adata.v6sctphdr))
214 #define v6tunsctpofs    (offsetof(struct v6frame,adata.tdata.v6sctphdr))
215
216 #define v6tcpcksum      ( v6data6.udata.ndata.adata.v6tcphdr.check)
217
218 #define v6udpcksum      ( v6data6.udata.ndata.adata.v6udphdr.check)
219 #define v6udpdstport    ( v6data6.udata.ndata.adata.v6udphdr.dest)
220 #define v6udpsrcport    ( v6data6.udata.ndata.adata.v6udphdr.source)
221
222
223 uint8_t router_linklocal_address [] = {
224         0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00,
225 };
226
227 uint8_t democlient_linklocal_address [] = {
228         0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x01,
229 };
230
231 uint8_t allnodes_linklocal_address [] = {
232         0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x01,
233 };
234
235 uint8_t allrouters_linklocal_address [] = {
236         0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x02,
237 };
238
239
240
241 #ifndef MAXNUM_MASQHOST
242 #define MAXNUM_MASQHOST 4
243 #endif
244
245 uint16_t num_masqhost = 0;
246 uint8_t masqhost [MAXNUM_MASQHOST][16];
247
248 // ports for 's', 't', 'u' -- SCTP, TCP, UDP have increasing numbers
249
250 #ifndef MAXNUM_PORTPAIRS
251 #define MAXNUM_PORTPAIRS 10
252 #endif
253
254 // masqportpairs holds triples <lowport,highport,masqhostnr>
255 uint16_t num_masqportpairs [3] = { 0, 0, 0 };
256 uint16_t masqportpairs [3][3*MAXNUM_PORTPAIRS];
257
258 // same for ICMPv6
259 uint16_t icmp_num_portpairs = 0;
260 uint16_t icmp_portpairs [3] = { 1, 1, 0 };
261
262
263
264 /*
265  *
266  * Driver routines
267  *
268  */
269
270 #ifndef INTERFACE_NAME_6BED4
271 #define INTERFACE_NAME_6BED4 "6bed4"
272 #endif
273
274 #ifdef LINUX
275 #define HAVE_SETUP_TUNNEL
276 /* Implement the setup_tunnel() command for Linux.
277  * Return 1 on success, 0 on failure.
278  */
279 int setup_tunnel (void) {
280         v6sox = open ("/dev/net/tun", O_RDWR);
281         if (v6sox == -1) {
282                 fprintf (stderr, "%s: Failed to access tunnel driver on /dev/net/tun: %s\n", program, strerror (errno));
283                 return 0;
284         }
285         int ok = 1;
286         struct ifreq ifreq;
287         memset (&ifreq, 0, sizeof (ifreq));
288         strncpy (ifreq.ifr_name, INTERFACE_NAME_6BED4, IFNAMSIZ);
289         ifreq.ifr_flags = IFF_TUN;
290         if (ok && (ioctl (v6sox, TUNSETIFF, (void *) &ifreq) == -1)) {
291                 ok = 0;
292         }
293         ifreq.ifr_name [IFNAMSIZ] = 0;
294         char cmd [512+1];
295         snprintf (cmd, 512, "/sbin/ip -6 addr flush dev %s", ifreq.ifr_name);
296         if (ok && system (cmd) != 0) {
297                 ok = 0;
298         }
299         snprintf (cmd, 512, "/sbin/ip addr add fe80::0 dev %s scope link", ifreq.ifr_name);
300         if (ok && system (cmd) != 0) {
301                 ok = 0;
302         }
303         snprintf (cmd, 512, "/sbin/ip -6 addr add %s dev %s", v6prefix, ifreq.ifr_name);
304         if (ok && system (cmd) != 0) {
305                 ok = 0;
306         }
307         snprintf (cmd, 512, "/sbin/ip link set %s up mtu 1280", ifreq.ifr_name);
308         if (ok && system (cmd) != 0) {
309                 ok = 0;
310         }
311         if (!ok) {
312                 close (v6sox);  /* This removes the tunnel interface */
313                 fprintf (stderr, "Failed to setup tunnel \"%s\"\n", INTERFACE_NAME_6BED4);
314         }
315         return ok;
316 }
317 #endif /* LINUX */
318
319
320 /*
321  *
322  * Utility functions
323  *
324  */
325
326
327 /* Produce an IPv6 address following the 6bed4 structures.
328  *  - The top half is taken from v6listen
329  *  - The bottom contains IPv4 address and port from v4name
330  *  - The last 14 bits are filled with the lanip parameter
331  */
332 void addr_6bed4 (struct in6_addr *dst_ip6, uint16_t lanip) {
333         memcpy (&dst_ip6->s6_addr [0], &v6listen, 8);
334         dst_ip6->s6_addr32 [2] = v4name.sin_addr.s_addr;
335         dst_ip6->s6_addr16 [6] = v4name.sin_port;
336         dst_ip6->s6_addr  [14] = ((dst_ip6->s6_addr [8] & 0x03) << 6)
337                                | ((lanip >> 8) & 0x3f);
338         dst_ip6->s6_addr  [15] = (lanip & 0xff);
339         dst_ip6->s6_addr  [8] &= 0xfc;
340 }
341
342 /* Calculate the ICMPv6 checksum field
343  */
344 uint16_t icmp6_checksum (struct in6_addr *src6, struct in6_addr *dst6,
345                                 uint16_t *payload, size_t payloadlen) {
346         uint16_t plenword = htons (payloadlen); // our ICMPv6 is small
347         uint16_t nxthword = htons (IPPROTO_ICMPV6);
348         uint16_t *area [] = { src6->s6_addr16, dst6->s6_addr16,
349                                 &plenword, &nxthword,
350                                 payload, &payload [2] };
351         uint8_t areawords [] = { 8, 8, 1, 1, 1, (payloadlen >> 1) - 2 };
352         uint32_t csum = 0;
353         u_int8_t i, j;
354         for (i=0; i < 6; i++) {
355                 for (j=0; j<areawords [i]; j++) {
356                         csum += ntohs (area [i] [j]);
357                 }
358         }
359         csum = (csum & 0xffff) + (csum >> 16);
360         csum = (csum & 0xffff) + (csum >> 16);
361         csum = htons (~csum);
362         return csum;
363 }
364
365
366 /* Mangle a packet by replacing an IPv6 address, correcting the checksum.
367  * In all of ICMPv6, UDPv6, TCPv6, SCTPv6, the checksumming is a 1's cpl
368  * of a sum of 16-bit words; the position of the words don't matter and
369  * we can subtract the old address' words and add the new address' words.
370  * Or, as a result of the one's complement, the opposite.  There is some
371  * inclusion of the top half of a 32-bit sum, but that is also neutral.
372  */
373 void masquerade_address (struct in6_addr *var,
374                         const struct in6_addr *new,
375                         uint16_t *csum_field) {
376         int32_t csum = ntohs (~*csum_field);
377         uint8_t i;
378         for (i=0; i<8; i++) {
379                 csum -= ntohs (var->s6_addr16 [i]);
380                 var->s6_addr16 [i] = new->s6_addr16 [i];
381                 csum += ntohs (var->s6_addr16 [i]);
382         }
383         csum = (csum & 0xffff) + (csum >> 16);
384         csum = (csum & 0xffff) + (csum >> 16);
385         *csum_field = htons (~csum);
386 }
387
388
389 /* Send an ICMPv6 reply.  This is constructed at the tunnel end, from
390  * the incoming message.  The parameter indicates how many bytes the
391  * ICMPv6 package counts after the ICMPv6 header.  It must be 4 (mod 8).
392  *
393  * Actions: v4/udp src becomes dest, set v4/udp/v6 src, len, cksum, send.
394  *          reply is always to v4src6, except that if it starts with
395  *          0x00,0x00 it will be replaced with allnodes_linklocal_address.
396  */
397 void icmp6_reply (size_t icmp6bodylen) {
398         v4v6hoplimit = 255;
399         if ((icmp6bodylen & 0x07) != 4) {
400                 return;   /* illegal length, drop */
401         }
402         v4v6plen = htons (icmp6bodylen + 4);
403         memcpy (v4dst6,
404                 (v4src6->s6_addr16 [0])
405                         ? (uint8_t *) v4src6
406                         : allnodes_linklocal_address,
407                 16);
408         memcpy (v4src6, router_linklocal_address, 16);
409         v4v6icmpcksum = icmp6_checksum (v4src6, v4dst6,
410                                 v4v6payload, ntohs (v4v6plen));
411         //
412         // Send the message to the IPv4 originator port
413 printf ("Sending ICMPv6-IPv6-UDP-IPv4 to %d.%d.%d.%d:%d, result = %zd\n",
414 ((uint8_t *) &v4name.sin_addr.s_addr) [0],
415 ((uint8_t *) &v4name.sin_addr.s_addr) [1],
416 ((uint8_t *) &v4name.sin_addr.s_addr) [2],
417 ((uint8_t *) &v4name.sin_addr.s_addr) [3],
418 ntohs (v4name.sin_port),
419         sendto (v4sox,
420                         v4data,
421                         sizeof (struct ip6_hdr) + 4 + icmp6bodylen,
422                         MSG_DONTWAIT,
423                         (struct sockaddr *) &v4name, sizeof (v4name)));
424 }
425
426
427 /* Append the current prefix to an ICMPv6 message.  Incoming optidx
428  * and return values signify original and new offset for ICMPv6 options.
429  * The endlife parameter must be set to obtain zero lifetimes, thus
430  * instructing the tunnel client to stop using an invalid prefix.
431  */
432 size_t icmp6_prefix_local (size_t optidx, uint8_t endlife) {
433         v4v6icmpdata [optidx++] = 3;    // Type
434         v4v6icmpdata [optidx++] = 4;    // Length
435         v4v6icmpdata [optidx++] = 114;  // This is a /114 prefix
436         v4v6icmpdata [optidx++] = 0xc0; // L=1, A=1, Reserved1=0
437         memset (v4v6icmpdata + optidx, endlife? 0x00: 0xff, 8);
438         optidx += 8;
439                                         // Valid Lifetime: Zero / Infinite
440                                         // Preferred Lifetime: Zero / Infinite
441         memset (v4v6icmpdata + optidx, 0, 4);
442         optidx += 4;
443                                         // Reserved2=0
444         addr_6bed4 ((struct in6_addr *) (v4v6icmpdata + optidx), 0);
445                                         // Set IPv6 prefix
446         optidx += 16;
447         return optidx;
448 }
449
450
451 /* Append an extra routed prefix to an ICMPv6 message.  Incoming optidx
452  * and return values signify original and new offset for ICMPv6 options.
453  * The endlife parameter must be set to obtain zero lifetimes, thus
454  * instructing the tunnel client to stop using an invalid prefix.
455  */
456 size_t icmp6_prefix_routed (size_t optidx, uint8_t endlife, struct in6_addr *prefix, uint8_t prefix_len) {
457         v4v6icmpdata [optidx++] = 3;    // Type
458         v4v6icmpdata [optidx++] = 4;    // Length
459         v4v6icmpdata [optidx++] = prefix_len;
460                                         // Prefix Length
461         v4v6icmpdata [optidx++] = 0x00; // L=0, A=0, Reserved1=0
462         memset (v4v6icmpdata + optidx, endlife? 0x00: 0xff, 8);
463         optidx += 8;
464                                         // Valid Lifetime: Zero / Infinite
465                                         // Preferred Lifetime: Zero / Infinite
466         memset (v4v6icmpdata + optidx, 0, 4);
467         optidx += 4;
468                                         // Reserved2=0
469         memcpy (v4v6icmpdata + optidx, prefix, 16);
470                                         // Set IPv6 prefix
471         optidx += 16;
472         return optidx;
473 }
474
475
476 /*
477  * TODO: DEPRECATED
478  *
479  * Append a Destination Link-Layer Address Option to an ICMPv6
480  * message.  The address is comprised from the remote's UDP port
481  * and IPv4 address, as seen by the router.  They are supplied
482  * in that order, in network byte order.  The resulting address
483  * is 6 bytes, but even though that makes it look like a MAC
484  * address, it really is another beast.
485  * Note that no effort is made in the router to recognise the
486  * "illegal port number" 0x3333 -- the client needs a message
487  * and will recognise it and act on it.
488  */
489 size_t icmp6_dest_linkaddr (size_t optidx) {
490         uint8_t typelen [2] = { ND_OPT_DESTINATION_LINKADDR, 1 };
491         memcpy (v4v6icmpdata + optidx + 0, &typelen, 2);
492         v4v6icmpdata [optidx + 2] = ntohs (v4name.sin_port) & 0xff;
493         v4v6icmpdata [optidx + 3] = ntohs (v4name.sin_port) >> 8;
494         memcpy (v4v6icmpdata + optidx + 4, &v4name.sin_addr, 4);
495         optidx += 8;
496         return optidx;
497 }
498
499
500 /*
501  * Test if an address is a local override.  This function is compiled-in
502  * to support hosts with a /64 from their own ISP and nothing more; they
503  * need to access local IPv6 addresses.  We rely on the 6bed4 port being
504  * 0 to decide that an address cannot be anything but a local override.
505  * Define LOCAL_OVERRIDES_PORT0 to enable this feature.
506  */
507 #ifdef LOCAL_OVERRIDES_PORT0
508 static inline bool is_local_override (struct in6_addr *ip6) {
509         return (ip6->s6_addr16 [6] == 0) && (memcmp (ip6->s6_addr, &v6listen, 8) == 0);
510 }
511 #else
512 #define is_local_override(_) false
513 #endif
514
515
516 /*
517  * Test if the provided IPv6 address matches the prefix used for 6bed4.
518  *TODO: This is oversimplistic, it only cares for the Hetzner /64
519  */
520 static inline bool is_6bed4 (struct in6_addr *ip6) {
521         return memcmp (&v6listen, ip6->s6_addr, 8) == 0;
522 }
523
524 /* Test if the provided IPv6 address matches the fc64::/16 prefix.
525  * If so, the traffic may be bounced using 6bed4 traffic, but it
526  * must not be relayed to the native IPv6 side.
527  * TODO: Perhaps allow only configured <netid>, so fc64:<netid>::/32
528  */
529 static inline bool is_fc64 (struct in6_addr *ip6) {
530         return ip6->s6_addr16 [0] == htons (0xfc64);
531 }
532
533 /* Test if the src and destination share the same /114 and the destination
534  * fills up the rest with zero bits; in other words, test that this is a
535  * package targeted from a 6bed4peer node to its 6bed4router.  This is used
536  * to distinguish special ICMPv6 messages, as well as masquerading targets.
537  */
538 static inline bool is_mine (struct in6_addr *src6, struct in6_addr *dst6) {
539         return ((dst6->s6_addr [15] == 0x00)
540                 && ((dst6->s6_addr [14] & 0x3f) == 0x00)
541                 && (memcmp (dst6->s6_addr, src6->s6_addr, 14) == 0));
542 }
543
544
545 /*
546  * Validate the originator's IPv6 address.  It should match the
547  * UDP/IPv4 coordinates of the receiving 6bed4 socket.  Also,
548  * the /64 prefix (but not the /114 prefix!) must match v6listen.
549  */
550 bool validate_originator (struct in6_addr *ip6) {
551         uint32_t addr;
552         //
553         // Require non-local top halves to match our v6listen_linklocal address
554         // We will enforce our own fallback address (and fc64:<netid>::/32)
555         if (memcmp (ip6, v6listen_linklocal, 8) != 0) {
556                 if (memcmp (&v6listen, ip6->s6_addr, 8) != 0) {
557                         return false;
558                 }
559         }
560         //
561         // Require the sender port to appear in its IPv6 address
562         if (v4name.sin_port != ip6->s6_addr16 [6]) {
563                 return false;
564         }
565         //
566         // Require the sender address to appear in its IPv6 address
567         addr = ntohl (ip6->s6_addr32 [2]) & 0xfcffffff;
568         addr |= ((uint32_t) (ip6->s6_addr [14] & 0xc0)) << (24-6);
569         if (addr != ntohl (v4name.sin_addr.s_addr)) {
570                 return false;
571         }
572         //
573         // We passed with flying colours
574         return true;
575 }
576
577
578
579 /*
580  * Major packet processing functions
581  */
582
583
584 /*
585  * Respond to a Router Solicitation received over the 6bed4 Network.
586  */
587 void handle_6bed4_router_solicit (void) {
588         struct in6_addr observed;
589         v4v6icmptype = ND_ROUTER_ADVERT;
590         v4v6icmpdata [0] = 0;                   // Cur Hop Limit: unspec
591         v4v6icmpdata [1] = 0x18;                // M=0, O=0
592                                                 // H=0, Prf=11=Low
593                                                 // Reserved=0
594 // TODO: wire says 0x44 for router_adv.flags
595         size_t writepos = 2;
596         memset (v4v6icmpdata+writepos, 0xff, 2+4+4);
597                                         // Router Lifetime: max, 18.2h
598                                         // Reachable Time: max
599                                         // Retrans Timer: max
600         writepos += 2+4+4;
601         writepos = icmp6_prefix_local (writepos, 0);
602         for (int i = 0; i < v6routable_prefixcount ; i++) {
603                 writepos = icmp6_prefix_routed (writepos, 0,
604                                 &v6routable_prefix    [i],
605                                  v6routable_prefixlen [i]);
606         }
607         icmp6_reply (writepos);
608 }
609
610
611 /* Handle the IPv4 message pointed at by msg as a neighbouring command.
612  *
613  * Type Code    ICMPv6 meaning                  Handling
614  * ---- ----    -----------------------------   ----------------------------
615  * 133  0       Router Solicitation             Send Router Advertisement
616  * 134  0       Router Advertisement            Ignore
617  * 135  0       Neighbour Solicitation          Send Neighbour Advertisement
618  * 136  0       Neighbour Advertisement         Ignore
619  * 137  0       Redirect                        Ignore
620  */
621 void handle_4to6_nd (ssize_t v4ngbcmdlen) {
622         uint16_t srclinklayer;
623         if (v4ngbcmdlen < sizeof (struct ip6_hdr) + sizeof (struct icmp6_hdr)) {
624                 return;
625         }
626         if (v4v6icmpcode != 0) {
627                 return;
628         }
629         if (icmp6_checksum (v4src6, v4dst6,
630                                 v4v6payload, v4ngbcmdlen-sizeof (struct ip6_hdr)
631                         ) != v4v6icmpcksum) {
632                 return;
633         }
634         //
635         // Approved.  Perform neighbourly courtesy.
636         switch (v4v6icmptype) {
637         case ND_ROUTER_SOLICIT:
638                 //
639                 // Validate Router Solicitation
640                 srclinklayer = 0;
641                 if (v4ngbcmdlen == sizeof (struct ip6_hdr) + 8 + 8) {
642                         // One option is possible, the source link-layer address
643                         if (v4v6icmpdata [4] != 1 || v4v6icmpdata [5] != 1) {
644                                 break;   /* bad opton, ignore */
645                         }
646                         // The source link-layer address is end-aligned
647                         srclinklayer = (v4v6icmpdata [10] << 8) | v4v6icmpdata [11];
648                         if (srclinklayer == 0) {
649                                 break;   /* illegal, ignore */
650                         }
651                 } else if (v4ngbcmdlen == sizeof (struct ip6_hdr) + 8) {
652                         srclinklayer = 0;   /* set for latter filling */
653                 } else {
654                         break;   /* illegal length, drop */
655                 }
656                 //
657                 // Having accepted the Router Advertisement, respond
658                 handle_6bed4_router_solicit ();
659                 break;
660         case ND_NEIGHBOR_SOLICIT:
661                 //
662                 // Validate Neigbour Solicitation
663                 if (!validate_originator (v4src6)) {
664                         break;  /* bad source address, drop */
665                 }
666                 if ((v4ngbcmdlen != sizeof (struct ip6_hdr) + 24) &&
667                     (v4ngbcmdlen != sizeof (struct ip6_hdr) + 24 + 8)) {
668                         break;   /* funny length, drop */
669                 }
670                 if ((memcmp (v4ngbsoltarget, v6listen_linklocal, 16) != 0) &&
671                     (memcmp (v4ngbsoltarget, v6listen_linklocal_complete, 16) != 0) &&
672                     (memcmp (v4ngbsoltarget, &v6listen_complete, 16) != 0)) {
673                         break;  /* target not known here, drop */
674                 }
675                 //
676                 // Construct Neigbour Advertisement
677                 v4v6icmptype = ND_NEIGHBOR_ADVERT;
678                 v4v6icmpdata [0] = 0xc0;
679                 v4v6icmpdata [1] =
680                 v4v6icmpdata [2] =
681                 v4v6icmpdata [3] = 0x00;        // R=1, S=1, O=1, Reserved=0
682                 memcpy (v4v6icmpdata +  4, &v6listen_complete, 16);
683                 // Append option: the target link-layer address
684                 // Note: wire does not include target link-layer address
685                 v4v6icmpdata [20] = 2;          // Type: Target Link-Layer Addr
686                 v4v6icmpdata [21] = 1;          // Length: 1x 8 bytes
687                 memcpy (v4v6icmpdata + 22, lladdr_6bed4, 6);
688                 icmp6_reply (28);       // 28 is the ICMPv6 response length
689                 break;
690         case ND_ROUTER_ADVERT:
691         case ND_NEIGHBOR_ADVERT:
692         case ND_REDIRECT:
693                 break;   /* drop */
694         }
695 }
696
697
698 /*
699  * Forward a message to the masquerading target, or drop it.  This is done
700  * with non-6bed4 packets that are sent from a 6bed4peer node to its
701  * 6bed4router address; see is_mine() for the definition.  The general idea
702  * is that the address that is to be masqueraded can later be reconstructed
703  * from the 6bed4peer's address.
704  */
705 void handle_4to6_masquerading (ssize_t v4datalen) {
706         fprintf (stderr, "Traffic to 6bed4router may be fit for masquerading\n");
707         uint16_t *portpairs = NULL;
708         uint16_t numpairs = 0;
709         uint16_t port = 0;
710         uint16_t *csum_field = NULL;
711         uint16_t sctp_offset = 0;
712         uint16_t skip_csum;
713         switch (v4v6nexthdr) {
714         case IPPROTO_SCTP:
715                 portpairs = masqportpairs [0];  // 's'
716                 numpairs  = num_masqportpairs [0];
717                 port = ntohs (v4v6sctpdstport);
718                 csum_field = &skip_csum;
719                 sctp_offset = v4v6sctpofs;
720                 break;
721         case IPPROTO_TCP:
722                 portpairs = masqportpairs [1];  // 't'
723                 numpairs  = num_masqportpairs [1];
724                 port = ntohs (v4v6tcpdstport);
725                 csum_field = &v4v6tcpcksum;
726                 break;
727         case IPPROTO_UDP:
728                 portpairs = masqportpairs [2];  // 'u'
729                 numpairs  = num_masqportpairs [2];
730                 port = ntohs (v4v6udpdstport);
731                 csum_field = &v4v6udpcksum;
732                 if ((port == 9899) && (v4v6udpsrcport == v4v6udpdstport)) {
733                         // SCTP tunneled over UDP (keep csum_field)
734                         portpairs = masqportpairs [0];
735                         numpairs = num_masqportpairs [0];
736                         port = ntohs (v4v6tunsctpdstport);
737                         sctp_offset = v4v6tunsctpofs;
738                 }
739                 break;
740         case IPPROTO_ICMPV6:
741                 portpairs = icmp_portpairs;
742                 numpairs = icmp_num_portpairs;
743                 port = icmp_portpairs [0];
744                 csum_field = &v4v6icmpcksum;
745                 break;
746         default:
747                 return;
748         }
749         fprintf (stderr, "DEBUG: Looking for masquerading of port %d in %d entries\n", port, numpairs);
750         while (numpairs-- > 0) {
751                 if ((port >= portpairs [0]) && (port <= portpairs [1])) {
752                         //
753                         // Replace masqueraded address by 6bed4router's
754                         fprintf (stderr, "DEBUG: Passing traffic to masquerading address number %d\n", portpairs [2]);
755                         masquerade_address (v4dst6,
756                                 (struct in6_addr *) masqhost [portpairs [2]],
757                                 csum_field);
758                         if (sctp_offset > 0) {
759                                 //TODO// Recompute SCTP's CRC-32 checksum
760                                 // recompute_sctp_checksum (ip6hdr, sctp_offset, framelen);
761                                 //BUT: SCTP checksum does not use pseudo IPhdr
762                                 //SO:  Address masquerading goes undetected :-D
763                         }
764                         //
765                         // Forward immediately, and return from this function
766 printf ("Writing Masqueraded IPv6, result = %zd\n",
767                         write (v6sox, &v4data6, sizeof (struct tun_pi) + v4datalen));
768                         return;
769                 }
770                 portpairs += 3;
771         }
772         //
773         // Silently skip the offered packet
774 }
775
776
777 /* 
778  * Forward a message received over the 6bed4 Network over IPv6.
779  * Note that existing checksums will work well, as only the
780  * Hop Limit has been altered, and this is not part of the
781  * checksum calculations.
782  */
783 void handle_4to6_plain_unicast (ssize_t v4datalen) {
784 printf ("Writing IPv6, result = %zd\n",
785         write (v6sox, &v4data6, sizeof (struct tun_pi) + v4datalen));
786 }
787
788
789 /*
790  * Forward a 6bed4 message to another 6bed4 destination address.
791  * Local address prefixes fc64:<netid>:<ipv4>::/64 are also relayed.
792  * Note that existing checksums will work well, as only the
793  * Hop Limit has been altered, and this is not part of the
794  * checksum calculations.
795  */
796 void relay_4to4_plain_unicast (uint8_t* data, ssize_t v4datalen, struct in6_addr *ip6) {
797         v4name.sin_port = htons (ip6->s6_addr [12] << 8 | ip6->s6_addr [13]);
798         uint8_t *addr = (uint8_t *) &v4name.sin_addr.s_addr;
799         addr [0] = (ip6->s6_addr [8] & 0xfc) | ip6->s6_addr [14] >> 6;
800         memcpy (addr + 1, ip6->s6_addr + 9, 3);
801 printf ("Relaying over 6bed4 Network to %d.%d.%d.%d:%d, result = %zd\n",
802 ((uint8_t *) &v4name.sin_addr.s_addr) [0],
803 ((uint8_t *) &v4name.sin_addr.s_addr) [1],
804 ((uint8_t *) &v4name.sin_addr.s_addr) [2],
805 ((uint8_t *) &v4name.sin_addr.s_addr) [3],
806 ntohs (v4name.sin_port),
807         sendto (v4sox,
808                         data, v4datalen,
809                         MSG_DONTWAIT,
810                         (struct sockaddr *) &v4name, sizeof (v4name)));
811 }
812
813
814 /* Receive a tunnel package, and route it to either the handler for the
815  * tunnel protocol, or to the handler that checks and then unpacks the
816  * contained IPv6.
817  */
818 void handle_4to6 (void) {
819         uint8_t buf [1501];
820         ssize_t buflen;
821         socklen_t adrlen = sizeof (v4name);
822         //
823         // Receive IPv4 package, which may be tunneled or a tunnel request
824         buflen = recvfrom (v4sox,
825                         v4data, MTU,
826                         MSG_DONTWAIT,
827                         (struct sockaddr *) &v4name, &adrlen
828                 );
829         if (buflen == -1) {
830                 printf ("%s: Error receiving IPv4-side package: %s",
831                                 program, strerror (errno));
832                 return;
833         }
834         if (buflen < sizeof (struct ip6_hdr)) {
835                 return;
836         }
837         if ((v4data [0] & 0xf0) != 0x60) {
838                 // Not an IPv6 packet
839                 return;
840         }
841         //
842         // Handle the tunneled IPv6 package (dependent on its class)
843         if ((v4v6nexthdr == IPPROTO_ICMPV6) &&
844                         (v4v6icmptype >= 133) && (v4v6icmptype <= 137)) {
845                 //
846                 // Not Plain: Router Adv/Sol, Neighbor Adv/Sol, Redirect
847                 if (v4v6hoplimit != 255) {
848                         return;
849                 }
850                 handle_4to6_nd (buflen);
851         } else if (is_mine (v4src6, v4dst6)) {
852                 handle_4to6_masquerading (buflen);
853         } else if ((v4dst6->s6_addr [0] != 0xff) && !(v4dst6->s6_addr [8] & 0x01)) {
854                 //
855                 // Plain Unicast
856                 if (is_local_override (v4dst6)) {
857                         // Accept 6bed4 clients, but not forged IPv6 senders
858                         if (!validate_originator (v4src6)) {
859                                 return;
860                         }
861                         handle_4to6_plain_unicast (buflen);
862                 } else if (validate_originator (v4src6)) {
863                         if (v4v6hoplimit-- <= 1) {
864                                 return;
865                         }
866                         if (is_6bed4 (v4dst6) || is_fc64 (v4dst6)) {
867                                 relay_4to4_plain_unicast (v4data, buflen, v4dst6);
868                         } else {
869                                 handle_4to6_plain_unicast (buflen);
870                         }
871                 } else if (is_6bed4 (v4src6)) {
872                         // The sender must not have kept NAT/firewall holes
873                         // open and should be instructed about a change in
874                         // its 6bed4 Link-Local Address.
875                         handle_6bed4_router_solicit ();
876                 }
877         } else {
878                 //
879                 // Plain Multicast
880                 //OPTIONAL// validate_originator, hoplimit, relay_mcast.
881                 return;
882         }
883 }
884
885
886 /* Receive an IPv6 package, check its address and pickup IPv4 address and
887  * port, then package it as a tunnel message and forward it to IPv4:port.
888  */
889 void handle_6to4 (void) {
890         uint16_t mqh;
891         //
892         // Receive the IPv6 package and ensure a consistent size
893         size_t rawlen = read (v6sox, &v6data6, sizeof (v6data6));
894         if (rawlen == -1) {
895                 return;         /* error reading, drop */
896         }
897         if (rawlen < sizeof (struct tun_pi) + sizeof (struct ip6_hdr) + 1) {
898                 return;         /* too small, drop */
899         }
900         if (v6tuncmd.proto != htons (ETH_P_IPV6)) {
901                 return;         /* no IPv6, drop */
902         }
903         if ((v6nexthdr == IPPROTO_ICMPV6) &&
904                         (v6icmptype >= 133) && (v6icmptype <= 137)) {
905                 return;         /* not plain IPv6, drop */
906         }
907         if (v6hoplimit-- <= 1) {
908                 // TODO: Send back an ICMPv6 error message
909                 return;         /* hop limit exceeded, drop */
910         }
911         if ((v6dst6->s6_addr [0] == 0xff) /* TODO:UDP_PORT_NOT_YET_FORCED_TO_EVEN || (v6dst6->s6_addr [8] & 0x01) */ ) {
912 printf ("Received multicast IPv6 data, flags=0x%04x, proto=0x%04x\n", v6tuncmd.flags, v6tuncmd.proto);
913                 //OPTIONAL// handle_6to4_plain_multicast ()
914                 return;         /* multicast, drop */
915         }
916 printf ("Received plain unicast IPv6 data, flags=0x%04x, proto=0x%04x\n", v6tuncmd.flags, v6tuncmd.proto);
917         //
918         // Replace masqueraded addresses configured with -m and its default ::1
919         //TODO// Better use the port number to find the find the masqhost
920         for (mqh=0; mqh<num_masqhost; mqh++) {
921                 if (memcmp (v6src6, masqhost [mqh], 16) == 0) {
922 printf ("Masqueraded sender address in 6to4 set to the client's 6bed4router address\n");
923                         uint16_t *csum_field = NULL;
924                         uint16_t fake_csum;
925                         struct in6_addr masq_src;
926                         uint16_t sctp_offset = 0;
927                         switch (v6nexthdr) {
928                         case IPPROTO_SCTP:
929                                 csum_field = &fake_csum;
930                                 sctp_offset = v6sctpofs;
931                                 break;
932                         case IPPROTO_TCP:
933                                 csum_field = &v6tcpcksum;
934                                 break;
935                         case IPPROTO_UDP:
936                                 csum_field = &v6udpcksum;
937                                 if ((v6udpsrcport == v6udpdstport) &&
938                                                 (v6udpsrcport == htons (9899))) {
939                                         // SCTP tunneled over UDP
940                                         sctp_offset = v6tunsctpofs;
941                                 }
942                                 break;
943                         case IPPROTO_ICMPV6:
944                                 csum_field = &v6icmpcksum;
945                                 break;
946                         default:
947                                 continue;
948                         }
949                         //
950                         // Construct v6src6 from v6dst6, ending in 14 zero bits
951                         memcpy (&masq_src, v6dst6, 16);
952                         masq_src.s6_addr16 [7] &= htons (0xc000);
953                         fprintf (stderr, "Masquerading cksum.old = 0x%04x, ", ntohs (*csum_field));
954                         masquerade_address (v6src6, &masq_src, csum_field);
955                         if (sctp_offset > 0) {
956                                 //TODO// Recompute SCTP's CRC-32 checksum
957                                 // recompute_sctp_checksum (ip6hdr, sctp_offset, framelen);
958                                 //BUT: SCTP checksum does not use pseudo IPhdr
959                                 //SO:  Address masquerading goes undetected :-D
960                         }
961                         fprintf (stderr, "cksum.new = 0x%04x\n", ntohs (*csum_field));
962                         break;
963                 }
964         }
965         //
966         // Ensure that the incoming IPv6 address is properly formatted
967         // Note that this avoids access to ::1/128, fe80::/10, fec0::/10
968 #ifndef TODO_PERMIT_BOUNCE_FOR_32BIT_PREFIX
969         if (memcmp (v6dst6, &v6listen, 8) != 0) {
970                 return;
971         }
972 #else
973         if (v6dst6->s6_addr32 [0] != v6listen.s6_addr32 [0]) {
974                 // Mismatch /32 so this is not going to fly (anywhere)
975                 return;
976         } else if (v6dst6->s6_addr32 [1] != v6listen.s6_addr32 [1]) {
977                 // Match /32 but mismatch /64 -- relay to proper fallback
978                 // that fc64::/16 is not welcome in 6to4 processing
979                 //TODO//OVER_6bed4// relay_6to6_plain_unicast (v6data, rawlen - sizeof (struct tun_pi), v6dst6);
980         }
981 #endif
982         //
983         // Harvest socket address data from destination IPv6, then send
984         relay_4to4_plain_unicast (v6data, rawlen - sizeof (struct tun_pi), v6dst6);
985 }
986
987
988 /* Run the daemon core code, passing information between IPv4 and IPv6 and
989  * responding to tunnel requests if so requested.
990  */
991 void run_daemon (void) {
992         fd_set io;
993         FD_ZERO (&io);
994         FD_SET (v4sox, &io);
995         FD_SET (v6sox, &io);
996         int nfds = (v4sox < v6sox)? (v6sox + 1): (v4sox + 1);
997         while (1) {
998                 select (nfds, &io, NULL, NULL, NULL);
999                 if (FD_ISSET (v4sox, &io)) {
1000                         handle_4to6 ();
1001                 } else {
1002                         FD_SET (v4sox, &io);
1003                 }
1004                 if (FD_ISSET (v6sox, &io)) {
1005                         handle_6to4 ();
1006                 } else {
1007                         FD_SET (v6sox, &io);
1008                 }
1009 fflush (stdout);
1010         }
1011 }
1012
1013
1014 /* Option descriptive data structures */
1015
1016 char *short_opt = "l:L:R:d:hit:u:s:m:x:";
1017
1018 struct option long_opt [] = {
1019         { "v4listen", 1, NULL, 'l' },
1020         { "v6prefix", 1, NULL, 'L' },
1021         { "v6route", 1, NULL, 'R' },
1022         { "tundev", 1, NULL, 'd' },
1023         { "help", 0, NULL, 'h' },
1024         { "icmp", 0, NULL, 'i' },
1025         { "tcp", 1, NULL, 't' },
1026         { "udp", 1, NULL, 'u' },
1027         { "sctp", 1, NULL, 's' },
1028         { "masqhost", 1, NULL, 'm' },
1029         { "xlate", 1, NULL, 'x' },
1030         // { "fallback4", 1 NULL, 'f' },
1031         // { "fallback6", 1, NULL, 'F' },
1032         { NULL, 0, NULL, 0 }    /* Array termination */
1033 };
1034
1035 /* Parse commandline arguments (and start to process them).
1036  * Return 1 on success, 0 on failure.
1037  */
1038 int process_args (int argc, char *argv []) {
1039         int ok = 1;
1040         int help = (argc == 1);
1041         int done = 0;
1042         int opt;
1043         while (!done) {
1044                 switch (opt = getopt_long (argc, argv, short_opt, long_opt, NULL)) {
1045                 case -1:
1046                         done = 1;
1047                         if (optind != argc) {
1048                                 fprintf (stderr, "%s: Extra arguments not permitted: %s...\n", program, argv [optind]);
1049                                 ok = 0;
1050                         }
1051                         break;
1052                 case 'l':
1053                         if (v4name.sin_family != 0) {
1054                                 ok = 0;
1055                                 fprintf (stderr, "%s: Only one -l argument is permitted\n", program);
1056                                 break;
1057                         }
1058                         v4name.sin_family = AF_INET;
1059                         v4server = optarg;
1060                         if (inet_pton (AF_INET, optarg, &v4name.sin_addr) <= 0) {
1061                                 ok = 0;
1062                                 fprintf (stderr, "%s: Failed to parse IPv4 address %s\n", program, optarg);
1063                                 break;
1064                         }
1065                         memcpy (&v4listen, &v4name.sin_addr, 4);
1066                         break;
1067                 case 'x':
1068                         if (v4name_xlate.sin_family != 0) {
1069                                 ok = 0;
1070                                 fprintf (stderr, "%s: At most one -x argument is permitted\n", program);
1071                                 break;
1072                         }
1073                         v4name_xlate.sin_family = AF_INET;
1074                         ((uint8_t *) &v4name_xlate.sin_addr.s_addr) [0] = 127;
1075                         ((uint8_t *) &v4name_xlate.sin_addr.s_addr) [1] = 0;
1076                         ((uint8_t *) &v4name_xlate.sin_addr.s_addr) [2] = 0;
1077                         ((uint8_t *) &v4name_xlate.sin_addr.s_addr) [3] = 1;
1078                         int port = atoi (optarg);
1079                         if ((port <= 0) || (port > 65535)) {
1080                                 ok = 0;
1081                                 fprintf (stderr, "%s: Port number for -x out of range\n", program);
1082                                 break;
1083                         }
1084                         v4name_xlate.sin_port = htons (port);
1085                         break;
1086                 case 'L':
1087                         if (v6server) {
1088                                 ok = 0;
1089                                 fprintf (stderr, "%s: Only one -L argument is permitted\n", program);
1090                                 break;
1091                         }
1092                         char *slash64 = strchr (optarg, '/');
1093                         if (!slash64 || strcmp (slash64, "/64") != 0) {
1094                                 ok = 0;
1095                                 fprintf (stderr, "%s: The -L argument must be an explicit /64 prefix and not %s\n", program, slash64? slash64: "implied");
1096                                 break;
1097                         }
1098                         *slash64 = '\0';
1099                         v6server = strdup (optarg);
1100                         *slash64 = '/';
1101                         v6prefix = optarg;
1102                         if (!v6server || (inet_pton (AF_INET6, v6server, &v6listen) <= 0)) {
1103                                 ok = 0;
1104                                 fprintf (stderr, "%s: Failed to parse IPv6 prefix %s\n", program, optarg);
1105                                 break;
1106                         }
1107                         if (v6listen.s6_addr32 [2] || v6listen.s6_addr32 [3]) {
1108                                 ok = 0;
1109                                 fprintf (stderr, "%s: IPv6 prefix contains bits beyond its /64 prefix: %s\n", program, optarg);
1110                                 break;
1111                         }
1112                         break;
1113                 case 'R':
1114                         if (v6routable_prefixcount >= MAX_ROUTABLE_PREFIXES) {
1115                                 ok = 0;
1116                                 fprintf (stderr, "%s: You cannot provide more than %d prefixes\n", program, MAX_ROUTABLE_PREFIXES);
1117                                 break;
1118                         }
1119                         char *prefix = strdup (optarg);
1120                         char *prefixslash = strchr (prefix, '/');
1121                         int prefixlen = atoi (prefixslash + 1);
1122                         *prefixslash = '\0';
1123                         if ((prefixlen < 16) || (prefixlen > 128)) {
1124                                 ok = 0;
1125                                 fprintf (stderr, "%s: IPv6 route prefix %s must be /16 up to /128\n", program, prefixslash + 1);
1126                         } else if (inet_pton (AF_INET6, prefix, &v6routable_prefix [v6routable_prefixcount]) <= 0) {
1127                                 ok = 0;
1128                                 fprintf (stderr, "%s: Failed to parse IPv6 route %s", program, optarg);
1129                         } else {
1130                                 v6routable_prefixlen [v6routable_prefixcount++] = prefixlen;
1131                         }
1132                         free (prefix);
1133                         break;
1134                 case 'd':
1135                         if (v6sox != -1) {
1136                                 ok = 0;
1137                                 fprintf (stderr, "%s: Multiple -d arguments are not permitted\n", program);
1138                                 break;
1139                         }
1140                         v6sox = open (optarg, O_RDWR);
1141                         if (v6sox == -1) {
1142                                 ok = 0;
1143                                 fprintf (stderr, "%s: Failed to open tunnel device %s: %s\n", program, optarg, strerror (errno));
1144                                 break;
1145                         }
1146                         break;
1147                 case 's':
1148                 case 't':
1149                 case 'u':
1150                 case 'i':
1151                         // Masqueraded port (range) for SCTP, TCP, UDP
1152                         //TODO// Should we support ICMPv6 as well? [honeypots]
1153                         if (num_masqhost == 0) {
1154                                 //TODO// Reference v6listen instead of ::1
1155                                 inet_pton (AF_INET6, "::1", masqhost [0]);
1156                                 num_masqhost = 1;
1157                         }
1158                         // Temporary variables in local scope
1159                         if (opt == 'i') {
1160                                 if (icmp_num_portpairs > 0) {
1161                                         fprintf (stderr, "%s: Only one ICMP masquerading setting is possible\n", program);
1162                                         ok = 0;
1163                                         break;
1164                                 }
1165                                 icmp_portpairs [2] = num_masqhost - 1;
1166                                 icmp_num_portpairs++;
1167                         } else {
1168                                 unsigned long fromport, toport;
1169                                 uint16_t *portpairs;
1170                                 errno = 0;
1171                                 if (*optarg != ':') {
1172                                         fromport = strtoul (optarg, &optarg, 10);
1173                                 } else {
1174                                         fromport = 1;
1175                                 }
1176                                 if (*optarg != ':') {
1177                                         toport = fromport;
1178                                 } else if (*++optarg) {
1179                                         toport = strtoul (optarg, &optarg, 10);
1180                                 } else {
1181                                         toport = 65535;
1182                                 }
1183                                 if (errno || *optarg) {
1184                                         fprintf (stderr, "%s: Failed to parse port or port:port\n", program);
1185                                         ok = 0;
1186                                         break;
1187                                 }
1188                                 if ((fromport < 1) || (fromport > toport) || (toport > 65535)) {
1189                                         fprintf (stderr, "%s: Invalid port or port range\n", program);
1190                                         ok = 0;
1191                                         break;
1192                                 }
1193                                 if (++num_masqportpairs [opt-'s'] >= MAXNUM_PORTPAIRS) {
1194                                         fprintf (stderr, "%s: You cannot define so many ports / port pairs\n", program);
1195                                         ok = 0;
1196                                         break;
1197                                 }
1198                                 portpairs = &masqportpairs [opt-'s'][3*(num_masqportpairs [opt-'s']-1)];
1199                                 portpairs [0] = fromport;
1200                                 portpairs [1] = toport;
1201                                 portpairs [2] = num_masqhost-1;
1202                         }
1203                         break;
1204                 case 'm':
1205                         // Masqueraded host for TCP, UDP, SCTP (default is ::1)
1206                         if (++num_masqhost >= MAXNUM_MASQHOST) {
1207                                 fprintf (stderr, "%s: No more than %d masquering hosts can be specified\n", program, MAXNUM_MASQHOST);
1208                                 ok = 0;
1209                                 break;
1210                         }
1211                         if (inet_pton (AF_INET6, optarg, masqhost [num_masqhost]) != 1) {
1212                                 fprintf (stderr, "%s: Unsupported masquerading host \"%s\"\n", program, optarg);
1213                                 ok = 0;
1214                                 break;
1215                         }
1216                         num_masqhost++;
1217                         break;
1218                 // case 'f':
1219                 // case 'F':
1220                 //      // Fallback addresses for IPv4, IPv6
1221                 //      ok = 0; //TODO:IMPLEMENT//
1222                 //      help = 1;
1223                 //      break;
1224                 default:
1225                         ok = 0;
1226                         /* continue into 'h' to produce usage information */
1227                 case 'h':
1228                         help = 1;
1229                         break;
1230                 }
1231                 if (help || !ok) {
1232                         done = 1;
1233                 }
1234         }
1235         if (help) {
1236 #ifdef HAVE_SETUP_TUNNEL
1237                 fprintf (stderr, "Usage: %s [-d /dev/tunX] -l <v4server> [-x <port>] -L <v6prefix>/64 [-R <v6route>/n]...\n       %s -h\n", program, program);
1238                 fprintf (stderr, "\tUse -s|-t|-u to masquerade a port (range) to last -m host or ::1\n");
1239 #else
1240                 fprintf (stderr, "Usage: %s -d /dev/tunX -l <v4server> -L <v6prefix>/64\n       %s -h\n", program, program);
1241                 fprintf (stderr, "\tUse -s|-t|-u to masquerade a port (range) to last -m host of ::1\n");
1242 #endif
1243                 return ok;
1244         }
1245         if (v4name.sin_family == 0) {
1246                 fprintf (stderr, "%s: Use -l to specify an IPv4 address for the tunnel interface\n", program);
1247                 return 0;
1248         }
1249         if (v4name_xlate.sin_family == 0) {
1250                 memcpy (&v4name_xlate, &v4name, sizeof (v4name_xlate));
1251         } else {
1252                 v4server = "127.0.0.1";
1253         }
1254         v4sox = socket (AF_INET, SOCK_DGRAM, 0);
1255         if (v4sox == -1) {
1256                 fprintf (stderr, "%s: Failed to allocate UDPv4 socket: %s\n", program, strerror (errno));
1257                 return 0;
1258         }
1259         if (bind (v4sox, (struct sockaddr *) &v4name_xlate, sizeof (v4name_xlate)) != 0) {
1260                 fprintf (stderr, "%s: Failed to bind to UDPv4 %s:%d: %s\n", program, v4server, ntohs (v4name_xlate.sin_port), strerror (errno));
1261                 ok = 0;
1262         }
1263         if (!ok) {
1264                 return 0;
1265         }
1266 #ifdef HAVE_SETUP_TUNNEL
1267         if (v6sox == -1) {
1268                 if (geteuid () != 0) {
1269                         fprintf (stderr, "%s: You should be root, or use -d to specify an accessible tunnel device\n", program);
1270                         return 0;
1271                 }
1272                 ok = setup_tunnel ();
1273         }
1274         if (!v6server) {
1275                 fprintf (stderr, "%s: Use -L to specify a /64 prefix on the IPv6 side\n", program);
1276                 return 0;
1277         }
1278 #else /* ! HAVE_SETUP_TUNNEL */
1279         if (v6sox == -1) {
1280                 fprintf (stderr, "%s: You must specify a tunnel device with -d that is accessible to you\n", program);
1281                 return 0;
1282         }
1283 #endif /* HAVE_SETUP_TUNNEL */
1284         return ok;
1285 }
1286
1287
1288 /* The main program parses commandline arguments and forks off the daemon
1289  */
1290 int main (int argc, char *argv []) {
1291         //
1292         // Initialise
1293         program = argv [0];
1294         memset (&v6name      , 0, sizeof (v6name      ));
1295         memset (&v4name      , 0, sizeof (v4name      ));
1296         memset (&v4name_xlate, 0, sizeof (v4name_xlate));
1297         v6name.sin6_family = AF_INET6;
1298         v4name.sin_port = htons (UDP_PORT_6BED4);   /* 6BED4 standard port */
1299         v4tunpi6.flags = 0;
1300         v4tunpi6.proto = htons (ETH_P_IPV6);
1301         //
1302         // Parse commandline arguments
1303         if (!process_args (argc, argv)) {
1304                 exit (1);
1305         }
1306         //
1307         // Setup a few addresses for later comparison/reproduction
1308         //  * lladdr_6bed4 is the 6bed4 Link-Local Address
1309         //  * v6listen_complete is the router's full IPv6 address (with if-id)
1310         //  * v6listen_linklocal_complete is fe80::/64 plus the router's if-id
1311         // A few others have already been setup at this time
1312         //  * v6listen is the router's 6bed4 prefix ending in 64 zero bits
1313         //  * v6listen_linklocal is the address fe80::/128
1314         //
1315         lladdr_6bed4 [0] = UDP_PORT_6BED4 & 0xff;
1316         lladdr_6bed4 [1] = UDP_PORT_6BED4 >> 8;
1317         memcpy (lladdr_6bed4 + 2, (uint8_t *) &v4name.sin_addr, 4);
1318         addr_6bed4 (&v6listen_complete, 0);
1319
1320         memcpy (v6listen_linklocal_complete, v6listen_linklocal, 8);
1321         memcpy (v6listen_linklocal_complete + 8, &v6listen_complete.s6_addr [8], 8);
1322 printf ("LISTEN lladdr_6bed4 = %02x:%02x:%02x:%02x:%02x:%02x\n", lladdr_6bed4 [0], lladdr_6bed4 [1], lladdr_6bed4 [2], lladdr_6bed4 [3], lladdr_6bed4 [4], lladdr_6bed4 [5]);
1323 printf ("LISTEN v6listen = %x:%x:%x:%x:%x:%x:%x:%x\n", htons (v6listen.s6_addr16 [0]), htons (v6listen.s6_addr16 [1]), htons (v6listen.s6_addr16 [2]), htons (v6listen.s6_addr16 [3]), htons (v6listen.s6_addr16 [4]), htons (v6listen.s6_addr16 [5]), htons (v6listen.s6_addr16 [6]), htons (v6listen.s6_addr16 [7]));
1324 printf ("LISTEN v6listen_complete = %x:%x:%x:%x:%x:%x:%x:%x\n", htons (v6listen_complete.s6_addr16 [0]), htons (v6listen_complete.s6_addr16 [1]), htons (v6listen_complete.s6_addr16 [2]), htons (v6listen_complete.s6_addr16 [3]), htons (v6listen_complete.s6_addr16 [4]), htons (v6listen_complete.s6_addr16 [5]), htons (v6listen_complete.s6_addr16 [6]), htons (v6listen_complete.s6_addr16 [7]));
1325 printf ("LISTEN v6listen_linklocal = %x:%x:%x:%x:%x:%x:%x:%x\n", htons (((uint16_t *) v6listen_linklocal) [0]), htons (((uint16_t *) v6listen_linklocal) [1]), htons (((uint16_t *) v6listen_linklocal) [2]), htons (((uint16_t *) v6listen_linklocal) [3]), htons (((uint16_t *) v6listen_linklocal) [4]), htons (((uint16_t *) v6listen_linklocal) [5]), htons (((uint16_t *) v6listen_linklocal) [6]), htons (((uint16_t *) v6listen_linklocal) [7]));
1326 printf ("LISTEN v6listen_linklocal_complete = %x:%x:%x:%x:%x:%x:%x:%x\n", htons (((uint16_t *) v6listen_linklocal_complete) [0]), htons (((uint16_t *) v6listen_linklocal_complete) [1]), htons (((uint16_t *) v6listen_linklocal_complete) [2]), htons (((uint16_t *) v6listen_linklocal_complete) [3]), htons (((uint16_t *) v6listen_linklocal_complete) [4]), htons (((uint16_t *) v6listen_linklocal_complete) [5]), htons (((uint16_t *) v6listen_linklocal_complete) [6]), htons (((uint16_t *) v6listen_linklocal_complete) [7]));
1327         //
1328         // Start the main daemon process
1329 #ifdef SKIP_TESTING_KLUDGE_IN_FOREGROUND
1330         switch (fork ()) {
1331         case -1:                /* Error forking */
1332                 fprintf (stderr, "%s: Failed to fork: %s\n", program, strerror (errno));
1333                 exit (1);
1334         case 0:                 /* Child process */
1335                 close (0);
1336                 //TODO: tmp.support for ^printf// close (1);
1337                 close (2);
1338                 setsid ();
1339                 run_daemon ();
1340                 break;
1341         default:                /* Parent process */
1342                 close (v4sox);
1343                 close (v6sox);
1344                 break;
1345         }
1346 #else
1347         run_daemon ();
1348 #endif
1349         //
1350         // Report successful creation of the daemon
1351         return 0;
1352 }