\fB\-l\fR \fIv4addr\fR
.TP
\fB\-\-v4listen\fR \fIv4addr\fR
-Bind to the given local IPv4 address and listen for incoming TSP
-tunnel commands and packaged-IPv6 traffic. Required.
+Bind to the given local IPv4 address and listen for incoming IPv6
+neighbour discovery packages as well as general IPv6 traffic. Required.
.TP
\fB\-L\fR \fIv6prefix/64\fR
.TP
.IP
If no \fB\-t\fR option is given, a tunnel will be created for the time that
\fB6bed4\fR is running, and the \fIv6prefix/64\fR is used as a router address
-on that interface. Routing table entries will not be setup by \fBpublicTSP\fR,
+on that interface. Routing table entries will not be setup by \fB6bed4\fR,
nor will the general ablity to forward IPv6 traffic.
.TP
\fB\-h\fR
.PP
The format of the IPv6 addresses managed by \fB6bed4\fR are:
.PP
-\fIv6prefix\fR + \fIv4addr\fR + \fIudp-port\fR + \fIlocalnet\fR
+\fIv6prefix\fR + \fIv4addr\fR + \fIudp-port\fR + \fIinterfaceidentifier\fR
.PP
In this format, the \fIv6prefix\fR is configured with the \fB\-L\fR option,
and the \fIv4addr\fR with the \fB\-l\fR option. The \fIudp-port\fR is noted on
arrival of a packet on the IPv4 tunnel side of \fB6bed4\fR.
.PP
-The \fIlocalnet\fR defaults to 0, but may be used to differentiate up to
-65,536 different hosts accessible through the same TSP client. As
+The \fIinterfaceidentifier\fR is always 0 on the router side, and may be set
+to other values to distinguish 65,535 different client addresses. As
the main application foreseen for \fB6bed4\fR is to get IPv6-only tools and
-devices working on an IPv4-only network, this is not a probable setup,
-but it is nevertheless possible. The current version of \fB6bed4\fR does
-not actually hand this over as a subnet.
+devices working on an IPv4-only network, it is very likely that the clients
+will pick a fixed \fIinterfaceidentifier\fR such as 1 and hard-code it.
.PP
-The router address that \fB6bed4\fR chooses for itself consists of the
-\fIv6prefix\fR with zeroes appended; this falls outside the setup above,
-because neither IPv4 addresses nor UDP port numbers are not permitted
-te be zero-valued.
+Due to the IPv6 practice of assigning link-local names composed of \fBfe80::\fR
+and the \fIinterfaceidentifier\fR, the router-side of a tunnel can always
+be addressed as \fBfe80::0\fR and clients can be found at addresses ranging
+from \fBfe80::1\fR to \fBfe80::ffff\fR.
.PP
Incoming IPv6 traffic destined for a serviced address is first checked
as specified under SECURITY CHECKS, and then forwarded to \fIudp-port\fR at
the \fIv4addr\fR and \fIudp-port\fR matching the client's public side. That
is, NAT may translate the IPv4 address and UDP port used, but these
parts of the IPv6 address should show how it is forwarded to \fB6bed4\fR.
-Note that the TSP protocol provides this necessary information at the
-time the TSP tunnel is created.
-.PP
-It is recommended to keep NAT state in tact by regularly sending over
-the UDP port to the tunnel endpoint. At the very least, a regular
+Note that autonegotiation protocol provides this necessary information at the
+time the 6bed4 daemon starts. If the NAT mapping changes during the uptime
+of the tunnel, a new Router Advertisement is sent from tunnel server to
+client, to notify it of the new prefix to use. The original message is
+then discarded.
+.PP
+If it is desired to keep the same IPv6 address for longer periods, it
+is recommended that the client keeps NAT state intact by regularly
+sending over the UDP port to the tunnel endpoint. For example, a regular
ping could do that. Alternatively, a client-mode only daemon could
ensure that it is sending regularly during the times that an outside
party might wish to send to it. This is under the assumption that no
#ifdef LINUX
#define HAVE_SETUP_TUNNEL
+static struct ifreq ifreq;
+static int have_tunnel = 0;
/* Implement the setup_tunnel() command for Linux.
* Return 1 on success, 0 on failure.
*/
return 0;
}
int ok = 1;
- static struct ifreq ifreq;
- static int have_tunnel = 0;
if (!have_tunnel) {
memset (&ifreq, 0, sizeof (ifreq));
ifreq.ifr_flags = IFF_TUN;
+ ((uint8_t *) &ifreq.ifr_hwaddr) [5] = 0x01;
if (ok && (ioctl (v6sox, TUNSETIFF, (void *) &ifreq) == -1)) {
ok = 0;
} else {
ifreq.ifr_name [IFNAMSIZ] = 0;
}
char cmd [512+1];
- snprintf (cmd, 512, "/sbin/ip -6 addr flush dev %s", ifreq.ifr_name);
+ snprintf (cmd, 512, "/sbin/ip addr add fe80::1 dev %s scope link", ifreq.ifr_name);
if (ok && system (cmd) != 0) {
ok = 0;
}
- snprintf (cmd, 512, "/sbin/ip -6 route flush dev %s", ifreq.ifr_name);
+ snprintf (cmd, 512, "/sbin/ip link set %s up mtu 1280", ifreq.ifr_name);
if (ok && system (cmd) != 0) {
ok = 0;
}
- snprintf (cmd, 512, "/sbin/ip addr add fe80::1 dev %s scope link", ifreq.ifr_name);
+ if (!ok) {
+ close (v6sox); /* This removes the tunnel interface */
+ }
+ return ok;
+}
+int setup_tunnel_address (void) {
+ int ok = have_tunnel;
+ char cmd [512+1];
+ snprintf (cmd, 512, "/sbin/ip -6 addr add %s dev %s", v6prefix, ifreq.ifr_name);
if (ok && system (cmd) != 0) {
ok = 0;
}
- if (* (uint16_t *) v6prefix != htons (0x0000)) {
- snprintf (cmd, 512, "/sbin/ip -6 addr add %s dev %s", v6prefix, ifreq.ifr_name);
- if (ok && system (cmd) != 0) {
- ok = 0;
- }
- snprintf (cmd, 512, "/sbin/ip -6 route add %s/112 mtu 1280 dev %s", v6prefix, ifreq.ifr_name);
- if (ok && system (cmd) != 0) {
- ok = 0;
- }
-#if 0
- snprintf (cmd, 512, "/sbin/ip -6 rule add from %s/112 table 64", v6prefix);
- if (ok && system (cmd) != 0) {
- ok = 0;
- }
-#endif
- snprintf (cmd, 512, "/sbin/ip -6 route flush table 64");
- if (ok && system (cmd) != 0) {
- ok = 0;
- }
- snprintf (cmd, 512, "/sbin/ip -6 route add table 64 default via %s dev %s metric 512", v6prefix, ifreq.ifr_name);
- if (ok && system (cmd) != 0) {
- ok = 0;
- }
- }
- snprintf (cmd, 512, "/sbin/ip link set %s up mtu 1280", ifreq.ifr_name);
+ snprintf (cmd, 512, "/sbin/ip -6 route add %s/112 mtu 1280 dev %s", v6prefix, ifreq.ifr_name);
if (ok && system (cmd) != 0) {
ok = 0;
}
- if (!ok) {
- close (v6sox); /* This removes the tunnel interface */
- }
return ok;
}
#endif /* LINUX */
&v6listen,
v6prefix,
sizeof (v6prefix));
- printf ("Assigning address %s to tunnel\n", v6prefix);
- setup_tunnel ();
+ fprintf (stderr, "Assigning address %s to tunnel\n", v6prefix);
+ setup_tunnel_address ();
}
rdofs += (v4v6icmpdata [rdofs + 1] << 3);
}
//
// Send the unwrapped IPv6 message out over v6sox
memcpy (&v6name.sin6_addr, v4dst6, sizeof (v6name.sin6_addr));
-printf ("Writing IPv6, result = %d\n",
+// printf ("Writing IPv6, result = %d\n",
+(
write (v6sox, &v4data6, sizeof (struct tun_pi) + v4datalen));
}
if (v6tuncmd.proto != htons (ETH_P_IPV6)) {
return;
}
-printf ("Received IPv6 data, flags=0x%04x, proto=0x%04x\n", v6tuncmd.flags, v6tuncmd.proto);
+// printf ("Received IPv6 data, flags=0x%04x, proto=0x%04x\n", v6tuncmd.flags, v6tuncmd.proto);
//
// Ensure that the incoming IPv6 address is properly formatted
+#if 0
// Note that this avoids access to ::1/128, fe80::/10, fec0::/10
// TODO: v6src6 or v6dst6?!?
if (memcmp (v6src6, &v6listen, 8) != 0) {
if (v6src6->s6_addr32 [1] != v6listen.s6_addr32 [1]) {
return;
}
+#endif
if (v6src6->s6_addr16 [7] == htons (0x0000)) {
return;
}
//
// Harvest socket address data from destination IPv6, then send
socklen_t v4namelen = sizeof (v4name);
-printf ("Sending IPv6-UDP-IPv4 to %d.%d.%d.%d:%d, result = %d\n",
-((uint8_t *) &v4peer.sin_addr.s_addr) [0],
-((uint8_t *) &v4peer.sin_addr.s_addr) [1],
-((uint8_t *) &v4peer.sin_addr.s_addr) [2],
-((uint8_t *) &v4peer.sin_addr.s_addr) [3],
-ntohs (v4peer.sin_port),
+// printf ("Sending IPv6-UDP-IPv4 to %d.%d.%d.%d:%d, result = %d\n",
+// ((uint8_t *) &v4peer.sin_addr.s_addr) [0],
+// ((uint8_t *) &v4peer.sin_addr.s_addr) [1],
+// ((uint8_t *) &v4peer.sin_addr.s_addr) [2],
+// ((uint8_t *) &v4peer.sin_addr.s_addr) [3],
+// ntohs (v4peer.sin_port),
+(
send (v4sox,
v6data,
rawlen - sizeof (struct tun_pi),
int done = 0;
int secs = 1;
while (!done) {
-printf ("Sending RouterSolicitation-IPv6-UDP-IPv4 to %d.%d.%d.%d:%d, result = %d\n",
-((uint8_t *) &v4name.sin_addr.s_addr) [0],
-((uint8_t *) &v4name.sin_addr.s_addr) [1],
-((uint8_t *) &v4name.sin_addr.s_addr) [2],
-((uint8_t *) &v4name.sin_addr.s_addr) [3],
-ntohs (v4name.sin_port),
+// printf ("Sending RouterSolicitation-IPv6-UDP-IPv4 to %d.%d.%d.%d:%d, result = %d\n",
+// ((uint8_t *) &v4name.sin_addr.s_addr) [0],
+// ((uint8_t *) &v4name.sin_addr.s_addr) [1],
+// ((uint8_t *) &v4name.sin_addr.s_addr) [2],
+// ((uint8_t *) &v4name.sin_addr.s_addr) [3],
+// ntohs (v4name.sin_port),
+(
sendto (v4sox,
ipv6_router_solicitation,
sizeof (ipv6_router_solicitation),
secs <<= 1;
}
}
- printf ("Got a response, liberally assuming it is an offer\n");
+ fprintf (stderr, "Got a first messsage, liberally assuming it is an offer\n");
}
} else {
FD_SET (v6sox, &io);
}
-fflush (stdout);
+//fflush (stdout);
}
}
exit (1);
}
printf ("\nThis tunnel client is ONLY FOR DEMONSTRATION PURPOSES.\n\nUntil there are plenty of tunnels and tunnel hosting parties agree, it is\nnot permitted to rolll out this application on desktops. Please acknowledge\nthat by entering the word demonstrate to the following prompt.\n\nExceptions are made for roll-outs on local networks, where the tunnel service\nis used from a non-standard IPv4 address and IPv6 /64 prefix.\n\nType the word from the text to proceed: ");
- fflush (stdout);
+ //fflush (stdout);
char demobuf [100];
if (fgets (demobuf, sizeof (demobuf)-1, stdin) == NULL
|| strcmp (demobuf, "demonstrate\n") != 0) {
}
//
// Start the main daemon process
- solicit_routers (); // DEMO -- only once
+ //NOTNEEDED:AUTOMATIC// solicit_routers (); // DEMO -- only once
run_daemon ();
//
// Report successful creation of the daemon
In doing so, it MUST NOT bypass the comparison of the IPv6 prefix,
IPv4 address and UDP port as mentioned in the source IPv6 address.
-If this fails, the traffic MUST be treated as traffic trying to pass
-up through the tunnel with an incorrectly set IPv6 address.
+If this comparison fails, the traffic MUST be treated as traffic
+trying to pass up through the tunnel with an incorrectly set
+IPv6 address.
Tunnel service profiles
be traced to IPv4 abusers, in the regional internet registry's whois
database.
-The traffic flowing through the local tunnel server MUST NOT perform
-more tapping than the weakest required form of tapping on the local
-network. In cases where a local network spans different jurisdictions,
-it is therefore not possible to apply stronger privacy-depriving
-standards to network users that are used to more privacy.
+
+En-route translation profile
+----------------------------
+
+Any public router connected to both IPv4 and IPv6 protocols can perform
+the translations specified in this document. It could perform this
+function en route, so on traffic that happens to pass through it. This
+means that the least possible energy and effort is required to support
+IPv6 to the embedded devices targeted by 6bed4. The vital distinction
+between such a 6bed4 profile and the public tunnel server profile is
+that the translation services are not announced over BGP.
+
+The major advantage of en-route translation is that it avoids any
+diversion of the traffic to a 6bed4 tunnel server. Instead of routing
+the traffic through an intermediary, it can be kept on the fastest
+route available, which is good for the routing budget of the Internet
+as a whole; furthermore, it can save on the budget of the en-route
+party if it has less need to steer traffic through core routers.
+
+It is possible to perform only one side of this translation en-route;
+a consumer-level ISP might want to support old IPv4-only routers and
+any 6bed4-based devices behind it. Similarly, a hosting provider
+could offer the service of translating the IPv6 side traffic to IPv4.
+
+An ISP wishing to provide this service to its own network but not to
+the whole world could implement such en-route translation, in order
+
+
+
NAT traversal issues
IANA Issues
===========
-Well-known IPv4 address, well-known IPv6 /64 prefix, well-known UDP port.
+Well-known IPv4 address, well-known IPv6 /64 prefix.
+Requested: IPv4 address 192.64.64.1/24 and IPv6 prefix 2001:6bed:4:0::/64.
+
+Possibly also, the well-known UDP port.
+Since this port is only bound to a well-known IPv4 address, the port
+could be anything. We suggest sharing the UDP port for TSP, which is
+3653.
+
+
+Privacy issues
+==============
+
+Tunnel servers can attract traffic, and especially the use of an anycast
+address means that the tunnel service provider is not easily known.
+As a result, there may be privacy issues when the traffic enters a
+jurisdiction that requires more excessive tapping and law enforcement
+than is assumed by communicating partners.
+
+For this reason, in jurisdictions where tapping, inspection and/or
+storage of traffic can be enforced by law, the BGP announcements of either
+or both well-known address prefixes MUST NOT reach jurisdictions where
+more more relaxed tapping requirements exist.
+
+A disadvantage of this requirement is that the use of 6bed4 with its
+well-known addresses is impaired in countries that enforce tapping of
+traffic at the routing level. The result may be slower performance,
+with a real impact on realtime media exchange. The economic impact
+that this could have is outside the scope of this specification.
Security issues
//
// Validate Neigbour Solicitation
if (v4dst6->s6_addr16 [0] == htons (0xff02)) {
- break; /* drop */
- }
- if (v4src6->s6_addr16 [9] == htons (0x0000)) {
- // TODO: 24 ---> 24 + bytes_voor_srclinklayaddr
- if (v4ngbcmdlen != sizeof (struct ip6_hdr) + 24) {
+ if (v4ngbcmdlen != sizeof (struct ip6_hdr) + 24 + 8) {
break; /* drop */
}
} else {
- if (v4ngbcmdlen != sizeof (struct ip6_hdr) + 24) {
+ if ((v4ngbcmdlen != sizeof (struct ip6_hdr) + 24) &&
+ (v4ngbcmdlen != sizeof (struct ip6_hdr) + 24 + 8)) {
break; /* drop */
}
}
+ if (v4src6->s6_addr16 [0] == htons (0x0000)) {
+ break; /* drop, we use link-layer addresses */
+ }
//
// Construct Neigbour Advertisement
v4v6icmptype = ND_NEIGHBOR_ADVERT;