By Robert Muchsel, Embedded.com
One of the driving forces behind the move from IPv4 to IPv6 has been low-cost embedded devices, which are going
online at an accelerating pace. But shoehorning the full IPv6 suite of protocols
into a small 8-bit microcontroller is an extreme sport of the first order. Here
are some tips from someone who's done that successfully.
The address space for Internet nodes is getting tight. While some IPv4
addresses have yet to be allocated, and hacks such as IP masquerading and
temporary address leases have slowed momentum, we're nevertheless likely to run
out of addresses in the next few years. To ensure that future Internet-connected
devices will have unique addresses, the next-generation of the Internet
Protocol, IPv6, extends the addressing space to a number far beyond human
imagination: 2128, which is about 6.67 x 1023 addresses
per square meter of our planet; in other words, plenty.
Having enough addresses eliminates the need for Network Address Translation
(NAT) (also known as IP masquerading), temporary address leases, and other
kludges necessary to conserve the strictly rationed IPv4 addresses. The industry
expects a greater number of classic network devices such as desktop and server
computers, but a tremendous number of smaller devices"including "always-on"
wireless and mobile devices like cell phones and PDAs, and sensors built into
everything from cars to water meters to refrigerators"will change the nature of
Internet traffic as we know it today.
Of course, IPv6 does more than simply extend the address space. This upgrade
to IPv4 (there is no IPv5"protocol ID 5 was used for the Internet Stream
Protocol, RFC 1819) makes node setup easy and automatic"another must for
embedded applications. It also makes the network as a whole more robust and
extensible, and adds security features and quality-of-service support not
previously available. Importantly, IPv6 also helps speed and simplify routing,
which has become a bottleneck as Internet use has increased.
The reengineered and better IPv6 is already deployed widely and set to
gradually replace IPv4. Many, if not all, routers have already been upgraded.
Having progressed far beyond the prototype stage, it now forms a standard part
of most desktop operating systems, including Windows XP, Mac OS X, Solaris, and
Linux. Meanwhile dual IPv4/IPv6 stacks support mixed environments and allow for
a gradual roll-out of IPv6. (Where IPv6 is not yet supported, nodes can still
communicate via "tunneling" over IPv4 intermediaries.)
This article introduces some of the changes in IPv6 and suggests practical
tips for adding IPv6 networking to devices based on small microcontrollers like
the 8051. Basic network literacy and a reasonable level of experience with IPv4
important aspect of the IPv6 auto-configure capability is the way addresses are
used. A 128-bit IPv6 address is typically divided into a 64-bit prefix (called
net bits, which define the subnet) and 64 host bits. The prefix,
which also shows the scope of an address, can be assigned by the network
provider and broadcast by routers, or it can be local to the site. Generally,
the first 48 of the net bits are assigned by the ISP; the other 16 are within
the site owner's discretion.
On an Ethernet, the 64 host bits can be derived from the device's unique
48-bit physical, also known as the media access control (MAC) address (see
sidebar on EUI-64 addresses). In other words, unlike IPv4 where the IP address
and the MAC address are distinct, each IPv6 node combines all addresses into one
and has a valid IP address as soon as it is plugged in. Again, unlike IPv4
(which requires help from a BOOTP/DHCP server), all IPv6 nodes can
self-configure, even in the absence of a server. To communicate globally, the
node must solicit or listen to the router broadcasts containing the prefix and
then combine the prefix with the EUI-64.
The 64-bit extended unique
identifier, or EUI-64, was defined in anticipation of the possible
overload of the unique 48-bit address space (EUI-48). Both EUI-48 and
EUI-64 define the first 24 bits as the Company_ID, which is administered
by the IEEE Registration Authority Committee (http://standards.ieee.org/regauth).
The organization owning the respective Company_ID assigns and administers
the remaining bits.
RFC 2373 describes how to insert a pair of 8-bit values (FF and FE)
after the third octet in the middle of the 48-bit MAC address to derive
For example, if 00-60-35 is the Company_ID and the 48-bit MAC address
of a node is 00-60-35-23-45-67, the EUI-64 host bits for this node will be
To generate an IPv6 address that specifies that node sufficiently for
the local network, the prefix FE80:0000:0000:0000 is inserted and,
following the rules of RFC 2373, bit 1 in the first octet of the EUI-64 is
IPv6 addresses are written in hexadecimal notation and in groups of 16 bits.
is an address of global scope. The same machine would have the "link local"
address FE80::0260:35FF:FE8D:6EE9, in which FE80::/64 is the prefix for
link-local addresses, (the number after the slash shows the length of the
prefix, in this case 64, and :: represents zeroes). The loopback host (127.0.0.1
in IPv4 parlance) is simply ::1. Site local addresses have a prefix of
FEC0::/10, but since there's no direct equivalent to site local addresses in
IPv4, those addresses are rarely used today.
Because long 128-bit hexadecimal addresses are difficult for humans to grasp,
they're normally hidden behind domain name system (DNS) names like
www.embedded.com. An IPv6-capable DNS server (for example, BIND9) is
necessary for serving IPv6 addresses. IPv6 address translation embodies no
fundamentally new concepts, so an IPv6 address entry in the DNS would be
created, for example, as:
IN AAAA 3FFE:AAAA:BBBB:CCCC:0260:35FF:FE8D:6EE9
instead of the similarly formatted IN A record used under IPv4. Use of DNS is
strongly encouraged, since IPv6 address prefixes are expected to change more
frequently than IPv4 addresses. Network renumbering is much easier with IPv6 and
can even be automated.
IPv6 includes both unicast and multicast addresses. In addition, it defines a
new anycast address destination. A packet addressed to an anycast IP is
delivered to the closest or best of several available hosts. Anycast helps to
balance loads through routing and is a considerable improvement over round-robin
DNS (used in IPv4), which doesn't take routing issues into consideration.
retains the higher-layer protocols UDP and TCP without change. However, the IP
packet header is modified to accommodate the larger addresses. The IP packet
header is also cleaned up and streamlined to be 64-bit aligned and, for the
benefit of routers, to always have a fixed length.
The IP header checksum is no longer used because UDP and TCP have checksums
that encompass parts of that header. Routers can route packets more quickly if
they don't have to first recalculate the header checksum on each packet. To
compensate for potential IP-packet header corruption, the higher layer checksum
is made mandatory in UDP. It was optional in IPv4 systems, though most hosts did
An interesting modification is the replacement of IPv4's Address Resolution
Protocol (ARP) with the new Neighbor Discovery Protocol (NDP), which is part of
the Internet Control Message Protocol version 6 (ICMPv6). Instead of
broadcasting address-resolution requests to all hosts, IPv6 maps multicast
groups and IPv6 addresses in a way that eliminates broadcasts and ensures that a
given node receives (almost) only the traffic that's of interest to it (see
sidebar on multicast groups).
A multicast address that's
computed as a function of the node address is called a solicited-node
multicast address. The full algorithm is defined in RFC 2373. In summary,
the solicited-node multicast address is formed by taking the low-order 24
bits of the address and appending those bits to the prefix
For example, the node address FE80::260:35FF:FE23:4567 computes to
The details of ICMPv6, multicasting, and NDP are beyond the scope of this
article. More information on those and other topics is available at http://www.ipv6.org/.
new world of embedded devices brings TCP/IP into the smallest appliances and
connects them to the network. While the vision of the network-enabled toaster
has rightfully died with the disappearance of certain startup companies, network
connectivity is a desirable feature for other everyday devices such as
electricity meters, personal video recorders, and answering machines.
There are several approaches to adding TCP/IP networking to embedded devices.
A common practice is to use an operating system, such as VxWorks, Windows CE, or
Linux, with a built-in TCP/IP protocol suite. If those solutions don't suit your
platform, you can add one of a large number of third-party TCP/IP
implementations to just about any real-time operating system.
high-powered hardware (processor and memory) is out of the question in your
system, IPv6 may seem difficult to achieve. Many embedded systems, for example,
have less than 64KB for code and 128KB for data, including all of the memory
available for the OS, TCP/IP stack with IPv6 support, and the actual application
Fortunately, the full implementation of all IPv6 features is not technically
necessary in several areas. These areas are spelled out in the InternetNode
document "Minimum Requirements of IPv6 for Low-Cost Network Appliances"
(available at www.taca.jp/docs). In
particular, many routing and security features are optional. For example,
security is often also available at the application level (especially if the
application has to support IPv4). IPv6 can be tunneled over existing IPv4
networks ("6over4," in the lingo), but this is another area where code can be
cut out of end nodes.
At Dallas Semiconductor, we modified an existing minimal IPv4 protocol suite
for compatibility with IPv6. We targeted an 8051-based DS80C400 8-bit
microcontroller with 64KB of ROM.1
When we started implementing IPv6 alongside IPv4, we were tempted to just
duplicate code, for example by creating a TCP6 module next to TCP4. This was
precluded, though, by our tight memory budget. Instead of creating a second set
of routines, we modified existing high-level protocol implementations (TCP, UDP,
and so on) to work with both IPv4 and IPv6.
The reality is that existing applications today support IPv4 and the vast
majority of new applications will still run under IPv4, not IPv6. To justify the
support of IPv6 on the application side, the network stack has to make it as
painless as possible to add IPv6 support to an application. For example, an
implementation that has a socket() function for IPv4 and a separate
socket6() for IPv6 will probably not be well received by the developers.
Keeping the high-level protocol implementations and API the same for both
versions will make it easier for the application programmer to adapt to the
We quickly found that a number of optimizations were necessary to squeeze
IPv6 into our small ROM. In addition to setting obvious limits like the maximum
supported packet size, an idea that saved us a lot of grief was to always use
128-bit wide addresses, even with IPv4. Since the ::0/96 prefix (12 bytes of
leading zeroes) is not currently used by IPv6 with the exception of the
localhost ::1, we declared all addresses starting with ::0/96 to be IPv4
addresses and put the actual IPv4 address into the remaining 32 bits. This
eliminated a large number of if-then-else constructs, made address protocol
flags unnecessary, and greatly simplified parameter passing. True, there's no
IPv6 localhost anymore, but the IPv4 localhost (127.0.0.1) still works and, when
talking to oneself, one really doesn't care too much about the underlying