Aller au contenu

Chapitre 9 - Entraînement : Réseaux, routage et cybersécurité


Soit le réseau suivant :

A ──── B ──── C ──── D
│ │
E ──── F ──── G ──── H

Tous les liens ont un coût identique (1 saut). Le routeur A connaît initialement ses voisins B et E.

a. Donner la table de routage initiale de A.

b. B envoie son vecteur : B connaît A (1), C (1). Mettre à jour la table de A.

c. E envoie son vecteur : E connaît A (1), F (1). Mettre à jour la table de A.

d. Après convergence complète, donner la table de routage finale de A.

Solution

a. Table initiale :

DestinationProchainSauts
BB1
EE1

b. Après vecteur de B : ajout de C via B (2 sauts).

DestinationProchainSauts
BB1
CB2
EE1

c. Après vecteur de E : ajout de F via E (2 sauts).

DestinationProchainSauts
BB1
CB2
EE1
FE2

d. Table finale (après convergence) :

DestinationProchainSauts
BB1
CB2
DB3
EE1
FE2
GE3
HB4 (ou E, 4)

Soit le réseau suivant avec les coûts indiqués :

A ──(1)── B ──(10)── C
│ │
(5) (1)
│ │
D ──(1)── E ──(1)── F

a. Calculer le coût du chemin A → B → C.

b. Calculer le coût du chemin A → D → E → F → C.

c. Quel chemin OSPF choisirait-il pour aller de A à C ? Et RIP ?

d. Si le débit de référence est 10⁸ bit/s et que le lien B-C a un débit de 10 Mbit/s, vérifier le coût indiqué.

Solution

a. A → B → C : coût = 1 + 10 = 11.

b. A → D → E → F → C : coût = 5 + 1 + 1 + 1 = 8.

c. OSPF choisit le chemin de coût minimal : A → D → E → F → C (coût 8). RIP choisit le chemin avec le moins de sauts : A → B → C (2 sauts vs 4 sauts).

d. Coût = 10⁸ / 10⁷ = 10. Le coût indiqué (10) est correct.


a. Chiffrer le message « informatique » avec un décalage de 5.

b. Déchiffrer le message « qjfwjyj » avec un décalage de 5.

c. Un message chiffré par César contient « g » comme lettre la plus fréquente. En sachant que la lettre la plus fréquente en français est « e », déduire la clé utilisée et déchiffrer « gnhtkngxg ».

Solution

a. i→n, n→s, f→k, o→t, r→w, m→r, a→f, t→y, i→n, q→v, u→z, e→j → « nsktwrfynvzj ».

b. q→l, j→e, f→a, w→r, j→e, y→t, j→e → « learete » soit « l'aérété » → « learete ».

c. Si « g » correspond à « e », le décalage est g - e = 7 - 5 = 2. En déchiffrant avec un décalage de 2 : g→e, n→l, h→f, t→r, k→i, n→l, g→e, x→v, g→e → « elfrileve » → « el frilève » → en vérifiant : « elfrileve ».

En pratique, la clé est bien 2 et on applique un décalage de -2 à chaque lettre.


a. Compléter le tableau :

CritèreChiffrement symétriqueChiffrement asymétrique
Nombre de clés??
Vitesse??
Problème principal??
Exemple d'algorithme??

b. Pourquoi utilise-t-on un chiffrement hybride pour HTTPS au lieu d'un chiffrement purement asymétrique ?

c. Ordonner les étapes d'une connexion HTTPS :

  1. Le navigateur chiffre une clé symétrique avec la clé publique du serveur.
  2. Le serveur envoie son certificat et sa clé publique.
  3. Les données sont échangées avec le chiffrement symétrique.
  4. Le navigateur demande une connexion HTTPS.
  5. Le serveur déchiffre la clé symétrique avec sa clé privée.
Solution

a.

CritèreChiffrement symétriqueChiffrement asymétrique
Nombre de clés1 (partagée)2 (publique + privée)
VitesseRapideLent
Problème principalÉchange de la clé secrèteLenteur, clés longues
Exemple d'algorithmeAESRSA

b. Le chiffrement asymétrique est trop lent pour chiffrer de grandes quantités de données. On l'utilise uniquement pour échanger la clé symétrique de manière sécurisée, puis on utilise le chiffrement symétrique (rapide) pour les données.

c. Ordre : 4 → 2 → 1 → 5 → 3.


Écrire un programme Python qui simule le protocole RIP sur un réseau modélisé par un dictionnaire d'adjacence. Le programme doit :

  1. Initialiser les tables de routage (chaque routeur connaît ses voisins) ;
  2. Simuler les échanges de vecteurs de distance ;
  3. Afficher l'évolution des tables de routage jusqu'à convergence.
Solution
def initialiser_tables(reseau):
tables = {}
for routeur, voisins in reseau.items():
tables[routeur] = {}
for voisin in voisins:
tables[routeur][voisin] = (voisin, 1)
return tables
def mise_a_jour(tables, reseau):
modifie = False
for routeur in reseau:
for voisin in reseau[routeur]:
for dest, (prochain, sauts) in tables[voisin].items():
if dest == routeur:
continue
nouveau_cout = sauts + 1
if dest not in tables[routeur] or nouveau_cout < tables[routeur][dest][1]:
tables[routeur][dest] = (voisin, nouveau_cout)
modifie = True
return modifie
def afficher_table(routeur, table):
print(f"\nTable de routage de {routeur} :")
print(f" {'Destination':<15} {'Prochain':<10} {'Sauts'}")
for dest in sorted(table):
prochain, sauts = table[dest]
print(f" {dest:<15} {prochain:<10} {sauts}")
reseau = {
'A': ['B', 'D'],
'B': ['A', 'C'],
'C': ['B', 'F'],
'D': ['A', 'E'],
'E': ['D', 'F'],
'F': ['C', 'E']
}
tables = initialiser_tables(reseau)
tour = 0
while True:
tour += 1
print(f"\n{'='*40}")
print(f"Tour {tour}")
if not mise_a_jour(tables, reseau):
print("Convergence atteinte !")
break
for routeur in sorted(tables):
afficher_table(routeur, tables[routeur])

Créer un programme Python qui simule un mini-réseau :

  1. L'utilisateur définit les routeurs et les liens (avec coûts) ;
  2. Le programme calcule les tables de routage selon RIP (nombre de sauts) et OSPF (coûts) ;
  3. L'utilisateur peut demander la route empruntée par un paquet entre deux routeurs ;
  4. Le programme affiche la route, le nombre de sauts et le coût total ;
  5. L'utilisateur peut simuler une panne de lien et observer la mise à jour des tables.
Solution
import heapq
class Reseau:
def __init__(self):
self.graphe = {}
def ajouter_routeur(self, nom):
if nom not in self.graphe:
self.graphe[nom] = {}
def ajouter_lien(self, r1, r2, cout):
self.ajouter_routeur(r1)
self.ajouter_routeur(r2)
self.graphe[r1][r2] = cout
self.graphe[r2][r1] = cout
def supprimer_lien(self, r1, r2):
if r2 in self.graphe.get(r1, {}):
del self.graphe[r1][r2]
del self.graphe[r2][r1]
def route_rip(self, source, destination):
visite = {source: (None, 0)}
file = [source]
while file:
courant = file.pop(0)
for voisin in self.graphe[courant]:
if voisin not in visite:
visite[voisin] = (courant, visite[courant][1] + 1)
file.append(voisin)
chemin = []
noeud = destination
while noeud is not None:
chemin.append(noeud)
noeud = visite[noeud][0]
chemin.reverse()
return chemin, visite[destination][1]
def route_ospf(self, source, destination):
distances = {r: float('inf') for r in self.graphe}
distances[source] = 0
precedent = {r: None for r in self.graphe}
file = [(0, source)]
while file:
dist, courant = heapq.heappop(file)
if dist > distances[courant]:
continue
for voisin, cout in self.graphe[courant].items():
nouvelle_dist = dist + cout
if nouvelle_dist < distances[voisin]:
distances[voisin] = nouvelle_dist
precedent[voisin] = courant
heapq.heappush(file, (nouvelle_dist, voisin))
chemin = []
noeud = destination
while noeud is not None:
chemin.append(noeud)
noeud = precedent[noeud]
chemin.reverse()
return chemin, distances[destination]
reseau = Reseau()
reseau.ajouter_lien('A', 'B', 1)
reseau.ajouter_lien('B', 'C', 10)
reseau.ajouter_lien('A', 'D', 5)
reseau.ajouter_lien('D', 'E', 1)
reseau.ajouter_lien('E', 'F', 1)
reseau.ajouter_lien('F', 'C', 1)
chemin_rip, sauts = reseau.route_rip('A', 'C')
print(f"RIP : {' → '.join(chemin_rip)} ({sauts} sauts)")
chemin_ospf, cout = reseau.route_ospf('A', 'C')
print(f"OSPF : {' → '.join(chemin_ospf)} (coût {cout})")
print("\nSimulation panne du lien B-C...")
reseau.supprimer_lien('B', 'C')
chemin_rip2, sauts2 = reseau.route_rip('A', 'C')
print(f"RIP : {' → '.join(chemin_rip2)} ({sauts2} sauts)")
chemin_ospf2, cout2 = reseau.route_ospf('A', 'C')
print(f"OSPF : {' → '.join(chemin_ospf2)} (coût {cout2})")