David van Moolenbroek 9a8b4f5601 netconf(8): rewrite
When possible, network drivers are now started automatically.  That
means that netconf(8)'s network driver selection has become obsolete.
This patch changes netconf(8) to allow the user to specify a network
configuration (currently one of DHCP IPv4+IPv6, DHCP IPv4-only,
manual IPv4-only) for any hardware network interfaces that are
currently present.

Selection of network drivers that require manual configuration first
(mainly old ISA cards) is still supported, but now as a special case.

Change-Id: I6208fc75192eb7f0b061862aaf7507f71a620da4
2017-04-30 13:16:19 +00:00

416 lines
9.6 KiB
Bash

#!/bin/sh
#
# netconf 0.2 - Configure network
#
# Changes:
# v0.2: rewrite for NetBSD network infrastructure
# - the primary choice is now for an interface, not a network card;
# - manual driver configuration is now an exception;
# - the menu transition system is slightly more solid;
# - all non-interactive functionality has been removed.
#
# Get system config
. /etc/rc.conf
LOCALRC=/usr/etc/rc.local
IFCONF=/etc/ifconfig.
RESOLVCONF=/etc/resolv.conf
HOSTNAME=/etc/hostname.file
USRKBFILE=/.usrkb
prefix=""
cd="no" # running from cd?
changed="no" # have any ifconfig.if(5) files been changed?
usage()
{
cat >&2 <<'EOF'
Usage:
netconf [-lh] [-p <prefix>]
flags:
-l Print a list of configurable interfaces
-h Print this help file
-p Set a path prefix for all configuration files (e.g., /mnt)
EOF
exit 1
}
backup_file()
{
# Do not make backups if we're running from CD.
if [ "$cd" != "yes" -a -f "$1" ]; then
mv "$1" "$1~" || exit 1
echo
echo "Backed up $1 to $1~"
fi
}
select_number()
{
while true; do
echo -n "$4 [$3] "
read input
case "$input" in
'')
return $3
;;
*[!0-9]*)
;;
*)
[ $input -ge $1 -a $input -le $2 ] && return $input
;;
esac
done
}
interfaces()
{
# Get a list of interfaces that are not virtual (i.e., cloners). There
# is always one virtual interface type ("lo", loopback).
cloners_regex='^('`ifconfig -C | sed 's/ /[0-9]|/g'`'[0-9])'
iflist=`ifconfig -l | tr ' ' '\n' | grep -vE "$cloners_regex"`
ifcount=0
ifunconf=0 # the first interface with no configuration file, or 0
if [ -z "$iflist" ]; then
echo " No network hardware interfaces detected!"
else
for if in $iflist; do
ifcount=$(($ifcount + 1))
if [ -r $IFCONF$if ]; then
info="($1)"
else
[ $ifunconf -eq 0 ] && ifunconf=$ifcount
info=""
fi
printf "%2d. %-8s %s\n" $ifcount "$if" "$info"
done
fi
}
do_step1()
{
echo "
The following network interfaces are available for configuration. These are
interfaces corresponding to network drivers that are currently running. If no
interface is listed for your network card here, then either MINIX 3 does not
support your card, or, if it is not a plug-and-play device, it may require
manual configuration first.
Please choose the interface you would like to configure, or another option.
"
interfaces "already configured"
echo
manual_choice=$(($ifcount + 1))
quit_choice=$(($ifcount + 2))
printf "%2d. Manually configure an ethernet driver\n" $manual_choice
printf "%2d. Quit\n\n" $quit_choice
default_choice=$ifunconf
[ $default_choice -eq 0 ] && default_choice=$quit_choice
select_number 1 $quit_choice $default_choice "Interface choice?"
choice=$?
case $choice in
$manual_choice)
step=do_stepM
;;
$quit_choice)
;;
*)
ifchoice="$(echo $iflist | cut -d' ' -f$choice)"
step=do_step2
esac
}
do_stepM()
{
# TODO: it would be nice if this list changed on a per-platform basis..
echo "
MINIX 3 has drivers for a limited number of older cards that require manual
configuration. They are shown below. Please choose one of the listed options.
1. 3Com 501 or 3Com 509 based ISA card (i386)
2. NE2000, 3Com 503, or WD based ISA card (i386) (emulated by Bochs, Qemu)
3. Go back to interface selection
4. Quit
"
select_number 1 4 4 "Card choice?"
case $? in
1)
driver=dpeth
driverargs="#dpeth_args='DPETH0=port:irq:memory'"
echo "
Note: After installing, edit $LOCALRC to the right configuration."
;;
2)
driver=dp8390
driverargs="dp8390_args='DPETH0=300:9'"
echo "
Note: After installing, edit $LOCALRC to the right configuration.
You may then also have to edit /etc/system.conf.d/dp8390 to match.
For now, the defaults for emulation by Bochs/Qemu have been set."
;;
3)
step=do_step1
return
;;
4)
return
;;
esac
backup_file "$LOCALRC"
echo "# Generated by netconf(8). Edit as necessary." > $LOCALRC
echo "netdriver='"$driver"'" >> $LOCALRC
echo "$driverargs" >> $LOCALRC
# $LOCALRC typically expands to /mnt/usr/etc/rc.local, so leave room..
echo "
A template to start the driver has been written to $LOCALRC . As
noted above, you may have to edit it. Once you are done editing, reboot the
system, after which the driver will be started. Once the driver is running,
you can run 'netconf' to configure the corresponding network interface."
}
do_step2()
{
iffile="$IFCONF$ifchoice"
echo "
Configure interface $ifchoice using DHCP or manually?
For now, the choice here is primarily about IPv4. With DHCP it is possible to
enable IPv6 as well. Even if the local network has no IPv6 facilities, enabling
IPv6 should do no harm. For IPv6-only mode or any other configuration that is
not supported here, you will have to edit $iffile yourself.
1. Automatically using DHCP (IPv4 + IPv6)
2. Automatically using DHCP (IPv4 only)
3. Manually (IPv4 only)"
if [ -r "$iffile" ]; then
echo " 4. Remove current configuration"
remove_choice=4
goback_choice=5
quit_choice=6
else
remove_choice=X
goback_choice=4
quit_choice=5
fi
echo
printf "%2d. Go back to interface selection\n" $goback_choice
printf "%2d. Quit\n\n" $quit_choice
select_number 1 $quit_choice 1 "Configuration choice?"
case $? in
1)
backup_file "$iffile"
echo 'up' > $iffile
echo '!dhcpcd -qM $int' >> $iffile
echo
echo "Interface $ifchoice configured for DHCP (IPv4 + IPv6)."
step=do_step3
;;
2)
backup_file "$iffile"
echo 'up' > $iffile
echo '!dhcpcd -qM -4 $int' >> $iffile
echo
echo "Interface $ifchoice configured for DHCP (IPv4 only)."
step=do_step3
;;
3)
# Query user for settings
#
# Some of these settings (hostname, nameservers) do not apply
# to just the selected interface. Still, they are what one has
# to specify for a complete manual configuration. In order to
# make manual configuration of multiple interfaces less
# frustrating in this regard, offer defaults that match what
# may just have been set already.
echo
# Hostname
if [ -r $HOSTNAME ]; then
hostname_default=$(cat $HOSTNAME)
else
hostname_default="minix"
fi
echo -n "Hostname [$hostname_default]: "
read hostname
if [ -z "$hostname" ]; then
hostname="$hostname_default"
fi
# IP address
ip=""
while [ -z "$ip" ]; do
echo -n "IP address []: "
read ip
done
# Netmask
echo -n "Netmask (optional) []: "
read netmask
[ -n "$netmask" ] && netmask=" netmask $netmask"
# Gateway (no gateway is fine for local networking)
echo -n "Gateway (optional) []: "
read gateway
# DNS Servers
dns1_default="$(grep '^nameserver' $RESOLVCONF 2>/dev/null | \
sed '1q' | awk '{print $2}')"
dns2_default="$(grep '^nameserver' $RESOLVCONF 2>/dev/null | \
sed '2q;d' | awk '{print $2}')"
echo -n "Primary DNS Server [$dns1_default]: "
read dns1
[ -z "$dns1" ] && dns1="$dns1_default"
if [ -n "$dns1" ]; then
echo -n "Secondary DNS Server (optional) [$dns2_default]: "
read dns2
[ -z "$dns2" ] && dns2="$dns2_default"
else
dns2=""
fi
backup_file "$HOSTNAME"
echo "$hostname" > $HOSTNAME
hostname "$hostname"
backup_file "$iffile"
echo 'up' > $iffile
echo "inet $ip$netmask" >> $iffile
if [ -n "$gateway" ]; then
echo "!route -q add default $gateway" >> $iffile
fi
if [ -n "$dns1" ]; then
backup_file "$RESOLVCONF"
echo "nameserver $dns1" > $RESOLVCONF
if [ -n "$dns2" ]; then
echo "nameserver $dns2" >> $RESOLVCONF
fi
fi
echo
echo "Interface $ifchoice configured manually."
step=do_step3
;;
$remove_choice)
backup_file "$iffile"
rm -f "$iffile"
echo
echo "Removed configuration for interface $ifchoice."
step=do_step3
;;
$goback_choice)
step=do_step1
;;
esac
}
do_step3()
{
# We get here only if one of the ifconfig.if(5) files have changed.
changed="yes"
echo "
Do you want to configure additional interfaces?
You can also invoke the 'netconf' command as root at any later time.
1. Go back to interface selection
2. Quit
"
# Note that "quit" is deliberately the default choice: most people will
# want to configure at most one interface, and keep pressing Enter in
# order to make it through the setup procedure as easily as possible.
select_number 1 2 2 "Menu choice?"
[ $? -eq 1 ] && step=do_step1
}
# Parse options
while getopts "p:hl" arg; do
case "$arg" in
p) prefix=$OPTARG; ;;
h) usage ;;
l) echo "The following network hardware interfaces are detected:"
echo
interfaces "configured"
exit 0
;;
\?) echo "Unknown option -$OPTARG"; usage ;;
:) echo "Missing required argument for -$OPTARG"; usage ;;
*) usage ;;
esac
done
if [ -n "$prefix" ] ; then
if [ ! -d $prefix ]; then
echo -e "It seems the supplied prefix (\`$prefix') is invalid."
exit 1
fi
LOCALRC=$prefix$LOCALRC
IFCONF=$prefix$IFCONF
RESOLVCONF=$prefix$RESOLVCONF
HOSTNAME=$prefix$HOSTNAME
fi
if [ `whoami` != root ] ; then
echo "Please run netconf as root."
exit 1
fi
if ! ifconfig -l >/dev/null 2>&1; then
echo "Unable to obtain a list of interfaces. Is the LWIP service running?"
exit 1
fi
# Are we running from CD?
if [ -f "$USRKBFILE" ] ; then
cd="yes" # We are running from CD
fi
# The interactive program.
step=do_step1
while [ $step != exit ]; do
proc=$step
step=exit
$proc
done
# Skip printing this last bit of information if it will not actually work. The
# fact that it will not work on the CD (i.e. from the setup program) at least
# yet, is also the reason why we do not simply issue the command ourselves
# right now. We might reconsider this later.
if [ "$changed" = "yes" -a -z "$prefix" ]; then
echo
echo "One or more of the interface configuration files have been changed."
echo "You can use the command 'service network restart' to reload them now."
fi
# Aesthetics.
echo
exit 0