Practical Networking for Linux Admins: IPv4 and IPv6 LAN Addressing

We’re cruising now. We know important basics about TCP/IP and IPv6. Today we’re learning about private and link-local addressing. Yes, I know, I promised routing. That comes next.

Private Address Spaces

IPv4 and IPv6 both have private address spaces. These are not meant to leave your private network, and you may use them without requesting assignments from an official authority, like your Internet service provider. Or, if you’re a bigwig, a direct allocation from a regional Internet registry.

IPv4 Private Addresses

You’re probably familiar with IPv4 private addressing, as we’ve all been using it since forever. There are four different private address spaces:

  • 10.0.0.0/8 (10.0.0.0 to 10.255.255.255), 16,777,216 addresses
  • 172.16.0.0/12 (172.16.0.0 to 172.31.255.255), 1,048,576 addresses
  • 192.168.0.0/16 (192.168.0.0 to 192.168.255.255), 65,536 addresses
  • 169.254.0.0/16 (169.254.0.0 to 169.254.255.255), 65,536 addresses

Let’s talk about the last one first, 169.254.0.0/16, because I find it annoying. I never warmed up to it because it just gets in my way. That is the link-local auto-configuration block, also called Avahi Zeroconf. Microsoft Windows and some Linux distributions use these, so even when you don’t assign an IP address to a network interface, or it does not receive one via DHCP, it will get a 169.254.0.0/16 address. What’s the point? Supposedly easy ad hoc networking, and enabling communication with a host when other means of address assignment fail. Link-local addresses are accessible only within their own broadcast domains and are not routable. I’ve been disabling it since forever without missing it. If you find it useful, perhaps you could share a comment on how you use it.

The other three address spaces are routable, even outside your LAN. That is why most firewall tutorials include rules to stop these from leaving your network. Most ISPs block them as well.

The four hexadecimal octets in IPv4 addresses are conversions from binary. This is a fun topic for another day; you might investigate it because IPv4 addressing makes more sense in binary. For everyday use, this is what you need to know:

Each octet is 8 bits, and the total is 32 bits.

10.0.0.0/8 means the subnet mask is 8 bits, 255.0.0.0. You cannot change the first octet, 10, which is the network ID. The remaining three octets are the host ID, 24 bits, and you can change them however you like. Each octet has possible values ranging from 0-255. 10.0.0.0 and 10.255.255.255 are reserved and you cannot use them for host addresses, so your usable addresses are 10.0.0.1 to 10.255.255.254.

172.16.0.0/12 has a 12-bit subnet mask, 255.240.0.0, which does not divide up neatly into hexadecimal octets. 172.16.0.0 and 172.31.255.255 are reserved and you cannot use them, so your usable addresses are 172.16.0.1 to 172.31.255.254.

192.168.0.0/16 has a 16-bit subnet mask, 255.255.0.0. Again, the first and last addresses are reserved, so your usable addresses are 192.168.0.1 to 192.168.255.254.

So, you ask, just what are the first and last addresses reserved for? The first address identifies your subnets, for example 192.168.1.0. The last address is the broadcast address. Suppose your subnet is 192.168.1.0/24, then 192.168.1.255 is the broadcast address. These broadcasts go to every host on the network segment, hence the term “broadcast domain”. This is how DHCP and routing tables are advertised.

IPv6 Private Addresses

IPv6 private link-local addresses, for whatever reason, are not pebbles in my shoes the way IPv4 link-local addresses are. Maybe because they’re so alien they bounce off my brain. And I have no choice, as the IPv6 protocol requires these. You can view yours with either the ip or ifconfig command:

$ ifconfig ifconfig wlan0 wlan0 Link encap:Ethernet HWaddr 9c:ef:d5:fe:8f:20 inet addr:192.168.0.135 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::b07:5c7e:2e69:9d41/64 Scope:Link

These fall into the fe80::/10 range. You can ping your computer:

$ ping6 -I wlan0 fe80::b07:5c7e:2e69:9d41PING fe80::b07:5c7e:2e69:9d41(fe80::b07:5c7e:2e69:9d41) from fe80::b07:5c7e:2e69:9d41 wlan0: 56 data bytes64 bytes from fe80::b07:5c7e:2e69:9d41: icmp_seq=1 ttl=64 time=0.032 ms

With ping6, you must always specify your interface name, even if it is the only one. You can discover your LAN neighbors:

$ ping6 -c4 -I wlan0 ff02::1PING ff02::1(ff02::1) from fe80::b07:5c7e:2e69:9d41 wlan0: 56 data bytes64 bytes from fe80::b07:5c7e:2e69:9d41: icmp_seq=1 ttl=64 time=0.078 ms64 bytes from fe80::4066:50ff:fee7:3ac4: icmp_seq=1 ttl=64 time=20.7 ms (DUP!)64 bytes from fe80::9eef:d5ff:fefe:17c: icmp_seq=1 ttl=64 time=27.7 ms (DUP!)

Cool, I have two neighbors. ff02::1 is a special link-local multicast address for discovering all link-local hosts. man ping tells us that DUP! means “ping will report duplicate and damaged packets. Duplicate packets should never occur, and seem to be caused by inappropriate link-level retransmissions.” In this context, it’s nothing to worry about, so I ping my neighbors:

$ ping6 -c4 -I wlan0 fe80::4066:50ff:fee7:3ac464 bytes from fe80::4066:50ff:fee7:3ac4: icmp_seq=1 ttl=64 time=4.72 ms

How is it that we can ping our LAN neighbors on their link-local addresses, when we couldn’t ping the 2001:0DB8::/32 addresses we created in last week’s installment? Because the routing is automatic. You won’t see IPv6 routes with the good ol’ route command, but must use the ip command:

$ ip -6 route showfe80::/64 dev wlan0 proto kernel metric 256 pref medium

Pretty slick. Come back next week, and we will really do some routing.

Learn more about Linux through the free “Introduction to Linux” course from The Linux Foundation and edX.


Leave a Reply