Favicon
NSI Terminale

Correction : TP RIP Graphes

Classe Routeur

D'après le principe utilisé dans le protocole RIP, un routeur va "explorer" la table de routage de ses voisins directs :


class Routeur:

    def __init__(self, nom: str):
        self.nom = nom
        self.table = {}
    
    def get_nom(self)->str:
        return str(self.nom)
    
    def get_table(self)->dict:
        return self.table
        
    def maj_table(self, voisin):
        
        nom_voisin = voisin.get_nom()
        
        """Voisin pas encore dans la table :
        Nouvelle entrée :
        voisin: ['', 1]
        """
        if nom_voisin not in self.table:
            self.table[nom_voisin] = ['', 1]
            
        """sinon, récupération de la table de routage
        du routeur, et maj des distances
        si nécessaire
        """
        else:
            table_voisin = voisin.get_table()
            
            for destination in table_voisin:
                
                """pour les entrées qui ne concernent pas le routeur
                lui-même
                """
                if destination != self.nom:
            
                    """Découverte d'une nouvelle destination :
                    Nouvelle entrée dans la table de routage :
                    destination: [routeur voisin, sauts depuis le voisin + 1]
                    Le nombre de sauts vers une destination est le 2ème élément
                    du tableau d'une destination dans la table de routage.
                    """
                    if destination not in self.table:
                        self.table[destination] = [nom_voisin, table_voisin[destination][1]+1]
                
                    """sinon ( la destination est déjà dans la table ),
                    maj de la distance si celle-ci est plus petite
                    que celle dans la table
                    """
                    else:
                        nv_distance = table_voisin[destination][1]+1
                        if nv_distance < self.table[destination][1]:
                            self.table[destination] = [nom_voisin, nv_distance]
			

On remarque que c'est bien un objet Routeur que prend la méthode maj_table comme paramètre, pas seulement le nom d'un routeur...

Fonction rip

Rien de compliqué : on parcourt la liste des routeurs du réseau, et on envoie chacun de leurs voisins comme argument à leur méthode maj_table :


def rip(reseau):
    
    for routeur in reseau:				# pour chaque routeur dans le réseau
        for voisin in reseau[routeur]:	# pour chacun de ces voisins
            routeur.maj_table(voisin) 	# on envoie le voisin en argument au routeur courant	
        

Création du réseau et lancement du protocole

Bien se souvenir qu'un routeur est un objet, à stocker dans une variable pour pouvoir ensuite le réutiliser :

  
r1 = Routeur('R1')
r2 = Routeur('R2')
r3 = Routeur('R3')
r4 = Routeur('R4')
r5 = Routeur('R5')
r6 = Routeur('R6')
r7 = Routeur('R7')
       
                
reseau = {
    r1: [r2, r3],
    r2: [r1, r3, r4],
    r3: [r1, r2, r5],
    r4: [r2, r5, r6],
    r5: [r3, r4, r6, r7],
    r6: [r4, r5, r7],
    r7: [r5, r6]
}

for i in range(3):
    print(f"RIP n°{i+1}")
    print('-----------------')
    
    for r in reseau:
        print(r.get_nom(), ':')
        for dest, ligne in r.get_table().items():
            print(dest, ':', ligne)
        print()

    print('-----------------')
    print()
    rip(reseau)
			

Les tables de routage se stabilisent très vite ( le réseau est petit...).

Simulation d'un incident


def incident(reseau, defaut):
    reseau[defaut] = []  					# on supprime tous les liens depuis le routeur en défaut
    nom_defaut = defaut.get_nom()
    
    for routeur in reseau:  				# pour chaque routeur dans le réseau
        if defaut in reseau[routeur]: 		# si le routeur en défaut est dans la liste d'adjacence du routeur courant,
            reseau[routeur].remove(defaut) 	# on supprime le routeur en défaut de cette liste.
            
        for destination in routeur.table: 	# pour chaque destination dans la table de routage du routeur courant,
            if destination == nom_defaut or routeur.table[destination][0] == nom_defaut: 	# si le routeur en défaut est la destination, ou si la destination passe par lui,
                routeur.table[destination][1] = 16											# alors on met la distance à 16.
           

Après avoir simulé un incident, par exemple en désactivant R5, on observe bien la mise à jour des tables de routage, qui passent maintenant par R6.