#!/bin/sh -u # # Add a logical interface with the specified address. # Allocates a fresh logical interface on the fly. # - Cameron Simpson 12may2005 # : ${ADDIF:=eth0} # default base interface : ${ADDIF_LOW:=1} # default base subinterface number trace= baseif=$ADDIF basen=$ADDIF_LOW netmask= cmd=`basename "$0"` usage="Usage: $cmd [-b basen] [-i baseif] [-m netmask] [-n] ipaddr... -b basen Base number. Default, from \$ADDIF_LOW: $basen -i baseif Base interface. Default, from \$ADDIF: $baseif -m mask Interface netmask. Default: from the base interface. -n No action. Recite commands." badopts= while [ $# -gt 0 ] do case $1 in -b) basen=$2; shift ;; -i) baseif=$2; shift ;; -m) netmask=$2; shift ;; -n) trace=echo ;; --) shift; break ;; -?*)echo "$cmd: unrecognised option: $1" >&2 badopts=1 ;; *) break ;; esac shift done [ $# = 0 ] && { echo "$cmd: missing ipaddrs" >&2; badopts=1; } # check final baseif synok=1 case "$baseif" in *:* | *[!a-z0-9]* ) synok= ;; lo | [a-z]*[0-9]) ;; *)synok= ;; esac if [ $synok ] then ifconfig "$baseif" >/dev/null \ || { echo "$cmd: can't find baseif \"$baseif\"" >&2 badopts=1 } else echo "$cmd: bad baseif name \"$baseif\": should match ^[a-z]+[0-9]+\$" >&2 badopts=1 fi [ $badopts ] && { echo "$usage" >&2; exit 2; } xit=0 os=`uname -s` || exit 1 if [ -z "$netmask" ] then netmask=`ifconfig "$baseif" | sed -n 's/.* Mask:\([^ ]*\).*/\1/p' | sed 1q` [ -n "$netmask" ] || netmask=`ifconfig "$baseif" | sed -n 's/.* netmask \(0x[0-9a-f]*\).*/\1/p' | sed 1q` [ -n "$netmask" ] || { echo "$cmd: can't deduce netmask for $baseif" >&2 exit 1 } fi for host do set -- `hostips "$host"` if [ $# = 0 ] then echo "$cmd: no ip addresses for \"$host\"" >&2 xit=1 continue fi for ipaddr do case "$os" in OpenBSD|Darwin) # no silly :n logical interfaces for BSD! ( set -x; $trace ifconfig "$baseif" alias "$ipaddr" netmask "$netmask" ) || xit=1 ;; *) # choose the next free interface number nextn=`ifconfig -a \ | sed -n "s/^$baseif"':\\([0-9][0-9]*\\) .*/\\1/p' \ | awk "BEGIN { n=$basen } \\$1 >= n { n=\\$1+1 } END { print n }"` || exit 1 # apply and then bump $basen ( set -x; $trace ifconfig "$baseif:$nextn" "$ipaddr" netmask "$netmask" ) || xit=1 basen=`expr "$nextn" + 1` ;; esac done done exit $xit