If there is one subject that throws people for a loop in the world of networking, it's TCP/IP addressing. There are many perfectly competent network administrators who understand the basics, but are a bit fuzzy on the details. So let's take a look under the hood and see what's going on. I am going to avoid discussing the workings of the protocol itself as well as the history behind it. Let's just focus on the bits.
In this article, I will be talking about converting from decimal numbers to binary, and back again. While this is a nice skill, it can help the learning process if you have an IP calculator open while reading. When addresses come up in the article, punch them into the calculator and look at the results. Rather than point you at a particular calculator, I would suggest you search for ‘IP calculator’ in your favorite search engine. Try out a few and see which you like.
The Binary Basics
A TCP/IP address is a 32 bit address. In other words, the address is composed of 32 ones and zeros. Hmmmmmmm…..32 bits, eh? Let's take a look at an example.
192.168.1.100
Where are the bits? They are there, but in most instances IP addresses are expressed in decimal format. We humans are better at remembering decimal numbers rather than long strings of ones and zeros. We are even better at remembering names, but let's leave a discussion of DNS for another day. Computers, of course, prefer binary math, working only with ones and zeros.
So how do we get from the decimal to binary? Look at the format of the address. There are 4 fields in the address. Each of the fields represents 8 bits, so we call them octets, just like the 8 sided shape, an octagon.
| 192 |
168 |
1 |
100 |
|
| 8 bits |
8 bits |
8 bits |
8 bits |
= 32 bits total |
| 1st Octet |
2nd Octet |
3rd Octet |
4th Octet |
|
Ok, so 192 is represented by 8 bits, and 168 is represented by 8 bits….how? Each bit has a different meaning for the computer. Let's draw out 8 fields for our bits, and their values.
| ____ |
__ |
__ |
__ |
__ |
__ |
__ |
__ |
| 128 |
64 |
32 |
16 |
8 |
4 |
2 |
1 |
If we add up all of these numbers, it adds up to 255. To create the number 192, we place a 1 above the numbers we need and place a 0 (zero) above those that we don't.
128 + 64 = 192, so it would look like this:
| __1__ |
_1_ |
_0_ |
_0_ |
_0_ |
_0_ |
_0_ |
_0_ |
| 128 |
64 |
32 |
16 |
8 |
4 |
2 |
1 |
So the binary number 1100000 will yield the decimal number 192.
If we do the same conversion for each of the fields in the address, we come up with this:
11000000.10101000.00000001.11001000
Here is the address and the associated binary number:
| 192 |
168 |
1 |
100 |
| 11000000 |
10101000 |
00000001 |
01100100 |
| 128 + 64 = 192 |
128 + 32 + 8 = 168 |
1 = 1 |
64 + 32 + 8 = 100 |
Now you may be asking yourself, why in the world does this matter? It is very important. Often when people are trying to learn TCP/IP they get tripped up by focusing on the decimal numbers. They look at the IP address and the subnet mask (we'll cover this later), and think, "There must be an addition or subtraction problem in there someplace...". There isn't. YOU MUST look at the binary to really understand what is going on.
Ok. So we have established that 192.168.1.100 looks like this in binary:
11000000.10101000.00000001.11001000
Subnets - Across the Great Divide:
Great, we have an address, but now we need to know what subnet we are on. Subnet? What a subnet?
Think of a subnet like a street name. I live at 1234 Maple Street. Now if a subnet is our street address, there must be other streets, right? Otherwise, this would be a pretty small town. In reality, are there plenty of offices with only one subnet? Sure. If you only have 20 workstations in your organization, you don't need multiple subnets. But as the number of workstations rises, we run into problems, both technical and administrative. Let's avoid the details of "Why?" for another place and time, but imagine you are a mailman with 4000 hourses to deliver mail to...better get good shoes. We need to divide things up.
So using the example above, let's take a look at our subnet address:
192.168.1.100
See it? No? Well it's there. In fact, the address above has two parts: our subnet address and our host address. The host address is the address assigned to our individual computer. So how do you know which part is our subnet address (NetworkID) and which part is our host address (Host ID)? The Subnet mask. By comparing our TCP/IP address with the subnet mask, we can figure out which portion is the Network ID and Host ID. This is where the binary really helps.
What would be a typical subnet mask that would be used with the address 192.168.1.100? 255.255.255.0 is very common. Let's look at our address and the subnet mask, written in binary. The grey portion on top is the address, the green portion on the bottom is the subnet mask.
| 192 |
168 |
1 |
100 |
| 11000000 |
10101000 |
00000001 |
01100100 |
| 11111111 |
11111111 |
11111111 |
00000000 |
| 255 |
255 |
255 |
0 |
So how do we figure this out? Look at the subnet mask, and compare it to the address above on a bit by bit basis. Any place there is a one in the subnet mask, that portion of the address becomes part of the Network ID. Any place there is a zero, that portion of the address becomes part of the Host ID. Let's look at the chart again:
| Network ID (subnet) |
Host ID |
| 192 |
168 |
1 |
100 |
| 11000000 |
10101000 |
00000001 |
01100100 |
| 11111111 |
11111111 |
11111111 |
00000000 |
| 255 |
255 |
255 |
0 |
The grey boxes are the Network ID or subnet: 192.168.1. By convention, we write the whole thing out and include some padding zeros on the end: 192.168.1.0 is our Network ID.
The white boxes are the Host ID: 100.
To compare this with our postal model, we are at house number 100 on 192.168.1.0 street.
So what is the subnet mask for? It tells us which portion of our address is the Network ID and which portion is the Host ID. In the example above, the first three octets represent the Network ID and the last octet represents the Host ID. Now in looking at it, you might have noticed that you don't really need the binary in our example above. You could just as easily say, "Anyplace there is a 255, that's the subnet, and if here is a zero, that's the host ID." Very good smarty pants, but what if it's not all 255s? That's right. What is we are not using the entire octet? If you are sitting there looking confused, then you are a perfectly normal human being. This is where it gets a bit thick...
Let's use a fresh example:
IP Address: 10.141.234.14
Subnet Mask: 255.255.240.0
| 10 |
141 |
234 |
14 |
| 255 |
255 |
240 |
0 |
So what is the Network ID and Host ID in this example?
Network ID = 10.141.224.0
Host ID = 10.14
Remember above when I was ranting about the importance of the binary? Here is where it really helps (again). Let's break this down to the bits.
| 10 |
141 |
234 |
14 |
| 00001010 |
10000011 |
1110 |
1010 |
00001110 |
| 11111111 |
11111111 |
1111 |
0000 |
00000000 |
| 255 |
255 |
240 |
0 |
Look at what happens in the third octet. The subnet mask only covers half of the octet, or 4 bits. Therefore, only the first 4 bits will be part of the Network ID, and the last 4 bits will be part of the Host ID. When we look at the number in decimal format we see the number 234. If you focus on this decimal number and try and figure it out, you will go crazy. Only the underlying bits can tell us what is really going on.
| 10 |
141 |
234 |
14 |
| 00001010 |
10000011 |
1110 = 224 |
1010 = 10 |
00001110 |
| 11111111 |
11111111 |
1111 |
0000 |
00000000 |
| 255 |
255 |
240 |
0 |
The grey areas are the Network ID, the green areas are the Host ID.
The Network ID is 10.141.224.0. We get 224 by looking at only the first 4 bits in the third octet: 1110. This includes 128+64+32 = 224.
The Host ID is 10.14. We get 10 by looking at only the last 4 bits in the third octet: 1010. This included 8+2 = 10.
Class vs. Classless: It's all in the numbers.
Now you may have noticed that the last example was much tougher than the first. In the first example, we used a "classful" subnet mask, 255.255.255.0. This means the subnet mask adheres to the address classes set out by an organization called the IANA. In the past, these were the folks that handled the IP address for the internet (today it is handled by ICANN).
Let's look at a rundown of what the address classes look like.
| Address Classes |
| IP Address Class |
Network ID Bits |
Host ID Bits |
Default Subnet Mask |
# of Addresses |
| Class A |
8 |
24 |
225.0.0.0 |
16,777,214 |
| Class B |
16 |
16 |
255.255.0.0 |
65,534 |
| Class C |
24 |
8 |
255.255.255.0 |
254 |
| Class D |
n/a |
n/a |
|
|
| Class E |
n/a |
n/a |
|
|
There is nothing filled in for Class D and Class E because they are not used day to day for addressing on our client machines. Class D is used for Multicasting, and Class E is reserved for experimental use. Both are beyond our discussion here.
So in the address classes above, the subnetting is much simpler because our subnet masks are always going to use an entire octet. None of the troublesome "splitting" the octet like we say earlier. So this is a good thing, right? Wrong. Look at the number of addresses in the chart above. If we were to only use classful addressing, we would have very limited choices in terms of the numbers of addresses we could assign to an organization. It is a huge jump between 16,777,214 addresses (Class A) and 65,534 addresses (Class B). Using non-classful addressing gives us the flexibility to give organizations just the number of addresses they need, without wasting addresses or forcing them to pay for addresses they don't want. Classful addressing is a thing of the past. Can you still get an entire Class C address if you want it? Sure, but today we give people just the number of addresses they need using CIDR, or Classless Inter-Domain Routing.
Wrap-up: An Example
Let's wrap things up by looking at an example where a subnet mask is selected based on the number of hosts needed. I am going to use a slightly different notation in this example called CIDR notation. This is simply a different way of writing your subnet mask. In the first example, we used the address 192.168.1.100. Using CIDR notation, we would write the address and subnet mask as 192.168.1.100/24. The 24 represents the 24 bits that go into making the subnet mask 255.255.255.0.
So anyway, I work for Freddies Filbert Emporium. And as it so happens, I need 3400 IP addresses to connect computers to the Internet (those must be some mighty fine filberts). I call my local ISP and they say fine, here is your addressing information:
Network ID: 141.168.160.0/20
Or, in binary:
Address 141.168.160.100
10001101.10101000.1010 0000.01100100
Netmask: 255.255.240.0 = 20
11111111.11111111.1111 0000.00000000
Now, why did they select this subnet mask? Well, we asked for 3400 addresses. By using the 20 bit subnet mask above, that gives us 4094 addresses. Now that's more than we asked for, but that's the best we can do given how the math works out. It's certainly better than our classful choide in the past, whichh was an entire Class B.
The calculation used to figure out that subnet mask starts by calculating how many bits are needed for host addresses. In the example above, we need 3400 addresses. So the equation would be this:
2x – 2 > 3400
The only variable to fill in is X, which is the number of bits that will be used for creating hosts. How do we figure out X? Guess! We know that 8 bits (a Class C) will provide for 254 addresses. We also know that 16 bits (a Class B) provides for 65,000+ addresses. So if you guess and pick a number right between them, 12, it works out perfectly (yes, I planned it that way).
212 – 2 = 4094
If we use 12 bits for the Host IDs, that must mean that there are 20 bits being used for the Network ID (remember, it's a 32 bit address total, 32-12 = 20). A 20 bit subnet mask comes out to be 255.255.240.0.
What if you had guessed a higher or lower number?
211 – 2 = 2046
213 – 2 = 8190
As you can see, the numbers roughly double with the addition of each bit, so it's pretty easy to zero in on a number. It also shows that there are still some limitations on how accurately we can assign addresses. Nevertheless, it's a drastic improvement over the past.
One last note about the examples above. Look at the equation we used. Why do we subtract 2 from the equation? It's because there are always going to be 2 unusable addresses in each subnet: the boradcast address and the Network ID.
For example:
192.168.100.0
255.255.255.0
We cannot use 192.168.100.0 as an address because that is the Network ID. If you look in the routing tables on the local router, you will see an entry that says 192.168.100.0. It would cause confusion if we also used this as an address on a workstation.
We also cannot use the address 192.168.100.255. This is the broadcast address. if I need to send a broadcast message to all the computers on the 192.168.100.0 subnet, I will send it to 192.168.100.255. Obviously this would not make a good workstation address.
I hope this article gave you a decent introduction to TCP/IP addressing. This article was about IP version 4. Of course, IP version 6 with 128 bit addressing is coming down the pipe soon, but that's an issue for another day.
Cheers,
Josh