calcul_ip.py

Note de lecture générée automatiquement

Le vrai fichier est scripts/reseaux/calcul_ip.py (Obsidian n’affiche pas les scripts eux-mêmes). Ne modifie pas cette note : modifie le script, puis relance python3 generer_vues_obsidian.py dans le dossier scripts.

Code

#!/usr/bin/env python3
"""
calcul_ip.py — Donne toutes les infos d'une adresse IPv4 avec son masque.
 
Utilisation :
    python3 calcul_ip.py 192.168.1.200/26
    python3 calcul_ip.py 192.168.1.200 255.255.255.192
 
Affiche : classe historique, privée/publique, masque, adresse réseau,
broadcast, 1re et dernière adresse utilisable, nombre d'hôtes, nombre magique,
et l'écriture binaire (pour vérifier ses calculs à la main).
"""
import ipaddress
import sys
 
 
def classe_historique(premier_octet: int) -> str:
    # La classe dépend uniquement du 1er octet (système d'avant le CIDR)
    if 1 <= premier_octet <= 126:
        return "A (masque par défaut /8)"
    if premier_octet == 127:
        return "Loopback (127.x.x.x)"
    if 128 <= premier_octet <= 191:
        return "B (masque par défaut /16)"
    if 192 <= premier_octet <= 223:
        return "C (masque par défaut /24)"
    if 224 <= premier_octet <= 239:
        return "D (multicast)"
    return "E (réservée)"
 
 
def en_binaire(adresse) -> str:
    # 192.168.1.0 -> 11000000.10101000.00000001.00000000
    return ".".join(f"{int(octet):08b}" for octet in str(adresse).split("."))
 
 
def analyser(saisie: str) -> None:
    interface = ipaddress.ip_interface(saisie)       # accepte "IP/CIDR" ou "IP/masque"
    reseau = interface.network
    adresse = interface.ip
    prefixe = reseau.prefixlen
    nb_total = reseau.num_addresses
    dernier_octet_masque = int(str(reseau.netmask).split(".")[-1])
 
    if prefixe <= 30:
        hotes = list(reseau.hosts())
        premiere, derniere = hotes[0], hotes[-1]
        nb_hotes = nb_total - 2
    else:                                            # /31 et /32 : cas particuliers
        premiere, derniere = reseau.network_address, reseau.broadcast_address
        nb_hotes = nb_total
 
    print(f"Adresse saisie      : {adresse}/{prefixe}")
    print(f"Classe historique   : {classe_historique(int(str(adresse).split('.')[0]))}")
    print(f"Type                : {'privée (RFC 1918)' if adresse.is_private else 'publique'}")
    print(f"Masque              : {reseau.netmask}  (/{prefixe})")
    print(f"Masque inverse      : {reseau.hostmask}  (wildcard, utilisé par OSPF/ACL)")
    print(f"Adresse réseau      : {reseau.network_address}")
    print(f"1re utilisable      : {premiere}")
    print(f"Dernière utilisable : {derniere}")
    print(f"Broadcast           : {reseau.broadcast_address}")
    print(f"Taille du bloc      : {nb_total} adresses")
    print(f"Hôtes utilisables   : {nb_hotes}")
    if prefixe >= 24:
        print(f"Nombre magique      : 256 - {dernier_octet_masque} = {256 - dernier_octet_masque}")
    print()
    print(f"IP en binaire       : {en_binaire(adresse)}")
    print(f"Masque en binaire   : {en_binaire(reseau.netmask)}")
    print(f"Réseau en binaire   : {en_binaire(reseau.network_address)}")
 
 
if __name__ == "__main__":
    if len(sys.argv) == 2:
        analyser(sys.argv[1])
    elif len(sys.argv) == 3:
        analyser(f"{sys.argv[1]}/{sys.argv[2]}")
    else:
        sys.exit(__doc__)