The ip address 192.168.1.100 represents a 32 bit number.
λ irb
irb(main):001:0> require 'ipaddr'
=> true
irb(main):002:0> IPAddr.new('192.168.1.100').to_i
=> 3232235876
But how? Let’s break it down. An IPv4 address can be broken down into 4 octets. (192, 168, 1, 100). Each octet represents 8 bits of the address.
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|192| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
|168| 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
|001| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
|100| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
irb(main):005:0> [192, 168, 1, 100].map { |x| x.to_s(2) }
=> ["11000000", "10101000", "1", "1100100"]
Class A _0--- ----_
- First bit is 0.
- 0.0.0.0 - 127.255.255.255
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|127| 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Class B _10-- ---_
- first bit is 1.
- second bit is 0.
- 128.0.0.0 to 191.255.255.255
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|128| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|191| 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Class C _110- ----_
- first bit is 1
- second bit is 1
- third bit is 0
- 192.0.0.0 - 233.255.255.255
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|192| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|233| 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Class D _1110 ----_
- first bit is 1
- second bit is 1
- third bit is 1
- fourth bit is 0
- 224.0.0.0 - 239.255.255.255
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|224| 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|239| 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Class E _1111 ----_
- first bit is 1
- second bit is 1
- third bit is 1
- fourth bit is 1
- 240.0.0.0 - 255.255.255.255
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|240| 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Netmasks and subnets
Breaking up a network in to sections is called subnetting. Each address is broken up into a network portion and a host portion. The different classes of IP addresses use different amounts of the address for the network portion and the host portion.
192.168.1.100 is a class C address. So the first 24 bits or 3 octets are
used for the network portion of the address. The last 8 bits are used to
assign to hosts. So 192.168.1 describes the network and 100 describes
the host.
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|192| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
|168| 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
|001| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
|100| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
The subnet mask for the class address is: 255.255.255.0
|ip | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
|---|-----|-----|-----|-----|-----|-----|-----|-----|
| | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|255| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|000| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
To get the network portion of an ip address we can AND it with the subnet mask.
|ip | binary | | | |
|-------------|--------|--------|--------|--------|
|192.168.1.100|11000000|10101000|00000001|01100100|
|255.255.255.1|11111111|11111111|11111111|00000000|
|192.168.1.0 |11000000|10101000|00000001|00000000|
This tells us that 192.168.1 is used for the network portion.
CIDR Notation
Classless Inter-Domain Routing is another way to represent an IP address.
An example of a CIDR address is 192.168.1.100/24.
This means that the first 24 bits of the IP address are used for the network portion and the last 8 bits are used for the host portion.
This gives us a range of 192.168.1.0 to 192.168.1.255.
irb(main):006:0> require 'netaddr'
irb(main):008:0> x = NetAddr::CIDR.create('192.168.1.100/24')
irb(main):009:0> [x.first, x.last]
=> ["192.168.1.0", "192.168.1.255"]