#!/usr/bin/env bash # # netdivide.sh - teilt eine VLAN-Range in gleich grosse Subnetze auf # # Autor: Matthias Meister — https://scripts.web.mm-core.de # Version: 2.0.0 # # Lizenz: MIT — Copyright (c) 2026 Matthias Meister # Volltext: https://scripts.web.mm-core.de/lizenz/ # set -euo pipefail readonly VERSION="2.0.0" readonly MIN_PREFIX=8 readonly MAX_PREFIX=30 usage() { cat <<'EOF' netdivide.sh - teilt eine VLAN-Range in gleich grosse Subnetze auf Nutzung: netdivide.sh [OPTIONEN] START-VLAN END-VLAN Optionen: -b, --base NETZ Basis-Netz (erste zwei Oktette). Default: 10.100 -a, --anchor VLAN VLAN-ID, die auf das erste Subnetz (x.x.0.0/PRAEFIX) zeigt. Default: 1001 -p, --prefix N CIDR-Praefixlaenge des Subnetzes je VLAN. Default: 27 Erlaubt: 8-30 -h, --help Diese Hilfe anzeigen -V, --version Versionsnummer anzeigen Logik: Jede VLAN-ID bekommt genau ein Subnetz der Groesse 2^(32-Praefix). Bei Praefix 24-30 passt das Subnetz ins vierte Oktett: Index = VLAN - Anchor pro /24 = 256 / Blockgroesse 3. Oktett = Index / pro_24 4. Oktett = (Index % pro_24) * Blockgroesse Bei Praefix 8-23 ist das Subnetz groesser als ein /24 und belegt mehrere Einheiten im dritten Oktett: Schrittweite = Blockgroesse / 256 3. Oktett = Index * Schrittweite 4. Oktett = 0 Beispiele: netdivide.sh 1001 1008 -> /27-Netze (Default), 10.100.0.0/27 bis 10.100.0.224/27 netdivide.sh --prefix 26 1001 1008 -> /26-Netze, je 64 Adressen netdivide.sh --prefix 23 --base 10.200 --anchor 2001 2001 2010 -> /23-Netze, je 512 Adressen ueber zwei Einheiten im 3. Oktett Exit-Codes: 0 alles gut 1 inhaltliches Problem (z. B. END-VLAN < START-VLAN) 2 Aufruffehler (falsche/fehlende Argumente) EOF } main() { local base_net="10.100" local anchor_vlan=1001 local prefix=27 local positional=() while [ "$#" -gt 0 ]; do case "$1" in -h|--help) usage return 0 ;; -V|--version) echo "netdivide.sh ${VERSION}" return 0 ;; -b|--base) [ "$#" -ge 2 ] || { echo "FEHLER: --base benoetigt ein Argument." >&2; return 2; } base_net="$2" shift 2 ;; -a|--anchor) [ "$#" -ge 2 ] || { echo "FEHLER: --anchor benoetigt ein Argument." >&2; return 2; } anchor_vlan="$2" shift 2 ;; -p|--prefix) [ "$#" -ge 2 ] || { echo "FEHLER: --prefix benoetigt ein Argument." >&2; return 2; } prefix="$2" shift 2 ;; --) shift while [ "$#" -gt 0 ]; do positional+=("$1") shift done ;; -*) echo "FEHLER: Unbekannte Option '$1'" >&2 echo "Hilfe: netdivide.sh --help" >&2 return 2 ;; *) positional+=("$1") shift ;; esac done set -- "${positional[@]}" if [ "$#" -ne 2 ]; then echo "FEHLER: Bitte START- und END-VLAN angeben." >&2 echo "Hilfe: netdivide.sh --help" >&2 return 2 fi local start_vlan="$1" end_vlan="$2" if ! [[ "$start_vlan" =~ ^[0-9]+$ && "$end_vlan" =~ ^[0-9]+$ && "$anchor_vlan" =~ ^[0-9]+$ ]]; then echo "FEHLER: VLAN-IDs und Anchor-VLAN muessen ganze Zahlen sein." >&2 return 2 fi if ! [[ "$prefix" =~ ^[0-9]+$ ]] || [ "$prefix" -lt "$MIN_PREFIX" ] || [ "$prefix" -gt "$MAX_PREFIX" ]; then echo "FEHLER: --prefix muss eine ganze Zahl zwischen ${MIN_PREFIX} und ${MAX_PREFIX} sein." >&2 return 2 fi if [ "$end_vlan" -lt "$start_vlan" ]; then echo "FEHLER: END-VLAN (${end_vlan}) ist kleiner als START-VLAN (${start_vlan})." >&2 return 1 fi if [ "$start_vlan" -lt "$anchor_vlan" ]; then echo "FEHLER: START-VLAN (${start_vlan}) liegt unter der Anchor-VLAN (${anchor_vlan})." >&2 return 1 fi local s_idx=$(( start_vlan - anchor_vlan )) local e_idx=$(( end_vlan - anchor_vlan )) local block_size=$(( 2 ** (32 - prefix) )) local s_third s_fourth e_third e_fourth if [ "$prefix" -ge 24 ]; then local per_24=$(( 256 / block_size )) s_third=$(( s_idx / per_24 )) s_fourth=$(( (s_idx % per_24) * block_size )) e_third=$(( e_idx / per_24 )) e_fourth=$(( (e_idx % per_24) * block_size )) else local step3=$(( block_size / 256 )) s_third=$(( s_idx * step3 )) s_fourth=0 e_third=$(( e_idx * step3 )) e_fourth=0 fi if [ "$e_third" -gt 255 ]; then echo "WARNUNG: Range ueberschreitet das 3. Oktett (>255). Basis-Netz oder Praefix zu klein." >&2 fi local start_net="${base_net}.${s_third}.${s_fourth}/${prefix}" local end_net="${base_net}.${e_third}.${e_fourth}/${prefix}" local count_vlans=$(( end_vlan - start_vlan + 1 )) local count24=$(( e_third - s_third + 1 )) echo echo " Basis-Netz: ${base_net}.x.x (Anchor-VLAN ${anchor_vlan} = ${base_net}.0.0/${prefix})" echo " VLAN-Range: ${start_vlan} - ${end_vlan}" echo " Praefix: /${prefix} (${block_size} Adressen je Subnetz)" echo echo " Benoetigte Subnetze: ${count_vlans} (verteilt auf ${count24} x /24)" echo echo " Start-Netz: ${start_net} (VLAN ${start_vlan})" echo " End-Netz: ${end_net} (VLAN ${end_vlan})" echo echo " --------------------------------------------" echo " Gesamt-Range: ${start_net} - ${end_net}" echo return 0 } main "$@"