Source code pulled from OpenBSD for OpenNTPD. The place to contribute to this code is via the OpenBSD CVS tree.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

308 lines
9.0 KiB

#!/bin/sh -
#
# $OpenBSD: netstart,v 1.176 2017/04/08 08:33:05 rpe Exp $
# Turn off Strict Bourne shell mode.
set +o sh
# Echo file $1 to stdout. Skip comment lines and delete everything
# after the first '#' from other lines. Strip leading and trailing
# whitespace if IFS is set.
# Usage: stripcom /path/to/file
stripcom() {
local _file=$1 _line
[[ -f $_file ]] || return
while read _line; do
[[ -n ${_line%%#*} ]] && print -r -- "$_line"
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
echo "WARNING: $_file is insecure, fixing permissions"
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.
# Usage: ifmstart "em iwm" "trunk vlan"
# Start "$1" interfaces in order or all interfaces if empty.
# Don't start "$2" interfaces. "$2" is optional.
ifmstart() {
local _sifs=$1 _xifs=$2 _hn _if _sif _xif
for _sif in ${_sifs:-ALL}; do
for _hn in /etc/hostname.*; do
_if=${_hn#/etc/hostname.}
[[ $_if == '*' ]] && continue
# Skip unwanted ifs.
for _xif in $_xifs; do
[[ $_xif == ${_if%%[0-9]*} ]] && continue 2
done
# Start wanted ifs.
[[ $_sif == @(ALL|${_if%%[0-9]*}) ]] && ifstart $_if
done
done
}
# IPv6 autoconf the interfaces in the $rtsolif list.
# Usage: ifv6autoconf
ifv6autoconf() {
local _if
# $ip6kernel will not have been set if we were invoked with a
# list of interface names
ifconfig lo0 inet6 >/dev/null 2>&1 || return 0
for _if in $rtsolif; do
ifconfig $_if inet6 autoconf
done
}
# Parse /etc/mygate and add default routes for IPv4 and IPv6
# Usage: defaultroute
defaultroute() {
[[ -z $dhcpif ]] && stripcom /etc/mygate | while read gw; do
[[ $gw == @(*:*) ]] && continue
route -qn delete default >/dev/null 2>&1
route -qn add -host default $gw && break
done
[[ -z $rtsolif ]] && stripcom /etc/mygate | while read gw; do
[[ $gw == !(*:*) ]] && continue
route -qn delete -inet6 default >/dev/null 2>&1
route -qn add -host -inet6 default $gw && break
done
}
# Make sure the invoking user has the right privileges.
if (($(id -u) != 0)); then
echo "${0##*/}: need root privileges"
exit 1
fi
# 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
# If we were invoked with a list of interface names, just reconfigure these
# interfaces (or bridges), add default routes and return.
if (($# > 0)); then
for _if; do ifstart $_if; done
ifv6autoconf
defaultroute
return
fi
# Otherwise, process with the complete network initialization.
# /etc/myname contains my symbolic name.
[[ -f /etc/myname ]] && hostname "$(stripcom /etc/myname)"
# Set the address for the loopback interface. Bringing the interface up,
# automatically invokes the IPv6 address ::1.
ifconfig lo0 inet 127.0.0.1/8
if ifconfig lo0 inet6 >/dev/null 2>&1; then
# IPv6 configurations.
ip6kernel=YES
# Disallow link-local unicast dest without outgoing scope identifiers.
route -qn add -inet6 fe80:: -prefixlen 10 ::1 -reject >/dev/null
# Disallow site-local unicast dest without outgoing scope identifiers.
# If you configure site-locals without scope id (it is permissible
# config for routers that are not on scope boundary), you may want
# to comment the line out.
route -qn add -inet6 fec0:: -prefixlen 10 ::1 -reject >/dev/null
# Disallow "internal" addresses to appear on the wire.
route -qn add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null
# Disallow packets to malicious IPv4 compatible prefix.
route -qn add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject >/dev/null
route -qn add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
route -qn add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
route -qn add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
# Disallow packets to malicious 6to4 prefix.
route -qn add -inet6 2002:e000:: -prefixlen 20 ::1 -reject >/dev/null
route -qn add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject >/dev/null
route -qn add -inet6 2002:0000:: -prefixlen 24 ::1 -reject >/dev/null
route -qn add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject >/dev/null
# Disallow packets without scope identifier.
route -qn add -inet6 ff01:: -prefixlen 16 ::1 -reject >/dev/null
route -qn add -inet6 ff02:: -prefixlen 16 ::1 -reject >/dev/null
# Completely disallow packets to IPv4 compatible prefix.
#
# This may conflict with RFC1933 under following circumstances:
# (1) An IPv6-only KAME node tries to originate packets to IPv4
# compatible destination. The KAME node has no IPv4 compatible
# support. Under RFC1933, it should transmit native IPv6
# packets toward IPv4 compatible destination, hoping it would
# reach a router that forwards the packet toward auto-tunnel
# interface.
# (2) An IPv6-only node originates a packet to an IPv4 compatible
# destination. A KAME node is acting as an IPv6 router, and
# asked to forward it.
#
# Due to rare use of IPv4 compatible addresses, and security issues
# with it, we disable it by default.
route -qn add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null
rtsolif=""
else
ip6kernel=NO
fi
# Configure all the non-loopback interfaces which we know about, but
# do not start interfaces which must be delayed. Refer to hostname.if(5)
ifmstart "" "trunk svlan vlan carp gif gre pfsync pppoe tun bridge switch pflow"
# The trunk interfaces need to come up first in this list.
# The (s)vlan interfaces need to come up after trunk.
# Configure all the carp interfaces which we know about before default route.
ifmstart "trunk svlan vlan carp"
# Now that $rtsolif has been populated, IPv6 autoconf those interfaces
ifv6autoconf
# Look for default routes in /etc/mygate.
defaultroute
# Multicast routing.
if [[ $multicast != YES ]]; then
route -qn delete 224.0.0.0/4 >/dev/null 2>&1
route -qn add -net 224.0.0.0/4 -interface 127.0.0.1 -reject >/dev/null
fi
# Configure PPPoE, GIF, GRE, TUN and PFLOW interfaces, delayed because they
# require routes to be set. TUN might depend on PPPoE, and GIF or GRE may
# depend on either of them. PFLOW might bind to ip addresses configured
# on either of them.
ifmstart "pppoe tun gif gre bridge switch pflow"
# Reject 127/8 other than 127.0.0.1.
route -qn add -net 127 127.0.0.1 -reject >/dev/null
if [[ $ip6kernel == YES ]]; then
# This is to make sure DAD is completed before going further.
count=0
while ((count++ < 10 && $(sysctl -n net.inet6.ip6.dad_pending) != 0)); do
sleep 1
done
fi