What is the single biggest way that IPv6 may bite you as an application developer? Sure, if you are dealing with network applications like, say, Wireshark, you’re going to be hit by changes down at the socket level. But for the vast majority of applications, which simply need to interact with other applications at a network layer, what is the biggest change?
The user interface!
“Huh?” you might be asking yourself…but think about it. How many times have you looked at an application’s “Preferences” or “Options” window and seen a screen like this:
How well will that work with an IPv6 address?
In fact, as I was first writing this book, I happened to notice that the game Minecraft had a new release. One of the many changes was related to the format of the IPv6 address being entered into the app:
* Fixed IPv6 addresses being parsed wrongly. To connect to a specific port in IPv6, use the format [1234:567::1]:25565
These are just two of the many little ways that IPv6 will mess with your mind and with your app. You’ll need to think about and investigate how you present IP addresses for display and how you accept IP addresses for input. This may, surprisingly, be the area that will cause you the most pain and require the most testing. Ideally, we will move away from using IP addresses and toward using DNS domain names, but in some cases, you may still need to accept or display IP addresses. In this chapter, you’ll look at the issues you need to consider.
The single biggest user-visible change with IPv6 is the move away from the IPv4 “dotted decimal” fixed format of four address blocks, to the IPv6 colon-separated format of varying size. Now instead of an IPv4 address such as:
you may have a much longer address, such as:
This change raises a number of questions about how you display (output) IP addresses and how you accept (input) IP addresses. Some questions to consider are:
Are display areas in your application wide enough to accommodate the larger IPv6 addresses? For example, if you have an “IP Address” field in a Preferences window or a pop-up dialog box, will an IPv6 address extend beyond the display area and be cut off or interfere with the design of the window?
Are your current input fields composed of four boxes for an IPv4 address? Do you need to change them to, for instance, a large text box to accommodate the IPv6 address?
You need to go through your application and look at every instance where you either display or accept IP addresses and determine whether an IPv6 address would work correctly there.
You also need to consider whether you are going to have two separate input/output fields for IPv4 and IPv6 addresses. Will you simply have a “IP address” field where a user can enter either an IPv4 or IPv6 address? Or will you have different entry fields with another control (such as a radio button) allowing the user to select which address will be entered?
The second biggest change is the variability in IP address length. With IPv4, addresses have a fixed format of four blocks of decimal numbers. However, in IPv6, the address can vary from the full eight blocks of hexadecimal numbers separated by colons—or blocks with zeros can be compressed with the double-colon (“::”) notation, resulting in a much shorter address. Consider that any of these are perfectly valid IPv6 addresses:
Can your application cope with the variability of the address format?
Now instead of thinking about an IP address as a simple case of four decimal numbers separated by dots, you have to think of it more as a text string to be parsed with separations based on a colon.
Consider these other examples:
In IPv4, the local loopback address is
127.0.0.1. In IPv6 it is
IPv4-mapped IPv6 addresses take the form
Is your application able to handle the variations?
Further confusing the matter is the fact that in IPv4 you append the TCP or UDP port number to the IPv4 address using a colon. For example, if you wanted to connect to the web server running on port 8000 of a given system, you would use a URL similar to this:
Do you see the problem this is going to cause in IPv6?
If the colon is used as a delimiter within the IPv6 address, how do you represent port numbers? One solution is discussed in the next section, but this is a general concern you need to think about. Where in your application are you representing or allowing IPv4 addresses with accompanying port numbers? Can you find all of those instances and ensure that they will also work with IPv6?
The primary way to get around the port number colon issue is to use square brackets around the IPv6 address as specified in RFC 3986. Consider that with IPv4, if you want to connect to a service running on a system, it is very common to simply enter the IPv4 address directly in the URL. For instance, in a web browser, you might enter either of these IP addresses:
With IPv6, the URLs might then look like:
Note that in the second instance the port number is outside the square brackets, thus solving the port number colon issue.
This square bracket notation does not just apply to web URLs. It can also be used in the URIs of other protocols. For instance, URIs used with the Session Initiation Protocol (SIP) for Voice over IP might look like this:
Of course, ideally you are using domain names and only have to type addresses like these for testing purposes.
If your application uses URLs or URIs anywhere, can it parse the square brackets correctly? What will it do if someone enters a URL with an IPv6 address without the square brackets?
Be aware that some protocols may have yet another way of
representating IPv6 addresses. For instance, the Simple Mail Transport
Protocol (SMTP) uses a notation that includes "
inside the square brackets, as in:
[IPv6:2001:db8:10ff::ae:44f2] (see section 4.1.3 of
RFC 5321). If you will be dealing with literal IPv6 addresses,
you will want to check how they are represented in each of the protocols
your application is using.
Another change in IPv6 is the way in which you differentiate the network portion of the IP address from the host portion. With IPv4, if you were giving someone your IP address, you would typically give it to them like this:
IP address 198.51.100.22 with subnet
From an application point-of-view, you would typically have two separate fields to enter the IPv4 address and the corresponding subnet.
Now, some people in the IPv4 world would use
Classless Inter-Domain Routing (CIDR) notation as specified in RFC 4632. You may have
also heard this called slash notation or something
similar. The idea is that instead of providing a specific subnet mask, you
specify the number of bits that are significant for
the network portion of the address. In the example above, the subnet mask
indicates that the first 24 bits (the three blocks of 8 bits) of the
address represent the network portion and the remaining 8 bits represent
the host portion. This is written in CIDR notation as:
While this notation is certainly used with IPv4 in some areas, many application interfaces still look for a separate IP address and subnet mask.
With IPv6, however, this notation is mandatory. All addresses are written using the slash notation. An IPv6 address might be written as:
indicating that the first 48 bits (the first three blocks of the address) represent the network portion of the address.
Similarly, if you are given an IPv6 network block, it would typically be written as:
indicating that the first 64 bits (or four blocks of the address) represent the network portion.
You may also hear people talk about a network as a “/48” (and saying “a slash 48”) or a “/64” (“slash 64”), as in “You’ll need to get a /48 from your ISP if you are going to have multiple IPv6 subnets.”
From an application developer point-of-view, the main issues here are:
How do you display the IPv6 address and netmask? If you previously displayed two different fields in a dialog box or command output, you’ll need to merge that information for IPv6 addresses.
Similarly, how do you accept input for an IPv6 address and the corresponding netmask? Will you have two separate fields? Or will you have users enter it all in one “IP Address” field and parse out the netmask portion?
As your application handles all these different IPv6 address formats, one more subtle change from IPv4 that may impact your app is the fact that IPv6 addresses can be entered with the text in either uppercase or lowercase. Consider that both of these addresses are identical:
And of course someone manually entering an IPv6 address could wind up with some mixture of upper- and lowercase letters. Is your application sensitive to case in any way?
For example, if your app later compares an IPv6 address to past addresses, is the comparison function case-insensitive? Or would it treat the above two addresses as different addresses?
A best practice to avoid any case-sensitivity issues is to simply normalize all IPv6 addresses to lowercase when your application receives them as input. This follows the recommendation of RFC 5952 that all IPv6 addresses should be written in lowercase. It does, though, require another step in the processing of an input field that you didn’t have to do with the numeric addresses of IPv4.
Finally, when thinking about changes in the address format, you need to think about validity testing in any input forms. Typically you want to perform some form of validity testing on any kind of input forms to ensure that a proper IP address has been entered and to guard against security issues such as cross-site scripting, injection attacks, and the like.
With IPv4, this is relatively straightforward. An IPv4 address has a fixed format and uses only decimal numbers. As you’ve seen in this chapter, IPv6 addresses can have a variable format and use hexadecimal numbers. Validity testing can certainly be done—it is just a bit more involved.
You also need to go back to the question raised at the beginning of this chapter: are you going to have one generic entry field for an “IP address” that accepts both IPv4 and IPv6 addresses? If so, you are going to need to test for both kinds of IP addresses.
Similarly, if you have fields allowing the entry of a URL/URI, you need to consider whether you are checking for IPv6 addresses—with and without the square brackets.