Revenir
Revenir

Suivre le routage d'un paquet de données

Prérequis : maîtriser les bases de la programmation Python (variables, boucles, entrées/sorties, fon...

Sommaire

Avant de commencerPrésentationRéseau d'établissement partiel - SchémaPréparationTraitement des données avec PythonLiens utilesVers le notebook Capytale - Site

Avant de commencer

Prérequis : maîtriser les bases de la programmation Python (variables, boucles, entrées/sorties, fonctions)
Contexte de la mise en œuvre de l'activité : en classe, en présence de l'enseignant

Présentation

La commande ping suivie d'une adresse IP ou d'un nom de domaine permet de savoir s'il est possible d'établir une connexion entre deux machines.
Nous partons du réseau d'établissement partiel que nous avons modélisé afin de simuler son fonctionnement. L'utilisateur donne l'adresse IP ou le nom de domaine après la commande ping et le programme renvoie le chemin emprunté du poste source vers sa destination.

Réseau d'établissement partiel - Schéma

Préparation

Le réseau étudié mobilise un switch, deux routeurs ainsi que des ordinateurs portables et des serveurs.
Le switch utilise une table ARP pour associer une adresse IP avec une adresse MAC.
Le routeur utilise une table de routage pour déterminer la route vers une adresse IP.
Le serveur DNS associe une adresse IP à un nom de domaine.
Pour convertir une chaîne de caractères en une liste en utilisant l'espace comme séparateur, on peut utiliser la méthode split :
chaine = "toto le héro"
chaine.split(" ") renvoie ['toto', 'le', 'héro']
Une liste permet de stocker des éléments que l'on peut rappeler à l'aide de leurs indices :
liste = ['a', 'b', 'c']
liste[0] renvoie a    liste[1] renvoie b
join permet de convertir une liste de caractères en chaîne de caractères :
''.join(une_liste) renvoie abcd
Un dictionnaire stocke également des éléments mais sous forme de couple clé/valeur. Il faut utiliser la clé et non un indice pour obtenir la valeur :
fruits = {'pomme':'rouge', 'poire':'jaune', 'banane':'jaune', 'abricot':'orange'}
fruits['banane'] renvoie jaune
La valeur peut être une liste :
fruits = {'pomme':['rouge', 'verte', 'jaune'], 'poire':'jaune', 'banane':'jaune', 'abricot':'orange'}
fruits['pomme'] renvoie ['rouge', 'verte', 'jaune']
On peut connaître le nombre d'éléments dans une liste ou un dictionnaire avec la fonction len :
len(fruits) renvoie 4    len(fruits['pomme']) renvoie 3
On peut convertir un entier en une chaîne de caractère avec str et inversement avec int : 
str(100) renvoie '100'    int('100') renvoie 100
On inverse un entier (ou une chaîne représentant un entier) sur huit bits avec :
256+~int('255') renvoie 0

Traitement des données avec Python

Nous allons déterminer la route pour aller de la machine source à la destination. La source est forcément l'un des deux ordinateurs portables. La destination peut être entrée avec la commande ping suivie d'une adresse IP ou d'un nom de domaine.
Soit le programme :
def est_ipv4(ad):
    # Permet de savoir si l'adresse ad est au format IPV4
    ad = ad.split('.')
    if len(ad) != 4:
        return False
    for a in ad:
        if not (0 <= int(a) <= 255):
            return False
    return True
def net_id(adresse, masque):
    # Renvoie l'adresse du réseau
    netid = [0]*4
    ad = adresse.split('.')
    ma = masque.split('.')
    for i in range(4):
        netid[i] = str(int(ad[i])&int(ma[i]))
    netid = '.'.join(netid)
    return netid
def host_id(adresse, masque):
    # Renvoie l'adresse de  la machine
    hostid = [0]*4
    ad = adresse.split('.')
    ma = masque.split('.')
    for i in range(4):
        hostid[i] = str(int(ad[i])&(256+~int(ma[i])))
    hostid = '.'.join(hostid)
    return hostid
# Pour les PC et serveurs
identifiants = {"172.16.100.10":"Portable 1", "172.16.100.12":"Portable 2",
                "172.16.100.2":"Serveur DNS", "213.186.33.19":"Serveur web Lycée",
                "217.70.184.56":"Serveur web Qwant", "194.4.208.20":"Serveur web fdj"}
# Serveur de nom de domaine
dns = {"www.qwant.fr":"217.70.184.56", "www.fdj.fr":"194.4.208.20",
       "www.monlycee.fr":"213.186.33.19"}
# Commutateur (switch)
table_ARP = {"172.16.100.10":"5D:4C:07:CD:C2:62", "172.16.100.12":"86:F7:BD:F0:1F:00",
             "172.16.100.2":"F3:43:84:E0:47:D0"}
# Routeurs
table_R1 = {"172.16.0.0":[None, "172.16.100.1"],
            "213.186.0.0":[None, "213.186.33.1"],
            "217.70.0.0":["192.168.0.1", "192.168.0.2"],
            "194.4.0.0":["192.168.0.1", "192.168.0.2"]}
table_R2 = {"172.16.0.0":["192.168.0.2", "192.168.0.1"],
            "213.186.0.0":["192.168.0.2", "192.168.0.1"],
            "217.70.0.0":[None, "217.70.184.1"],
            "194.4.0.0":[None, "194.4.208.1"]}
source = input("Votre adresse IP : ")
destination = input("ping ")
1. Complétez ce programme afin de conserver l'adresse IP destination ou de remplacer le nom de domaine par son adresse IP. On donne :
# On vérifie si adresse IPV4 ou nom de domaine
if not est_ipv4(..................................):
    destination = ............................................
print("La route pour aller vers ", destination)
source = identifiants.get(......................)
print("source : ", source)
print("\t--> Switch")
Si la destination est directement connectée au switch, la route est déterminée, sinon il faut aller vers le routeur R1. De la même manière, on détermine s'il faut aller vers le routeur R2 ou s'arrêter à R1.
2. Complétez le programme.
# L'adresse est-elle dans le sous-réseau local ?
if table_ARP.get(..........................) == None:
    print("\t--> ...............................")
    masque = "255.255.0.0"
    netid = net_id(.........................................)
    # L'adresse est-elle dans le réseau local ?
    if table_R1.get(netid)[0] != .....................:
        print("\t--> ...........................")
destination = ......................................
print("destination : ", destination)

Liens utiles

https://www.qwant.fr

https://www.qwant.fr

https://www.fdj.fr

https://www.fdj.fr

https://www.monlycee.fr

https://www.monlycee.fr

Vers le notebook Capytale - Site