1. Overview

In this tutorial, we’ll look at ways to view an IPv6 network address from the Linux terminal.

First, we’ll look at command options to retrieve the network addresses. Next, we’ll see examples of how to format the address information in our queries to focus on specifics. After that, we’ll understand different formatting options for the output. Finally, we’ll query the Linux filesystem directly to obtain the address and use different methods to extract the information.

The commands in this article have been tested on SUSE 15 and Debian 11.6, using GNU Bash version 4.4.23. All code snippets should work in most Linux environments.

2. The ip Command

Linux provides the ip command to show and manipulate networking devices’ information. Running ip without arguments displays the command’s usage information:

$ ip
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { address | addrlabel | fou | help | ila | l2tp | link |
                   macsec | maddress | monitor | mptcp | mroute | mrule |
                   neighbor | neighbour | netconf | netns | nexthop | ntable |
                   ntbl | route | rule | sr | tap | tcpmetrics |
                   token | tunnel | tuntap | vrf | xfrm }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec | -j[son] | -p[retty] |
                    -f[amily] { inet | inet6 | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -M | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |

The output lists the parts of the networking configuration available to query. Since we want to focus on the IP addresses, we’ll pass address as the object parameter in our queries. Then, for the options, we have a couple of parameters that we’ll use to restrict the output to only the IPv6 protocol.

3. Viewing Address Information

Many networking devices commonly support dual-stacking, a method that allows both IPv4 and IPv6 addresses to be assigned to an interface.

To view IPv6 alone, we can specify the option -f[amily] inet6. Many of the objects and options in the ip command have long, short, and shorter versions, so both -6 and -f[amily] inet6 have the same function. Similarly, using any of the conventions a, addr, or address will work the same when specifying an address as the object to return.

Now, let’s query IPv6 address information using the short form -6:

$ ip -6 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UP qlen 1000
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 state UP qlen 1000
    inet6 2001:bb6:434c:4d00:6045:6de9:33d0:f385/64 scope global dynamic noprefixroute 
       valid_lft 3593sec preferred_lft 3593sec 
    inet6 fe80::364e:a016:c75b:cd4d/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

By default, this command returns the address along with information on the network interface settings and configuration. Found interfaces are returned in a numbered list. Our example found two interfaces, lo (loopback) and enp0s3. Here’s a brief overview of the information contained in the output:

  • name of the interface (loenp0s3), followed by the links’ addressing method, operational state, mtu (maximum transmission unit) size, and the transmission queue length (qlen)
  • the next lines show the IP address or addresses and their operational area
  • each of these lines is then followed by lifetime (*lft) information, i.e., how long the address is considered valid

In the following examples, we’ll see how to extract the address.

4. Shortening the Query Output

To focus the results on just the address and link state, we can shorten the output with the -brief (-br) option:

$ ip -brief -6 address 
lo               UNKNOWN        ::1/128 
enp0s3 UP 2001:bb6:434c:4d00:6045:6de9:33d0:f385/64 fe80::364e:a016:c75b:cd4d/64

This combination of parameters lists the links’ names first, followed by the operational state and address or addresses. In this example, the loopback operational state is reported as UNKNOWN, which indicates that the link is up but nothing is connected. Other possibilities are UP or DOWN.

Now, let’s have a look at the addresses that our query found. The first address listed, for lo, is the loopback address which will always be in the compressed format ::1. The second interface, enp0s3 in this example, has two addresses. Of these, the first is the globally routable address, starting with 2001. Following that is the link-local address that’s automatically part of the interface at boot time. In fact, these types of addresses refer to the physical link and have the prefix FE80.

5. Limiting the Query Scope

Sometimes, we may want to only view global IP addresses. So, to exclude the loopback address, we have a few options.

Firstly, we can pass the show dev argument, specifying the interface name:

$ ip -6 address show dev enp0s3
2: enp0s3: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet6 2001:bb6:434c:4d00:6045:6de9:33d0:f385/64 scope global dynamic noprefixroute
      valid_lft 3561sec preferred_lft 3561sec
    inet6 fe80::364e:a016:c75b:cd4d/64 scope link noprefixroute
      valid_lft forever preferred_lft forever

Alternatively, we can use the scope parameter to query the area of the address. In fact, there are three areas:

  • global – access the Internet
  • link – link-local address
  • host – loopback

In these examples, we’re changing the show action from dev to scope followed by the scope area:

$ ip -6 -brief address show scope global
enp0s3             UP             2001:bb6:434c:4d00:6045:6de9:33d0:f385/64
$ ip -6 -brief address show scope link
enp0s3             UP             fe80::364e:a016:c75b:cd4d/64 
$ ip -6 -brief address show scope host
lo               UNKNOWN        ::1/128

This combination of parameters limited our queries to the area specified by scope and showed one line with the link name, the link’s operational state, and its address.

6. Customizing ip Output Format

Earlier, when we ran the ip command without any parameters, the usage information showed options for formatting the command output in various ways.

For example, to print in JSON, we can specify -json or -j:

$ ip -6 -json -brief address show dev enp0s3

Additionally, we can add the -pretty option to include indentation in our JSON output:

$ ip -6 -json -pretty address show dev enp0s3
[ {
        "ifname": "enp0s3",
        "operstate": "UP",
        "addr_info": [ {
                "local": "2001:bb6:434c:4d00:6045:6de9:33d0:f385",
                "prefixlen": 64
            } ]
    } ]

There’s also the -oneline parameter, which can be useful when piping the output to other commands:

$ ip -6 -brief -oneline address show dev enp0s3
enp0s3             UP             2001:bb6:434c:4d00:6045:6de9:33d0:f385/64

These options and their combinations provide flexibility for formatting address information output.

7. Querying IPv6 Network Files

IPv6 addresses are 128 bits long and use different convention styles to represent and abbreviate the address in text. If we want to view the address without any of this syntax, we can cat the if_inet6 file directly from the proc pseudo-filesystem. This will show all IPv6 addresses on a system without any colons:

$ cat /proc/net/if_inet6
fe80000000000000364ea016c75bcd4d 02 40 20 80 enp0s3
20010bb6434c4d0060456de933d0f385 02 40 00 00 enp0s3
00000000000000000000000000000001 01 80 10 80 lo

Another option is to use grep to query for a single interface:

$ grep enp0s3 /proc/net/if_inet6
fe80000000000000364ea016c75bcd4d 02 40 20 80 enp0s3
20010bb6434c4d0060456de933d0f385 02 40 00 00 enp0s3

Now, let’s use awk to check a single global interface address and print the output with the interface information removed. An example use of this would be to obtain the address and use it as input to another command in a script:

$ $ awk '/2001/ {print $1}' /proc/net/if_inet6

As we see above, this type of output may be useful in situations where we want to view the full address including the leading zeroes.

8. Conclusion

In this article, we learned how to obtain IPv6 addresses from the command line.

We started with a discussion on what information is returned by the ip command, then we saw examples of how to refine our queries to return only IPv6 addresses. Further, we looked at the options to focus our queries on a single interface or all. Next, we understood how to query the addresses based on their scope. We also saw how to change the output to a JSON format or a single line.

Finally, we queried the filesystem files directly for IP addresses and looked at a couple of examples of how to extract the addresses from these.