setup-interfaces.in 7.22 KB
Newer Older
Natanael Copa's avatar
Natanael Copa committed
1 2 3 4 5
#!/bin/sh

PROGRAM=setup-interfaces
PREFIX=

Natanael Copa's avatar
Natanael Copa committed
6 7 8
for i in ./libalpine.sh $PREFIX/lib/libalpine.sh; do
	[ -e $i ] && . $i && break
done
Natanael Copa's avatar
Natanael Copa committed
9

10 11 12 13
unconfigured_add() {
	touch $1.noconf
}

Natanael Copa's avatar
Natanael Copa committed
14 15 16 17
unconfigured_detect() {
	local i=
	for i in ${INTERFACES:-$(available_ifaces)}; do
		if [ "$i" != "lo" ]; then
18
			unconfigured_add $i
Natanael Copa's avatar
Natanael Copa committed
19 20
		fi
	done
Natanael Copa's avatar
Natanael Copa committed
21 22
}

Natanael Copa's avatar
Natanael Copa committed
23
unconfigured_get_first() {
Natanael Copa's avatar
Natanael Copa committed
24 25 26
	ls *.noconf 2>/dev/null | head -n 1 | sed 's/.noconf//'
}

Natanael Copa's avatar
Natanael Copa committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
unconfigured_del() {
	rm $1.noconf
}

unconfigured_all_done() {
	local i=
	for i in *.noconf; do
		[ -e $i ] && return 1
	done
	return 0
}

unconfigured_list() {
	local list= i=
	for i in *.noconf; do
		[ -e "$i" ] || continue
		list="${list} ${i%.noconf}"
	done
	echo $list
}

unconfigured_isin() {
	[ -f $1.noconf ]
}

52 53 54 55
iface_exists() {
	test -e /sys/class/net/$1
}

Natanael Copa's avatar
Natanael Copa committed
56 57 58 59
get_default_addr() {
	# check if dhcpcd is running
	if pidof dhcpcd > /dev/null && [ -f "$ROOT/var/lib/dhcpc/dhcpcd-$1.info" ]; then
		echo dhcp
60
	elif iface_exists; then
Natanael Copa's avatar
Natanael Copa committed
61
		ip addr show $1 | awk '/inet / {print $2}' | head -n 1 | sed 's:/.*::'
62
	fi
Natanael Copa's avatar
Natanael Copa committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76
}

get_default_mask() {
	if [ "$1" ] ; then
		ipcalc -m $1 | sed 's/.*=//'
	else
		echo "255.255.255.0"
	fi
}

get_default_gateway() {
	ip route show dev $1 | awk '/^default/ {print $3}'
}

77 78 79 80 81 82 83 84 85 86 87 88 89
ipaddr_help() {
	cat <<__EOF__

For static ip:
Enter the ip address in the format x.x.x.x

For dhcp:
Enter 'dhcp'

To add this interface to a bridge enter the bridge name (eg 'br0' or 'bridge0')

__EOF__
}
Natanael Copa's avatar
Natanael Copa committed
90

91 92 93 94 95 96 97 98 99 100
bridge_add_iface() {
	local bridge=$1 iface=
	shift
	for iface; do
		echo $iface >> $bridge.bridge_ports
		unconfigured_add $bridge
		unconfigured_del $iface
	done
}

Natanael Copa's avatar
Natanael Copa committed
101 102
config_iface() {
	local iface=$1
103
	local prefix=$2
104
	local address= netmask= gateway= bridge_ports=
105
	local bridge
106
	local conf=$prefix$iface.conf
107
	local answer=
108

109
	while [ -n "$ask_bridge" ]; do
110
		ask "Do you want to bridge the interface $iface?" no
111 112
		case "$resp" in
			yes|y) resp=yes; break;;
113 114 115
			no|n) break;;
		esac
	done
116

117
	if [ "$resp" = "yes" ]; then
118
		bridge="br"`echo $iface | sed 's/[^0-9]//g'`
119 120 121
		ask "Name of the bridge you want add $iface to:" $bridge
		bridge_add_iface $resp $iface
		return
122
	fi
123

124 125 126 127
	if [ -r "$iface.bridge_ports" ]; then
		bridge_ports=$(sed 's/\n/ /' $iface.bridge_ports)
		echo "bridge_ports=\"$bridge_ports\"" >> $conf
	fi
128 129 130 131
	# use ipcalc to validate the address. we do accept /mask
	# we are no interested in the result, only error code, so
	# we send result to /dev/null
	while ! ipcalc -s -m $address >/dev/null 2>&1; do
Natanael Copa's avatar
Natanael Copa committed
132
		address=`get_default_addr $iface`
133
		[ -z "$address" ] && address="dhcp"
134
		ask "Ip address for $iface? (or 'dhcp' or '?')" $address
135
		address=$resp
136 137 138 139
		case "$resp" in
		'?')	ipaddr_help;;
		"abort") return;;
		"dhcp")
Natanael Copa's avatar
Natanael Copa committed
140
			HAS_DHCP=yes
141
			echo "type=dhcp" >> $conf
Natanael Copa's avatar
Natanael Copa committed
142
			unconfigured_del $iface
143 144 145 146 147 148
			return ;;
		br[0-9]*|bridge[0-9]*)
			case "$iface" in
				# we dont allow bridge bridges
				br[0-9]*|bridge[0-9]*) continue;;
			esac
149
			bridge_add_iface $resp $iface
150 151
			return ;;
		esac
Natanael Copa's avatar
Natanael Copa committed
152 153
	done

154 155 156 157 158 159 160 161
	# extract netmask if entered together with address
	if [ "$address" != "${address%%/*}" ]; then
		netmask=$(ipcalc -s -m $address | cut -d= -f2)
	fi

	# use ipcalc -m to validate netmask. we dont accept <addr>/mask suffix
	# so we pass on a dummy mask to ipcalc.
	while ! ipcalc -s -m $netmask/0 >/dev/null 2>&1; do
Natanael Copa's avatar
Natanael Copa committed
162
		netmask=`get_default_mask $address`
163 164
		ask "Netmask?" $netmask
		netmask=$resp
Natanael Copa's avatar
Natanael Copa committed
165 166 167
		[ "$netmask" = "abort" ] && return
	done

168 169 170
	# use ipcalc -m to validate netmask. we dont accept <addr>/mask suffix
	# so we pass on a dummy mask to ipcalc.
	while ! ipcalc -s -m $gateway/0 >/dev/null 2>&1; do
Natanael Copa's avatar
Natanael Copa committed
171 172
		gateway=`get_default_gateway $iface`
		[ -z "$gateway" ] && gateway=none
173 174
		ask "Gateway? (or 'none')" $gateway
		gateway=$resp
Natanael Copa's avatar
Natanael Copa committed
175 176 177 178 179
		[ "$gateway" = "abort" ] && return
		[ "$gateway" = "none" ] && gateway=""
		[ -z "$gateway" ] && break
	done
	
180
	echo "type=static" >> $conf
181 182 183
	if [ -n "$bridge_ports" ]; then
		echo "bridge_ports=$bridge_ports" >> $conf
	fi
184 185 186
	echo "address=${address%%/*}" >> $conf  #strip off /mask if there
	echo "netmask=$netmask" >> $conf
	echo "gateway=$gateway" >> $conf
187

188

189 190
	# print summary
	echo "Configuration for $iface:"
191
	sed 's/^/  /' $conf
Natanael Copa's avatar
Natanael Copa committed
192
	
Natanael Copa's avatar
Natanael Copa committed
193
	unconfigured_del $iface
Natanael Copa's avatar
Natanael Copa committed
194 195
}

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
is_bridge() {
	[ -e /sys/class/net/$1/bridge ] || [ -e $i.bridge_ports ]
}

unconfigured_non_bridges() {
	local local i= iflist=
	for i in $(unconfigured_list); do
		if ! is_bridge $i; then
			iflist="${iflist}${iflist:+ }$i"
		fi
	done
	echo $iflist
}

unconfigured_all_are() {
	local i=
	for i; do
		unconfigured_isin $i || return 1
	done
	return 0
}

config_bridge() {
	local bridge=$1 iflist=
	while ! unconfigured_all_done; do
		set -- $(unconfigured_non_bridges)
		[ $# -eq 0 ] && return 0;
223 224
		echo "Available bridge ports are: $@"
		ask "Which port(s) do you want add to bridge $bridge? (or 'done')" $1
225 226 227 228 229 230 231 232 233 234 235 236
		case $resp in
			'abort') return 1;;
			'done') return 0;;
		esac
		if unconfigured_all_are $resp; then
			bridge_add_iface $bridge $resp
			continue
		fi
		echo "$resp is not a valid interface"
	done
}

237 238
usage() {
        cat <<__EOF__
239
usage: setup-interfaces [-bhi] [-p ROOT]
Natanael Copa's avatar
Natanael Copa committed
240

241
Setup network interfaces
Natanael Copa's avatar
Natanael Copa committed
242

243
options:
244
 -b  Ask for bridging of interfaces
245 246
 -h  Show this help
 -i  Read new contents of /etc/network/interfaces from stdin
247
 -p  Use ROOT as system prefix
248 249 250
__EOF__
        exit 1
}
Natanael Copa's avatar
Natanael Copa committed
251

Natanael Copa's avatar
Natanael Copa committed
252
prompt_for_interfaces() {
253 254 255
	init_tmpdir TMP
	
	cd $TMP
Natanael Copa's avatar
Natanael Copa committed
256
	unconfigured_detect
257 258
	
	index=1
Natanael Copa's avatar
Natanael Copa committed
259 260
	while ! unconfigured_all_done; do
		echo "Available interfaces are: $(unconfigured_list)."
261 262 263
		ask "Which one do you want to initialize? (or 'done')" \
			$(unconfigured_get_first)
		iface=$resp
264
	
265 266 267 268 269 270
		case "$iface" in
			"done") break;;
			br[0-9]*|bridge[0-9]*|virbr[0-9]*)
				config_bridge $iface || continue;;
			*) unconfigured_isin $iface || continue;;
		esac
271 272 273 274 275 276
		config_iface $iface $(printf "%.3d~" $index)
		index=$(( $index + 1 ))
	done
	
	echo "type=loopback" > 000~lo.conf
	echo "" > interface
Natanael Copa's avatar
Natanael Copa committed
277
	hostname=$(cat $ROOT/etc/hostname 2>/dev/null)
278 279 280 281
	
	for i in *.conf ; do
		iface=`basename $i .conf`
		iface=${iface#[0-9]*~}
282 283 284 285
		bridge_ports=
		address=
		type=
		gateway=
286
		. ./$i
287 288
		echo "auto $iface" >> interfaces
		echo "iface $iface inet $type" >> interfaces
289 290 291
		if [ -n "$bridge_ports" ]; then
			echo -e "\tbridge-ports $bridge_ports" >> interfaces
		fi
292 293 294 295 296 297 298 299 300 301 302 303
		case $type in
		dhcp)
			[ -n "$hostname" ] \
				&& echo -e "\thostname $hostname" >> interfaces
			;;
		static)
			echo -e "\taddress $address" >> interfaces
			echo -e "\tnetmask $netmask" >> interfaces
			[ "$gateway" ] \
				&& echo -e "\tgateway $gateway" >> interfaces
			;;
		esac
304 305 306 307
		if [ -n "$bridge" ]; then
			echo -e "\tpost-down brctl delif $bridge $iface" >> interfaces
			echo -e "\tpost-down brctl delbr $bridge" >> interfaces
		fi
308
		echo "" >> interfaces
309
		bridge=""
310 311 312
	done
	
	while [ "$answer" != "yes" ] && [ "$answer" != "no" ] ; do
313
		ask "Do you want to do any manual network configuration?" no
314 315 316 317 318
		case $resp in
			y) answer=yes;;
			n) answer=no;;
			*) answer=$resp;;
		esac
319
	done
Natanael Copa's avatar
Natanael Copa committed
320

321
	if yesno "$answer"; then
322
		case "$EDITOR" in
323 324
			nano)	apk add nano;;
			vim)	apk add vim;;
325 326 327 328 329 330
		esac
		${EDITOR:-vi} interfaces
	fi
		
	mkdir -p $ROOT/etc/network
	cp interfaces $ROOT/etc/network/
Natanael Copa's avatar
Natanael Copa committed
331 332
}

333 334 335
ask_bridge=
is_xen_dom0 && ask_bridge=1

Natanael Copa's avatar
Natanael Copa committed
336
while getopts "bhip:" opt; do
Natanael Copa's avatar
Natanael Copa committed
337
        case $opt in
338
		b) ask_bridge=1;;
Natanael Copa's avatar
Natanael Copa committed
339 340
                h) usage;;
		i) STDINPUT=1;;
Natanael Copa's avatar
Natanael Copa committed
341
		p) ROOT=$OPTARG;;
Natanael Copa's avatar
Natanael Copa committed
342 343 344
        esac
done

Natanael Copa's avatar
Natanael Copa committed
345
mkdir -p $ROOT/etc/network
Natanael Copa's avatar
Natanael Copa committed
346 347 348 349
if [ "$STDINPUT" = "1" ]; then
	cat > $ROOT/etc/network/interfaces
else
	prompt_for_interfaces
Natanael Copa's avatar
Natanael Copa committed
350
fi