1#!/bin/sh 2# 3# $NetBSD: network,v 1.69 2014/10/14 20:49:47 christos Exp $ 4# 5 6# PROVIDE: network 7# REQUIRE: ipfilter ipsec mountcritlocal root tty sysctl 8# BEFORE: NETWORKING 9 10$_rc_subr_loaded . /etc/rc.subr 11 12name="network" 13start_cmd="network_start" 14stop_cmd="network_stop" 15 16nl=' 17' # a newline 18 19intmissing() 20{ 21 local int="$1" 22 shift 23 for i; do 24 if [ "$int" = "$i" ]; then 25 return 1 26 fi 27 done 28 return 0 29} 30 31have_inet6() 32{ 33 /sbin/ifconfig lo0 inet6 >/dev/null 2>&1 34} 35 36network_start() 37{ 38 # set hostname, turn on network 39 # 40 echo "Starting network." 41 42 network_start_hostname 43 network_start_domainname 44 network_start_loopback 45 have_inet6 && 46 network_start_ipv6_route 47 [ "$net_interfaces" != NO ] && 48 network_start_interfaces 49 network_start_aliases 50 network_start_defaultroute 51 network_start_defaultroute6 52 have_inet6 && 53 network_start_ipv6_autoconf 54 network_start_local 55} 56 57network_start_hostname() 58{ 59 # If $hostname is set, use it for my Internet name, 60 # otherwise use /etc/myname 61 # 62 if [ -z "$hostname" ] && [ -f /etc/myname ]; then 63 hostname=$(cat /etc/myname) 64 fi 65 if [ -n "$hostname" ]; then 66 echo "Hostname: $hostname" 67 hostname $hostname 68 else 69 # Don't warn about it if we're going to run 70 # DHCP later, as we will probably get the 71 # hostname at that time. 72 # 73 if ! checkyesno dhclient && ! checkyesno dhcpcd && \ 74 [ -z "$(hostname)" ] 75 then 76 warn "\$hostname not set." 77 fi 78 fi 79} 80 81network_start_domainname() 82{ 83 # Check $domainname first, then /etc/defaultdomain, 84 # for NIS/YP domain name 85 # 86 if [ -z "$domainname" ] && [ -f /etc/defaultdomain ]; then 87 domainname=$(cat /etc/defaultdomain) 88 fi 89 if [ -n "$domainname" ]; then 90 echo "NIS domainname: $domainname" 91 domainname $domainname 92 fi 93 94 # Flush all routes just to make sure it is clean 95 if checkyesno flushroutes; then 96 /sbin/route -qn flush 97 fi 98} 99 100network_start_loopback() 101{ 102 # Set the address for the first loopback interface, so that the 103 # auto-route from a newly configured interface's address to lo0 104 # works correctly. 105 # 106 # NOTE: obscure networking problems will occur if lo0 isn't configured. 107 # 108 /sbin/ifconfig lo0 inet 127.0.0.1 109 110 # According to RFC1122, 127.0.0.0/8 must not leave the node. 111 # 112 /sbin/route -q add -inet 127.0.0.0 -netmask 0xff000000 127.0.0.1 -reject 113} 114 115network_start_ipv6_route() 116{ 117 # IPv6 routing setups, and host/router mode selection. 118 # 119 # We have IPv6 support in kernel. 120 121 # disallow link-local unicast dest without outgoing scope 122 # identifiers. 123 # 124 /sbin/route -q add -inet6 fe80:: -prefixlen 10 ::1 -reject 125 126 # disallow the use of the RFC3849 documentation address 127 # 128 /sbin/route -q add -inet6 2001:db8:: -prefixlen 32 ::1 -reject 129 130 # IPv6 site-local scoped address prefix (fec0::/10) 131 # has been deprecated by RFC3879. 132 # 133 if [ -n "$ip6sitelocal" ]; then 134 warn "\$ip6sitelocal is no longer valid" 135 fi 136 137 # disallow "internal" addresses to appear on the wire. 138 # 139 /sbin/route -q add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject 140 141 # disallow packets to malicious IPv4 compatible prefix 142 # 143 /sbin/route -q add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject 144 /sbin/route -q add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject 145 /sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject 146 /sbin/route -q add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject 147 148 # disallow packets to malicious 6to4 prefix 149 # 150 /sbin/route -q add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 151 /sbin/route -q add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 152 /sbin/route -q add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 153 /sbin/route -q add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 154 155 # Completely disallow packets to IPv4 compatible prefix. 156 # This may conflict with RFC1933 under following circumstances: 157 # (1) An IPv6-only KAME node tries to originate packets to IPv4 158 # compatible destination. The KAME node has no IPv4 159 # compatible support. Under RFC1933, it should transmit 160 # native IPv6 packets toward IPv4 compatible destination, 161 # hoping it would reach a router that forwards the packet 162 # toward auto-tunnel interface. 163 # (2) An IPv6-only node originates a packet to IPv4 compatible 164 # destination. A KAME node is acting as an IPv6 router, and 165 # asked to forward it. 166 # Due to rare use of IPv4 compatible address, and security 167 # issues with it, we disable it by default. 168 # 169 /sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject 170 171 /sbin/sysctl -qw net.inet6.ip6.forwarding=0 172 /sbin/sysctl -qw net.inet6.ip6.accept_rtadv=0 173 174 case $ip6mode in 175 router) 176 echo 'IPv6 mode: router' 177 /sbin/sysctl -qw net.inet6.ip6.forwarding=1 178 179 # disallow unique-local unicast forwarding without 180 # explicit configuration. 181 if ! checkyesno ip6uniquelocal; then 182 /sbin/route -q add -inet6 fc00:: -prefixlen 7 \ 183 ::1 -reject 184 fi 185 ;; 186 187 autohost) 188 echo 'IPv6 mode: autoconfigured host' 189 /sbin/sysctl -qw net.inet6.ip6.accept_rtadv=1 190 ;; 191 192 host) 193 echo 'IPv6 mode: host' 194 ;; 195 196 *) warn "invalid \$ip6mode value "\"$ip6mode\" 197 ;; 198 199 esac 200} 201 202network_start_interfaces() 203{ 204 # Configure all of the network interfaces listed in $net_interfaces; 205 # if $auto_ifconfig is YES, grab all interfaces from ifconfig. 206 # In the following, "xxN" stands in for interface names, like "le0". 207 # 208 # For any interfaces that has an $ifconfig_xxN variable 209 # associated, we break it into lines using ';' as a separator, 210 # then process it just like the contents of an /etc/ifconfig.xxN 211 # file. 212 # 213 # For each line from the $ifconfig_xxN variable or the 214 # /etc/ifconfig.xxN file, we ignore comments and blank lines, 215 # treat lines beginning with "!" as commands to execute, treat 216 # "dhcp" as a special case to invoke dhcpcd, and for any other 217 # line we run "ifconfig xxN", using each line of the file as the 218 # arguments for a separate "ifconfig" invocation. 219 # 220 # In order to configure an interface reasonably, you at the very least 221 # need to specify "[addr_family] [hostname]" (e.g "inet my.domain.org"), 222 # and probably a netmask (as in "netmask 0xffffffe0"). You will 223 # frequently need to specify a media type, as in "media UTP", for 224 # interface cards with multiple media connections that do not 225 # autoconfigure. See the ifconfig manual page for details. 226 # 227 # Note that /etc/ifconfig.xxN takes multiple lines. The following 228 # configuration is possible: 229 # inet 10.1.1.1 netmask 0xffffff00 230 # inet 10.1.1.2 netmask 0xffffff00 alias 231 # inet6 2001:db8::1 prefixlen 64 alias 232 # 233 # You can put shell script fragment into /etc/ifconfig.xxN by 234 # starting a line with "!". Refer to ifconfig.if(5) for details. 235 # 236 ifaces="$(/sbin/ifconfig -l)" 237 if checkyesno auto_ifconfig; then 238 tmp="$ifaces" 239 for cloner in $(/sbin/ifconfig -C); do 240 for int in /etc/ifconfig.${cloner}[0-9]*; do 241 [ ! -f $int ] && break 242 tmp="$tmp ${int##*.}" 243 done 244 done 245 else 246 tmp="$net_interfaces" 247 fi 248 echo -n 'Configuring network interfaces:' 249 for int in $tmp; do 250 eval argslist=\$ifconfig_$int 251 252 # Skip interfaces that do not have explicit 253 # configuration information. If auto_ifconfig is 254 # false then also warn about such interfaces. 255 # 256 if [ -z "$argslist" ] && ! [ -f /etc/ifconfig.$int ] 257 then 258 if ! checkyesno auto_ifconfig; then 259 echo 260 warn \ 261 "/etc/ifconfig.$int missing and ifconfig_$int not set;" 262 warn "interface $int not configured." 263 fi 264 continue 265 fi 266 267 echo -n " $int" 268 269 # Create the interface if necessary. 270 # If the interface did not exist before, 271 # then also resync ipf(4). 272 # 273 if intmissing $int $ifaces; then 274 if /sbin/ifconfig $int create && \ 275 checkyesno ipfilter; then 276 /sbin/ipf -y >/dev/null 277 fi 278 fi 279 280 # If $ifconfig_xxN is empty, then use 281 # /etc/ifconfig.xxN, which we know exists due to 282 # an earlier test. 283 # 284 # If $ifconfig_xxN is non-empty and contains a 285 # newline, then just use it as is. (This allows 286 # semicolons through unmolested.) 287 # 288 # If $ifconfig_xxN is non-empty and does not 289 # contain a newline, then convert all semicolons 290 # to newlines. 291 # 292 case "$argslist" in 293 '') 294 cat /etc/ifconfig.$int 295 ;; 296 *"${nl}"*) 297 echo "$argslist" 298 ;; 299 *) 300 ( 301 set -o noglob 302 IFS=';'; set -- $argslist 303 #echo >&2 "[$#] [$1] [$2] [$3] [$4]" 304 IFS="$nl"; echo "$*" 305 ) 306 ;; 307 esac | 308 collapse_backslash_newline | 309 while read -r args; do 310 case "$args" in 311 ''|"#"*|create) 312 ;; 313 "!"*) 314 # Run arbitrary command in a subshell. 315 ( eval "${args#*!}" ) 316 ;; 317 dhcp) 318 if ! checkyesno dhcpcd; then 319 /sbin/dhcpcd -n \ 320 ${dhcpcd_flags} $int 321 fi 322 ;; 323 *) 324 # Pass args to ifconfig. Note 325 # that args may contain embedded 326 # shell metacharacters, such as 327 # "ssid 'foo;*>bar'". We eval 328 # one more time so that things 329 # like ssid "Columbia University" work. 330 ( 331 set -o noglob 332 eval set -- $args 333 #echo >&2 "[$#] [$1] [$2] [$3]" 334 /sbin/ifconfig $int "$@" 335 ) 336 ;; 337 esac 338 done 339 configured_interfaces="$configured_interfaces $int" 340 done 341 echo "." 342} 343 344network_start_aliases() 345{ 346 echo -n "Adding interface aliases:" 347 348 # Check if each configured interface xxN has an $ifaliases_xxN variable 349 # associated, then configure additional IP addresses for that interface. 350 # The variable contains a list of "address netmask" pairs, with 351 # "netmask" set to "-" if the interface default netmask is to be used. 352 # 353 # Note that $ifaliases_xxN works only in certain cases and its 354 # use is not recommended. Use /etc/ifconfig.xxN or multiple 355 # commands in $ifconfig_xxN instead. 356 # 357 for int in lo0 $configured_interfaces; do 358 eval args=\$ifaliases_$int 359 if [ -n "$args" ]; then 360 set -- $args 361 while [ $# -ge 2 ]; do 362 addr=$1 ; net=$2 ; shift 2 363 if [ "$net" = "-" ]; then 364 # for compatibility only, obsolete 365 /sbin/ifconfig $int inet alias $addr 366 else 367 /sbin/ifconfig $int inet alias $addr \ 368 netmask $net 369 fi 370 echo -n " $int:$addr" 371 done 372 fi 373 done 374 375 # /etc/ifaliases, if it exists, contains the names of additional IP 376 # addresses for each interface. It is formatted as a series of lines 377 # that contain 378 # address interface netmask 379 # 380 # Note that /etc/ifaliases works only in certain cases and its 381 # use is not recommended. Use /etc/ifconfig.xxN or multiple 382 # commands in $ifconfig_xxN instead. 383 # 384 if [ -f /etc/ifaliases ]; then 385 while read addr int net; do 386 if [ -z "$net" ]; then 387 # for compatibility only, obsolete 388 /sbin/ifconfig $int inet alias $addr 389 else 390 /sbin/ifconfig $int inet alias $addr netmask $net 391 fi 392 done < /etc/ifaliases 393 fi 394 395 echo "." # for "Adding interface aliases:" 396} 397 398network_start_defaultroute() 399{ 400 # Check $defaultroute, then /etc/mygate, for the name or address 401 # of my IPv4 gateway host. If using a name, that name must be in 402 # /etc/hosts. 403 # 404 if [ -z "$defaultroute" ] && [ -f /etc/mygate ]; then 405 defaultroute=$(cat /etc/mygate) 406 fi 407 if [ -n "$defaultroute" ]; then 408 /sbin/route add default $defaultroute 409 fi 410} 411 412network_start_defaultroute6() 413{ 414 # Check $defaultroute6, then /etc/mygate6, for the name or address 415 # of my IPv6 gateway host. If using a name, that name must be in 416 # /etc/hosts. Note that the gateway host address must be a link-local 417 # address if it is not using an stf* interface. 418 # 419 if [ -z "$defaultroute6" ] && [ -f /etc/mygate6 ]; then 420 defaultroute6=$(cat /etc/mygate6) 421 fi 422 if [ -n "$defaultroute6" ]; then 423 if [ "$ip6mode" = "autohost" ]; then 424 echo 425 warn \ 426 "ip6mode is set to 'autohost' and a v6 default route is also set." 427 fi 428 /sbin/route add -inet6 default $defaultroute6 429 fi 430} 431 432network_start_ipv6_autoconf() 433{ 434 # IPv6 interface autoconfiguration. 435 436 dadcount=$(/sbin/sysctl -n net.inet6.ip6.dad_count 2>/dev/null) 437 if [ -n "$dadcount" -a "$dadcount" != 0 ]; then 438 # wait till DAD is completed 439 echo 'Waiting for DAD to complete for' \ 440 'statically configured addresses...' 441 # Add 1 for MAX_RTR_SOLICITATION_DELAY and another 442 # to give time for the last DAD packet to respond and 443 # a few more for luck. 444 waitsecs=$((dadcount + 4)) 445 /sbin/ifconfig -w $waitsecs 446 fi 447 448 # dhcpcd will ensure DAD completes before forking 449 if checkyesnox rtsol && ! checkyesno dhcpcd; then 450 if [ "$ip6mode" = "autohost" ]; then 451 echo 452 warn "rtsol has been removed, " \ 453 "please configure dhcpcd in its place." 454 fi 455 fi 456} 457 458network_start_local() 459{ 460 # XXX this must die 461 if [ -s /etc/netstart.local ]; then 462 sh /etc/netstart.local start 463 fi 464} 465 466network_stop() 467{ 468 echo "Stopping network." 469 470 network_stop_local 471 network_stop_aliases 472 [ "$net_interfaces" != NO ] && 473 network_stop_interfaces 474 network_stop_route 475} 476 477network_stop_local() 478{ 479 # XXX this must die 480 if [ -s /etc/netstart.local ]; then 481 sh /etc/netstart.local stop 482 fi 483} 484 485network_stop_aliases() 486{ 487 echo "Deleting aliases." 488 if [ -f /etc/ifaliases ]; then 489 while read addr int net; do 490 /sbin/ifconfig $int inet delete $addr 491 done < /etc/ifaliases 492 fi 493 494 for int in $(/sbin/ifconfig -lu); do 495 eval args=\$ifaliases_$int 496 if [ -n "$args" ]; then 497 set -- $args 498 while [ $# -ge 2 ]; do 499 addr=$1 ; net=$2 ; shift 2 500 /sbin/ifconfig $int inet delete $addr 501 done 502 fi 503 done 504} 505 506network_stop_interfaces() 507{ 508 # down interfaces 509 # 510 echo -n 'Downing network interfaces:' 511 if checkyesno auto_ifconfig; then 512 tmp=$(/sbin/ifconfig -l) 513 else 514 tmp="$net_interfaces" 515 fi 516 for int in $tmp; do 517 eval args=\$ifconfig_$int 518 if [ -n "$args" ] || [ -f /etc/ifconfig.$int ]; then 519 echo -n " $int" 520 if [ -f /var/run/dhcpcd-$int.pid ]; then 521 /sbin/dhcpcd -k $int 2> /dev/null 522 fi 523 /sbin/ifconfig $int down 524 if /sbin/ifconfig $int destroy 2>/dev/null && \ 525 checkyesno ipfilter; then 526 # resync ipf(4) 527 /sbin/ipf -y >/dev/null 528 fi 529 fi 530 done 531 echo "." 532} 533 534network_stop_route() 535{ 536 # flush routes 537 # 538 /sbin/route -qn flush 539 540} 541 542load_rc_config $name 543load_rc_config_var dhclient dhclient 544load_rc_config_var dhcpcd dhcpcd 545load_rc_config_var ipfilter ipfilter 546run_rc_command "$1" 547