Subnets and early Unix implementations of TCP/IP networking

August 19, 2017

If you've been involved in networking (well, Internet and IP networking at least), you've probably heard and used the term 'subnet' and 'subnets'. As a term, subnet has a logical and completely sensible definition, and certainly the direct meaning is probably part of why we wound up with the term. If you've been around networking a while, you've probably also heard of 'CIDR' notation for networks, for example 192.168.1.0/24, and you may know that CIDR stands for Classless Inter-Domain Routing. You may even have heard of 'class C' and 'class B' networks, and had people refer to /24 CIDRs and /16 CIDRs as 'class C' and 'class B' respectively.

Back in the early days of IP, the entire IP network address space was statically divided up into a number of chunks of different sizes, and these different sizes were called the class of the particular chunk or network. When I say 'statically divided', I mean that what sort of network you had was determined by what your IP address was. If your IP address was, say, 8.10.20.30, you were in a class A network and everything in 8.*.*.* was (theoretically) on the same network as your machine. You can read the full details and the history on Wikipedia.

At the very beginning of Unix's support for IP networking, in 4.2 BSD, this approach was fine (and anyway it was the standard for how IP address space was divided up, so it was just how you did IP networking at the time). There were Ethernet LANs using IP (RFC 826 on ARP dates from that time), but there weren't many machines on them regardless of what class the network was. As a result of this, 4.2 BSD had no concept of network masks for interfaces. Really, it's right there in the 4.2 BSD ifconfig manpage; in 4.2 BSD, network interfaces were configured purely by specifying the interface's IP address. If the IP address was in a class A network, or a class B network, or a class C one, that was what you got; the 4.2 BSD kernel directly hard-coded how to split an arbitrary IP address into the standard (classful) network and host portions.

(See in_netof and in_lnaof in the 4.2 BSD sys/netinet/in.c.)

Naturally, this didn't last very long. The universities, research organizations, and so on that started using 4.2 BSD were also the places that got large class A (/8) and class B (/16) networks in the early days of the ARPANET, and so pretty soon they had far too many hosts to have them all on a single 10 MBit/sec LAN (especially once they had hosts in several different buildings). As a result, Unix networking (ie BSD networking) gained the concept of a netmask and subnets. The 4.3 BSD ifconfig manpage describes it this way:

netmask mask
(Inet only) Specify how much of the address to reserve for subdividing networks into sub-networks. The mask includes the network part of the local address and the subnet part, which is taken from the host field of the address. [...]

The idea here was that your university might have a class B, but your department would have what we would now call a /24 from that class B. The normal class B netmask is 255.255.0.0, but on your machines you'd set the netmask as 255.255.255.0 so they'd know that addresses outside that were not on the local network and had to be sent through the router instead of ARP'd for.

However, the bad news is that the non-netmask version of 4.2 BSD IP networking did last long enough to get out into the field, both in real 4.2 BSD machines and in early versions of commercial Unixes like SunOS. Some of these early SunOS workstations and servers were bought by universities with class B networks that were starting to subnet them. This wound up causing the obvious fun problems, where some of your department's machines might not be able to talk to the rest of the university because they were grimly determined that they were on a class B network and so could reach every host in 128.100.*.* on the local LAN.

(They could reach hosts that weren't on 128.100.*.* just fine, at least if you configured the right gateway.)

It turns out that this history is visible in an interesting series of RFCs. RFC 917 from 1984 begins the conversation on subnets, then RFC 925 suggests extending ARP to work across multiple interconnected LANs. Subnets are formalized in RFC 950, "proxy ARP" appears in RFC 1009, and finally RFC 1027 describes how the authors used proxy ARP at the University of Texas at Austin to implement transparent subnet gateways, where hosts on your (sub)net don't have to be aware that they are on a subnet instead of the full class A or class B network that they think they're on. Transparent subnet gateways are also know as 'how you get your 4.2 BSD and SunOS 2.x hosts to talk to the rest of the university'.

(Since IP networking started out by talking about 'networks', not 'subnets', it seems highly likely that our current use of subnet' comes from this terminology invention and growth in the early to mid 1980s. I find it interesting that the 1986 4.3 BSD ifconfig manpage is still talking about 'sub-networks' instead of shortening it to 'subnets'.)

Written on 19 August 2017.
« How ZFS on Linux names disks in ZFS pools
The surprising longevity of Unix manpage formatting »

Page tools: View Source.
Search:
Login: Password:

Last modified: Sat Aug 19 01:31:32 2017
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.