feat: smart interface detection — lists all interfaces, validates choice, auto-detects subnet mask

This commit is contained in:
Claus Lohmar 2026-07-29 07:40:54 +00:00
parent 075c914a36
commit 2b65c25219

View file

@ -21,6 +21,7 @@ CONFIG_SAVE="/root/.dnsmasq-setup.conf"
# User-provided values (populated by prompts or saved config) # User-provided values (populated by prompts or saved config)
IFACE=""; RANGE_START=""; RANGE_END=""; NETMASK="" IFACE=""; RANGE_START=""; RANGE_END=""; NETMASK=""
LEASE_TIME=""; GATEWAY_IP=""; DNS_SERVERS="" LEASE_TIME=""; GATEWAY_IP=""; DNS_SERVERS=""
SUBNET_MASK="255.255.255.0" # auto-detected from interface
# Detected values # Detected values
ZORAXY_MODE="" # baremetal | docker | fresh ZORAXY_MODE="" # baremetal | docker | fresh
@ -118,51 +119,97 @@ install_deps() {
# INTERACTIVE CONFIGURATION # 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() { 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}' | sed 's/@.*//' || true)
IFACE_DEFAULT=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $5; exit}' || true)
[ -z "$IFACE_DEFAULT" ] && IFACE_DEFAULT="eth0" [ -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) 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/,$//') 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" [ -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() { prompt_config() {
echo "" echo ""
echo -e "${BOLD}─────────────────────────────────────────${NC}" echo -e "${BOLD}─────────────────────────────────────────${NC}"
echo -e "${BOLD} Network Configuration${NC}" echo -e "${BOLD} Network Interface${NC}"
echo -e "${BOLD}─────────────────────────────────────────${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 set +eo pipefail
detect_defaults detect_defaults
set -eo pipefail set -eo pipefail
# Network interface # Show interfaces + let user choose
read -rp " Network interface [$IFACE_DEFAULT]: " IFACE || true list_interfaces
while true; do
echo ""
read -rp " DHCP interface [$IFACE_DEFAULT]: " IFACE || true
IFACE="${IFACE:-$IFACE_DEFAULT}" 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 # DHCP range
echo "" echo ""
echo " DHCP IP Range" 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 read -rp " Start IP [10.2.0.100]: " RANGE_START || true
RANGE_START="${RANGE_START:-10.2.0.100}" 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}" RANGE_END="${RANGE_END:-10.2.0.150}"
read -rp " Subnet mask [255.255.255.0]: " NETMASK || true read -rp " Subnet mask [$SUBNET_MASK]: " NETMASK || true
NETMASK="${NETMASK:-255.255.255.0}" NETMASK="${NETMASK:-$SUBNET_MASK}"
read -rp " Lease time [12h]: " LEASE_TIME || true read -rp " Lease time [12h]: " LEASE_TIME || true
LEASE_TIME="${LEASE_TIME:-12h}" LEASE_TIME="${LEASE_TIME:-12h}"
# Gateway & DNS # Gateway & DNS
echo "" echo ""
echo -e "${BOLD}─────────────────────────────────────────${NC}"
echo -e "${BOLD} Gateway & DNS${NC}"
echo -e "${BOLD}─────────────────────────────────────────${NC}"
read -rp " Gateway IP [$GATEWAY_DEFAULT]: " GATEWAY_IP || true read -rp " Gateway IP [$GATEWAY_DEFAULT]: " GATEWAY_IP || true
GATEWAY_IP="${GATEWAY_IP:-$GATEWAY_DEFAULT}" GATEWAY_IP="${GATEWAY_IP:-$GATEWAY_DEFAULT}"
read -rp " DNS servers (comma-separated) [$DNS_DEFAULT]: " DNS_SERVERS || true read -rp " DNS servers (comma-separated) [$DNS_DEFAULT]: " DNS_SERVERS || true