1#!/bin/sh
2#-
3# Copyright (c) 2011 Nathan Whitehorn
4# All rights reserved.
5# Copyright (c) 2011 The FreeBSD Foundation
6# All rights reserved.
7#
8# Portions of this software were developed by Bjoern Zeeb
9# under sponsorship from the FreeBSD Foundation.
10#
11# Redistribution and use in source and binary forms, with or without
12# modification, are permitted provided that the following conditions
13# are met:
14# 1. Redistributions of source code must retain the above copyright
15#    notice, this list of conditions and the following disclaimer.
16# 2. Redistributions in binary form must reproduce the above copyright
17#    notice, this list of conditions and the following disclaimer in the
18#    documentation and/or other materials provided with the distribution.
19#
20# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30# SUCH DAMAGE.
31#
32
33BSDCFG_SHARE="/usr/share/bsdconfig"
34. $BSDCFG_SHARE/common.subr || exit 1
35
36INTERFACES=""
37BSDDIALOG_ITEMS=""
38
39: ${BSDDIALOG_OK=0}
40: ${BSDDIALOG_CANCEL=1}
41: ${BSDDIALOG_HELP=2}
42: ${BSDDIALOG_EXTRA=3}
43: ${BSDDIALOG_ESC=5}
44: ${BSDDIALOG_ERROR=255}
45
46for IF in `ifconfig -l`; do
47	test "$IF" = "lo0" && continue
48	(ifconfig -g wlan | egrep -wq $IF) && continue
49	INTERFACES="$INTERFACES $IF"
50done
51
52WIRELESS_INTERFACES="$(sysctl -in net.wlan.devices)"
53INTERFACES="$INTERFACES${WIRELESS_INTERFACES:+ }$WIRELESS_INTERFACES"
54is_wireless_if() {
55	for IF in $(sysctl -in net.wlan.devices); do
56		if [ $IF = $1 ]; then
57			return 0
58		fi
59	done
60	return 1
61}
62
63for IF in $INTERFACES; do
64	DESC=`sysctl -n dev.$(echo $IF | sed -E 's/([[:alpha:]]*)([[:digit:]]*)/\1.\2/g').%desc`
65	BSDDIALOG_ITEMS="$BSDDIALOG_ITEMS $IF \"$DESC\""
66done
67
68if [ -z "$INTERFACES" ]; then
69	bsddialog --backtitle "$OSNAME Installer" \
70	    --title 'Network Configuration' \
71	    --msgbox 'No network interfaces present to configure.' 0 0
72	exit 1
73fi
74
75exec 5>&1
76INTERFACE=$(echo $BSDDIALOG_ITEMS | xargs -o bsddialog \
77    --backtitle "$OSNAME Installer" --title 'Network Configuration' \
78    --ok-label 'Auto' --extra-button --extra-label 'Manual' \
79    --menu 'Please select a network interface and configuration mode:' 0 0 0 2>&1 1>&5)
80# xargs collapses exit codes to 0/1 (ignoring signals and 255), so exploit
81# bsddialog output being empty when cancelling to distinguish Manual (Extra)
82# from Cancel.
83if [ $? -eq $BSDDIALOG_OK ]; then
84	AUTO=auto
85else
86	if [ -z "$INTERFACE" ]; then
87		exit 1
88	fi
89	AUTO=
90fi
91exec 5>&-
92
93: > $BSDINSTALL_TMPETC/._rc.conf.net
94
95IFCONFIG_PREFIX=""
96if is_wireless_if $INTERFACE; then
97	NEXT_WLAN_IFACE=wlan0	# XXX
98	sysrc -f $BSDINSTALL_TMPETC/._rc.conf.net wlans_$INTERFACE="$NEXT_WLAN_IFACE"
99	IFCONFIG_PREFIX="WPA "
100	if [ ! -z $BSDINSTALL_CONFIGCURRENT ]; then
101		ifconfig $NEXT_WLAN_IFACE create wlandev $INTERFACE
102		ifconfig $NEXT_WLAN_IFACE up
103	fi
104	bsdinstall wlanconfig $NEXT_WLAN_IFACE || exec $0
105	INTERFACE="$NEXT_WLAN_IFACE"
106fi
107
108IPV6_AVAIL=0
109IPV4_AVAIL=0
110sysctl -N kern.features.inet6 > /dev/null 2>&1
111case $? in
1120)	IPV6_AVAIL=1 ;;
113esac
114sysctl -N kern.features.inet > /dev/null 2>&1
115case $? in
1160)	IPV4_AVAIL=1 ;;
117esac
118
119AUTO_FAIL=
120if [ ${IPV4_AVAIL} -eq 1 -a -z "$AUTO" ]; then
121	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
122	    --yesno 'Would you like to configure IPv4 for this interface?' 0 0
123	if [ $? -ne $BSDDIALOG_OK ]; then
124		IPV4_AVAIL=0
125	fi
126fi
127if [ ${IPV4_AVAIL} -eq 1 ]; then
128	bsdinstall netconfig_ipv4 ${INTERFACE} "${IFCONFIG_PREFIX}" $AUTO
129	if [ $? -ne $BSDDIALOG_OK ]; then
130		if [ -z "$AUTO" ]; then
131			exec $0
132		fi
133		IPV4_AVAIL=0
134		AUTO_FAIL="$AUTO_FAIL${AUTO_FAIL:+, }IPv4"
135	fi
136fi
137# In case wlanconfig left an option and we do not support IPv4 we need to write
138# it out on its own.  We cannot write it out with IPv6 as that suffix.
139if [ ${IPV4_AVAIL} -eq 0 -a -n ${IFCONFIG_PREFIX} ]; then
140	sysrc -f $BSDINSTALL_TMPETC/._rc.conf.net ifconfig_$INTERFACE="${IFCONFIG_PREFIX}"
141fi
142if [ ${IPV6_AVAIL} -eq 1 -a -z "$AUTO" ]; then
143	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
144	    --yesno 'Would you like to configure IPv6 for this interface?' 0 0
145	if [ $? -ne $BSDDIALOG_OK ]; then
146		IPV6_AVAIL=0
147	fi
148fi
149if [ ${IPV6_AVAIL} -eq 1 ]; then
150	bsdinstall netconfig_ipv6 ${INTERFACE} $AUTO
151	if [ $? -ne $BSDDIALOG_OK ]; then
152		if [ -z "$AUTO" ]; then
153			exec $0
154		fi
155		IPV6_AVAIL=0
156		AUTO_FAIL="$AUTO_FAIL${AUTO_FAIL:+, }IPv6"
157	fi
158fi
159
160SEARCH=""
161IP4_1=""
162IP4_2=""
163IP6_1=""
164IP6_2=""
165while read key value; do
166	case "${key}" in
167	search)		SEARCH="${value}" ;;
168	nameserver)	# is more trick as we have to distinguish v4 and v6
169		case "${value}" in
170		[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)
171			if [ -z "${IP4_1}" ] ; then
172				IP4_1="${value}"
173			elif [ -z "${IP4_2}" ]; then
174				IP4_2="${value}"
175			fi
176			;;
177		[0-9A-Fa-f:]*:*)
178			if [ -z "${IP6_1}" ] ; then
179				IP6_1="${value}"
180			elif [ -z "${IP6_2}" ]; then
181				IP6_2="${value}"
182			fi
183			;;
184		esac
185		;;
186	# ignore others
187	esac
188done < ${BSDINSTALL_TMPETC}/resolv.conf
189
190RESOLV=""
191if [ ${IPV6_AVAIL} -eq 1 -a ${IPV4_AVAIL} -eq 1 ];  then
192	RESOLV="
193	    'Search' 1 1 \"${SEARCH}\" 1 16 50 50 0
194	    'Nameserver' 2 1 \"Nameserver\" 2 1 11 11 2
195	    'IPv6 DNS #1' 2 1 \"${IP6_1}\" 2 16 50 50 0
196	    'IPv6 DNS #2' 3 1 \"${IP6_2}\" 3 16 50 50 0
197	    'IPv4 DNS #1' 4 1 \"${IP4_1}\" 4 16 16 16 0
198	    'IPv4 DNS #2' 5 1 \"${IP4_2}\" 5 16 16 16 0"
199elif [ ${IPV6_AVAIL} -eq 1 ]; then
200	RESOLV="
201	    'Search' 1 1 \"${SEARCH}\" 1 16 50 50 0
202	    'Nameserver' 2 1 \"Nameserver\" 2 1 11 11 2
203	    'IPv6 DNS #1' 2 1 \"${IP6_1}\" 2 16 50 50 0
204	    'IPv6 DNS #2' 3 1 \"${IP6_2}\" 3 16 50 50 0"
205elif [ ${IPV4_AVAIL} -eq 1 ]; then
206	RESOLV="
207	    'Search' 1 1 \"${SEARCH}\" 1 16 50 50 0
208	    'Nameserver' 2 1 \"Nameserver\" 2 1 11 11 2
209	    'IPv4 DNS #1' 2 1 \"${IP4_1}\" 2 16 16 16 0
210	    'IPv4 DNS #2' 3 1 \"${IP4_2}\" 3 16 16 16 0"
211else
212	if [ -n "$AUTO_FAIL" ]; then
213		bsddialog --backtitle "$OSNAME Installer" \
214		    --msgbox "Failed to automatically configure interface (tried $AUTO_FAIL)." 0 0
215		exec $0
216	fi
217	exit 0
218fi
219
220# Auto only guaranteed to have IPv4 and/or IPv6 address; may not have
221# nameserver available
222if [ -n "$AUTO" ] && [ -n "${IP4_1}" -o -n "${IP6_1}" ]; then
223	# Convert from bsddialog arguments to default output
224	RESOLV=$(echo "${RESOLV}" | xargs -n9 sh -c 'echo "$4"' '')
225else
226	exec 5>&1
227	RESOLV=$(echo "${RESOLV}" | xargs -o bsddialog --backtitle "$OSNAME Installer" \
228		--title 'Network Configuration' \
229		--mixedform 'Resolver Configuration' 0 0 0 \
230	2>&1 1>&5)
231	if [ $? -eq $BSDDIALOG_CANCEL ]; then exec $0; fi
232	exec 5>&-
233fi
234
235echo ${RESOLV} | tr ' ' '\n' | \
236awk '
237BEGIN {
238	search=-1;
239}
240{
241	if (/^[[:space:]]+$/) {
242		next;
243	}
244	if (/^Nameserver$/) {
245		printf "\n";
246		search=0;
247		next;
248	}
249	if (search == -1) {
250		printf "search ";
251		search=1;
252	}
253	if (search > 0) {
254		printf "%s%s", (search > 1) ? " " : "", $1;
255		search++;
256		next;
257	}
258	printf "nameserver %s\n", $1;
259}' > ${BSDINSTALL_TMPETC}/resolv.conf
260
261mv $BSDINSTALL_TMPETC/._rc.conf.net $BSDINSTALL_TMPETC/rc.conf.net
262