IPv4 can address 4 billion stations (each with a unique 32-bit address). IPv6 extends that to 128-bits and means you can have a unique address for every grain of sand on Earth's surface or a whole 32-bit Internet for each square metre of the surface. 128-bit is a massive leap.
Back in 2011 as part of IPv6 day I started looking at IPv6 in more detail. I'd got to grips with IPv4 (it helps that my ISP gives me a fixed address) and could do everything needed to write a client program (connect, open read/write, close, disconnect) and a server program (connect, open, listen, accept, read/write, close, disconnect). Most of my TCP/IP programming is done with REXX sockets. My home network uses NAT with a RFC 1918 network on the home LAN. I started with 10.1.1.0/24 (a class C subnet carved from the 10.0.0.0/8 class A non-routable range). I've got a DHCP server (my Linksys ADSL modem/router).
I'm running a DNS (so that I can give things names without proliferating HOSTS files). The DNS includes reverse lookup x.1.1.10.in-addr.arpa so I can map names to addresses or addresses to names. I learned how to do that stuff from DNS and BIND, 3rd Edition ISBN 1-56592-512-2 and implemented my DNS more than ten years ago. It's worth pulling the sample code examples.oreilly.com/9780596100575/dns.5ed.tar.Z and using the h2n-hp programs to migrate from hosts to DNS.
IPv4 is simple, the packets are simple (the IP header is 20 bytes (I'll ignore the optional fields that can expand an IPv4 header to 60 bytes) with the source and destination addresses taking 8 bytes and flags, length, the checksum and stuff taking 12 bytes). The rest of the packet (up to the MTU length of 1500) is payload (TCP or UDP).
IPv6 extends the header (quite significantly but gives it a fixed length and has extensibility). It reduces the payload size (since MTU is still the same) but not by much. IPv6 reduces the number of flag & length bytes to 8 and increased the source and destination addresses to 128-bits each (32 bytes). So overall it's double the simple IPv4 length and reduces the payload by 20 bytes (again assuming we don't use any optional headers).
The TCP or UDP payload (layer 4) remains the same. Going from IPv4 to IPv6 is a change to layer 3 only. From a programming point of view we have to change our DNS lookups and connect using AF_INET6 instead of AF_INET.
So how do we get ready for IPv6 running on an IPv4 network (without replacing my ADSL router and changing things at the ISP which will happen some time in the future). We need a conversion protocol we need to be able to fiddle with IPv6 packets to send them out to the public Internet across a IPv4 tunnel. The protocol is 6to4 www.ietf.org/rfc/rfc3056.txt and my provider for that is Freenet6 (amsterdam.freenet6.net). They provide a free service that's open to anybody.
Any IPv6 packets from my network that are routed to the public Internet are encapsulated in an IPv4 packet and sent to 18.104.22.168 where the IPv4 wrapper is ripped off and the reassembled IPv6 packet is routed on Freenet's IPv6 backbone. When they receive a packet destined for my IPv6 subnet they rebuild an IPv4 wrapper and route it back to my public IPv4 address and through my NAT to my copy of gogoc. Gogoc maintains a routing table and runs route advertisement (radvd) so that the machines on my LAN know where the IPv6 gateway is located. With IPv6 there's no DHCP all of my address assignment is semi-autonomous.
The LAN machine can't tell that the router is tunnelling. The IPv6 hosts we're connecting to can't tell that there's a tunnel. Everybody appears to have a public IPv6 address that can be addressed from anywhere (no more NAT). It does expose us and we need to ensure that firewalls are in place at the right points else there's a risk of punching a great big hole in the network.
The configuration for gogoc is simple. You start at www.gogo6.com/profile/gogoCLIENT or Linux users can find a RPM or deb package that can be installed with yum or apt-get / aptitude. Then visit www.gogo6.com/freenet6/account to register an id/pw on the Amsterdam or Montreal server. I've registered an ID on the Amsterdam server (as I think the route to 22.214.171.124 (13 hops 55.8ms) is shorter than the route to 126.96.36.199 (13 hops 109.7ms)). Registration is "desired username", "email address" and "password"/"password confirm" with the usual email confirmation. Beware that the password can be sent in clear text so needs to be unique to Freenet6 (or in other words don't set it to your PayPal password).
userid=<username> passwd=<password> server=amsterdam.freenet6.net auth_method=passdss-3des-1 host_type=router prefixlen=64 if_prefix=eth0 dns_server= gogoc_dir= auto_retry_connect=yes retry_delay=30 retry_delay_max=300 keepalive=yes keepalive_interval=30 tunnel_mode=v6anyv4 if_tunnel_v6v4=sit1 if_tunnel_v6udpv4=tun if_tunnel_v4v6=sit0 client_v4=auto client_v6=auto template=linux proxy_client=no broker_list=/var/lib/gogoc/tsp-broker-list.txt last_server=/var/lib/gogoc/tsp-last-server.txt always_use_same_server=no log_stderr=0 log_file=1 log_filename=/var/log/gogoc/gogoc.log log_rotation=yes log_rotation_size=32 log_rotation_delete=yes syslog_facility=USER
/etc/gogoc/gogoc.conf - configuration file for 6to4 tunnel
The server needs write access to /var/lib/gogoc and /var/log/gogoc log_file=1 is for normal running when you've got all of the bugs out. Gogoc gives us the minimum required info at level 1 logging. Highest level is level 3 logging and that's very verbose.
2013/07/16 20:13:31 I gogoc: Built on ///Linux rothera 2.6.24-27-server #1 SMP ... ... Fri Mar 12 01:45:06 UTC 2010 i686 i686 i386 GNU/Linux/// 2013/07/16 20:13:32 I gogoc: Your IPv6 address is 2001:0xxx:1400:000b:0000:0000:0000:23b3. 2013/07/16 20:13:32 I gogoc: Your IPv6 prefix is 2001:0xxx:1505:xx00:0000:0000:0000:0000/56. 2013/07/16 20:13:32 I gogoc: Your IPv6 DNS address is 2001:4860:4860:0000:0000:0000:0000:8888.
/var/log/gogoc/gogoc.log - level 1 log file (redacted)
Take note of the 56-bit prefix 2001:0xxx:1505:xxnn::/56 (Note: I've removed some bits from my prefix to keep my address range private) that gives you a network with 72-bits to address your local devices. Bits 57-64 are the site-level address (SLA) which are available for my use, bits 65-128 are the interface ID. I've not used all of the 256 addresses in my IPv4 10.1.1.0/24 network. Now I've got more addresses than I'd ever need to play with. My assigned addresses run from 2001:0xxx:1505:xx00:0000:0000:0000:0000 to 2001:0xxx:1505:xxff:ffff:ffff:ffff:ffff (4,722,366,482,869,645,213,696 addresses) It gets slightly less complex when you use the calculator at http://www.gestioip.net/cgi-bin/subnet_calculator.cgi To untangle things those things.
Because gogoc is the IPv6 gateway it's using router advertising (radvd) to assign semi-autonomous addresses to machines on my network. They're, normally, built using the advertised 56-bit prefix and the MAC address from the interface for the client system. Curiously, my Win8 machine gets these two addresses assigned to it
MAC address: 08:3e:8e:ab:de:93 2001:0xxx:1505:xx00:d86d:9bea:a350:a189 2001:0xxx:1505:xx00:d5d9:513a:9eda:2c7c
Windows appears to use it's own scheme for assigning the interface ID (bottom 64-bit of the address). It seems to have a random element and is not simply based on the MAC address.
My Linux machine and my Raspberry Pi (running Raspbian) use the more sane process described here: www.tcpipguide.com/free/t_IPv6InterfaceIdentifiersandPhysicalAddressMapping-2.htm that starts with the MAC address, breaks it in half, adds FF:FE in the middle and always changes bit 7 to 1. IPv4 with the ARP table gives us a simple way to find MAC addresses so we can predict those IPv6 address. But for Windows systems we can only predict the link local addresses.
MAC address: 80:1f:02:68:c6:af 2001:0xxx:1505:xx00:821f:2ff:fe68:c6af/64 Scope:Global fe80::821f:2ff:fe68:c6af/64 Scope:Link
My Linux system running gogoc gets a Scope:Global address of 2001:0xxx:1505:xx00::1 Which makes perfect sense and makes it easy to discover.
The important thing when you're playing with your home LAN is to try to avoid disconnecting the rest of the family, to try to avoid getting routing tables messed up and try to leave everything working when you're done. That doesn't always happen. I got things so messed up one night that my router, both my Linux server and my Pi needed to be re-booted. There's plenty of websites out there that don't have a IPv4 interface, my favourite is ipv6.google.com. If you can reach Google that way your IPv6 network is running. I use news.bbc.co.uk for IPv4 testing, as it's reliable, it's available 24hours a day and ICMP packets aren't blocked.
The funniest failure was with Mozilla Thunderbird and my ISP's mailserver (mailhost.ifb.net). My wife says to me, "I can't send email, I keep getting 5.7.1 errors. Can you fix that?". So I installed wireshark on her system and stoked up TBird to send a test email from her system to my GMail id. Straight away I got that same failure.
The wireshark trace showed the reason. TBird prefers to use a IPv6 address rather than IPv4 address if the machine has a valid IPv6 routing table. So it looks up mailhost.ifb.net and gets the TYPE=AAAA address (in this case it's 2a00:1670:8:12::4). TBIrd then attempts to connect to port 25 on there. The packet goes down the 6to4 tunnel, arrives in Amsterdam and routes back to IFB in Aberdeen. So the connection comes in from the public interface and IFB decided it dislikes that as it looks like a spammer testing whether it can use IFB as an open relay. Sensibly they reject the connection (with the cryptic error). The cure was a about:config change in TBird so that it wouldn't use IPv6 (we can re-enable that when we switch from our fixed IPv4 to native IPv6). When TBird uses IPv4 mailhost.ifb.net resolves to 188.8.131.52 and that's in the same subnet as my fixed IPv4 address so the connection to port 25 is allowed. The lesson learned is expect the unexpected, that one was a bit of a googlie. Once I found the reason it was obvious and the cure was simple.
In part 3 I'll talk about DNS, mDNS and OpenVPN with IPv6.