1#!/bin/sh - 2# 3# $OpenBSD: netstart,v 1.139 2013/08/22 07:53:11 mpi 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 /etc/rc.conf 152. /etc/rc.conf 153 154# If we were invoked with a list of interface names, just reconfigure these 155# interfaces (or bridges) and return. 156if [[ $1 == autoboot ]]; then 157 shift 158fi 159if [ $# -gt 0 ]; then 160 while [ $# -gt 0 ]; do 161 ifstart $1 162 shift 163 done 164 return 165fi 166 167# Otherwise, process with the complete network initialization. 168 169# /etc/myname contains my symbolic name 170if [ -f /etc/myname ]; then 171 hostname=`stripcom /etc/myname` 172 hostname $hostname 173else 174 hostname=`hostname` 175fi 176 177# Set the address for the loopback interface. Bringing the interface up, 178# automatically invokes the IPv6 address ::1. 179ifconfig lo0 inet 127.0.0.1/8 180 181if ifconfig lo0 inet6 >/dev/null 2>&1; then 182 # IPv6 configurations. 183 ip6kernel=YES 184 185 # Disallow link-local unicast dest without outgoing scope identifiers. 186 route -qn add -inet6 fe80:: -prefixlen 10 ::1 -reject > /dev/null 187 188 # Disallow site-local unicast dest without outgoing scope identifiers. 189 # If you configure site-locals without scope id (it is permissible 190 # config for routers that are not on scope boundary), you may want 191 # to comment the line out. 192 route -qn add -inet6 fec0:: -prefixlen 10 ::1 -reject > /dev/null 193 194 # Disallow "internal" addresses to appear on the wire. 195 route -qn add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject > /dev/null 196 197 # Disallow packets to malicious IPv4 compatible prefix. 198 route -qn add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject > /dev/null 199 route -qn add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject > /dev/null 200 route -qn add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject > /dev/null 201 route -qn add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject > /dev/null 202 203 # Disallow packets to malicious 6to4 prefix. 204 route -qn add -inet6 2002:e000:: -prefixlen 20 ::1 -reject > /dev/null 205 route -qn add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject > /dev/null 206 route -qn add -inet6 2002:0000:: -prefixlen 24 ::1 -reject > /dev/null 207 route -qn add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject > /dev/null 208 209 # Disallow packets without scope identifier. 210 route -qn add -inet6 ff01:: -prefixlen 16 ::1 -reject > /dev/null 211 route -qn add -inet6 ff02:: -prefixlen 16 ::1 -reject > /dev/null 212 213 # Completely disallow packets to IPv4 compatible prefix. 214 # This may conflict with RFC1933 under following circumstances: 215 # (1) An IPv6-only KAME node tries to originate packets to IPv4 216 # compatible destination. The KAME node has no IPv4 compatible 217 # support. Under RFC1933, it should transmit native IPv6 218 # packets toward IPv4 compatible destination, hoping it would 219 # reach a router that forwards the packet toward auto-tunnel 220 # interface. 221 # (2) An IPv6-only node originates a packet to an IPv4 compatible 222 # destination. A KAME node is acting as an IPv6 router, and 223 # asked to forward it. 224 # Due to rare use of IPv4 compatible addresses, and security issues 225 # with it, we disable it by default. 226 route -qn add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject > /dev/null 227 228 rtsolif="" 229else 230 ip6kernel=NO 231fi 232 233 234# Configure all the non-loopback interfaces which we know about, but 235# do not start interfaces which must be delayed. Refer to hostname.if(5) 236ifmstart "" "trunk svlan vlan carp gif gre pfsync pppoe tun bridge" 237 238# The trunk interfaces need to come up first in this list. 239# The (s)vlan interfaces need to come up after trunk. 240# Configure all the carp interfaces which we know about before default route. 241ifmstart "trunk svlan vlan carp" 242 243if [ "$ip6kernel" = "YES" -a "x$rtsolif" != "x" ]; then 244 fw=`sysctl -n net.inet6.ip6.forwarding` 245 ra=`sysctl -n net.inet6.ip6.accept_rtadv` 246 if [ "x$fw" = "x0" -a "x$ra" = "x1" ]; then 247 echo "IPv6 autoconf:$rtsolif" 248 rtsol $rtsolif 249 else 250 echo "WARNING: inconsistent config - check /etc/sysctl.conf for IPv6 autoconf" 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