IPv4address

IPv4 Address

An IPv4 address identifies a device on the Internet uniquely(although there are some technique to make it non-unique)

IPv4 address : 32 bits long, a.b.c.d

Each octet is represented in decimal

Netmask

Some devices may be in the same network

For example,network 255.255.255.0 means if the 24 bits are the same, these IPs are in the same network

1
2
3
4
$ ifconfig
....
inet 192.168.1.3 netmask 0xffffff00
....
1
2
3
4
5
6
7
8
9
def same_network_with_me(netmask:int,other_device_IP:int,my_IP:int):
myprefix = netmask & my_IP
otherprefix = netmask & other_device_IP
return myprefix == otherprefix


def ip2int(ip:str):
ls = ['{:02x}'.format(int(x)) for x in ip.split('.')]
return int(''.join(ls) , 16)

quiz

My solution :

1
2
3
4
5
6
7
8
9
10
11
12
13
source = ['128.34.1.15' , '10.0.1.4' , '10.0.1.4' , '171.64.15.33' , '171.64.15.33']
destination = ['128.35.1.15' , '10.0.1.5' , '10.0.2.5' , '171.64.15.5' , '171.19.201.2']
netmasks = ['255.255.0.0' , '255.255.255.0' , '255.255.255.0','255.255.225.224' , '255.0.0.0']

for s,d,n in zip(source , destination , netmasks):
print(same_network_with_me(ip2int(n) , ip2int(d) , ip2int(s)))
'''
False
True
False
False
True
'''

Classless Inter-Domain Routing (CIDR)

historical classes

Lots of IPs are wasted in this allocation policy

Today’s Address Structure

  • Still assign contiguous ranges of address to nearby networks
  • Assign addresses by block
  • Address block is a pair : (address , count)
  • count is power of 2, specifing the netmask length
  • 171.64.0.0/16 means any address in range 171.64.0.0 to 171.64.255.255
  • xxx.xxx.xxx.xxx/24 describe a block of 256 addresses

How IPv4 addresses are assigned?

Managed by IANA(International Assign Number Authority)

Longest Prefix Match

The algorithm used by routers to forward packages to different directions of link

Inside each hop

  • The router resort to a Forwarding table to forword the package
  • It search the forwarding table for a best match and forward the package
  • If no match is found, any package will fall back to the default match whose pattern is x.x.x.x, matching any IP

Longest Prefix Match

actual table entry

Quiz

quiz

My solution :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# maybe some bit level searching tree will have better performance

class Entry():
def __init__(self , dest , link):
self.link = link
ls = dest.split('/')
self.ip = ip2int(ls[0])
self.masklen = int(ls[1])
self.mask = int('1'*self.masklen + '0'*(32 - self.masklen) , 2)

def isMatch(self, packageip):
return self.ip & self.mask == packageip & self.mask

def getlen(self):
return self.masklen

def getlink(self):
return self.link


ForwardingTable = [
Entry('0.0.0.0/0' , 1),
Entry('18.0.0.0/8' , 5),
Entry('171.0.0.0/8' , 2),
Entry('171.0.0.0/10' , 4),
Entry('171.0.15.0/24' , 1),
Entry('55.128.0.0/10' , 6),
Entry('63.19.5.0/30' , 3)
]

PackageIPs = [
'63.19.5.3',
'171.15.15.0',
'63.19.5.32',
'44.199.230.1',
'171.128.16.0'
]

for packageip in PackageIPs:
maxlen = 0
forward2 = None

for entry in ForwardingTable:
# <= here allow default link to update forward2
if entry.isMatch(ip2int(packageip)) and maxlen <= entry.getlen():
maxlen = entry.getlen()
forward2 = entry.getlink()

print('Package with IP : {} \tgoes to link {}'.format(packageip , forward2))
1
2
3
4
5
Package with IP : 63.19.5.3 	goes to link 3
Package with IP : 171.15.15.0 goes to link 4
Package with IP : 63.19.5.32 goes to link 1
Package with IP : 44.199.230.1 goes to link 1
Package with IP : 171.128.16.0 goes to link 2

My implementation

tcam

Of course, there can be other implementation

binary tries

Address Resolution Protocal(ARP)

ARP provides a mechanism to translate IP addresses to link-layer addresses.

  • Each layer has its own address
    • port for application layer
    • IP address for network layer
    • link layer address(Network card address, MAC) for link layer
  • An IP address specify a host in the network which can have multiple network card
  • A link layer address can specify a unique device(network card) which can receive and send link frames
  • A ethernet card is a typical network card whose address is in form of xx:xx:xx:xx:xx:xx, represented by hexadecimal, 48-bit long.

why we need arp

1
2
3
4
5
6
7
A ------------------------------> B
A ---------> gateway -----------> B
A.send(dstIP : 171.43.22.5 , MAC : 0:18:e7:f3:ce:1a)
gateway.recevied()
gateway.process()
gateway.send(dstIP : 171.43.22.5, MAC : 9:9:9:9:9:9)
B.received()

So we can see that we need a way to decide a MAC address from a given IP address, which means we need a Mapping(ARP)

ARP

video

Request and Relay mode

  • The NIC first search local ARP cache for destination host’s MAC address
1
$ arp -a
  • If not found, the NIC send a arp request package via broadcast(ff:ff:ff:ff:ff:ff)

arp

  • All nodes in the network receive the package, if someone see that the requested IP is correspond to his own IP, he will then send a relay package
  • The NIC receive the relay package and update the ARP cache

ARP spoof

ARP spoof

The attack can only be used on networks that use ARP, and requires attacker have direct access to the local network segment to be attacked

(Since ARP only work in a LAN !)