The following 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
irb(main):003:0>

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— —-

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– —

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- —-

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 —-

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 —-

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"]
comments powered by Disqus