There are a few fundamental ideas about TCP/IP networks that people seem to get confused about. This article might help.

First, let's pretend that you are setting up a few machines, but they will not be connected to the Internet. They are all yours, under your control. In this situation, you can use any IP addresses you want; the addresses just have to meet certain rules:

IP addresses look like this:

10.1.1.80
192.168.6.200
172.16.21.7

Each of the numbers between the dots must be between 1 and 254 (except sometimes some of the numbers can be zero's, but for now we won't use those). For reasons we'll go into later, a good choice would be to use some number beginning with 10, but you can choose something else if you insist. The very worst choice you could make would be 127 (for the very first number only; it's OK elsewhere), so stay away from that one for now (it's special).

You'll also need a "subnet mask". Your choice for that depends on how many machines will be on this network. Your choices would be:

Machines               Mask
up to 254              255.255.255.0
up to 64,516           255.255.0.0
up to 16,387,064       255.0.0.0

It is possible that you may have been assigned a number or range of numbers and a mask by someone else. If so, just go with the flow for now and pretend that isn't true. If it is true, the number(s) you have may be a little strange because they are "supernetted", or assigned out of a specific block of numbers. This will be covered in another article (November 1998, I hope), but for now just accept that you have something different and this "basics" article doesn't cover that.

If you don't have an assigned number, then you should use one in the following ranges:

*       10.0.0.1 throuugh 10.254.254.254

*       172.16.0.1 through 172.31.254.254

*       192.168.0.1 through 192.168.254.254

Nowadays, those ranges would usually be referred to with their CIDR notation:

*       10.0.0.0/8

*       172.16.0.0/12

*       192.168.0.0/16

Every machine needs a unique number. So, if I were setting up the very first machine, I might assign it 10.1.1.30, and then the next 10.1.1.31, and so on. What I can't do is decide that machine number 4 will be 11.1.1.34. instead of 10.1.1.34 And, if I used the subnet mask of 255.255.255.0, I can't assign the next machine 10.1.4.30 either.

The reason for that has to do with that mysterious subnet mask, and this is where it gets confusing. Really, it's simple: it's just one of those silly things that seem confusing at first.

Think of the "255"'s as markers that determine how many of the numbers in your network addresses cannot be changed (that is, if they were changed, the address would be on a different subnet). If your network mask is 255.255.255.0 and you started numbering machines as 10.1.1.30 , then you cannot change the 10.1.1 part in any address. So all of these numbers are good:

10.1.1.98
10.1.1.15
10.1.1.223

but all of these are "bad" (that is, they are on a different subnet):

10.1.2.98
10.3.1.15
172.16.1.223

Why does it matter if they are on a different subnet? Because you can't talk (telnet, ftp, ping) to machines on a different subnet without a route. There are good reasons why you might actually want this (such as having too many machines for one subnet, or for security, or for performance reasons), but we'll talk about those in another article.

If you had used 255.255.0.0 as your mask, then only the 10.1 part would be frozen, and you could use:

10.1.32.98
10.1.15.15
10.1.223.223

but not:

10.2.32.98
172.16.15.15
192.168.223.223

Remember the 10.1.1.30 was just one choice we could have made. Instead we might have chosen 172.16.35.40 as the address for our first machine. If our mask again were 255.255.255.0 , then the 172.16.35 would be the "fixed" part of our addresses.

Why would you choose one network mask over another? Good question. If you think about it, one answer might be because your choice affects how many hosts (machines) you can have in the one subnet. If the mask is 255.255.255.0, then the first three octets (geek talk for the first three numbers; "octet" because they are 8 bit numbers) are fixed; you can't change them without changing the subnet. That would leave only 0 to 255 for hosts, and you can't (I haven't told you why yet, so just accept it for now) use 0 or 255 here, so that's only 253 machines, which might not be enough even if you aren't General Motors Corp. So you might need to use 255.255.0.0 to get more hosts.

That "fixed" part is actually the "network" address. I said earlier that you can't change any of those fixed numbers. If you do, you are creating another network, and if machines on one network (say 10.1.1) need to talk to machines having a different network address (all beginning with 172.16.76, for example), they need to do so through a "router", which can be a machine with two (or more) network cards in it, or a specialized piece of equipment. Whatever it is, the router will always have addresses on every network it is connected to.

So, a router might have 10.1.1.1 on one port, and 192.168.15.1 on another. Visualize a bunch of machines to the left of this box all having addresses beginning with 10.1.1, and another bunch of machines to the right of it all with addresses beginning 192.168.15.

If a machine on the left wants to talk to a machine on the right, it cannot unless it has a route to that other machine. In many cases, those are the only other machines that the machine on the left can talk to, so the route becomes the default route.

In every case, when setting a route, the route must be to a machine on the same network (with the same "fixed" numbers) as the machine you are setting it on. So, if you are setting a route on machine 10.1.1.40, the address on the router must be the 10.1.1 address. It cannot be the 192.168.15 address or any other address on the router. This is because ordinary machines (machines that are not routers) can ONLY talk to machines on their very own network. So, if you were working on machine 10.1.30 in this imaginary network, and you wanted to set a route to the 192.168.15 network, you might say:

route add 192.168.15.0 10.1.1.1

or even:

route add default 10.1.1.1

What you'd be saying in the second case is "send anything that isn't on my network to 10.1.1.1, and (I hope) that machine will get it to where it needs to go".

To make that route permanent, you need to do more.  For NT, a /P adds the route to the registry. Linux has a slightly different format for the command; you need a "gw" keyword after default, and to make it permanent you'd usually use "linuxconf".

 

Advanced TCP/IP

I mentioned earlier that certain network numbers are "special", and that they would be bad choices. You may also realize (or need to know) that if the machines you are assigning numbers to are connected directly to the Internet, without going through a firewall or router that is translating or otherwise proxying network addresses, the choice of numbers isn't up to you at all. That's because the IP addresses used on the Internet are specifically asigned to the people who own them: you can't just grab any arbitrary number out of a hat and use it. You have to get your own assigned IP addressees.

In many companies, IP addresses are assigned automatically by a DHCP (Dynamic Host Configuration Protocol) server. Still, somebody has to tell that server what addresses to hand out.

However, most small business networks either are not connected at all, or will be connected through a NAT (Network Address Translation) router or through a proxy firewall. It's a little too early to discuss either of these subjects, so let's just move along with you happily assigning your own IP addresses.

First, you can't use 127 as the first number. This is because the address 127.0.0.1 is reserved as a "loopback" address; an address that always refers to the machine at hand. In other words, every machine on your network can telnet to 127.0.0.1 and they will always end up at themselves, and not anywhere else. What's the point? Actually, it's useful. Consider the case of a client-server application where you want to run the client on the same machine as the server. Or consider a programmer who wants to test a network program, but doesn't want to go out on the real network just yet.

You also may have had support people ask you to "ping 127.0.0.1" to test your TCP/IP configuration. What's being tested there is strictly TCP/IP, with the network card not in the loop, and no interference or confusion from the rest of the network. It's strictly local, strictly a loopback. It needs to be there: don't ever delete this address from /etc/hosts.

The next addresses you shouldn't use are anything beginning with 224 or above. These are the Class D and Class E addresses (that's old terminolgy, but people still use it, so will I), reserved for special use. One use being made of them now is for Multicast addresses, where one computer sends data but many other computers receive it.

Just about anything else is available to you, following the rules that none of the four numbers can be 0 (really, some of them could be zero, but it's less confusing right now if we pretend that they cannot) and none of them can be 255. Keep in mind that the rules about 127 and 224 and up only apply to the first number of the four: you shouldn't use 225.10.1.8, but 10.225.1.8 is fine.

By the way, these four numbers are usually referred to as "octets", simply because they hold numbers that can be expressed in 8 bits. If it makes your head hurt to talk about bits, this might be a good time to bail out, because we're going to be getting into that pretty heavily from this point on. On the other hand, I'm going to try to make it painless, so you might consider hanging in there.

Don't panic, but we're going to talk bits!

An eight bit number can be anything from 0 to 255. This is because of the value of the bits. The 0 bit (computer geeks number things starting with 0, not to annoy you, but because it's easier when working with low-level computer registers) is worth 1 if set (and 0 if not), the 1 bit is worth 2 (again, if set, and zero if it isn't), the 2 bit is 4, and so on. Usually that's illustrated something like this:

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

In this case, since bits 7, 4, and 1 are checked. the value would be 128 + 16 + 2, or 146.

Let's try a different one:

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

Here, we have bits 7, 6, 5 and 4 checked, so the value would be 128 + 64 + 32 +16, or 240. If all 8 bits were "on", that would add up to 255.

Confused yet?

What do you think it might mean if I said the subnet mask was going to be 255.255.255.0? Yes, it would mean that all bits in the first three octets are set, or "on". If I said it's 255.255.240.0, it would (of course) mean that all bits in the first two octets were set, but only the leftmost 4 bits (the "high order" bits) were set in the third octet.

Now, I said before that where ever you see "255", that means you can't change that part of the network numbers without ending up on a different network. So, 10.1.35.12 with a mask of 255.255.255.0 is on a different network than 10.1.68.12 (the first network is 10.1.35.0 and the other is 10.1.68.0), but if the mask were 255.255.0.0, those machines would be on the same network (the network is 10.1.0.0).

So what if the mask is 255.255.240.0? What I hope you are thinking right now is "Oh, it isn't the "255" that's magic, it's the bits that are set". If that is indeed what you were thinking, that's good, because you are correct. It's the bits that are important, and the "240" means that the network portion of the address (the part you can't change without changing to another network) is 4 bits bigger than it would be otherwise.

So what network is 10.1.35.12 part of if the subnet mask is 255.255.240.0? The important number here is "35". Let's look at the bits:

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

32 + 2 + 1 = 35. So the "network" part of this address is actually 10.1.32.0. The "32" that's part of the "35" is within the network portion. Why? Because the netmask ending in 240 only runs through the 16 bit (128 + 64 + 32 + 16 = 240). So everything to the right of the 16 bit belongs to the host, not to the network. Therefore, this is host 3.12 on network 10.1.32.0. Why host 3.12? Because those are the host bits. The "35" is made up of "32" (which belongs to the network part) plus "2" and "1" (which is "3" that belongs to the host part of the address- the bits that fall outside of the netmask). Got it?

Now let's look at the other address. Again, I hope it's obvious that the "68" is the important part, because that's the octet that has a partial (not 255) mask:

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

So, 10.1.68.12 is on the 10.1.64.0 network, which is different than the 10.1.32.0 network. This is host 4.12 on network 10.1.64.0.

What's on this network?

How can you assign another address that is on the 10.1.68.0 network? Just as before, by not changing any of the numbers that are "covered" by the bits of the subnet mask. So, we can change any of bits 0 through 3, but not the "64" bit. Therefore, we end up with anything from 10.1.65.xxx (the xxx can be anything from 1 through 254) to 10.1.78.xxx, plus part of 10.1.79.xxx. Here's what "65" and "78" look like:

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

 

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

The addresses 10.1.65.2, 10.1.73.2, and 10.1.78.223 are all on the same network (again, remembering that our subnet mask is 10.1.240.0). The numbers have changed (65,73,78), but the network part (the 4 bits that represent the network) hasn't.

It's really just bits

If you are really paying attention, you might ask "What about 79?". The answer is that the rule we learned before about not using "255" also has to do with bits, and not with something magic about "255". With this mask (255.255.240.0), "10.1.79.255" would mean that the address portion was "all bits set", and that (as we'll learn later) is a "broadcast" address. This gets really confusing. It's actually simple; just bits set or not set, but since we humans don't think that way, it's hard for us to see what's going on easily. Strangely, for this subnet, 10.1.73.255 would technically be legal, even though it looks like a broadcast address on the 10.1.1.0 network. It isn't, though, because the network is actually 10.1.64.0, so the broadcast bits are not set. But for 10.1.79.255 on 10.1.64.0, the broadcast bits would be set. Let's look at the bits:

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

That's "73"

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

and that's "79". In both cases, the network part is the "64" bit, and the rest is address. When the final octet is "255", the 10.1.73.255 does not have all of it's address bits set to 1; bits 1 and 2 are not set in the third octet. But with 10.1.79.255, everything in the address part is set (the "address" part is all the bits that are not in the "network" part).

Life is confusing enough without this!

Computers don't have problems with this, because they simply "and" the bits to determine what the network portion of an address is. The rules are easy for them, but we poor humans have to step more slowly.

I wouldn't recommend using those 255 addresses because they will confuse people. It confused me even while writing this article, because I originally used a subnet mask of 255.255.255.240 as the example, but decided to "move it to the left" the make the point more plain. With that mask, 10.1.1.79 is the broadcast address for network 10.1.1.64, and my editing left that indication in.

The fine print

There are some other rules, too. You aren't supposed to have a network composed of "all bits set", either. So all these would be "legal" networks when the mask is 255.255.240.0:

10.1.16.0, 10.1.32.0, 10.1.48.0, 10.1.64.0

10.1.80.0, 10.1.96.0, 10.1.112.0, 10.1.128.0

10.1.144.0, 10.1.160.0, 10.1.176.0, 10.1.192.0

10.1.208.0, 10.1.224.0

but 10.1.240.0 is not. For similar reasons, 10.1.0.0 is not legal for this subnet, either. So, for a subnet mask of 255.255.240.0, an address of less than 10.1.17.1 or greater than 10.1.239.254 is not legal. You should know, however, that there are plenty of functional networks that violate these rules. For example, I've seen the mask of 255.255.255.192 used. This actually only gives us 2 networks (10.1.1.64, and 10.1.1.128), but I've seen people uses addresses above 10.1.1.192 (which would be the "illegal" network of 10.1.1.192) and below 10.1.1.64 (which would be the other "wrong" network of 10.1.1.0). The networks work. If I understand recent changes correctly, these are now even "legal"; that is, subnets of all "0"'s or all "1"'s are now acceptable. This gets even more confusing when we get into classless routing (another article; hopefully for November 1998).

Stranger stuff

Interestingly (well, I think it's interesting, though you may be wishing you could smash all those network bits into little pieces and force-feed them to me), the RFC's on subnetting used to say that split netmasks are also legal. Thus, you could have a subnet mask of 10.1.1.129. This is a strange bit pattern:

Bit

7

6

5

4

3

2

1

0

 

Value

128

64

32

16

8

4

2

1

By the rules we've learned, the bits set in the netmask determine the network. The network with none of the bits set is invalid, as is the network with both set. So for this netmask, we get just two networks, 10.1.1.128 and 10.1.1.1. The valid addresses for the 10.1.1.1 network are the odd addresses from 10.1.1.3 to 10.1.1.125, and for the 10.1.1.128 network, we use the even addresses from 10.1.1.130 to 10.1.1.252.

It gets even more weird. The broadcast address on the 128 network is 10.1.1.254, but the broadcast on the 10.1.1.1 network would be 10.1.1.127. All other addresses (like 10.1.1.2 and 10.1.1.133) are "illegal". If this doesn't give you a headache, there is something very wrong with you!

I have never seen split subnet masks actually used, and I can't imagine why anyone would want or need to. That's probably why they aren't "legal" anymore.

What about that broadcast?

I've mentioned broadcast addresses more than once, but haven't yet explained what that's all about. Painful as it is for both of us, it's time to do that.

The first thing you need to know is that these tcp/ip addresses don't mean anything, and are absolutely and completely unimportant, useless, and meaningless to a network card. Yes, you read that correctly: these addresses are not used by your network card at all. Never. Not in Unix, not in NT, not in your next door neighbor's shiny red convertible. Not used. Useless. Meaningless.

This does not mean that tcp/ip addresses are useless to you: without some form of high level addressing we couldn't have routing, and the only way to break up networks into smaller junks would be bridging. But when it comes down to the real basics underneath, network cards do NOT use these addresses.

Your network card, and mine, and even Bill Gates network card, only understands the MAC address that is burned into that card's on-board chips (not 100% true because the address can also be assigned by software, but it's still not a tcp/ip address). That address is a 6 octet number that might look like 00:04:05:54:17:d5 (hex numbers). When one network card wants to talk to another network card, they do so only by knowing each other's MAC addresses.

So how do they get the address?

By a broadcast, of course. A broadcast address is an address of all hex ff's (decimal 255's) that every card will listen to. The broadcast message asks a question: "who has this tcp/ip address 205.15.68.1?". All the cards on the network read that message, but only one (we hope) says "Yup, that's me?".

But that still doesn't have anything to do with tcp/ip broadcast addresses. That was a MAC address broadcast. So what use is a tcp/ip broadcast?

The full answer to that is another whole article on routers and bridges and switches and hubs, but the short answer is that the broadcast gets limited to a "broadcast domain". In other words, we expect the machines in a certain sub-net to be gathered together on one segment of a network. So when I said above that all the cards read the broadcast, I wasn't entirely telling the truth. All the cards that see it will read it, but broadcasts do not pass through routers.

This means that the machines that belong to a particular sub-net only broadcast to each other, thus limiting traffic to other sub-nets.

So how does a machine on one sub-net get to talk to some other machine on a different sub-net, or perhaps (as may be happening as you read this) even half across the country or even the world?

We've seen how TCP/IP addresses combined with netmasks determine networks. For example, 192.168.200.83 and 192.168.201.35 are on separate networks if the netmask is 255.255.255.0 (a class C netmask).

So, let's say that 192.168.200.83 is our server, and 192.168.201.35 is a Windows 95 machine. Again, it's a class C netmask (255.255.255.0), so there is going to have to be a router in the network. That router is going to have to have one port on the 192.168.200 network, and one on the 192.168.201 network.

How that happens depends on the router, but usually these things get configured initially by connecting to a serial port, and typing commands to set addresses and protocols on the other network ports. For the purposes of this article, we'll assume that the router has one port addressed at 192.168.200.1 and another at 192.168.201.1 (it's very common for routers to use the "1" address).

Starting at the Win95 machine, it needs to have a route so that it can get off its network (192.168.201) to the server's network (192.168.200). You'd do this in Settings->Control Panel ->Networks. Under the Properties for TCP/IP, you'd find a tab for Gateway. Here you'd enter the address of the router port on your network. That's 192.168.201.1 because the Win95 machine is on the 192.168.201 network.

If you dropped out to DOS and typed "ping 192.168.200.83" (that's the server address) before setting that gateway, you'd get "Destination host unreachable" (from a Unix machine you would get "No route to host"). After making this setting (and rebooting the 95 machine, you'll get "Request timed out" instead.

The problem is that the Win95 machine knows how to get to the server through the router, but the server doesn't know how to get back. The server needs a route to get to the 192.168.200 network.

So we need to do it there, also. If the server were a SCO Unix machine, we might type "route add 192.168.201.0 192.168.200.1" (on older SCO you'd do "route add 192.168.201.0 192.168.200.1 0".

Note that we are saying our route goes to 192.168.201.0, not to a specific address: the .0 says we're giving a route to the whole network. If this were a class A network (255.0.0.0 netmask) we'd use route add 10.0.0.0, etc.

NT is similar to Win95, though in both cases you can also issue "route add" commands at the command prompt. With NT and (I think) 95, doing this adds the routing information to the registry, so it sticks through a reboot. On SCO, that's not the case. You'll need to add the commands to a start-up file (/etc/rc2.d/S99route, for example: it doesn't exist, but you can create it) or modify the /etc/gateways file (see 'man routed'for the syntax of that file). The disadvantage of /etc/gateways is that it is used by routed, so if you are not running routed, that won't work.

You could also modify /etc/tcp and add your routes after it sets up its default routes. That has the disadvantage of modifying a system file: an upgrade will overwrite that.

SCO 5.0.4 adds a /etc/rc2.d/S90iproute script that reads /usr/internet/etc/sco_ip/routes. It's the Internet Manager that can add info to that file, but there's no reason you can't do it manually. The format is simple:

# comments are ok
# simple form
net default 10.1.1.3
# it's smart enough to delete the previous default
net default 192.168.1.2 
# routes to specific hosts
host 192.168.1.8 10.1.1.7
# netmasks optional
net 192.168.1.0 10.1.1.3 255.255.255.0
# if field 1 isn't host or net, it's ignored
happiness 172.16.80.10 10.1.1.1
sanjose 172.16.80.10 10.1.1.1

Another advantage of this script is that when called with "stop" (/etc/rc2.d/S90iproute   stop), it will delete the routes listed in the file.

Beginning with 5.0.6, you can add the default route in /etc/default/tcp. Just modify the GATEWAY= line, and /etc/tcp will read that. DON'T DO THIS ON PRIOR RELEASES; /etc/tcp doesn't look for that until 5.0.6

So how does the OS know where to send a packet when you have more than one card in your machine such as when you have DS internet access and an internal network? You may not have realized this, but that's routing.

The OS "knows" by the addresseses and netmask you have put on the cards.

Lets say you have two cards: your internal network card which is 192.168.2.10 with a mask of 255.255.255.0, and your external card which gets a DHCP address that's real, but let's pretend that right this minute it's 64.xxx,xxx.12 again with a 255.255.255.0 mask.

If you "ping 192.168.2.27" (some other machine on your internal network, the only place that packet will be sent to is your 192.168.2.10 card.

If you ping something on the network of the other card, that's where those packets will go.

So what if you ping something else like "132.xxx.xxx.89" ? That's where your default route comes into play. It might, for example, be 64.xxx,xxx.1. It *has* to be something on one of the networks defined by your cards. It could not be "144.xxx.xxx.1" for instance because you have no such network. So, if it were 64.xxx.xxx.1, the packets would go out your 64. interface and find their way to that router, which presumably can get them to the 132 address, either directly or by sending them along somewhere else.

You can see this stuff in action by using "traceroute"

Here's a traceroute from my machine to world.std.com

 1  65.96.8.1 (65.96.8.1)  12.640 ms  23.976 ms  12.765 ms
 2  65.96.8.1 (65.96.8.1)  12.103 ms  13.057 ms  12.767 ms
 3  24.128.9.177 (24.128.9.177)  12.732 ms  12.472 ms  12.177 ms
 4  SRP2-0-NDHMMA1-RTR01.necore.mediaone.net (24.91.0.55)  13.177 ms  22.586 ms  11.567 ms
 5  12.125.33.21 (12.125.33.21)  16.168 ms  14.617 ms  16.164 ms
 6  gbr1-p60.cb1ma.ip.att.net (12.123.40.138)  15.968 ms  21.932 ms  19.366 ms
 7  gbr3-p70.cb1ma.ip.att.net (12.122.5.53)  14.354 ms  16.152 ms  20.548 ms
 8  gbr4-p10.n54ny.ip.att.net (12.122.2.13)  40.957 ms  25.775 ms  19.749 ms
 9  ggr1-p370.n54ny.ip.att.net (12.123.1.125)  22.161 ms  20.915 ms  18.146 ms
10  att-gw.ny.uu.net (192.205.32.178)  49.996 ms  21.813 ms  20.946 ms
11  0.so-5-2-0.XL1.NYC8.ALTER.NET (152.63.19.54)  20.369 ms  21.435 ms  19.783 ms
12  0.so-3-0-0.XR1.NYC8.ALTER.NET (152.63.19.30)  20.199 ms  20.250 ms  20.146 ms
13  283.ATM7-0.XR1.BOS1.ALTER.NET (152.63.16.181)  30.349 ms  30.457 ms  29.981 ms
14  191.ATM7-0.GW3.BOS1.ALTER.NET (146.188.177.209)  35.961 ms  26.439 ms  40.353 ms
15  Boston-STD.std.com (192.74.137.80)  43.999 ms  61.854 ms  50.184 ms
16  world.std.com (192.74.137.5)  63.528 ms  81.948 ms  84.958 ms