=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/etc/netstart,v retrieving revision 1.176 retrieving revision 1.177 diff -c -r1.176 -r1.177 *** src/etc/netstart 2017/04/08 08:33:05 1.176 --- src/etc/netstart 2017/04/24 20:31:48 1.177 *************** *** 1,6 **** #!/bin/sh - # ! # $OpenBSD: netstart,v 1.176 2017/04/08 08:33:05 rpe Exp $ # Turn off Strict Bourne shell mode. set +o sh --- 1,6 ---- #!/bin/sh - # ! # $OpenBSD: netstart,v 1.177 2017/04/24 20:31:48 rpe Exp $ # Turn off Strict Bourne shell mode. set +o sh *************** *** 19,39 **** done <$_file } # Start a single interface. # Usage: ifstart if1 ifstart() { ! # Note: Do not rename the 'if' variable which is documented as being ! # usable in hostname.if(5) files. ! local if=$1 _file=/etc/hostname.$1 _stat # Interface names must be alphanumeric only. We check to avoid # configuring backup or temp files, and to catch the "*" case. ! [[ $if != +([[:alpha:]])+([[:digit:]]) ]] && return if [[ ! -f $_file ]]; then echo "netstart: $_file: No such file or directory" return fi # Not using stat(1), we can't rely on having /usr yet. set -A _stat -- $(ls -nL $_file) if [ "${_stat[0]#???????} ${_stat[2]} ${_stat[3]}" != "--- 0 0" ]; then --- 19,98 ---- done <$_file } + # Parse and "unpack" a hostname.if(5) line given as positional parameters. + # Fill the _cmds array with the resulting interface configuration commands. + parse_hn_line() { + local _af=0 _name=1 _mask=2 _bc=3 _prefix=2 _c _cmd _prev _daddr + set -A _c -- "$@" + set -o noglob + + case ${_c[_af]} in + ''|*([[:blank:]])'#'*) + return + ;; + inet) ((${#_c[*]} > 1)) || return + [[ ${_c[_name]} == alias ]] && _mask=3 _bc=4 + [[ -n ${_c[_mask]} ]] && _c[_mask]="netmask ${_c[_mask]}" + if [[ -n ${_c[_bc]} ]]; then + _c[_bc]="broadcast ${_c[_bc]}" + [[ ${_c[_bc]} == *NONE ]] && _c[_bc]= + fi + _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" + ;; + inet6) ((${#_c[*]} > 1)) || return + if [[ ${_c[_name]} == autoconf ]]; then + _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" + rtsolif="$rtsolif $_if" + return + fi + [[ ${_c[_name]} == alias ]] && _prefix=3 + [[ -n ${_c[_prefix]} ]] && _c[_prefix]="prefixlen ${_c[_prefix]}" + _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" + ;; + dest) ((${#_c[*]} == 2)) && _daddr=${_c[1]} || return + _prev=$((${#_cmds[*]} - 1)) + ((_prev >= 0)) || return + set -A _c -- ${_cmds[_prev]} + _name=3 + [[ ${_c[_name]} == alias ]] && _name=4 + _c[_name]="${_c[_name]} $_daddr" + _cmds[$_prev]="${_c[@]}" + ;; + dhcp) _c[0]= + _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]} down;dhclient $_if" + dhcpif="$dhcpif $_if" + ;; + rtsol) # XXX Support the rtsol keyword for some time to enable a smooth + # XXX transition to autoconf. + _c[0]= + _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]} up" + _cmds[${#_cmds[*]}]="ifconfig $_if inet6 autoconf" + rtsolif="$rtsolif $_if" + ;; + '!'*) _cmd=$(print -- "${_c[@]}" | sed 's/\$if/'$_if'/g') + _cmds[${#_cmds[*]}]="${_cmd#!}" + ;; + *) _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" + ;; + esac + unset _c + } + # Start a single interface. # Usage: ifstart if1 ifstart() { ! local _if=$1 _file=$HN_DIR/hostname.$1 _cmds _i=0 _line _stat ! set -A _cmds # Interface names must be alphanumeric only. We check to avoid # configuring backup or temp files, and to catch the "*" case. ! [[ $_if != +([[:alpha:]])+([[:digit:]]) ]] && return if [[ ! -f $_file ]]; then echo "netstart: $_file: No such file or directory" return fi + # Not using stat(1), we can't rely on having /usr yet. set -A _stat -- $(ls -nL $_file) if [ "${_stat[0]#???????} ${_stat[2]} ${_stat[3]}" != "--- 0 0" ]; then *************** *** 41,137 **** chmod -LR o-rwx $_file chown -LR root.wheel $_file fi - # Check for ifconfig'able interface. - (ifconfig $if || ifconfig $if create) >/dev/null 2>&1 || return ! # Now parse the hostname.* file. ! while :; do ! if [ "$cmd2" ]; then ! # We are carrying over from the 'read dt dtaddr' ! # last time. ! set -- $cmd2 ! af=$1 name=$2 mask=$3 bcaddr=$4 ext1=$5 cmd2= ! # Make sure and get any remaining args in ext2, ! # like the read below. ! i=1 ! while [ $i -lt 6 -a -n "$1" ]; do shift; let i=i+1; done ! ext2="$@" else ! # Read the next line or exit the while loop. ! read af name mask bcaddr ext1 ext2 || break fi ! # $af can be "dhcp", "up", "rtsol", an address family, commands, ! # or a comment. ! case "$af" in ! "#"*|"") ! # Skip comments and empty lines. ! continue ! ;; ! "!"*) # Parse commands. ! cmd="${af#*!} ${name} ${mask} ${bcaddr} ${ext1} ${ext2}" ! ;; ! "dhcp") ! [ "$name" = "NONE" ] && name= ! [ "$mask" = "NONE" ] && mask= ! [ "$bcaddr" = "NONE" ] && bcaddr= ! cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 down" ! cmd="$cmd;dhclient $if" ! dhcpif="$dhcpif $if" ! ;; ! "rtsol") ! rtsolif="$rtsolif $if" ! cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 up" ! ;; ! *) ! read dt dtaddr ! if [ "$name" = "alias" ]; then ! # Perform a 'shift' of sorts. ! alias=$name ! name=$mask ! mask=$bcaddr ! bcaddr=$ext1 ! ext1=$ext2 ! ext2= ! else ! alias= ! fi ! cmd="ifconfig $if $af $alias $name" ! case "$dt" in ! dest) ! cmd="$cmd $dtaddr" ! ;; ! *) ! cmd2="$dt $dtaddr" ! ;; ! esac ! case $af in ! inet) ! if [ ! -n "$name" ]; then ! echo "/etc/hostname.$if: inet alone is invalid" ! return ! fi ! [ "$mask" ] && cmd="$cmd netmask $mask" ! if [ "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then ! cmd="$cmd broadcast $bcaddr" ! fi ! ;; ! inet6) ! if [ ! -n "$name" ]; then ! echo "/etc/hostname.$if: inet6 alone is invalid" ! return ! fi ! [ "$mask" ] && cmd="$cmd prefixlen $mask" ! cmd="$cmd $bcaddr" ! ;; ! *) ! cmd="$cmd $mask $bcaddr" ! ;; ! esac ! cmd="$cmd $ext1 $ext2" ! ;; ! esac ! eval "$cmd" ! done <$_file } # Start multiple interfaces by driver name. --- 100,129 ---- chmod -LR o-rwx $_file chown -LR root.wheel $_file fi ! # Check for ifconfig'able interface, except if -n option is specified. ! if ! $PRINT_ONLY; then ! (ifconfig $_if || ifconfig $_if create) >/dev/null 2>&1 || ! return ! fi ! ! # Parse the hostname.if(5) file and fill _cmds array with interface ! # configuration commands. ! set -o noglob ! while IFS= read -- _line; do ! parse_hn_line $_line ! done <$_file ! ! # Apply the interface configuration commands stored in _cmds array. ! while ((_i < ${#_cmds[*]})); do ! if $PRINT_ONLY; then ! print -r -- "${_cmds[_i]}" else ! eval "${_cmds[_i]}" fi ! ((_i++)) ! done ! unset _cmds } # Start multiple interfaces by driver name. *************** *** 195,200 **** --- 187,209 ---- # Get network related vars from rc.conf using the parsing routine from rc.subr. FUNCS_ONLY=1 . /etc/rc.d/rc.subr _rc_parse_conf + + HN_DIR=${HN_DIR:-/etc} + PRINT_ONLY=false + USAGE="USAGE: ${0##*/} [-n] [interface ...]" + while getopts ":n" opt; do + case $opt in + n) PRINT_ONLY=true;; + *) print -u2 "$USAGE"; exit 1;; + esac + done + shift $((OPTIND-1)) + + # Option -n is only supported if interface names are specified as parameters. + if $PRINT_ONLY && (($# == 0)); then + print -u2 "Missing parameters.\n$USAGE" + exit 1 + fi # If we were invoked with a list of interface names, just reconfigure these # interfaces (or bridges), add default routes and return.