struct my_sctphdr {
uint16_t source, dest;
uint32_t vtag;
- uint32_t checksum;
+ uint32_t cksum;
};
char *program;
struct {
struct ip6_hdr v6hdr;
union {
- struct icmp6_hdr v6icmphdr;
+ struct icmp6_hdr v6icmphdr;
struct my_sctphdr v6sctphdr;
- struct tcphdr v6tcphdr ;
- struct udphdr v6udphdr ;
+ struct tcphdr v6tcphdr ;
+ struct udphdr v6udphdr ;
} adata;
- struct icmp6_hdr v6icmphdr;
- struct my_sctphdr v6sctphdr;
- struct tcphdr v6tcphdr ;
- struct udphdr v6udphdr ;
} ndata;
} udata;
} v4data6;
#define v4src6 (&v4data6.udata.idata.v6hdr.ip6_src)
#define v4dst6 (&v4data6.udata.idata.v6hdr.ip6_dst)
+#define v4v6payload ((uint16_t *) &v4data6.udata.ndata.adata)
#define v4v6plen ( v4data6.udata.ndata.v6hdr.ip6_plen)
#define v4v6nexthdr ( v4data6.udata.ndata.v6hdr.ip6_nxt)
#define v4v6hoplimit ( v4data6.udata.ndata.v6hdr.ip6_hops)
-#define v4icmp6 (&v4data6.udata.ndata.adata.v6icmphdr)
#define v4v6icmpdata ( v4data6.udata.ndata.adata.v6icmphdr.icmp6_data8)
#define v4v6icmptype ( v4data6.udata.ndata.adata.v6icmphdr.icmp6_type)
#define v4v6icmpcode ( v4data6.udata.ndata.adata.v6icmphdr.icmp6_code)
#define v4v6sctpsrcport ( v4data6.udata.ndata.adata.v6sctphdr.source)
#define v4v6sctpdstport ( v4data6.udata.ndata.adata.v6sctphdr.dest)
+#define v4v6sctpcksum ( v4data6.udata.ndata.adata.v6sctphdr.cksum)
#define v4v6tcpsrcport ( v4data6.udata.ndata.adata.v6tcphdr.source)
#define v4v6tcpdstport ( v4data6.udata.ndata.adata.v6tcphdr.dest)
+#define v4v6tcpcksum ( v4data6.udata.ndata.adata.v6tcphdr.check)
#define v4v6udpsrcport ( v4data6.udata.ndata.adata.v6udphdr.source)
#define v4v6udpdstport ( v4data6.udata.ndata.adata.v6udphdr.dest)
+#define v4v6udpcksum ( v4data6.udata.ndata.adata.v6udphdr.check)
#define v4ngbsoltarget (&v4data6.udata.ndata.adata.v6icmphdr.icmp6_data8 [4])
struct tun_pi tun;
union {
uint8_t data [MTU];
- struct ip6_hdr v6hdr;
- struct icmp6_hdr v6icmp;
+ struct {
+ struct ip6_hdr v6hdr;
+ union {
+ struct icmp6_hdr v6icmphdr;
+ struct my_sctphdr v6sctphdr;
+ struct tcphdr v6tcphdr ;
+ struct udphdr v6udphdr ;
+ } adata;
+ } ndata;
} udata;
uint8_t zero;
} v6data6;
#define v6tuncmd ( v6data6.tun)
#define v6data ( v6data6.udata.data)
-#define v6hdr6 (&v6data6.udata.v6hdr)
-#define v6src6 (&v6data6.udata.v6hdr.ip6_src)
-#define v6dst6 (&v6data6.udata.v6hdr.ip6_dst)
-#define v6hoplimit ( v6data6.udata.v6hdr.ip6_hops)
+#define v6hdr6 (&v6data6.udata.ndata.v6hdr)
+#define v6src6 (&v6data6.udata.ndata.v6hdr.ip6_src)
+#define v6dst6 (&v6data6.udata.ndata.v6hdr.ip6_dst)
+#define v6hoplimit ( v6data6.udata.ndata.v6hdr.ip6_hops)
+#define v6nexthdr ( v6data6.udata.ndata.v6hdr.ip6_nxt)
-#define v6nexthdr ( v6data6.udata.v6hdr.ip6_nxt)
-#define v6icmptype ( v6data6.udata.v6icmp.icmp6_type)
+#define v6icmptype ( v6data6.udata.ndata.adata.v6icmphdr.icmp6_type)
+#define v6icmpcksum ( v6data6.udata.ndata.adata.v6icmphdr.icmp6_cksum)
+
+#define v6sctpcksum ( v6data6.udata.ndata.adata.v6sctphdr.cksum)
+
+#define v6tcpcksum ( v6data6.udata.ndata.adata.v6tcphdr.check)
+
+#define v6udpcksum ( v6data6.udata.ndata.adata.v6udphdr.check)
uint8_t router_linklocal_address [] = {
/* Calculate the ICMPv6 checksum field
*/
-uint16_t icmp6_checksum (size_t payloadlen) {
- uint16_t plenword = htons (payloadlen);
+uint16_t icmp6_checksum (struct in6_addr *src6, struct in6_addr *dst6,
+ uint16_t *payload, size_t payloadlen) {
+ uint16_t plenword = htons (payloadlen); // our ICMPv6 is small
uint16_t nxthword = htons (IPPROTO_ICMPV6);
- uint16_t *area [] = { (uint16_t *) v4src6, (uint16_t *) v4dst6, &plenword, &nxthword, (uint16_t *) v4icmp6, (uint16_t *) v4v6icmpdata };
- uint8_t areawords [] = { 8, 8, 1, 1, 1, payloadlen/2 - 2 };
+ uint16_t *area [] = { src6->s6_addr16, dst6->s6_addr16,
+ &plenword, &nxthword,
+ payload, &payload [2] };
+ uint8_t areawords [] = { 8, 8, 1, 1, 1, (payloadlen >> 1) - 2 };
uint32_t csum = 0;
u_int8_t i, j;
for (i=0; i < 6; i++) {
}
+/* Mangle a packet by replacing an IPv6 address, correcting the checksum.
+ * In all of ICMPv6, UDPv6, TCPv6, SCTPv6, the checksumming is a 1's cpl
+ * of a sum of 16-bit words; the position of the words don't matter and
+ * we can subtract the old address' words and add the new address' words.
+ * Or, as a result of the one's complement, the opposite. There is some
+ * inclusion of the top half of a 32-bit sum, but that is also neutral.
+ */
+void masquerade_address (struct in6_addr *var,
+ const struct in6_addr *new,
+ uint16_t *csum_field) {
+ int32_t csum = ntohs (~*csum_field);
+ uint8_t i;
+ for (i=0; i<8; i++) {
+ csum -= ntohs (var->s6_addr16 [i]);
+ var->s6_addr16 [i] = new->s6_addr16 [i];
+ csum += ntohs (var->s6_addr16 [i]);
+ }
+ csum = (csum & 0xffff) + (csum >> 16);
+ csum = (csum & 0xffff) + (csum >> 16);
+ *csum_field = htons (~csum);
+}
+
+
/* Send an ICMPv6 reply. This is constructed at the tunnel end, from
* the incoming message. The parameter indicates how many bytes the
* ICMPv6 package counts after the ICMPv6 header. It must be 4 (mod 8).
: allnodes_linklocal_address,
16);
memcpy (v4src6, router_linklocal_address, 16);
- v4v6icmpcksum = icmp6_checksum (ntohs (v4v6plen));
+ v4v6icmpcksum = icmp6_checksum (v4src6, v4dst6,
+ v4v6payload, ntohs (v4v6plen));
//
// Send the message to the IPv4 originator port
printf ("Sending ICMPv6-IPv6-UDP-IPv4 to %d.%d.%d.%d:%d, result = %zd\n",
if (v4v6icmpcode != 0) {
return;
}
- if (icmp6_checksum (v4ngbcmdlen - sizeof (struct ip6_hdr)) != v4v6icmpcksum) {
+ if (icmp6_checksum (v4src6, v4dst6,
+ v4v6payload, v4ngbcmdlen-sizeof (struct ip6_hdr)
+ ) != v4v6icmpcksum) {
return;
}
//
fprintf (stderr, "Traffic to 6bed4router may be fit for masquerading\n");
uint16_t *portpairs = NULL;
uint16_t numpairs = 0;
- uint16_t port;
+ uint16_t port = 0;
+ uint16_t *csum_field = NULL;
switch (v4v6nexthdr) {
+#ifdef CHECKSUM_SCTP_WOULD_BE_LIKE_FOR_OTHERS
case IPPROTO_SCTP:
portpairs = masqportpairs [0]; // 's'
numpairs = num_masqportpairs [0];
port = ntohs (v4v6sctpdstport);
+ csum_field = &v4v6sctpcksum;
break;
+#endif
case IPPROTO_TCP:
portpairs = masqportpairs [1]; // 't'
numpairs = num_masqportpairs [1];
port = ntohs (v4v6tcpdstport);
+ csum_field = &v4v6tcpcksum;
break;
case IPPROTO_UDP:
portpairs = masqportpairs [2]; // 'u'
numpairs = num_masqportpairs [2];
port = ntohs (v4v6udpdstport);
+ csum_field = &v4v6udpcksum;
break;
+ //TODO// ICMPv6
default:
break;
}
//
// Replace masqueraded address by 6bed4router's
fprintf (stderr, "DEBUG: Passing traffic to masquerading address number %d\n", portpairs [2]);
- memcpy (v4dst6, masqhost [portpairs [2]], 16);
+ masquerade_address (v4dst6,
+ (struct in6_addr *) masqhost [portpairs [2]],
+ csum_field);
//
// Forward immediately, and return from this function
printf ("Writing Masqueraded IPv6, result = %zd\n",
for (mqh=0; mqh<num_masqhost; mqh++) {
if (memcmp (v6src6, masqhost [mqh], 16) == 0) {
printf ("Masqueraded sender address in 6to4 set to the client's 6bed4router address\n");
- memcpy (v6src6, v6dst6, 15);
- v6src6->s6_addr [15] &= 0xc0;
- v6src6->s6_addr [16] = 0x00;
+ uint16_t *csum_field = NULL;
+ struct in6_addr masq_src;
+ switch (v6nexthdr) {
+#ifdef CHECKSUM_SCTP_WOULD_BE_LIKE_FOR_OTHERS
+ case IPPROTO_SCTP:
+ csum_field = &v6sctpcksum;
+ break;
+#endif
+ case IPPROTO_TCP:
+ csum_field = &v6tcpcksum;
+ break;
+ case IPPROTO_UDP:
+ csum_field = &v6udpcksum;
+ break;
+ case IPPROTO_ICMPV6:
+ csum_field = &v6icmpcksum;
+ break;
+ default:
+ continue;
+ }
+ //
+ // Construct v6src6 from v6dst6, ending in 14 zero bits
+ memcpy (&masq_src, v6dst6, 16);
+ masq_src.s6_addr16 [7] &= htons (0xc000);
+ fprintf (stderr, "Masquerading cksum.old = 0x%04x, ", ntohs (*csum_field));
+ masquerade_address (v6src6, &masq_src, csum_field);
+ fprintf (stderr, "cksum.new = 0x%04x\n", ntohs (*csum_field));
break;
}
}
/* Option descriptive data structures */
-char *short_opt = "l:L:d:ht:u:s:m:";
+char *short_opt = "l:L:d:hit:u:s:m:";
struct option long_opt [] = {
{ "v4listen", 1, NULL, 'l' },
{ "v6prefix", 1, NULL, 'L' },
{ "tundev", 1, NULL, 'd' },
{ "help", 0, NULL, 'h' },
+ { "icmp", 0, NULL, 'i' },
{ "tcp", 1, NULL, 't' },
{ "udp", 1, NULL, 'u' },
{ "sctp", 1, NULL, 's' },
v6server = strdup (optarg);
*slash64 = '/';
v6prefix = optarg;
- if (!v6server || inet_pton (AF_INET6, v6server, &v6listen) <= 0) {
+ if (!v6server || (inet_pton (AF_INET6, v6server, &v6listen) <= 0)) {
ok = 0;
fprintf (stderr, "%s: Failed to parse IPv6 prefix %s\n", program, optarg);
break;
// Masqueraded port (range) for SCTP, TCP, UDP
//TODO// Should we support ICMPv6 as well? [honeypots]
if (num_masqhost == 0) {
+ //TODO// Reference v6listen instead of ::1
inet_pton (AF_INET6, "::1", masqhost [0]);
num_masqhost = 1;
}
6bed4router \- server-side daemon for 6bed4 service
.SH SYNOPSYS
.B 6bed4router
-[\fB\-d\fR \fI/dev/tunX\fR] \fB\-l\fR \fIv4addr\fR \fB\-L\fR \fIv6prefix/64\fR [\fB\-m\fR/\fBs\fR/\fBt\fR/\fBu\fR \fI...\fR]
+[\fB\-d\fR \fI/dev/tunX\fR] \fB\-l\fR \fIv4addr\fR \fB\-L\fR \fIv6prefix/64\fR [\fB\-m\fR/\fB\-i\fR/\fBs\fR/\fBt\fR/\fBu\fR \fI...\fR]
.PP
.B 6bed4router
[\fB\-h\fR]
\fB\-udp\fR \fIport\fR[\fB:\fIport\fR]
Apply the masquerading port or port range for SCTP, TCP or UDP to the
masquerading host set by the last preceding \fB\-\-masqhost\fR option,
-or use \fB::1\fR
+or use the tunnel's IPv6-side address
if none was set yet. Ports that have been previously bound will not make it,
so it is possible to first relay a port with \fB\-t 22\fR to a service and
then pass the rest to a honeypot with \fB\-t 1:65535\fR.
.TP
+\fB\-i\fR
+Apply masquerading for ICMPv6 to the masquerading host set by the last
+preceding \fB\-\-masqhost\fR option, or use the tunnel's IPv6-side address
+if none was set yet. The ICMPv6 messages with a special meaning to 6bed4
+are exempted (Router and Neighbor Solicitation and Advertisement, as well
+as Redirect) but other messages will be masqueraded.
+.TP
\fB\-h\fR
.TP
\fB\-\-help\fR
+++ /dev/null
-1. Initially, this was "pubtsp", a public version of the Tunnel Setup Protocol.
-2. Then, the branch pubtsp-plus-autoconf was created
-3. The pubtsp-plus-autoconf branch was enhanced with autoconfiguration support
-DONE_UP_TO_HERE
-4. The branch autoconf was created
-5. Specifics for TSP were removed from the autoconf branch
-6. The master branch (with pubtsp-pnly support) was renamed to pubtsp
-7. The autoconf branch became the new master branch
-8. The original public-tsp branch was left as is
-9. The new branch structure is published as a new project named 6bed4
--- /dev/null
+1. Initially, this was "pubtsp", a public version of the Tunnel Setup Protocol.
+2. Then, the branch pubtsp-plus-autoconf was created
+3. The pubtsp-plus-autoconf branch was enhanced with autoconfiguration support
+DONE_UP_TO_HERE
+4. The branch autoconf was created
+5. Specifics for TSP were removed from the autoconf branch
+6. The master branch (with pubtsp-pnly support) was renamed to pubtsp
+7. The autoconf branch became the new master branch
+8. The original public-tsp branch was left as is
+9. The new branch structure is published as a new project named 6bed4
+++ /dev/null
-Copyright (c) 2010, OpenFortress, as the creator of 0cpm technology
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the names of OpenFortress, 0cpm or Rick van Rein, nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
--- /dev/null
+Copyright (c) 2010-2017, OpenFortress, as the creator of 0cpm technology
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the names of OpenFortress, 0cpm or Rick van Rein, nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+++ /dev/null
-6BED4 PREFIXES AND PROMISES
-===========================
-
-> *6bed4 works over a globally registered prefix TBD1 and a standard
-> UDP port TBD2. But there can be alternatives that route through the
-> same 6bed4 infrastructure.*
-
-
-Facilitation by 6bed4
----------------------
-
-The 6bed4 facilities are as follows:
-
- * The prefix of the address may or may not be globally routable. This is
- impartial to 6bed4, but not necessarily for its users. Locally routable
- addresses can serve internal purposes (which is a vague term) including
- (potentially large) peer-to-peer networks. Global routability means that
- anyone can route to the IPv6 endpoing addresses of 6bed4 peers, possibly
- going through the 6bed4router.
-
- * The prefix may also help to learn about the capability of an address for
- opportunistic peering. This capability must apply to both the sender and
- recipient for a frame, because any NAT traversal must be kept open, thus
- requiring a bidirectional UDP stream. Note that no assumptions may be
- made in general about remote nodes, other than the recognition of globally
- defined prefix capabilities.
-
- * The top-half of the address contains a fallback server, which can be used
- when direct contact between peers is not possible. Without this, it is
- still possible to communicate with a configured fallback server, but peers
- will only keep NAT open towards their own fallback server. As a result,
- the fallback server is a necessary hop between peers, and not finding a
- peer's fallback server in their IPv6 address top half could lead to failure
- to connect. Because of this, communication can only be done locally.
-
- * The lower half of the address contains a peer's public IPv4 address and
- UDP port. This information can be used for opportunistic peering, with
- the option of the fallback server to deal with unroutable situations
- between direct peers. Port numbers 0 in the lower half can never be
- used meaningfully in a 6bed4 address, so their handling is undefined.
-
-So, when the top-half has no room for the fallback server's IP address, then
-it can only be used on one 6bed4router (or on a cluster, but certainly not
-globally).
-
-
-Candidate Prefixes
-------------------
-
-The following prefixes spring to mind for use with 6bed4:
-
- * TBD1::/32 is the perfect prefix for 6bed4. It supports the top-half and
- bottom-half structures, and is globally defined to do so.
-
- * fc64:<netid>:<ipv4>::/64 may be used for 6bed4 as well. The <netid> could
- be varied to indicate different applications, so the prefix is as for 6bed4,
- the fc64:<netid>::/32 prefix. The fc00::/8 prefix indicates locally unique
- addresses. Since this also limits the scope, any connection between such
- nets may be read as an indication that they are on the same local net and
- the interpretation may therefore be assumed. This is true for all fc00::/8
- addresses, but we suggest leaving room for other uses by setting fc64::/8
- specifically for the 6bed4 interpretation of the remainder of the address.
- Note that fd00::/8 also covers unique local addresses, but it is followed
- by random bits, so no policy can be applied without breaking standards
- (and software). Note that fc00::/8 is a local scoped name space, but it
- is possible to connect 6bed4peers behind different fallback servers. It
- is simply a matter of distribution of addresses whether two peers will be
- able to communicate. We believe this scheme is perfect for peer-to-peer
- operations, especially with the use of IPsec.
-
- * Native IPv6 /48 or /64 prefixes may be used, but they will not facilitate
- the top-half. Sometimes the native use of native addresses may compete
- with use in a 6bed4router; this is especially true when only one /64 is
- available. In this case, the undefined behaviour of port 0 in the lower
- half may be used to bypass native traffic to a natively connected service.
- Other than this, any 6bed4peer collecting these addresses can do anything;
- native addresses can be reached, opportunistic connections to peers are
- possible and even the native services using port 0 would work. The one
- thing that is impossible, as with fc64::/16, is that independent
- 6bed4router processes can serve the same prefix and have their 6bedpeer
- clients reach each other; this is due to the lacking fallback server in
- the top half.
-
- * 2002:<ipv4>::/48 is based on the 6to4 prefix 2002::/16, but instead of
- using the peer's address and relying on the ability to pass IPv6 directly
- over IPv4, the 6bed4router can be used as an intermediate. The place of
- the <ipv4> address is different than after the /32 of normal 6bed4
- addresses, but this is easily inferred from the prefix. So, it is quite
- possible to interpret <ipv4> as the fallback server. What is not safe
- to assume though, is that the underlying portion is a 6bed4 address. To
- allow for that, we define a "special SLA value" be64, as a hint that the
- lower half may be interpreted for opportunistic peering.
- TODO: This breaks with traditions... NOT FIT FOR A FORMAL SPEC
-
-
-
-Implementation
---------------
-
-The 6bed4router accepts multiple prefixes, simply by issuing more than one
-`-L` prefix. Each of these will be provided to the 6bed4peers in Router
-Advertisements, after having completed them to a /114 prefix length.
-When a 6bed4peer receives such prefixes, it should configure them all,
-after setting its preference(s) of <lanip> in the last 14 bits.
-
-The sizes of the various prefixes vary. The following things are added
-when possible:
-
- * the fallback server IPv4 address, when at least 32 bits are available;
- * the literal value be64, to fill up any remaining 16 bits
-
-This format works for prefixes of sizes 16, 32, 48 and 64:
-
- * xxxx::/16 becomes top half xxxx:<ipv4>:be64::/64
- * xxxx:yyyy::/32 becomes top half xxxx:yyyy:<ipv4>::/64
- * xxxx:yyyy:zzzz::/48 becomes top half xxxx:yyyy:zzzz:be64::/64
- * xxxx:yyyy:zzzz:wwww::/64 is unaltered
-
-Specifically for the indicated candidate prefixes:
-
- * TBD1::/32 becomes top half TBD1:<ipv4>::/64
- * fc64:<netid>::/32 becomes top half fc64:<netid>:<ipv4>::/64
- * xxxx:yyyy:zzzz::/48 becomes top half xxxx:yyyy:zzzz:be64::/64
- * xxxx:yyyy:zzzz:wwww::/64 is unaltered
- * 2002::/16 becomes top half 2002:<ipv4>:be64::/64
-
-These do all support routing based on the bottom half. Furthermore:
-
- * The fallback server appearing as <ipv4> in the top half enables unrelated 6bed4router connectivity
- * The rules for global routing determine whether the addresses can communicate with native IPv6 addresses
-
--- /dev/null
+6BED4 PREFIXES AND PROMISES
+===========================
+
+> *6bed4 works over a globally registered prefix TBD1 and a standard
+> UDP port TBD2. But there can be alternatives that route through the
+> same 6bed4 infrastructure.*
+
+
+Facilitation by 6bed4
+---------------------
+
+The 6bed4 facilities are as follows:
+
+ * The prefix of the address may or may not be globally routable. This is
+ impartial to 6bed4, but not necessarily for its users. Locally routable
+ addresses can serve internal purposes (which is a vague term) including
+ (potentially large) peer-to-peer networks. Global routability means that
+ anyone can route to the IPv6 endpoing addresses of 6bed4 peers, possibly
+ going through the 6bed4router.
+
+ * The prefix may also help to learn about the capability of an address for
+ opportunistic peering. This capability must apply to both the sender and
+ recipient for a frame, because any NAT traversal must be kept open, thus
+ requiring a bidirectional UDP stream. Note that no assumptions may be
+ made in general about remote nodes, other than the recognition of globally
+ defined prefix capabilities.
+
+ * The top-half of the address contains a fallback server, which can be used
+ when direct contact between peers is not possible. Without this, it is
+ still possible to communicate with a configured fallback server, but peers
+ will only keep NAT open towards their own fallback server. As a result,
+ the fallback server is a necessary hop between peers, and not finding a
+ peer's fallback server in their IPv6 address top half could lead to failure
+ to connect. Because of this, communication can only be done locally.
+
+ * The lower half of the address contains a peer's public IPv4 address and
+ UDP port. This information can be used for opportunistic peering, with
+ the option of the fallback server to deal with unroutable situations
+ between direct peers. Port numbers 0 in the lower half can never be
+ used meaningfully in a 6bed4 address, so their handling is undefined.
+
+So, when the top-half has no room for the fallback server's IP address, then
+it can only be used on one 6bed4router (or on a cluster, but certainly not
+globally).
+
+
+Candidate Prefixes
+------------------
+
+The following prefixes spring to mind for use with 6bed4:
+
+ * TBD1::/32 is the perfect prefix for 6bed4. It supports the top-half and
+ bottom-half structures, and is globally defined to do so.
+
+ * fc64:<netid>:<ipv4>::/64 may be used for 6bed4 as well. The <netid> could
+ be varied to indicate different applications, so the prefix is as for 6bed4,
+ the fc64:<netid>::/32 prefix. The fc00::/8 prefix indicates locally unique
+ addresses. Since this also limits the scope, any connection between such
+ nets may be read as an indication that they are on the same local net and
+ the interpretation may therefore be assumed. This is true for all fc00::/8
+ addresses, but we suggest leaving room for other uses by setting fc64::/8
+ specifically for the 6bed4 interpretation of the remainder of the address.
+ Note that fd00::/8 also covers unique local addresses, but it is followed
+ by random bits, so no policy can be applied without breaking standards
+ (and software). Note that fc00::/8 is a local scoped name space, but it
+ is possible to connect 6bed4peers behind different fallback servers. It
+ is simply a matter of distribution of addresses whether two peers will be
+ able to communicate. We believe this scheme is perfect for peer-to-peer
+ operations, especially with the use of IPsec.
+
+ * Native IPv6 /48 or /64 prefixes may be used, but they will not facilitate
+ the top-half. Sometimes the native use of native addresses may compete
+ with use in a 6bed4router; this is especially true when only one /64 is
+ available. In this case, the undefined behaviour of port 0 in the lower
+ half may be used to bypass native traffic to a natively connected service.
+ Other than this, any 6bed4peer collecting these addresses can do anything;
+ native addresses can be reached, opportunistic connections to peers are
+ possible and even the native services using port 0 would work. The one
+ thing that is impossible, as with fc64::/16, is that independent
+ 6bed4router processes can serve the same prefix and have their 6bedpeer
+ clients reach each other; this is due to the lacking fallback server in
+ the top half.
+
+ * 2002:<ipv4>::/48 is based on the 6to4 prefix 2002::/16, but instead of
+ using the peer's address and relying on the ability to pass IPv6 directly
+ over IPv4, the 6bed4router can be used as an intermediate. The place of
+ the <ipv4> address is different than after the /32 of normal 6bed4
+ addresses, but this is easily inferred from the prefix. So, it is quite
+ possible to interpret <ipv4> as the fallback server. What is not safe
+ to assume though, is that the underlying portion is a 6bed4 address. To
+ allow for that, we define a "special SLA value" be64, as a hint that the
+ lower half may be interpreted for opportunistic peering.
+ TODO: This breaks with traditions... NOT FIT FOR A FORMAL SPEC
+
+
+
+Implementation
+--------------
+
+The 6bed4router accepts multiple prefixes, simply by issuing more than one
+`-L` prefix. Each of these will be provided to the 6bed4peers in Router
+Advertisements, after having completed them to a /114 prefix length.
+When a 6bed4peer receives such prefixes, it should configure them all,
+after setting its preference(s) of <lanip> in the last 14 bits.
+
+The sizes of the various prefixes vary. The following things are added
+when possible:
+
+ * the fallback server IPv4 address, when at least 32 bits are available;
+ * the literal value be64, to fill up any remaining 16 bits
+
+This format works for prefixes of sizes 16, 32, 48 and 64:
+
+ * xxxx::/16 becomes top half xxxx:<ipv4>:be64::/64
+ * xxxx:yyyy::/32 becomes top half xxxx:yyyy:<ipv4>::/64
+ * xxxx:yyyy:zzzz::/48 becomes top half xxxx:yyyy:zzzz:be64::/64
+ * xxxx:yyyy:zzzz:wwww::/64 is unaltered
+
+Specifically for the indicated candidate prefixes:
+
+ * TBD1::/32 becomes top half TBD1:<ipv4>::/64
+ * fc64:<netid>::/32 becomes top half fc64:<netid>:<ipv4>::/64
+ * xxxx:yyyy:zzzz::/48 becomes top half xxxx:yyyy:zzzz:be64::/64
+ * xxxx:yyyy:zzzz:wwww::/64 is unaltered
+ * 2002::/16 becomes top half 2002:<ipv4>:be64::/64
+
+These do all support routing based on the bottom half. Furthermore:
+
+ * The fallback server appearing as <ipv4> in the top half enables unrelated 6bed4router connectivity
+ * The rules for global routing determine whether the addresses can communicate with native IPv6 addresses
+
--- /dev/null
+# IPv6 Everywhere with 6bed4
+
+> *The 6bed4 tunnel and peer-to-peer toolkit enables IPv6 everywhere.
+> It connects programs and hosts over UDP/IPv4. It tries hard to setup
+> connections as direct peer-to-peer connections, but may fall back to
+> a server failing this.*
+
+The intention of 6bed4 is to assure protocol designers of the availability
+of IPv6 on all nodes that run their protocol. For instance, a designer
+of a peer-to-peer search application should be able to connect to peers
+over IPv6, thereby bypassing many problems resulting from NAT. One might
+say that IPv6 is used to encapsulate all problems with NAT traversal.
+
+
+## Status
+
+This code is **WORK IN PROGRESS**, while we are finalising our 6bed4
+Internet Draft.
+
+
+## Programs
+
+The `6bed4peer` program runs an interface over which IPv6 routing is
+available, and for which up to 16383 local extensions can be allocated
+and made available over a tunnel interface.
+
+The `6bed4node` program is an extended `6bed4peer` in that it does not
+provide a network interface but a network service that offers IPv6
+addresses over a standard network interface, though this requires a few
+extra programs like `radvd` and possibly a DHCPv6 server. In this case,
+programs can use native IPv6 network stacks. A typical use case for the
+`6bed4node` is on a network router, such as one of the OpenWRT routers.
+
+The `6bed4router` program runs as a fallback router. Even when it could
+be considered a server program, it is faithful to the idea of peer-to-peer
+communication in the sense that multiple of these routers can collaborate
+to connect `6bed4peer` programs. A user can choose which router to use,
+although this
+[depends on the prefix](PREFIXES.MD)
+used. We have arranged for public 6bed4 service at 145.136.0.1 port 25790.
+
+**TODO:** 6bed4node remains to be done.
+
+**TODO:** A socket-replacing library would be useful.
+
+For use with Java, we have **TODO:** Android6bed4 and Socket6bed4.
+
+
+## Usage
+
+TODO