vlsm.py
Note de lecture générée automatiquement
Le vrai fichier est
scripts/reseaux/vlsm.py(Obsidian n’affiche pas les scripts eux-mêmes). Ne modifie pas cette note : modifie le script, puis relancepython3 generer_vues_obsidian.pydans le dossierscripts.
- À quoi il sert : Calculateur VLSM
- Lancer (dans le dossier
scripts/reseaux/) :python3 vlsm.py 192.168.1.0/24 A=100 B=50 C=25 D=2 - Fiche : R04 - Sous-réseaux et VLSM
- Retour : 00 - Tous les scripts
Code
#!/usr/bin/env python3
"""
vlsm.py — Calculateur VLSM (découpage en sous-réseaux de tailles différentes).
Utilisation :
python3 vlsm.py 192.168.1.0/24 Commercial=100 Compta=50 Serveurs=25 Liaison=2
Le script applique la règle d'or : du PLUS GROS besoin au PLUS PETIT.
Il affiche un tableau prêt à recopier dans un compte rendu.
"""
import ipaddress
import math
import sys
def prefixe_necessaire(nb_hotes: int) -> int:
# On cherche le plus petit nombre de bits hôte tel que 2^bits - 2 >= besoin
bits_hote = max(2, math.ceil(math.log2(nb_hotes + 2)))
return 32 - bits_hote
def calculer_vlsm(reseau_depart: str, besoins: dict) -> None:
reseau = ipaddress.ip_network(reseau_depart, strict=True)
adresse_courante = int(reseau.network_address)
entete = f"{'Nom':<14}{'Besoin':>7} {'Réseau':<19}{'Masque':<17}{'1re IP':<16}{'Dernière IP':<16}{'Broadcast':<16}{'Dispo':>6}"
print(entete)
print("-" * len(entete))
for nom, nb_hotes in sorted(besoins.items(), key=lambda b: b[1], reverse=True):
prefixe = prefixe_necessaire(nb_hotes)
sous_reseau = ipaddress.ip_network(f"{ipaddress.ip_address(adresse_courante)}/{prefixe}")
if not sous_reseau.subnet_of(reseau):
sys.exit(f"\nErreur : plus assez d'adresses pour '{nom}' ({nb_hotes} hôtes).")
hotes = list(sous_reseau.hosts())
print(f"{nom:<14}{nb_hotes:>7} {str(sous_reseau):<19}{str(sous_reseau.netmask):<17}"
f"{str(hotes[0]):<16}{str(hotes[-1]):<16}{str(sous_reseau.broadcast_address):<16}{len(hotes):>6}")
adresse_courante = int(sous_reseau.broadcast_address) + 1
fin = int(reseau.broadcast_address)
if adresse_courante <= fin:
print(f"\nEspace encore libre : {ipaddress.ip_address(adresse_courante)} -> {reseau.broadcast_address}"
f" ({fin - adresse_courante + 1} adresses)")
if __name__ == "__main__":
if len(sys.argv) < 3:
sys.exit(__doc__)
besoins_saisis = {}
for argument in sys.argv[2:]:
nom, valeur = argument.split("=")
besoins_saisis[nom] = int(valeur)
calculer_vlsm(sys.argv[1], besoins_saisis)