You may have heard that computers represent
all numbers as "bits", or "zeros and ones." It would be more fair to say that computers
work primarily with groups of eight 0's or 1's, called bytes.
In practice, most desktop PC's work with clumps of four bytes at a time, or 32 bits.
That's why 80386 through Pentium IV processors are called 32-bit processors.
[Athough Pentium class processors have some 64-bit attributes such as a 64-bit
external memory bus,they still do most operations as 32-bit operations.]
Now, think back to first grade math, when the teacher was describing the decimal numbering
system. As it happens, it's called "decimal" (the root of the word is from Latin decima,
a tenth part or tithe) because it's a numbering system that uses ten
numbers: the numbers zero through nine. If you need to represent a number larger than nine,
you have to start adding additional digits; then the teacher described the ones place,
the tens place, the hundreds place, etc. For example,
the number 45678 has a four in the "ten thousands" place, a five in the "thousands" place,
a six in the "hundreds" place, a seven in the "tens" place, and a 8 in the "ones" place:
Ten Thousands
Thousands
Hundreds
Tens
Ones
4
5
6
7
8
Since computers work in binary, and only have "0" and "1" to work with, they have to start
new digits ("binary places", not "decimal places") as soon as they get past the
number one! In decimal, the "decimal places" were all powers of ten:
10^{0}=1,
10^{1}=10,
10^{2}=100,
10^{3}=1000, etc.
In binary, the "binary places" follow powers of two:
2^{0}=1 (1 binary),
2^{1}=2 (10 binary),
2^{2}=4 (100 binary),
2^{3}=8 (1000 binary),
2^{4}=16 (10000 binary),
2^{5}=32 (100000 binary),
2^{6}=64 (1000000 binary),
2^{7}=128 (10000000 binary),
2^{8}=256 (100000000 binary), etc.
The number 45678 is represented in binary as follows:
(Binary Places, expressed as Decimal:)
32768
16384
8192
4096
2048
1024
512
256
128
64
32
16
8
4
2
1
1
0
1
1
0
0
1
0
0
1
1
0
1
1
1
0
(Add up the columns where you find ones: 32768 plus 8192 plus 4096 plus 512 plus 64 plus 32 plus 8 plus 4 plus 2 equals 45678!)
Counting to Forty:
Decimal
Binary
Decimal
Binary
Decimal
Binary
Decimal
Binary
1
1
11
1011
21
10101
31
11111
2
10
12
1100
22
10110
32
100000
3
11
13
1101
23
10111
33
100001
4
100
14
1110
24
11000
34
100010
5
101
15
1111
25
11001
35
100011
6
110
16
10000
26
11010
36
100100
7
111
17
10001
27
11011
37
100101
8
1000
18
10010
28
11100
38
100110
9
1001
19
10011
29
11101
39
100111
10
1010
20
10100
30
11110
40
101000
Now, an IP Address is four bytes, eight bits each, represented as decimal numbers with
periods in between; for example, 10.5.72.230. This number can be represented in binary
(remember when I said that IP Addresses are best expresses as 32-bit binary numbers?
I did mention that, didn't I?) as b00001010.00000101.01001000.11100110.
(The "b" means "binary"; that and the periods are added for your convenience.)
Now, 2^{32} (two to the thirty-second power) is 4294967296, or just over four
billion. So, theoretically, there are over four billion IP addresses available to the world;
so why is there a shortage? (Oh yeah, have you heard? There's a shortage. Last I checked,
they're projecting to run out of IP addresses around the year 2025.)
Well, as it turns out, trying to keep track of where four billion individual hosts are
would be pretty much impossible for equipment today, and certainly impossible for equipment
many years ago when TCP/IP routing was being developed. So, routing was (over)simplified by splitting
the IP address space into "classes"; those IP addresses whose first byte was in the
range 1-126 would belong to networks of 16,777,214 (2^{24}-2) hosts; these were called
"Class A" networks, and there are 127 of them. In Class A networks, the first eight bits
are the "network portion", and the last 24 bits are the "host portion." Those IP addresses
whose first byte was in the range 128-191 were called "Class B" networks of 65,534
(2^{16}-2) hosts, and there were 16,384 (that's (192-128)*256) of them. That's 16 bits
for the network portion, and 16 bits for the host portion. "Class C" networks, where the first
byte is in the range 192-223, have a 24 bit network portion, and an 8 bit host portion.
Note how neatly everything lines up on byte boundaries:
Class
Network bits
Network Mask
Network Mask (binary)
A
8
255.0.0.0
b11111111.00000000.00000000.00000000
B
16
255.255.0.0
b11111111.11111111.00000000.00000000
C
24
255.255.255.0
b11111111.11111111.11111111.00000000
Now, since it's unlikely that a network administratior is going to want to have some
16,777,214 (nearly seventeen million) hosts on the same network segment(!), network administators
were allowed to administratively split up their networks by subnetting them. Routing on
the Internet backbones was fairly simple... until they started to hit the Class C networks
hard. If your company needed 1,000 IP addresses, you'd probably get four Class C networks to
accomodate them... but that would add four individual routes propagated to every "backbone" router
on the Internet! Hence the need to split up networks on other than just byte boundaries.
This is where everything got hard.
It turns out that you can combine four "Class C" networks together into one routing table entry
by using a subnet mask (aka Network Prefix) of 255.255.252.0. But not just any four;
as it happens, they must be contiguous, and the third byte of the first network must
be a multiple of four (like the number 204 is.) If you want to join eight of them
together, the first network must be a multiple of eight (which the number 204 is not.)
If you want to join ten networks together... well, you can't. Ten is not a power
of two. Funny how everything follows powers of two...
B. Boolean Logic and The Binary "AND"
Named after the nineteenth-century mathematician George Boole, Boolean logic is a form of
algebra in which all values are reduced to either TRUE (1) or FALSE (0). All math performed
by modern computers is done using Boolean algebra. A few basic operations:
Operation
Result
Examples
AND
true if A AND B are true
1 AND 1 = 1
1 AND 0 = 0
0 AND 1 = 0
0 AND 0 = 0
OR
true if A OR B are true
1 OR 1 = 1
1 OR 0 = 1
0 OR 1 = 1
0 OR 0 = 0
XOR (eXclusive Or)
true if either A or B are true
1 XOR 1 = 0
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 0 = 0
NOT
opposite of A
NOT 1 = 0
NOT 0 = 1
The binary "and" operation is often used when you want to see only certain bits of a given byte--
a procedure called "masking." Some of you may have seen a similar thing in school; some of my
teachers used to conduct multiple-choice tests where you would fill in a circle cooresponding to
the answer you thought was correct. The teacher would then take an overlay, or mask, and place it over the
answer sheet. This overlay had holes only where the marking spots for the correct answers were,
and the teacher would mark any answers where he/she didn't see a mark, as incorrect. The subnet mask
is used in this fashion by the computer to determine which address bits are in the network portion of an IP
address, and which bits are used for the host, or workstation, portion.
C. The Subnet "Mask"
The subnet mask is used to figure out what network you're on. The reason it's called a "mask"
is the same reason the tape you use to cover trim when painting is called "masking tape"; you
use it to cover up the parts you don't want to deal with right now. Did you notice how, in
a binary AND, any time B is zero, the result is zero? And any time B is one, the result is
whatever A is? Hmmm.....
The primary use of the subnet mask (from our perspective at the Near Side of the 'Net) is for
workstations to determine whether or not the server or workstation they're trying to talk to
(the "destination IP address") is on the same subnet as itself; if the destination IP address
is on your subnet, you'll send the IP packet directly to the other computer via the Ethernet or
Token Ring (or whatever) network you're on, without bothering the router... at all!
The first routing decision made on an IP packet is made by the workstation sending it;
it decides whether or not to send the packet to a router. Doing this is a four step process:
Step 1: Convert the IP Addresses to Binary.
If necessary, the IP address is converted from the familiar dotted-decimal into a 32-bit
binary value. It sucks as much for the computer to do it as it does for humans to do it,
but computers generally complain less, and they're good at math :-)
Step 2: Apply Source subnet mask to Source addresses:
The network portion of the workstation's IP address is determined by performing
a binary AND operation on the workstation's IP address and its subnet mask. This operation "masks
off" all of the bits of the "host portion" of the IP address, and leaves the "network portion"
behind for comparison with the destination's network portion. Hey, wait a minute? How do we
know what the subnet mask of the destination is?
Step 3: Apply Source subnet mask to Destination addresses:
As it happens, we don't care what the subnet mask of the destination is. We only care if the
destination is on our same network segment! Since every workstation on our network segment
shares the same subnet mask, we can apply our subnet mask to the destination to determine if
its network portion matches ours. So, the network portion of the destination
workstation's IP address that we can use to see if it matches ours is determined by performing
a binary AND operation on the destination IP address and our subnet mask.
Step 4: Compare the derived network portions for equality:
At this point, we can compare the network portions we have masked from the source and destination
IP addresses to see if they're the same. If they are, then we must be on the same subnet
so we send the packet directly; if they are different, even by only one bit, the destination is
on another network segment...somewhere. We don't know where. Maybe the router does...
OK, so let's try this a few times ourselves; get a few IP addresses and subnet masks together
and plug 'em into Daryl's Subnet Calculator! (The next section of the Primer.) Requires JavaScript to be
enabled on your browser. If you're reading a hard copy of this, the full URL is
http://ipprimer.windsorcs.com/subnet.cfm .
Remember the part about combining four "Class C" networks together? Watch your binary arithmetic:
(network prefix bits shown in green)
Networks
Networks, in Binary
192.168.8.0
b11000000.10101000.00001000.00000000
192.168.9.0
b11000000.10101000.00001001.00000000
192.168.10.0
b11000000.10101000.00001010.00000000
192.168.11.0
b11000000.10101000.00001011.00000000
Mask, 255.255.252.0
b11111111.11111111.11111100.00000000
Notice how all of the bits above the ones in the subnet mask stay the same; following the rules
above, all hosts on these networks, if you apply the mask, are on the same network.
This was called "supernetting", but now is called "CIDR Routing", pronounced "Cider Routing".
Doing it wrong:
(carefully watch the network-portion bit in red)
Networks
Networks, in Binary
192.168.10.0
b11000000.10101000.00001010.00000000
192.168.11.0
b11000000.10101000.00001011.00000000
192.168.12.0
b11000000.10101000.00001100.00000000
192.168.13.0
b11000000.10101000.00001101.00000000
Mask, 255.255.252.0
b11111111.11111111.11111100.00000000
Oops-- seems the sixth bit of the third byte changed within the
network prefix portion (the part above the 1's in the subnet mask), so with the given subnet mask
(22 bits, or 255.255.252.0), 10.0 and 11.0 would ALWAYS be on a different network aggregation
than networks 12.0 and 13.0. Confused? Play with it in the
Subnet Calculator, and compare the network portions.
D. "Slash" Notation
Subnet masks are often abbreviated using a forward slash "/" and the number of "one" bits in the mask.
For example, a network 192.168.1.0 with a subnet mask of 255.255.255.0 can be expressed as
192.168.1.0/24 (since 255.255.255.0 is 24 binary ones followed by eight binary zeros.) Therefore, a /25 subnet
is a subnet with a mask of 255.255.255.128, and a /26 subnet has a mask of 255.255.255.192, etc.
E. A Neat Trick
Now that you actually understand the binary arithmetic behind subnet masking (well, I hope you do,
anyway) we can cover some of the neat tricks for computing subnet masks. To determine the number of
hosts on a given subnet (assuming the subnet is smaller than class "C",) simply subtract the last number
of the subnet mask from 256. For example, a subnet mask of 255.255.255.224 has 32 hosts (256-224=32.)
Then you can just divide the result into 256 to determine the number of subnets (256/32=8.) So, using
a subnet mask of 255.255.255.224 gives you 8 subnets of 32 hosts each. Of course, this only works when
you are subtracting a number that is a power of two (1, 2, 4, 8, 16, 32, 64, or 128.) When the network
prefix is larger than class "C", you can determine how many class "C" networks are aggregated by
subtracting the third byte from 256-- so a network prefix of 255.255.240.0 is an aggregation of
(256-240) 16 class "C" networks. Thanks to Gael M. for this tip.
F. In closing...
Why all this crap about binary arithmetic? Do I have to know this stuff? I'm afraid so;
subnet masks are created and used on a bit-by-bit basis; in order to effectively use subnet
masks that don't fall on byte boundaries (like 255.255.255.0 does), you have to determine what
hosts are on each subnet by using binary arithmetic. It sucks, it's hard, it's confusing
(espically since IP addresses and masks are expressed in decimal instead of hexadecimal notation)
but you must use and understand IP addresses and subnet masks as binary.