#!/bin/sh # Quick network configurator for the local console. # Type 'a' at any prompt to abort, 'b' to go back. set -e # Requires root for ip/dhclient/resolv.conf — re-exec via sudo if needed. if [ "$(id -u)" -ne 0 ]; then exec sudo "$0" "$@" fi abort() { echo "Aborted."; exit 0; } 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 } # ── 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 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 "" 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" } # ── 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" 2>/dev/null || true echo "nameserver $DNS" > /etc/resolv.conf echo "Done." } # ── 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"