From 2b65c252195cab82db17d08faff671dd5c7ef767 Mon Sep 17 00:00:00 2001 From: cclohmar Date: Wed, 29 Jul 2026 07:40:54 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20smart=20interface=20detection=20?= =?UTF-8?q?=E2=80=94=20lists=20all=20interfaces,=20validates=20choice,=20a?= =?UTF-8?q?uto-detects=20subnet=20mask?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.sh | 83 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/install.sh b/install.sh index 158a2c6..9d42c0d 100755 --- a/install.sh +++ b/install.sh @@ -21,6 +21,7 @@ CONFIG_SAVE="/root/.dnsmasq-setup.conf" # User-provided values (populated by prompts or saved config) IFACE=""; RANGE_START=""; RANGE_END=""; NETMASK="" LEASE_TIME=""; GATEWAY_IP=""; DNS_SERVERS="" +SUBNET_MASK="255.255.255.0" # auto-detected from interface # Detected values ZORAXY_MODE="" # baremetal | docker | fresh @@ -118,51 +119,97 @@ install_deps() { # INTERACTIVE CONFIGURATION #============================================================================== +# list_interfaces prints available physical/virtual interfaces with IPs. +list_interfaces() { + echo "" + echo " Available network interfaces:" + ip -o addr show 2>/dev/null | awk '/inet / && $2 != "lo" { + split($2, iface, "@"); name=iface[1]; ip=$4; + state=$(NF); gsub(/state /, "", state); + printf " %-12s %-18s %s\n", name, ip, state + }' || true +} + +# detect_defaults uses routing info to guess the primary interface. detect_defaults() { - # Auto-detect primary network interface (graceful fallback if ip route fails) - IFACE_DEFAULT=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $5; exit}' || true) + IFACE_DEFAULT=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $5; exit}' | sed 's/@.*//' || true) [ -z "$IFACE_DEFAULT" ] && IFACE_DEFAULT="eth0" - # Auto-detect gateway GATEWAY_DEFAULT=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $3; exit}' || true) - [ -z "$GATEWAY_DEFAULT" ] && GATEWAY_DEFAULT="10.2.0.10" - # Auto-detect DNS from resolv.conf DNS_DEFAULT=$( (grep '^nameserver' /etc/resolv.conf 2>/dev/null || true) | awk '{print $2}' | tr '\n' ',' | sed 's/,$//') [ -z "$DNS_DEFAULT" ] && DNS_DEFAULT="1.1.1.1,8.8.8.8" + + # Try to derive subnet from the selected interface's IP + local iface_ip iface_cidr + iface_ip=$(ip -o addr show "$IFACE_DEFAULT" 2>/dev/null | awk '/inet / {print $4; exit}' || true) + iface_cidr="${iface_ip#*/}" + case "$iface_cidr" in + 24) SUBNET_MASK="255.255.255.0" ;; + 16) SUBNET_MASK="255.255.0.0" ;; + 8) SUBNET_MASK="255.0.0.0" ;; + *) SUBNET_MASK="255.255.255.0" ;; + esac +} + +# validate_interface checks the chosen interface exists and is UP. +validate_interface() { + local iface="$1" + if ! ip link show "$iface" >/dev/null 2>&1; then + err "Interface '$iface' does not exist." + return 1 + fi + if ! ip link show "$iface" 2>/dev/null | grep -q "state UP"; then + warn "Interface '$iface' is DOWN. DHCP won't work until it's brought up." + fi + return 0 } prompt_config() { echo "" echo -e "${BOLD}─────────────────────────────────────────${NC}" - echo -e "${BOLD} Network Configuration${NC}" + echo -e "${BOLD} Network Interface${NC}" echo -e "${BOLD}─────────────────────────────────────────${NC}" - echo "" - # Disable strict error handling during detection + prompts - # (ip route may fail, read may hit EOF without TTY) set +eo pipefail detect_defaults set -eo pipefail - # Network interface - read -rp " Network interface [$IFACE_DEFAULT]: " IFACE || true - IFACE="${IFACE:-$IFACE_DEFAULT}" + # Show interfaces + let user choose + list_interfaces + + while true; do + echo "" + read -rp " DHCP interface [$IFACE_DEFAULT]: " IFACE || true + IFACE="${IFACE:-$IFACE_DEFAULT}" + if validate_interface "$IFACE"; then break; fi + done + + # Detect gateway from the chosen interface if not already set + if [ -z "$GATEWAY_DEFAULT" ]; then + GATEWAY_DEFAULT="10.2.0.10" + fi # DHCP range echo "" - echo " DHCP IP Range" - read -rp " Start IP [10.2.0.100]: " RANGE_START || true + echo -e "${BOLD}─────────────────────────────────────────${NC}" + echo -e "${BOLD} DHCP Range${NC}" + echo -e "${BOLD}─────────────────────────────────────────${NC}" + + read -rp " Start IP [10.2.0.100]: " RANGE_START || true RANGE_START="${RANGE_START:-10.2.0.100}" - read -rp " End IP [10.2.0.150]: " RANGE_END || true + read -rp " End IP [10.2.0.150]: " RANGE_END || true RANGE_END="${RANGE_END:-10.2.0.150}" - read -rp " Subnet mask [255.255.255.0]: " NETMASK || true - NETMASK="${NETMASK:-255.255.255.0}" - read -rp " Lease time [12h]: " LEASE_TIME || true + read -rp " Subnet mask [$SUBNET_MASK]: " NETMASK || true + NETMASK="${NETMASK:-$SUBNET_MASK}" + read -rp " Lease time [12h]: " LEASE_TIME || true LEASE_TIME="${LEASE_TIME:-12h}" # Gateway & DNS echo "" + echo -e "${BOLD}─────────────────────────────────────────${NC}" + echo -e "${BOLD} Gateway & DNS${NC}" + echo -e "${BOLD}─────────────────────────────────────────${NC}" read -rp " Gateway IP [$GATEWAY_DEFAULT]: " GATEWAY_IP || true GATEWAY_IP="${GATEWAY_IP:-$GATEWAY_DEFAULT}" read -rp " DNS servers (comma-separated) [$DNS_DEFAULT]: " DNS_SERVERS || true