Annotation of src/etc/netstart, Revision 1.174
1.1 deraadt 1: #!/bin/sh -
2: #
1.174 ! rpe 3: # $OpenBSD: netstart,v 1.173 2017/04/07 21:44:07 rpe Exp $
1.153 rpe 4:
5: # Turn off Strict Bourne shell mode.
6: set +o sh
1.101 millert 7:
1.173 rpe 8: # Echo file $1 to stdout. Skip comment lines and delete everything
9: # after the first '#' from other lines. Strip leading and trailing
10: # whitespace if IFS is set.
1.160 rpe 11: # Usage: stripcom /path/to/file
1.101 millert 12: stripcom() {
1.160 rpe 13: local _file=$1 _line
14:
15: [[ -f $_file ]] || return
16:
17: while read _line; do
18: [[ -n ${_line%%#*} ]] && print -r -- "$_line"
19: done <$_file
1.101 millert 20: }
1.45 millert 21:
1.160 rpe 22: # Start a single interface.
23: # Usage: ifstart if1
1.83 miod 24: ifstart() {
1.174 ! rpe 25: # Note: Do not rename the 'if' variable which is documented as being
! 26: # usable in hostname.if(5) files.
1.84 deraadt 27: if=$1
1.174 ! rpe 28:
1.83 miod 29: # Interface names must be alphanumeric only. We check to avoid
30: # configuring backup or temp files, and to catch the "*" case.
1.137 rpe 31: [[ $if != +([[:alpha:]])+([[:digit:]]) ]] && return
1.83 miod 32:
1.119 deraadt 33: file=/etc/hostname.$if
1.121 todd 34: if ! [ -f $file ]; then
35: echo "netstart: $file: No such file or directory"
36: return
37: fi
1.146 rpe 38: # Not using stat(1), we can't rely on having /usr yet.
1.166 rpe 39: set -A stat -- $(ls -nL $file)
1.123 sthen 40: if [ "${stat[0]#???????} ${stat[2]} ${stat[3]}" != "--- 0 0" ]; then
1.119 deraadt 41: echo "WARNING: $file is insecure, fixing permissions"
1.122 sthen 42: chmod -LR o-rwx $file
43: chown -LR root.wheel $file
1.119 deraadt 44: fi
1.136 rpe 45: # Check for ifconfig'able interface.
46: (ifconfig $if || ifconfig $if create) >/dev/null 2>&1 || return
1.83 miod 47:
1.146 rpe 48: # Now parse the hostname.* file.
1.83 miod 49: while :; do
50: if [ "$cmd2" ]; then
51: # We are carrying over from the 'read dt dtaddr'
52: # last time.
53: set -- $cmd2
54: af="$1" name="$2" mask="$3" bcaddr="$4" ext1="$5" cmd2=
55: # Make sure and get any remaining args in ext2,
1.146 rpe 56: # like the read below.
1.83 miod 57: i=1
1.126 simon 58: while [ $i -lt 6 -a -n "$1" ]; do shift; let i=i+1; done
1.83 miod 59: ext2="$@"
60: else
61: # Read the next line or exit the while loop.
62: read af name mask bcaddr ext1 ext2 || break
63: fi
1.146 rpe 64: # $af can be "dhcp", "up", "rtsol", an address family, commands,
65: # or a comment.
1.83 miod 66: case "$af" in
1.146 rpe 67: "#"*|"") # Skip comments and empty lines.
1.83 miod 68: continue
69: ;;
1.146 rpe 70: "!"*) # Parse commands.
1.83 miod 71: cmd="${af#*!} ${name} ${mask} ${bcaddr} ${ext1} ${ext2}"
72: ;;
73: "dhcp")
74: [ "$name" = "NONE" ] && name=
75: [ "$mask" = "NONE" ] && mask=
76: [ "$bcaddr" = "NONE" ] && bcaddr=
1.143 claudio 77: cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 down"
1.106 todd 78: cmd="$cmd;dhclient $if"
1.110 todd 79: dhcpif="$dhcpif $if"
1.83 miod 80: ;;
81: "rtsol")
1.84 deraadt 82: rtsolif="$rtsolif $if"
1.106 todd 83: cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 up"
1.83 miod 84: ;;
85: *)
86: read dt dtaddr
87: if [ "$name" = "alias" ]; then
1.146 rpe 88: # Perform a 'shift' of sorts.
1.83 miod 89: alias=$name
90: name=$mask
91: mask=$bcaddr
92: bcaddr=$ext1
93: ext1=$ext2
94: ext2=
95: else
96: alias=
97: fi
1.114 todd 98: cmd="ifconfig $if $af $alias $name"
1.83 miod 99: case "$dt" in
100: dest)
101: cmd="$cmd $dtaddr"
102: ;;
1.130 todd 103: *)
1.83 miod 104: cmd2="$dt $dtaddr"
105: ;;
106: esac
107: case $af in
108: inet)
1.128 todd 109: if [ ! -n "$name" ]; then
110: echo "/etc/hostname.$if: inet alone is invalid"
111: return
112: fi
1.83 miod 113: [ "$mask" ] && cmd="$cmd netmask $mask"
114: if [ "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then
115: cmd="$cmd broadcast $bcaddr"
116: fi
117: ;;
1.128 todd 118: inet6)
119: if [ ! -n "$name" ]; then
120: echo "/etc/hostname.$if: inet6 alone is invalid"
121: return
122: fi
123: [ "$mask" ] && cmd="$cmd prefixlen $mask"
1.83 miod 124: cmd="$cmd $bcaddr"
125: ;;
126: *)
127: cmd="$cmd $mask $bcaddr"
128: ;;
129: esac
1.139 mpi 130: cmd="$cmd $ext1 $ext2"
1.83 miod 131: ;;
132: esac
133: eval "$cmd"
1.147 rpe 134: done </etc/hostname.$if
1.83 miod 135: }
136:
1.161 rpe 137: # Start multiple interfaces by driver name.
138: # Usage: ifmstart "em iwm" "trunk vlan"
1.146 rpe 139: # Start "$1" interfaces in order or all interfaces if empty.
1.161 rpe 140: # Don't start "$2" interfaces. "$2" is optional.
1.105 todd 141: ifmstart() {
1.161 rpe 142: local _sifs=$1 _xifs=$2 _hn _if _sif _xif
143:
144: for _sif in ${_sifs:-ALL}; do
145: for _hn in /etc/hostname.*; do
146: _if=${_hn#/etc/hostname.}
147: [[ $_if == '*' ]] && continue
1.113 david 148:
1.146 rpe 149: # Skip unwanted ifs.
1.161 rpe 150: for _xif in $_xifs; do
151: [[ $_xif == ${_if%%[0-9]*} ]] && continue 2
1.105 todd 152: done
153:
1.146 rpe 154: # Start wanted ifs.
1.161 rpe 155: [[ $_sif == @(ALL|${_if%%[0-9]*}) ]] && ifstart $_if
1.105 todd 156: done
157: done
158: }
159:
1.162 rpe 160: # IPv6 autoconf the interfaces in the $rtsolif list.
161: # Usage: ifv6autoconf
162: ifv6autoconf() {
163: local _if
164:
1.156 sthen 165: # $ip6kernel will not have been set if we were invoked with a
166: # list of interface names
1.162 rpe 167: ifconfig lo0 inet6 >/dev/null 2>&1 || return 0
168:
169: for _if in $rtsolif; do
170: ifconfig $_if inet6 autoconf
171: done
1.154 sthen 172: }
1.170 jasper 173:
1.172 mpi 174: # Parse /etc/mygate and add default routes for IPv4 and IPv6
175: # Usage: defaultroute
176: defaultroute() {
177: [[ -z $dhcpif ]] && stripcom /etc/mygate | while read gw; do
178: [[ $gw == @(*:*) ]] && continue
179: route -qn delete default >/dev/null 2>&1
180: route -qn add -host default $gw && break
181: done
182: [[ -z $rtsolif ]] && stripcom /etc/mygate | while read gw; do
183: [[ $gw == !(*:*) ]] && continue
184: route -qn delete -inet6 default >/dev/null 2>&1
185: route -qn add -host -inet6 default $gw && break
186: done
187: }
188:
1.170 jasper 189: # Make sure the invoking user has the right privileges.
190: if (($(id -u) != 0)); then
191: echo "${0##*/}: need root privileges"
192: exit 1
193: fi
1.154 sthen 194:
1.151 rpe 195: # Get network related vars from rc.conf using the parsing routine from rc.subr.
196: FUNCS_ONLY=1 . /etc/rc.d/rc.subr
1.150 ajacouto 197: _rc_parse_conf
1.1 deraadt 198:
1.83 miod 199: # If we were invoked with a list of interface names, just reconfigure these
1.172 mpi 200: # interfaces (or bridges), add default routes and return.
1.159 rpe 201: if (($# > 0)); then
202: for _if; do ifstart $_if; done
1.162 rpe 203: ifv6autoconf
1.172 mpi 204: defaultroute
1.83 miod 205: return
206: fi
207:
208: # Otherwise, process with the complete network initialization.
209:
1.146 rpe 210: # /etc/myname contains my symbolic name.
1.159 rpe 211: [[ -f /etc/myname ]] && hostname "$(stripcom /etc/myname)"
1.4 dm 212:
1.131 sobrado 213: # Set the address for the loopback interface. Bringing the interface up,
214: # automatically invokes the IPv6 address ::1.
1.129 henning 215: ifconfig lo0 inet 127.0.0.1/8
1.24 kstailey 216:
1.54 itojun 217: if ifconfig lo0 inet6 >/dev/null 2>&1; then
218: # IPv6 configurations.
219: ip6kernel=YES
220:
1.83 miod 221: # Disallow link-local unicast dest without outgoing scope identifiers.
1.147 rpe 222: route -qn add -inet6 fe80:: -prefixlen 10 ::1 -reject >/dev/null
1.66 itojun 223:
1.83 miod 224: # Disallow site-local unicast dest without outgoing scope identifiers.
1.66 itojun 225: # If you configure site-locals without scope id (it is permissible
226: # config for routers that are not on scope boundary), you may want
227: # to comment the line out.
1.147 rpe 228: route -qn add -inet6 fec0:: -prefixlen 10 ::1 -reject >/dev/null
1.66 itojun 229:
1.83 miod 230: # Disallow "internal" addresses to appear on the wire.
1.147 rpe 231: route -qn add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null
1.66 itojun 232:
1.83 miod 233: # Disallow packets to malicious IPv4 compatible prefix.
1.147 rpe 234: route -qn add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject >/dev/null
235: route -qn add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
236: route -qn add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
237: route -qn add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject >/dev/null
1.66 itojun 238:
1.83 miod 239: # Disallow packets to malicious 6to4 prefix.
1.147 rpe 240: route -qn add -inet6 2002:e000:: -prefixlen 20 ::1 -reject >/dev/null
241: route -qn add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject >/dev/null
242: route -qn add -inet6 2002:0000:: -prefixlen 24 ::1 -reject >/dev/null
243: route -qn add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject >/dev/null
1.115 itojun 244:
245: # Disallow packets without scope identifier.
1.147 rpe 246: route -qn add -inet6 ff01:: -prefixlen 16 ::1 -reject >/dev/null
247: route -qn add -inet6 ff02:: -prefixlen 16 ::1 -reject >/dev/null
1.66 itojun 248:
249: # Completely disallow packets to IPv4 compatible prefix.
1.146 rpe 250: #
1.66 itojun 251: # This may conflict with RFC1933 under following circumstances:
252: # (1) An IPv6-only KAME node tries to originate packets to IPv4
1.77 deraadt 253: # compatible destination. The KAME node has no IPv4 compatible
1.66 itojun 254: # support. Under RFC1933, it should transmit native IPv6
255: # packets toward IPv4 compatible destination, hoping it would
256: # reach a router that forwards the packet toward auto-tunnel
257: # interface.
1.77 deraadt 258: # (2) An IPv6-only node originates a packet to an IPv4 compatible
1.66 itojun 259: # destination. A KAME node is acting as an IPv6 router, and
260: # asked to forward it.
1.146 rpe 261: #
1.77 deraadt 262: # Due to rare use of IPv4 compatible addresses, and security issues
1.66 itojun 263: # with it, we disable it by default.
1.147 rpe 264: route -qn add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null
1.56 itojun 265:
266: rtsolif=""
1.54 itojun 267: else
268: ip6kernel=NO
269: fi
270:
1.105 todd 271:
272: # Configure all the non-loopback interfaces which we know about, but
1.127 deraadt 273: # do not start interfaces which must be delayed. Refer to hostname.if(5)
1.171 rzalamen 274: ifmstart "" "trunk svlan vlan carp gif gre pfsync pppoe tun bridge switch pflow"
1.56 itojun 275:
1.118 brad 276: # The trunk interfaces need to come up first in this list.
1.132 mpf 277: # The (s)vlan interfaces need to come up after trunk.
1.118 brad 278: # Configure all the carp interfaces which we know about before default route.
1.132 mpf 279: ifmstart "trunk svlan vlan carp"
1.118 brad 280:
1.154 sthen 281: # Now that $rtsolif has been populated, IPv6 autoconf those interfaces
1.162 rpe 282: ifv6autoconf
1.102 mcbride 283:
1.138 todd 284: # Look for default routes in /etc/mygate.
1.172 mpi 285: defaultroute
1.44 deraadt 286:
1.48 niklas 287: # Multicast routing.
1.168 sthen 288: if [[ $multicast != YES ]]; then
289: route -qn delete 224.0.0.0/4 >/dev/null 2>&1
1.147 rpe 290: route -qn add -net 224.0.0.0/4 -interface 127.0.0.1 -reject >/dev/null
1.168 sthen 291: fi
1.105 todd 292:
1.152 florian 293: # Configure PPPoE, GIF, GRE, TUN and PFLOW interfaces, delayed because they
294: # require routes to be set. TUN might depend on PPPoE, and GIF or GRE may
295: # depend on either of them. PFLOW might bind to ip addresses configured
296: # on either of them.
1.171 rzalamen 297: ifmstart "pppoe tun gif gre bridge switch pflow"
1.92 deraadt 298:
1.146 rpe 299: # Reject 127/8 other than 127.0.0.1.
1.147 rpe 300: route -qn add -net 127 127.0.0.1 -reject >/dev/null
1.116 david 301:
1.159 rpe 302: if [[ $ip6kernel == YES ]]; then
1.146 rpe 303: # This is to make sure DAD is completed before going further.
1.124 markus 304: count=0
1.159 rpe 305: while ((count++ < 10 && $(sysctl -n net.inet6.ip6.dad_pending) != 0)); do
1.124 markus 306: sleep 1
307: done
1.116 david 308: fi