Tutorial 2 - IPv6 & TCP
Submission process:
- Submission deadline is November 18, 16:00 CET (before the lecture) .
- Commit and push your solution as separate notebook files per subtask via git as ./tutorial/tutorial2/tutorial2_1.ipynb. Please take care of the correct subfolder/filename since submission is denied otherwise.
- During the first lecture after the deadline we will discuss a sample solution in class.
- Afterwards, you have time until November 22, 23:59 CET to submit a corrected version of your submission:
- Rework your solution according to our discussion in class.
- Commit and push the corrected version as a separate file per subtask via git as ./tutorial/tutorial2/tutorial2_1.ipynb. Please take care of the correct filename since submission is denied otherwise.
Remarks:
- Grading is done based on both versions of your submission.
- If the first submission is missing your submission will not be graded.
- If the second submission contains major flaws after revision not more than half of the credits for this tutorial can be achieved.
- A sample solution is provided after November 22, 23:59 CET eventually.
- Do NOT duplicate cells or change the type of cells, otherwise you might receive zero points for your submission
- Please use acn@net.in.tum.de for questions regarding lecture, tutorial, and project of ACN.
Problem 1 IPv6 (3.5 credits)
IPv6 is the successor if IPv4. Instead of 32 bits, 128 bits are used for each address. This offers enough space for many different address types. However, the text representation of the addresses becomes more complex as well.
a) [1 credits] Write a function convert_ipv6.
The function receives a bytearray containing a valid IPv6 address and should return the shortest possible string representation of the address. Make sure the following requirements are fulfilled.
- remove leading zeros for each byte-pair (do not remove trailing ones)
- the longest serie of consecutive 0s can be merged with ::
- your function implementation should be able to correctly handle any given IPv6 address
Remark: For this problem you are not allowed to use any modules like ipaddress.
def convert_ipv6(address):
# begin insert code
out = []
zero_len = 0
zero_start = None
max_zero_len = 0
max_zero_start = None
for i, b in enumerate(address[::2]):
part = '{:02x}{:02x}'.format(address[i*2], address[i*2+1])
part = part.lstrip('0') or '0'
if part == '0':
if zero_start is None:
zero_start = i
zero_len = 0
zero_len += 1
if part != '0' or i == 7:
if zero_len > max_zero_len:
max_zero_len = zero_len
max_zero_start = zero_start
zero_start = None
out.append(part)
if max_zero_start is not None and max_zero_len>1:
return '::'.join([
':'.join(out[:max_zero_start]),
':'.join(out[max_zero_start+max_zero_len:])
])
return ':'.join(out)
# end insert code
return shortend_ipv6
ipv6 = bytearray(b'\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\xd7\x6d\xa0')
# should convert to ff02::1:ffd7:6da0
convert_ipv6(ipv6)
'ff02::1:ffd7:6da0'
Stateless Address Auto Configuration (SLAAC) is a protocol to automatically set up Link-Local addresses. RFC 4291 describes in Section 2.5.6 how Link-Local addresses are computed using the device's MAC address.
b) [0.5 credits] Write a function generate_link_local.
The functions receives a bytearray containing a MAC address and should return a bytearray with the corresponding Link-Local address.
Remark: For this problem you are not allowed to use any modules like ipaddress.
def generate_link_local(mac):
# begin insert code
addr = bytearray(16) # create an empty bytearray of size 16
addr[:2] = b'\xfe\x80' # set Link-Local prefix
addr[8] = mac[0] ^ 0x02 # flip 7th bit of the first octet of the mac address
addr[9:] = mac[1:3] # set remaining 2 octets from the mac address
addr[11:] = b'\xff\xfe' # insert 0xfffe
addr[13:] = mac[3:] # set last 3 bytes of the mac address
return addr
# end insert code
return bytearray(16)
mac = bytearray(b'\x01\x02\x03\x04\x05\x06')
convert_ipv6(generate_link_local(mac))
'fe80::302:3ff:fe04:506'
IPv6 Multicast Address spaces are defined in RFC 4291 in Section 2.7. For Neigbor Discovery the Solicited-Node Address is used.
c) [0.5 credits] Write two functions:
- compute_solicited_node_multicast, which gets as input a bytearray containing an IPv6 address and returns a bytearray containing the Solicited-Node Multicast address of the IPv6 address.
- compute_multicast_mac, which gets as input a bytearray containing an IPv6 address and returns a bytearray containing the multicast MAC address as specified in RFC 2464 in Section 7.
def compute_solicited_node_multicast(ipv6):
# begin insert code
# From RFC4291: FF02:0:0:0:0:1:FFXX:XXXX
# With XX:XXXX being the last 3 bytes of the IPv6 address
addr = bytearray(16)
addr[:2] = b'\xff\x02'
addr[11:12] = b'\x01'
addr[12:] = b'\xff'
addr[13:] = bytearray(ipv6[-3:])
return addr
# end insert code
return ipv6
def compute_multicast_mac(ipv6):
# begin insert code
solicited = compute_solicited_node_multicast(ipv6)
addr = bytearray(6)
addr[0:2] = b'\x33\x33'
addr[2:] = solicited[-4:]
return addr
# end insert code
return bytearray(6)
ipv6 = bytearray(b'\x20\x01\x4c\xa0\x20\x01\x00\x40\xe1\x14\x90\xfe\x38\x62\x55\x4f')
print(convert_ipv6(compute_solicited_node_multicast(ipv6)))
mac = compute_multicast_mac(ipv6)
print('{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}'.format(*mac))
ff02::1:ff62:554f 33:33:ff:62:55:4f
In the next subproblem you will analyze how IPv6 addresses are distributed. First you will download a file from the ACN website which contains two datasets with different IPv6 addresses.
Run the following cell to download the file and print some sample values from each dataset.
# Download IPv6 address lists from ACN website
!wget -nc https://acn.net.in.tum.de/exercise/ipv6_dataset.npz -O ipv6_dataset.npz
# Load file into Python
import numpy as np
data = np.load('ipv6_dataset.npz')
# Print sample data
print('Dataset 1:')
print('\n'.join(map(convert_ipv6, data['dataset1'][:3])))
print('\nDataset 2:')
print('\n'.join(map(convert_ipv6, data['dataset2'][:3])))
7[Files: 0 Bytes: 0 [0 B/s] Re]8
7[https://acn.net.in.tum.de/exer]87File 'ipv6_dataset.npz' already there; not retrieving.
87ipv6_dataset.npz 100% [=============================>] 3.05M --.-KB/s87HTTP response 200 [https://acn.net.in.tum.de/exercise/ipv6_dataset.npz] 87ipv6_dataset.npz 100% [=============================>] 3.05M --.-KB/s87[Files: 1 Bytes: 3.05M [9.75MB]8
Dataset 1: 6920:e145:d470:5813:2622:c8e7:a681:7934 5b4c:a84a:1a62:364a:98fd:9d46:54f0:394f c68d:5c81:4ee8:e653:4433:33f1:a010:1afb Dataset 2: a085:7030:5674:7e43::1 d853:a02d:e303:1f2c:20:330:850:1401 cf94:8484:c858:41b8::1
d) [0.5 credits] Write a function count_ones.
The function receives a bytearray containing an IPv6 address and should return the number of bits set to 1 in the last 64 bits of the IPv6 address.
def count_ones(ipv6):
# begin insert code
ipv6 = ''.join(map(lambda i: "{0:08b}".format(i), ipv6[8:])) # convert address to bitstring
return ipv6.count('1')
# end insert code
return 0
Once you finished the previous subproblem you can run the following cell which plots the distributions of bits set to one for each dataset.
%matplotlib inline
import matplotlib.pyplot as plt
def plot_histogram(dataset1, dataset2):
fig, axis = plt.subplots(1, 2, figsize=(15, 4))
axis[0].hist(list(map(count_ones, dataset1)), bins=64, range=(0,64), density=True)
axis[1].hist(list(map(count_ones, dataset2)), bins=64, range=(0,64), density=True)
axis[0].set(xlabel='# of 1', ylabel='Density', title='Dataset 1')
axis[1].set(xlabel='# of 1', ylabel='Density', title='Dataset 2')
plot_histogram(data['dataset1'], data['dataset2'])
e) [1 credits] Explain how the addresses in the two datasets differ. Give a reason for the differences and what kind of addresses are most likely contained in each dataset.
The number of ones of the addresses in dataset1 approximates a normal distribution with a mean of 32. This means that each individual bit is set to 1 with a probability of 0.5. The reason for this is that the addresses were generated automatically using the IPv6 privacy extension.
The addresses in dataset2 follow a different distribution. There only a few bits are set to 1, which results from these addresses being assigned manually (e.g. by network admins) and tend to a more human readable form.
Advanced Computer Networking by Prof. Dr.-Ing. Georg Carle
Teaching assistants: Christian Dietze, Sebastian Gallenmüller, Marcel Kempf, Lorenz Lehle, Nikolas Gauder, Patrick Dirks