diff --git a/iso/overlay/usr/local/bin/netconf b/iso/overlay/usr/local/bin/netconf index 277713e..651caf8 100755 --- a/iso/overlay/usr/local/bin/netconf +++ b/iso/overlay/usr/local/bin/netconf @@ -1,61 +1,163 @@ #!/bin/sh # Quick network configurator for the local console. +# Type 'a' at any prompt to abort, 'b' to go back. set -e -# List interfaces (exclude lo) -IFACES=$(ip -o link show | awk -F': ' '$2 != "lo" {print $2}' | cut -d@ -f1) +abort() { echo "Aborted."; exit 0; } -echo "Interfaces:" -i=1 -for iface in $IFACES; do - ip=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet /{print $2}' | head -1) - echo " $i) $iface ${ip:-no IP}" - i=$((i+1)) -done -echo "" -printf "Interface number or name [Enter = first]: " -read INPUT +ask() { + # ask VARNAME "prompt" [default] + # Sets VARNAME. Returns 1 on 'b' (back), calls abort on 'a'. + _var="$1"; _prompt="$2"; _default="$3" + while true; do + if [ -n "$_default" ]; then + printf "%s [%s] (b=back a=abort): " "$_prompt" "$_default" + else + printf "%s (b=back a=abort): " "$_prompt" + fi + read _input + case "$_input" in + a|A) abort ;; + b|B) return 1 ;; + "") + if [ -n "$_default" ]; then + eval "$_var=\"\$_default\"" + return 0 + else + echo " Required — please enter a value." + fi + ;; + *) + eval "$_var=\"\$_input\"" + return 0 + ;; + esac + done +} -if [ -z "$INPUT" ]; then - IFACE=$(echo "$IFACES" | head -1) -elif echo "$INPUT" | grep -qE '^[0-9]+$'; then - # Numeric input — resolve to name - IFACE=$(echo "$IFACES" | awk "NR==$INPUT") - if [ -z "$IFACE" ]; then - echo "Error: no interface with number $INPUT" +# ── Step 1: choose interface ─────────────────────────────────────────────────── + +choose_iface() { + IFACES=$(ip -o link show | awk -F': ' '$2 != "lo" {print $2}' | cut -d@ -f1) + if [ -z "$IFACES" ]; then + echo "No network interfaces found." exit 1 fi -else - IFACE="$INPUT" -fi -echo "Selected: $IFACE" -echo "" -echo " 1) DHCP" -echo " 2) Static" -printf "Mode [1]: " -read MODE -MODE=${MODE:-1} + echo "" + echo "Interfaces:" + i=1 + for iface in $IFACES; do + ip=$(ip -4 addr show "$iface" 2>/dev/null | awk '/inet /{print $2}' | head -1) + echo " $i) $iface ${ip:-no IP}" + i=$((i+1)) + done + echo "" -if [ "$MODE" = "1" ]; then + FIRST=$(echo "$IFACES" | head -1) + while true; do + printf "Interface number or name [%s] (a=abort): " "$FIRST" + read INPUT + case "$INPUT" in + a|A) abort ;; + "") + IFACE="$FIRST" + break + ;; + *) + if echo "$INPUT" | grep -qE '^[0-9]+$'; then + IFACE=$(echo "$IFACES" | awk "NR==$INPUT") + if [ -z "$IFACE" ]; then + echo " No interface #$INPUT — try again." + continue + fi + else + # Validate name exists + if ! echo "$IFACES" | grep -qx "$INPUT"; then + echo " Unknown interface '$INPUT' — try again." + continue + fi + IFACE="$INPUT" + fi + break + ;; + esac + done + echo "Selected: $IFACE" +} + +# ── Step 2: choose mode ──────────────────────────────────────────────────────── + +choose_mode() { + echo "" + echo " 1) DHCP" + echo " 2) Static IP" + echo "" + while true; do + printf "Mode [1] (b=back a=abort): " + read INPUT + case "$INPUT" in + a|A) abort ;; + b|B) return 1 ;; + ""|1) MODE=dhcp; break ;; + 2) MODE=static; break ;; + *) echo " Enter 1 or 2." ;; + esac + done +} + +# ── Step 3a: DHCP ───────────────────────────────────────────────────────────── + +run_dhcp() { echo "Running DHCP on $IFACE..." dhclient -v "$IFACE" -else - printf "IP address (e.g. 192.168.1.100/24): " - read ADDR - printf "Gateway (e.g. 192.168.1.1): " - read GW - printf "DNS [8.8.8.8]: " - read DNS - DNS=${DNS:-8.8.8.8} +} + +# ── Step 3b: Static ─────────────────────────────────────────────────────────── + +run_static() { + while true; do + ask ADDR "IP address (e.g. 192.168.1.100/24)" || return 1 + # Basic format check: must contain a dot and a / + if ! echo "$ADDR" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$'; then + echo " Invalid format — use x.x.x.x/prefix (e.g. 192.168.1.10/24)." + continue + fi + break + done + + while true; do + ask GW "Gateway (e.g. 192.168.1.1)" || return 1 + if ! echo "$GW" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then + echo " Invalid IP address." + continue + fi + break + done + + ask DNS "DNS server" "8.8.8.8" || return 1 ip addr flush dev "$IFACE" ip addr add "$ADDR" dev "$IFACE" ip link set "$IFACE" up - ip route add default via "$GW" + ip route add default via "$GW" 2>/dev/null || true echo "nameserver $DNS" > /etc/resolv.conf echo "Done." -fi +} + +# ── Main loop ───────────────────────────────────────────────────────────────── + +choose_iface + +while true; do + choose_mode || { choose_iface; continue; } + + if [ "$MODE" = "dhcp" ]; then + run_dhcp && break + else + run_static && break || continue + fi +done echo "" ip -4 addr show "$IFACE"