1#!/bin/sh - 2# 3# $OpenBSD: netstart,v 1.144 2014/12/03 19:55:49 florian Exp $ 4 5# Strip comments (and leading/trailing whitespace if IFS is set) 6# from a file and spew to stdout 7stripcom() { 8 local _l 9 [[ -f $1 ]] || return 10 while read _l; do 11 [[ -n ${_l%%#*} ]] && echo $_l 12 done<$1 13} 14 15# Start the $1 interface 16ifstart() { 17 if=$1 18 # Interface names must be alphanumeric only. We check to avoid 19 # configuring backup or temp files, and to catch the "*" case. 20 [[ $if != +([[:alpha:]])+([[:digit:]]) ]] && return 21 22 file=/etc/hostname.$if 23 if ! [ -f $file ]; then 24 echo "netstart: $file: No such file or directory" 25 return 26 fi 27 # Not using stat(1), we can't rely on having /usr yet 28 set -A stat -- `ls -nL $file` 29 if [ "${stat[0]#???????} ${stat[2]} ${stat[3]}" != "--- 0 0" ]; then 30 echo "WARNING: $file is insecure, fixing permissions" 31 chmod -LR o-rwx $file 32 chown -LR root.wheel $file 33 fi 34 # Check for ifconfig'able interface. 35 (ifconfig $if || ifconfig $if create) >/dev/null 2>&1 || return 36 37 # Now parse the hostname.* file 38 while :; do 39 if [ "$cmd2" ]; then 40 # We are carrying over from the 'read dt dtaddr' 41 # last time. 42 set -- $cmd2 43 af="$1" name="$2" mask="$3" bcaddr="$4" ext1="$5" cmd2= 44 # Make sure and get any remaining args in ext2, 45 # like the read below 46 i=1 47 while [ $i -lt 6 -a -n "$1" ]; do shift; let i=i+1; done 48 ext2="$@" 49 else 50 # Read the next line or exit the while loop. 51 read af name mask bcaddr ext1 ext2 || break 52 fi 53 # $af can be "dhcp", "up", "rtsol", an address family, 54 # commands, or a comment. 55 case "$af" in 56 "#"*|"") # skip comments and empty lines 57 continue 58 ;; 59 "!"*) # parse commands 60 cmd="${af#*!} ${name} ${mask} ${bcaddr} ${ext1} ${ext2}" 61 ;; 62 "dhcp") 63 [ "$name" = "NONE" ] && name= 64 [ "$mask" = "NONE" ] && mask= 65 [ "$bcaddr" = "NONE" ] && bcaddr= 66 cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 down" 67 cmd="$cmd;dhclient $if" 68 dhcpif="$dhcpif $if" 69 ;; 70 "rtsol") 71 rtsolif="$rtsolif $if" 72 cmd="ifconfig $if $name $mask $bcaddr $ext1 $ext2 up" 73 ;; 74 *) 75 read dt dtaddr 76 if [ "$name" = "alias" ]; then 77 # perform a 'shift' of sorts 78 alias=$name 79 name=$mask 80 mask=$bcaddr 81 bcaddr=$ext1 82 ext1=$ext2 83 ext2= 84 else 85 alias= 86 fi 87 cmd="ifconfig $if $af $alias $name" 88 case "$dt" in 89 dest) 90 cmd="$cmd $dtaddr" 91 ;; 92 *) 93 cmd2="$dt $dtaddr" 94 ;; 95 esac 96 case $af in 97 inet) 98 if [ ! -n "$name" ]; then 99 echo "/etc/hostname.$if: inet alone is invalid" 100 return 101 fi 102 [ "$mask" ] && cmd="$cmd netmask $mask" 103 if [ "$bcaddr" -a "X$bcaddr" != "XNONE" ]; then 104 cmd="$cmd broadcast $bcaddr" 105 fi 106 ;; 107 inet6) 108 if [ ! -n "$name" ]; then 109 echo "/etc/hostname.$if: inet6 alone is invalid" 110 return 111 fi 112 [ "$mask" ] && cmd="$cmd prefixlen $mask" 113 cmd="$cmd $bcaddr" 114 ;; 115 *) 116 cmd="$cmd $mask $bcaddr" 117 ;; 118 esac 119 cmd="$cmd $ext1 $ext2" 120 ;; 121 esac 122 eval "$cmd" 123 done < /etc/hostname.$if 124} 125 126# Start multiple: 127# start "$1" interfaces in order or all interfaces if empty 128# don't start "$2" interfaces 129ifmstart() { 130 for sif in ${1:-ALL}; do 131 for hn in /etc/hostname.*; do 132 # Strip off /etc/hostname. prefix 133 if=${hn#/etc/hostname.} 134 test "$if" = "*" && continue 135 136 # Skip unwanted ifs 137 s="" 138 for xf in $2; do 139 test "$xf" = "${if%%[0-9]*}" && s="1" && break 140 done 141 test "$s" = "1" && continue 142 143 # Start wanted ifs 144 test "$sif" = "ALL" -o \ 145 "$sif" = "${if%%[0-9]*}" \ 146 && ifstart $if 147 done 148 done 149} 150 151# re-read rc.subr if we are not inside /etc/rc 152[ -n ${INRC} ] && FUNCS_ONLY=1 . /etc/rc.d/rc.subr 153_rc_parse_conf 154 155# If we were invoked with a list of interface names, just reconfigure these 156# interfaces (or bridges) and return. 157if [[ $1 == autoboot ]]; then 158 shift 159fi 160if [ $# -gt 0 ]; then 161 while [ $# -gt 0 ]; do 162 ifstart $1 163 shift 164 done 165 return 166fi 167 168# Otherwise, process with the complete network initialization. 169 170# /etc/myname contains my symbolic name 171if [ -f /etc/myname ]; then 172 hostname=`stripcom /etc/myname` 173 hostname $hostname 174else 175 hostname=`hostname` 176fi 177 178# Set the address for the loopback interface. Bringing the interface up, 179# automatically invokes the IPv6 address ::1. 180ifconfig lo0 inet 127.0.0.1/8 181 182if ifconfig lo0 inet6 >/dev/null 2>&1; then 183 # IPv6 configurations. 184 ip6kernel=YES 185 186 # Disallow link-local unicast dest without outgoing scope identifiers. 187 route -qn add -inet6 fe80:: -prefixlen 10 ::1 -reject > /dev/null 188 189 # Disallow site-local unicast dest without outgoing scope identifiers. 190 # If you configure site-locals without scope id (it is permissible 191 # config for routers that are not on scope boundary), you may want 192 # to comment the line out. 193 route -qn add -inet6 fec0:: -prefixlen 10 ::1 -reject > /dev/null 194 195 # Disallow "internal" addresses to appear on the wire. 196 route -qn add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject > /dev/null 197 198 # Disallow packets to malicious IPv4 compatible prefix. 199 route -qn add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject > /dev/null 200 route -qn add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject > /dev/null 201 route -qn add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject > /dev/null 202 route -qn add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject > /dev/null 203 204 # Disallow packets to malicious 6to4 prefix. 205 route -qn add -inet6 2002:e000:: -prefixlen 20 ::1 -reject > /dev/null 206 route -qn add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject > /dev/null 207 route -qn add -inet6 2002:0000:: -prefixlen 24 ::1 -reject > /dev/null 208 route -qn add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject > /dev/null 209 210 # Disallow packets without scope identifier. 211 route -qn add -inet6 ff01:: -prefixlen 16 ::1 -reject > /dev/null 212 route -qn add -inet6 ff02:: -prefixlen 16 ::1 -reject > /dev/null 213 214 # Completely disallow packets to IPv4 compatible prefix. 215 # This may conflict with RFC1933 under following circumstances: 216 # (1) An IPv6-only KAME node tries to originate packets to IPv4 217 # compatible destination. The KAME node has no IPv4 compatible 218 # support. Under RFC1933, it should transmit native IPv6 219 # packets toward IPv4 compatible destination, hoping it would 220 # reach a router that forwards the packet toward auto-tunnel 221 # interface. 222 # (2) An IPv6-only node originates a packet to an IPv4 compatible 223 # destination. A KAME node is acting as an IPv6 router, and 224 # asked to forward it. 225 # Due to rare use of IPv4 compatible addresses, and security issues 226 # with it, we disable it by default. 227 route -qn add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject > /dev/null 228 229 rtsolif="" 230else 231 ip6kernel=NO 232fi 233 234 235# Configure all the non-loopback interfaces which we know about, but 236# do not start interfaces which must be delayed. Refer to hostname.if(5) 237ifmstart "" "trunk svlan vlan carp gif gre pfsync pppoe tun bridge" 238 239# The trunk interfaces need to come up first in this list. 240# The (s)vlan interfaces need to come up after trunk. 241# Configure all the carp interfaces which we know about before default route. 242ifmstart "trunk svlan vlan carp" 243 244if [ "$ip6kernel" = "YES" -a "x$rtsolif" != "x" ]; then 245 fw=`sysctl -n net.inet6.ip6.forwarding` 246 if [ "x$fw" = "x0" ]; then 247 echo "IPv6 autoconf:$rtsolif" 248 ifconfig $rtsolif inet6 autoconf 249 else 250 echo "IPv6 autoconf not supported while IPv6 forwarding is enabled" 251 fi 252fi 253 254# Look for default routes in /etc/mygate. 255[[ -z $dhcpif ]] && stripcom /etc/mygate | while read gw; do 256 [[ $gw == @(*:*) ]] && continue 257 route -qn delete default > /dev/null 2>&1 258 route -qn add -host default $gw && break 259done 260[[ -z $rtsolif ]] && stripcom /etc/mygate | while read gw; do 261 [[ $gw == !(*:*) ]] && continue 262 route -qn delete -inet6 default > /dev/null 2>&1 263 route -qn add -host -inet6 default $gw && break 264done 265 266# Multicast routing. 267# 268# The routing to the 224.0.0.0/4 net is setup according to these rules: 269# multicast_host multicast_router route comment 270# NO NO -reject no multicast 271# NO YES none installed daemon will run 272# YES/interface NO -interface YES=def. iface 273# Any other combination -reject config error 274route -qn delete 224.0.0.0/4 > /dev/null 2>&1 275case "$multicast_host:$multicast_router" in 276NO:NO) 277 route -qn add -net 224.0.0.0/4 -interface 127.0.0.1 -reject > /dev/null 278 ;; 279NO:YES) 280 ;; 281*:NO) 282 maddr=`if [ "$multicast_host" = "YES" ]; then 283 ed -s '!route -qn show -inet' <<EOF 284/^default/p 285EOF 286 else 287 ed -s "!ifconfig $multicast_host" <<EOF 288/^ inet /p 289EOF 290 fi 2> /dev/null` 291 if [ "X${maddr}" != "X" ]; then 292 set $maddr 293 route -qn add -net 224.0.0.0/4 -interface $2 > /dev/null 294 else 295 route -qn add -net 224.0.0.0/4 -interface \ 296 127.0.0.1 -reject > /dev/null 297 fi 298 ;; 299*:*) 300 echo 'config error, multicasting disabled until rc.conf is fixed' 301 route -qn add -net 224.0.0.0/4 -interface 127.0.0.1 -reject > /dev/null 302 ;; 303esac 304 305 306# Configure PPPoE, GIF, GRE and TUN interfaces, delayed because they require 307# routes to be set. TUN might depend on PPPoE, and GIF or GRE may depend on 308# either of them. 309ifmstart "pppoe tun gif gre bridge" 310 311# reject 127/8 other than 127.0.0.1 312route -qn add -net 127 127.0.0.1 -reject > /dev/null 313 314if [ "$ip6kernel" = "YES" ]; then 315 # this is to make sure DAD is completed before going further. 316 count=0 317 while [ $((count++)) -lt 10 -a "x"`sysctl -n net.inet6.ip6.dad_pending` != "x0" ]; do 318 sleep 1 319 done 320fi 321