setup-interfaces.in 7.24 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
bridge_add_port() {
92 93 94 95 96 97 98 99 100
	local bridge=$1 iface=
	shift
	for iface; do
		echo $iface >> $bridge.bridge_ports
		unconfigured_add $bridge
		unconfigured_del $iface
	done
}

101 102 103 104 105 106
bridge_list_ports() {
	if [ -r $1.bridge_ports ]; then
		echo $(cat $1.bridge_ports)
	fi
}

Natanael Copa's avatar
Natanael Copa committed
107 108
config_iface() {
	local iface=$1
109
	local prefix=$2
110
	local address= netmask= gateway= bridge_ports=
111
	local bridge
112
	local conf=$prefix$iface.conf
113
	local answer=
114

115
	while [ -n "$ask_bridge" ]; do
116
		ask "Do you want to bridge the interface $iface?" no
117 118
		case "$resp" in
			yes|y) resp=yes; break;;
119 120 121
			no|n) break;;
		esac
	done
122

123
	if [ "$resp" = "yes" ]; then
124
		bridge="br"`echo $iface | sed 's/[^0-9]//g'`
125
		ask "Name of the bridge you want add $iface to:" $bridge
126
		bridge_add_port $resp $iface
127
		return
128
	fi
129

130
	if [ -r "$iface.bridge_ports" ]; then
131
		bridge_ports=$(echo $(cat $iface.bridge_ports))
132 133
		echo "bridge_ports=\"$bridge_ports\"" >> $conf
	fi
134 135 136 137
	# 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
138
		address=`get_default_addr $iface`
139
		[ -z "$address" ] && address="dhcp"
140
		ask "Ip address for $iface? (or 'dhcp' or '?')" $address
141
		address=$resp
142 143 144 145
		case "$resp" in
		'?')	ipaddr_help;;
		"abort") return;;
		"dhcp")
Natanael Copa's avatar
Natanael Copa committed
146
			HAS_DHCP=yes
147
			echo "type=dhcp" >> $conf
Natanael Copa's avatar
Natanael Copa committed
148
			unconfigured_del $iface
149 150 151 152 153 154
			return ;;
		br[0-9]*|bridge[0-9]*)
			case "$iface" in
				# we dont allow bridge bridges
				br[0-9]*|bridge[0-9]*) continue;;
			esac
155
			bridge_add_port $resp $iface
156 157
			return ;;
		esac
Natanael Copa's avatar
Natanael Copa committed
158 159
	done

160 161 162 163 164 165 166 167
	# 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
168
		netmask=`get_default_mask $address`
169 170
		ask "Netmask?" $netmask
		netmask=$resp
Natanael Copa's avatar
Natanael Copa committed
171 172 173
		[ "$netmask" = "abort" ] && return
	done

174 175 176
	# 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
177 178
		gateway=`get_default_gateway $iface`
		[ -z "$gateway" ] && gateway=none
179 180
		ask "Gateway? (or 'none')" $gateway
		gateway=$resp
Natanael Copa's avatar
Natanael Copa committed
181 182 183 184 185
		[ "$gateway" = "abort" ] && return
		[ "$gateway" = "none" ] && gateway=""
		[ -z "$gateway" ] && break
	done
	
186
	echo "type=static" >> $conf
187 188 189
	if [ -n "$bridge_ports" ]; then
		echo "bridge_ports=$bridge_ports" >> $conf
	fi
190 191 192
	echo "address=${address%%/*}" >> $conf  #strip off /mask if there
	echo "netmask=$netmask" >> $conf
	echo "gateway=$gateway" >> $conf
193

194

195 196
	# print summary
	echo "Configuration for $iface:"
197
	sed 's/^/  /' $conf
Natanael Copa's avatar
Natanael Copa committed
198
	
Natanael Copa's avatar
Natanael Copa committed
199
	unconfigured_del $iface
Natanael Copa's avatar
Natanael Copa committed
200 201
}

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
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() {
225
	local bridge=$1 iflist= i= ports=
226 227 228
	while ! unconfigured_all_done; do
		set -- $(unconfigured_non_bridges)
		[ $# -eq 0 ] && return 0;
229 230 231 232
		ports=$(bridge_list_ports $bridge)
		if [ -n "$ports" ]; then
			echo "Bridge ports in $bridge are: $ports"
		fi
233 234
		echo "Available bridge ports are: $@"
		ask "Which port(s) do you want add to bridge $bridge? (or 'done')" $1
235 236 237 238
		case $resp in
			'abort') return 1;;
			'done') return 0;;
		esac
239 240 241 242 243 244 245
		for i in $resp; do
			if unconfigured_isin $i; then
				bridge_add_port $bridge $i
			else
				echo "$i is not valid"
			fi
		done
246 247 248
	done
}

249 250
usage() {
        cat <<__EOF__
251
usage: setup-interfaces [-bhi] [-p ROOT]
Natanael Copa's avatar
Natanael Copa committed
252

253
Setup network interfaces
Natanael Copa's avatar
Natanael Copa committed
254

255
options:
256
 -b  Ask for bridging of interfaces
257 258
 -h  Show this help
 -i  Read new contents of /etc/network/interfaces from stdin
259
 -p  Use ROOT as system prefix
260 261 262
__EOF__
        exit 1
}
Natanael Copa's avatar
Natanael Copa committed
263

Natanael Copa's avatar
Natanael Copa committed
264
prompt_for_interfaces() {
265 266 267
	init_tmpdir TMP
	
	cd $TMP
Natanael Copa's avatar
Natanael Copa committed
268
	unconfigured_detect
269 270
	
	index=1
Natanael Copa's avatar
Natanael Copa committed
271 272
	while ! unconfigured_all_done; do
		echo "Available interfaces are: $(unconfigured_list)."
273 274 275
		ask "Which one do you want to initialize? (or 'done')" \
			$(unconfigured_get_first)
		iface=$resp
276
	
277 278 279 280 281 282
		case "$iface" in
			"done") break;;
			br[0-9]*|bridge[0-9]*|virbr[0-9]*)
				config_bridge $iface || continue;;
			*) unconfigured_isin $iface || continue;;
		esac
283 284 285 286 287 288
		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
289
	hostname=$(cat $ROOT/etc/hostname 2>/dev/null)
290 291 292 293
	
	for i in *.conf ; do
		iface=`basename $i .conf`
		iface=${iface#[0-9]*~}
294 295 296 297
		bridge_ports=
		address=
		type=
		gateway=
298
		. ./$i
299 300
		echo "auto $iface" >> interfaces
		echo "iface $iface inet $type" >> interfaces
301 302 303
		if [ -n "$bridge_ports" ]; then
			echo -e "\tbridge-ports $bridge_ports" >> interfaces
		fi
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
		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
	done
	
	while [ "$answer" != "yes" ] && [ "$answer" != "no" ] ; do
319
		ask "Do you want to do any manual network configuration?" no
320 321 322 323 324
		case $resp in
			y) answer=yes;;
			n) answer=no;;
			*) answer=$resp;;
		esac
325
	done
Natanael Copa's avatar
Natanael Copa committed
326

327
	if yesno "$answer"; then
328
		case "$EDITOR" in
329 330
			nano)	apk add nano;;
			vim)	apk add vim;;
331 332 333 334 335 336
		esac
		${EDITOR:-vi} interfaces
	fi
		
	mkdir -p $ROOT/etc/network
	cp interfaces $ROOT/etc/network/
Natanael Copa's avatar
Natanael Copa committed
337 338
}

339 340 341
ask_bridge=
is_xen_dom0 && ask_bridge=1

Natanael Copa's avatar
Natanael Copa committed
342
while getopts "bhip:" opt; do
Natanael Copa's avatar
Natanael Copa committed
343
        case $opt in
344
		b) ask_bridge=1;;
Natanael Copa's avatar
Natanael Copa committed
345 346
                h) usage;;
		i) STDINPUT=1;;
Natanael Copa's avatar
Natanael Copa committed
347
		p) ROOT=$OPTARG;;
Natanael Copa's avatar
Natanael Copa committed
348 349 350
        esac
done

Natanael Copa's avatar
Natanael Copa committed
351
mkdir -p $ROOT/etc/network
Natanael Copa's avatar
Natanael Copa committed
352 353 354 355
if [ "$STDINPUT" = "1" ]; then
	cat > $ROOT/etc/network/interfaces
else
	prompt_for_interfaces
Natanael Copa's avatar
Natanael Copa committed
356
fi