xref: /minix/minix/commands/netconf/netconf.sh (revision fb9c64b2)
1#!/bin/sh
2#
3#	netconf 0.2 - Configure network
4#
5# Changes:
6#	v0.2: rewrite for NetBSD network infrastructure
7#	 - the primary choice is now for an interface, not a network card;
8#	 - manual driver configuration is now an exception;
9#	 - the menu transition system is slightly more solid;
10#	 - all non-interactive functionality has been removed.
11#
12
13# Get system config
14. /etc/rc.conf
15
16LOCALRC=/usr/etc/rc.local
17IFCONF=/etc/ifconfig.
18RESOLVCONF=/etc/resolv.conf
19HOSTNAME=/etc/hostname.file
20USRKBFILE=/.usrkb
21
22prefix=""
23cd="no" # running from cd?
24changed="no" # have any ifconfig.if(5) files been changed?
25
26usage()
27{
28    cat >&2 <<'EOF'
29Usage:
30
31  netconf [-lh] [-p <prefix>]
32
33  flags:
34     -l Print a list of configurable interfaces
35     -h Print this help file
36     -p Set a path prefix for all configuration files (e.g., /mnt)
37EOF
38    exit 1
39}
40
41backup_file()
42{
43	# Do not make backups if we're running from CD.
44	if [ "$cd" != "yes" -a -f "$1" ]; then
45		mv "$1" "$1~" || exit 1
46		echo
47		echo "Backed up $1 to $1~"
48	fi
49}
50
51select_number()
52{
53	while true; do
54		echo -n "$4 [$3] "
55		read input
56		case "$input" in
57		'')
58			return $3
59			;;
60		*[!0-9]*)
61			;;
62		*)
63			[ $input -ge $1 -a $input -le $2 ] && return $input
64			;;
65		esac
66	done
67}
68
69interfaces()
70{
71	# Get a list of interfaces that are not virtual (i.e., cloners). There
72	# is always one virtual interface type ("lo", loopback).
73	cloners_regex='^('`ifconfig -C | sed 's/ /[0-9]|/g'`'[0-9])'
74	iflist=`ifconfig -l | tr ' ' '\n' | grep -vE "$cloners_regex"`
75
76	ifcount=0
77	ifunconf=0 # the first interface with no configuration file, or 0
78	if [ -z "$iflist" ]; then
79		echo "    No network hardware interfaces detected!"
80	else
81		for if in $iflist; do
82			ifcount=$(($ifcount + 1))
83			if [ -r $IFCONF$if ]; then
84				info="($1)"
85			else
86				[ $ifunconf -eq 0 ] && ifunconf=$ifcount
87				info=""
88			fi
89			printf "%2d. %-8s %s\n" $ifcount "$if" "$info"
90		done
91	fi
92}
93
94do_step1()
95{
96	echo "
97The following network interfaces are available for configuration. These are
98interfaces corresponding to network drivers that are currently running. If no
99interface is listed for your network card here, then either MINIX 3 does not
100support your card, or, if it is not a plug-and-play device, it may require
101manual configuration first.
102
103Please choose the interface you would like to configure, or another option.
104"
105	interfaces "already configured"
106	echo
107	manual_choice=$(($ifcount + 1))
108	quit_choice=$(($ifcount + 2))
109	printf "%2d. Manually configure an ethernet driver\n" $manual_choice
110	printf "%2d. Quit\n\n" $quit_choice
111
112	default_choice=$ifunconf
113	[ $default_choice -eq 0 ] && default_choice=$quit_choice
114
115	select_number 1 $quit_choice $default_choice "Interface choice?"
116	choice=$?
117
118	case $choice in
119	$manual_choice)
120		step=do_stepM
121		;;
122	$quit_choice)
123		;;
124	*)
125		ifchoice="$(echo $iflist | cut -d' ' -f$choice)"
126		step=do_step2
127	esac
128}
129
130do_stepM()
131{
132	# TODO: it would be nice if this list changed on a per-platform basis..
133	echo "
134MINIX 3 has drivers for a limited number of older cards that require manual
135configuration. They are shown below. Please choose one of the listed options.
136
137 1. 3Com 501 or 3Com 509 based ISA card (i386)
138 2. NE2000, 3Com 503, or WD based ISA card (i386) (emulated by Bochs, Qemu)
139
140 3. Go back to interface selection
141 4. Quit
142"
143
144	select_number 1 4 4 "Card choice?"
145
146	case $? in
147	1)
148		driver=dpeth
149		driverargs="#dpeth_args='DPETH0=port:irq:memory'"
150		echo "
151Note: After installing, edit $LOCALRC to the right configuration."
152		;;
153	2)
154		driver=dp8390
155		driverargs="dp8390_args='DPETH0=300:9'"
156		echo "
157Note: After installing, edit $LOCALRC to the right configuration.
158You may then also have to edit /etc/system.conf.d/dp8390 to match.
159For now, the defaults for emulation by Bochs/Qemu have been set."
160		;;
161	3)
162		step=do_step1
163		return
164		;;
165	4)
166		return
167		;;
168	esac
169
170	backup_file "$LOCALRC"
171	echo "# Generated by netconf(8). Edit as necessary." > $LOCALRC
172	echo "netdriver='"$driver"'" >> $LOCALRC
173	echo "$driverargs" >> $LOCALRC
174
175	# $LOCALRC typically expands to /mnt/usr/etc/rc.local, so leave room..
176	echo "
177A template to start the driver has been written to $LOCALRC . As
178noted above, you may have to edit it. Once you are done editing, reboot the
179system, after which the driver will be started. Once the driver is running,
180you can run 'netconf' to configure the corresponding network interface."
181}
182
183do_step2()
184{
185	iffile="$IFCONF$ifchoice"
186
187	echo "
188Configure interface $ifchoice using DHCP or manually?
189
190For now, the choice here is primarily about IPv4. With DHCP it is possible to
191enable IPv6 as well. Even if the local network has no IPv6 facilities, enabling
192IPv6 should do no harm. For IPv6-only mode or any other configuration that is
193not supported here, you will have to edit $iffile yourself.
194
195 1. Automatically using DHCP (IPv4 + IPv6)
196 2. Automatically using DHCP (IPv4 only)
197 3. Manually (IPv4 only)"
198
199	if [ -r "$iffile" ]; then
200		echo " 4. Remove current configuration"
201		remove_choice=4
202		goback_choice=5
203		quit_choice=6
204	else
205		remove_choice=X
206		goback_choice=4
207		quit_choice=5
208	fi
209
210	echo
211	printf "%2d. Go back to interface selection\n" $goback_choice
212	printf "%2d. Quit\n\n" $quit_choice
213
214	select_number 1 $quit_choice 1 "Configuration choice?"
215
216	case $? in
217	1)
218		backup_file "$iffile"
219		echo 'up' > $iffile
220		echo '!dhcpcd -qM $int' >> $iffile
221
222		echo
223		echo "Interface $ifchoice configured for DHCP (IPv4 + IPv6)."
224		step=do_step3
225		;;
226	2)
227		backup_file "$iffile"
228		echo 'up' > $iffile
229		echo '!dhcpcd -qM -4 $int' >> $iffile
230
231		echo
232		echo "Interface $ifchoice configured for DHCP (IPv4 only)."
233		step=do_step3
234		;;
235	3)
236		# Query user for settings
237		#
238		# Some of these settings (hostname, nameservers) do not apply
239		# to just the selected interface. Still, they are what one has
240		# to specify for a complete manual configuration. In order to
241		# make manual configuration of multiple interfaces less
242		# frustrating in this regard, offer defaults that match what
243		# may just have been set already.
244
245		echo
246
247		# Hostname
248		if [ -r $HOSTNAME ]; then
249			hostname_default=$(cat $HOSTNAME)
250		else
251			hostname_default="minix"
252		fi
253		echo -n "Hostname [$hostname_default]: "
254		read hostname
255		if [ -z "$hostname" ]; then
256			hostname="$hostname_default"
257		fi
258
259		# IP address
260		ip=""
261		while [ -z "$ip" ]; do
262			echo -n "IP address []: "
263			read ip
264		done
265
266		# Netmask
267		echo -n "Netmask (optional) []: "
268		read netmask
269		[ -n "$netmask" ] && netmask=" netmask $netmask"
270
271		# Gateway (no gateway is fine for local networking)
272		echo -n "Gateway (optional) []: "
273		read gateway
274
275		# DNS Servers
276		dns1_default="$(grep '^nameserver' $RESOLVCONF 2>/dev/null | \
277		    sed '1q' | awk '{print $2}')"
278		dns2_default="$(grep '^nameserver' $RESOLVCONF 2>/dev/null | \
279		    sed '2q;d' | awk '{print $2}')"
280
281		echo -n "Primary DNS Server [$dns1_default]: "
282		read dns1
283		[ -z "$dns1" ] && dns1="$dns1_default"
284
285		if [ -n "$dns1" ]; then
286			echo -n "Secondary DNS Server (optional) [$dns2_default]: "
287			read dns2
288			[ -z "$dns2" ] && dns2="$dns2_default"
289		else
290			dns2=""
291		fi
292
293		backup_file "$HOSTNAME"
294		echo "$hostname" > $HOSTNAME
295		hostname "$hostname"
296
297		backup_file "$iffile"
298		echo 'up' > $iffile
299		echo "inet $ip$netmask" >> $iffile
300		if [ -n "$gateway" ]; then
301			echo "!route -q add default $gateway" >> $iffile
302		fi
303
304		if [ -n "$dns1" ]; then
305			backup_file "$RESOLVCONF"
306			echo "nameserver $dns1" > $RESOLVCONF
307			if [ -n "$dns2" ]; then
308				echo "nameserver $dns2" >> $RESOLVCONF
309			fi
310		fi
311
312		echo
313		echo "Interface $ifchoice configured manually."
314		step=do_step3
315		;;
316	$remove_choice)
317		backup_file "$iffile"
318		rm -f "$iffile"
319		echo
320		echo "Removed configuration for interface $ifchoice."
321		step=do_step3
322		;;
323	$goback_choice)
324		step=do_step1
325		;;
326	esac
327}
328
329do_step3()
330{
331
332	# We get here only if one of the ifconfig.if(5) files have changed.
333	changed="yes"
334
335	echo "
336Do you want to configure additional interfaces?
337
338You can also invoke the 'netconf' command as root at any later time.
339
340 1. Go back to interface selection
341 2. Quit
342"
343
344	# Note that "quit" is deliberately the default choice: most people will
345	# want to configure at most one interface, and keep pressing Enter in
346	# order to make it through the setup procedure as easily as possible.
347	select_number 1 2 2 "Menu choice?"
348
349	[ $? -eq 1 ] && step=do_step1
350}
351
352# Parse options
353while getopts "p:hl" arg; do
354    case "$arg" in
355	p) prefix=$OPTARG; ;;
356	h) usage ;;
357	l) echo "The following network hardware interfaces are detected:"
358	   echo
359	   interfaces "configured"
360	   exit 0
361	   ;;
362	\?) echo "Unknown option -$OPTARG"; usage ;;
363	:) echo "Missing required argument for -$OPTARG"; usage ;;
364	*)  usage ;;
365    esac
366done
367
368if [ -n "$prefix" ] ; then
369    if [ ! -d $prefix ]; then
370    	echo -e "It seems the supplied prefix (\`$prefix') is invalid."
371    	exit 1
372    fi
373    LOCALRC=$prefix$LOCALRC
374    IFCONF=$prefix$IFCONF
375    RESOLVCONF=$prefix$RESOLVCONF
376    HOSTNAME=$prefix$HOSTNAME
377fi
378
379if [ `whoami` != root ] ; then
380    echo "Please run netconf as root."
381    exit 1
382fi
383
384if ! ifconfig -l >/dev/null 2>&1; then
385    echo "Unable to obtain a list of interfaces. Is the LWIP service running?"
386    exit 1
387fi
388
389# Are we running from CD?
390if [ -f "$USRKBFILE" ] ; then
391    cd="yes" # We are running from CD
392fi
393
394# The interactive program.
395step=do_step1
396while [ $step != exit ]; do
397	proc=$step
398	step=exit
399	$proc
400done
401
402# Skip printing this last bit of information if it will not actually work.  The
403# fact that it will not work on the CD (i.e. from the setup program) at least
404# yet, is also the reason why we do not simply issue the command ourselves
405# right now.  We might reconsider this later.
406if [ "$changed" = "yes" -a -z "$prefix" ]; then
407	echo
408	echo "One or more of the interface configuration files have been changed."
409	echo "You can use the command 'service network restart' to reload them now."
410fi
411
412# Aesthetics.
413echo
414
415exit 0
416