#!/usr/bin/env python3 """ Liten IP-lekeapp for IN1020 – med stegvis forklaring Basert på: - Subnettadresse = IP AND nettverksmaske - Kringkastingsadresse = IP OR (~nettverksmaske) Eksempel som i forelesning: IP: 192.168.1.5 = 11000000.10101000.00000001.00000101 Maske:255.255.255.0 = 11111111.11111111.11111111.00000000 AND ----------------------------------------------- 11000000.10101000.00000001.00000000 = 192.168.1.0 (subnett) """ import ipaddress def octets(ip_str: str): """Returner liste med heltallsoktetter fra '192.168.1.5'.""" return [int(x) for x in ip_str.split(".")] def to_binary_octets(ip_str: str) -> str: """Gjør '192.168.1.5' om til '11000000.10101000.00000001.00000101'.""" return ".".join(f"{o:08b}" for o in octets(ip_str)) def and_binary_str(ip_str: str, mask_str: str) -> str: """IP AND maske, retur binærstreng per oktett (for forklaring).""" ip_oct = octets(ip_str) m_oct = octets(mask_str) res_oct = [ip_oct[i] & m_oct[i] for i in range(4)] return ".".join(f"{o:08b}" for o in res_oct) def or_binary_str(ip_str: str, inv_mask_str: str) -> str: """IP OR invers maske, retur binærstreng per oktett (for forklaring).""" ip_oct = octets(ip_str) inv_oct = octets(inv_mask_str) res_oct = [ip_oct[i] | inv_oct[i] for i in range(4)] return ".".join(f"{o:08b}" for o in res_oct) def invert_mask(mask_str: str) -> str: """Bitvis invers av nettverksmasken, oktett for oktett (255-mask).""" m_oct = octets(mask_str) inv_oct = [255 - o for o in m_oct] return ".".join(str(o) for o in inv_oct) def show_network_info(cidr: str) -> None: """Skriv ut stegvis forklaring fra IP/CIDR til subnett og kringkasting.""" # ip_interface holder på IP+prefiks (verts-IP, ikke nødvendigvis nettverksadressen) iface = ipaddress.ip_interface(cidr) net = iface.network # tilhørende subnett ip_str = str(iface.ip) mask_str = str(net.netmask) subnet_str = str(net.network_address) broadcast_str = str(net.broadcast_address) ip_bin = to_binary_octets(ip_str) mask_bin = to_binary_octets(mask_str) subnet_bin = and_binary_str(ip_str, mask_str) inv_mask_str = invert_mask(mask_str) inv_mask_bin = to_binary_octets(inv_mask_str) broadcast_bin = or_binary_str(ip_str, inv_mask_str) num_addresses = net.num_addresses num_hosts = max(num_addresses - 2, 0) print("=" * 72) print(f"🧠 Leker med IP: {ip_str}/{net.prefixlen}") print("=" * 72) # Steg 1: Skriv IP og maske i binær, forklar nettverksdel/vertsdel print("\n[1] Skriv IP-adresse og nettverksmaske i binær form:") print(f" IP-adresse: {ip_str:<15} = {ip_bin}") print(f" Nettverksmaske: {mask_str:<15} = {mask_bin}") print(" -> Bits som er '1' i masken er nettverksdelen; bits som er '0' er vertsdelen.") print(" (disse 0-bitene kan varieres for å lage ulike vertsadresser i subnettet)") # # # Steg 2: Subnett med bitvis AND print("\n[2] Finn subnettadressen med bitvis AND mellom IP og nettverksmaske:") print(" IP: ", ip_bin) print(" AND maske: ", mask_bin) print(" = subnett: ", subnet_bin) print(f"\n Tilsvarer subnettadresse: {subnet_str}/{net.prefixlen}") print(" Dette er den FØRSTE IP-adressen i subnettet og brukes til å identifisere subnettet.") # # Steg 3: Invers maske og kringkastingsadresse print("\n[3] Finn kringkastingsadressen med bitvis OR mot invers nettverksmaske:") print(" Nettverksmaske: ", mask_str, " => ", mask_bin) print(" Invers nettverksmaske: ", inv_mask_str, " => ", inv_mask_bin) print("\n IP: ", ip_bin) print(" OR invers maske: ", inv_mask_bin) print(" = kringkastingsadresse:", broadcast_bin) print(f"\n Tilsvarer kringkastingsadresse: {broadcast_str}") print(" Alle i samme LAN/nett mottar meldinger som sendes til denne adressen.") # # Steg 4: Hvor mange adresser har vi? print("\n[4] Hvor mange adresser finnes i dette subnettet?") print(f" Antall adresser totalt i subnettet: {num_addresses}") print(f" Antall «vanlige» verts-adresser (utenom subnett og kringkasting): {num_hosts}") print(" -> Intervallet er:") print(f" {subnet_str} (subnettadresse)") print(f" ...") print(f" {broadcast_str} (kringkastingsadresse)") print(" Alle adresser imellom kan tildeles maskiner (vertsdelen).") # print("\n[5] Oppsummering av fremgangsmåten:") print(" 1. Del IP og nettverksmaske opp i oktetter og skriv dem i binær.") print(" 2. Gjør bitvis AND mellom IP og maske for å finne subnettadressen.") print(" 3. Inverter masken (255 - hver oktett) for å få vertsdelen.") print(" 4. Gjør bitvis OR mellom IP og invers maske for å få kringkastingsadressen.") print(" 5. Antall verts-adresser = antall adresser i subnettet minus 2") print(" (subnettadresse + kringkastingsadresse brukes til spesielle formål).") print("=" * 72) print() def main(): print("Velkommen til IP-lekeappen for IN1020! 🎉") print("Her kan du se STEGVIS hvordan vi finner subnett- og kringkastingsadresse.") print("Skriv inn en IP-adresse i CIDR-notasjon, f.eks.:") print(" - 192.168.1.50/24") print(" - 192.168.100.10/26") print(" - 10.10.100.130/23\n") print("Tom linje avslutter.\n") while True: cidr = input("CIDR > ").strip() if not cidr: print("Ha det! 🖐 (Husk å øve videre på oppgave 5 i settet!)") break try: show_network_info(cidr) except ValueError as e: print(f"\nOops, det der så ikke ut som gyldig CIDR-notasjon: {e}") print("Prøv igjen, f.eks. 192.168.1.50/24 eller 10.10.100.130/23.\n") if __name__ == "__main__": main()