IPv6 on a microcontroller

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 are assumed.

IPv6 overview
An 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.

EUI-64 addresses
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 the EUI-64.

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 00-60-35-FF-FE-23-45-67.

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 set: FE80:0000:0000:0000:0260:35FF:FE23:4567.

IPv6 addresses are written in hexadecimal notation and in groups of 16 bits. For example:


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 ( 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:


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.

Upper layers
IPv6 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 use it.

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).

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 FF02:0:0:0:0:1:FF00::/104.

For example, the node address FE80::260:35FF:FE23:4567 computes to FF02::1:FF23:4567.

The details of ICMPv6, multicasting, and NDP are beyond the scope of this article. More information on those and other topics is available at www.ipv6.org.

Embedding IPv6
The 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.

Micro IPv6
If 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 code.

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” (this document, along with others, is available at http://www.taca.jp/docs.html). 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 change.

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 ( still works and, when talking to oneself, one really doesn't care too much about the underlying protocol.

Table 1: The size of the TCP/IP code in the DS80C400 ROM
Module Code Size
IPv4 IPv6 Shared
ARP 1,111 x
DHCP 2,366 x
ICMP 1,949 x
IGMP 1,346 x
IP 2,487 x
ICMP6/Ping6 3,346 x
IP 6 6,999 x
NDP6 7,962 x
Ethernet Driver 2,677 x
TCP 10,494 x
TFTP 584 x
UDP 1,225 x
Total size: 42,546 9,259 18,307 14,980

Table 1 shows the code sizes for each module in the revised TCP/IP protocol suite. The code was written in 8051 assembler.

Ready, set, go
IPv6 is becoming more important. Support for this technology will be crucial for the success of many forthcoming connected embedded devices. In addition to fine-tuning the IP protocol, IPv6 provides auto-configuration, a virtually unlimited number of IP addresses, and some streamlining of the IP protocol and routing process.

The implementation of IPv6 in an embedded device can be tricky, and you do have to make compromises. The benefits, however, are well worth the effort, and it's by no means impossible—even on an 8-bit microcontroller with 64KB of ROM.

Robert Muchsel is a senior software engineer at Dallas Semiconductor. He holds a degree in computer science from the Swiss Federal Institute of Technology in Zurich and has been developing software for 12 years. His e-mail address is .

End notes
1. The IPv6 portion of the DS80C400 Silicon Software was developed in close collaboration with InternetNode, a joint venture of Yokogawa and Wide Research Institute.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.