1# 2# Copyright (c) 2003 The FreeBSD Project. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions 6# are met: 7# 1. Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# 2. Redistributions in binary form must reproduce the above copyright 10# notice, this list of conditions and the following disclaimer in the 11# documentation and/or other materials provided with the distribution. 12# 13# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 17# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23# SUCH DAMAGE. 24# 25# $FreeBSD: src/etc/network.subr,v 1.156 2004/08/28 07:58:02 yar Exp $ 26# $DragonFly: src/etc/network.subr,v 1.4 2005/12/24 14:29:47 corecode Exp $ 27# 28 29# 30# Subroutines commonly used from network startup scripts. 31# Requires that rc.conf be loaded first. 32# 33 34# ifconfig_up if 35# Evaluate ifconfig(8) arguments for interface $if and 36# run ifconfig(8) with those arguments. It returns 0 if 37# arguments were found and executed or 1 if the interface 38# had no arguments. 39# 40ifconfig_up() 41{ 42 eval ifconfig_args=\$ifconfig_$1 43 if [ -n "${ifconfig_args}" ]; then 44 ifconfig $1 ${ifconfig_args} 45 return 0 46 fi 47 return 1 48} 49 50# ifconfig_down if 51# Remove all inet entries from the $if interface. It returns 52# 0 if inet entries were found and removed. It returns 1 if 53# no entries were found or they could not be removed. 54# 55ifconfig_down() 56{ 57 [ -z "$1" ] && return 1 58 _ifs="^" 59 _ret=1 60 61 inetList="`ifconfig $1 | grep 'inet ' | tr "\n" "$_ifs"`" 62 63 oldifs="$IFS" 64 IFS="$_ifs" 65 for _inet in $inetList ; do 66 # get rid of extraneous line 67 [ -z "$_inet" ] && break 68 69 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 70 71 IFS="$oldifs" 72 ifconfig $1 ${_inet} delete 73 IFS="$_ifs" 74 _ret=0 75 done 76 IFS="$oldifs" 77 78 return $_ret 79} 80 81# ifalias_up if 82# Configure aliases for network interface $if. 83# It returns 0 if at least one alias was configured or 84# 1 if there were none. 85# 86ifalias_up() 87{ 88 _ret=1 89 alias=0 90 while : ; do 91 eval ifconfig_args=\$ifconfig_$1_alias${alias} 92 if [ -n "${ifconfig_args}" ]; then 93 ifconfig $1 ${ifconfig_args} alias 94 alias=$((${alias} + 1)) 95 _ret=0 96 else 97 break 98 fi 99 done 100 return $_ret 101} 102 103#ifalias_down if 104# Remove aliases for network interface $if. 105# It returns 0 if at least one alias was removed or 106# 1 if there were none. 107# 108ifalias_down() 109{ 110 _ret=1 111 alias=0 112 while : ; do 113 eval ifconfig_args=\$ifconfig_$1_alias${alias} 114 if [ -n "${ifconfig_args}" ]; then 115 ifconfig $1 ${ifconfig_args} -alias 116 alias=$((${alias} + 1)) 117 _ret=0 118 else 119 break 120 fi 121 done 122 return $_ret 123} 124 125# ifscript_up if 126# Evaluate a startup script for the $if interface. 127# It returns 0 if a script was found and processed or 128# 1 if no script was found. 129# 130ifscript_up() 131{ 132 if [ -r /etc/start_if.$1 ]; then 133 . /etc/start_if.$1 134 return 0 135 fi 136 return 1 137} 138 139# ifscript_down if 140# Evaluate a shutdown script for the $if interface. 141# It returns 0 if a script was found and processed or 142# 1 if no script was found. 143# 144ifscript_down() 145{ 146 if [ -r /etc/stop_if.$1 ]; then 147 . /etc/stop_if.$1 148 return 0 149 fi 150 return 1 151} 152 153# Create cloneable interfaces. 154# 155clone_up() 156{ 157 _prefix= 158 _list= 159 for ifn in ${cloned_interfaces}; do 160 ifconfig ${ifn} create 161 if [ $? -eq 0 ]; then 162 _list="${_list}${_prefix}${ifn}" 163 [ -z "$_prefix" ] && _prefix=' ' 164 fi 165 done 166 debug "Cloned: ${_list}" 167} 168 169# Destroy cloned interfaces. Destroyed interfaces are echoed 170# to standard output. 171# 172clone_down() 173{ 174 _prefix= 175 _list= 176 for ifn in ${cloned_interfaces}; do 177 ifconfig ${ifn} destroy 178 if [ $? -eq 0 ]; then 179 _list="${_list}${_prefix}${ifn}" 180 [ -z "$_prefix" ] && _prefix=' ' 181 fi 182 done 183 debug "Destroyed clones: ${_list}" 184} 185 186gif_up() { 187 case ${gif_interfaces} in 188 [Nn][Oo] | '') 189 ;; 190 *) 191 for i in ${gif_interfaces}; do 192 eval peers=\$gifconfig_$i 193 case ${peers} in 194 '') 195 continue 196 ;; 197 *) 198 ifconfig $i create >/dev/null 2>&1 199 ifconfig $i tunnel ${peers} 200 ifconfig $i up 201 ;; 202 esac 203 done 204 ;; 205 esac 206} 207 208# 209# ipx_up ifn 210# Configure any IPX addresses for interface $ifn. Returns 0 if IPX 211# arguments were found and configured; returns 1 otherwise. 212# 213ipx_up() 214{ 215 ifn="$1" 216 eval ifconfig_args=\$ifconfig_${ifn}_ipx 217 if [ -n "${ifconfig_args}" ]; then 218 ifconfig ${ifn} ${ifconfig_args} 219 return 0 220 fi 221 return 1 222} 223 224# ipx_down ifn 225# Remove IPX addresses for interface $ifn. Returns 0 if IPX 226# addresses were found and unconfigured. It returns 1, otherwise. 227# 228ipx_down() 229{ 230 [ -z "$1" ] && return 1 231 _ifs="^" 232 _ret=1 233 234 ipxList="`ifconfig $1 | grep 'ipx ' | tr "\n" "$_ifs"`" 235 236 oldifs="$IFS" 237 IFS="$_ifs" 238 for _ipx in $ipxList ; do 239 # get rid of extraneous line 240 [ -z "$_ipx" ] && break 241 242 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 243 244 IFS="$oldifs" 245 ifconfig $1 ${_ipx} delete 246 IFS="$_ifs" 247 _ret=0 248 done 249 IFS="$oldifs" 250 251 return $_ret 252} 253 254# 255# list_net_interfaces type 256# List all network interfaces. The type of interface returned 257# can be controlled by the type argument. The type 258# argument can be any of the following: 259# nodhcp - all interfaces, excluding DHCP configured interfaces 260# dhcp - list only DHCP configured interfaces 261# If no argument is specified all network interfaces are output. 262# Note that the list will include cloned interfaces if applicable. 263# Cloned interfaces must already exist to have a chance to appear 264# in the list if ${network_interfaces} is set to `auto'. 265# 266list_net_interfaces() 267{ 268 type=$1 269 270 # Get a list of ALL the interfaces. NOTE: cloned interfaces 271 # have already been configured so they should show up in the 272 # ifconfig -l output. 273 # 274 case ${network_interfaces} in 275 [Aa][Uu][Tt][Oo]) 276 _tmplist="`ifconfig -l`" 277 ;; 278 *) 279 _tmplist="${network_interfaces} ${cloned_interfaces}" 280 ;; 281 esac 282 283 if [ -z "$type" ]; then 284 echo $_tmplist 285 return 0 286 fi 287 288 # Separate out dhcp and non-dhcp intefraces 289 # 290 _aprefix= 291 _bprefix= 292 for _if in ${_tmplist} ; do 293 eval _ifarg="\$ifconfig_${_if}" 294 case "$_ifarg" in 295 [Dd][Hh][Cc][Pp]) 296 _dhcplist="${_dhcplist}${_aprefix}${_if}" 297 [ -z "$_aprefix" ] && _aprefix=' ' 298 ;; 299 ''|*) 300 _nodhcplist="${_nodhcplist}${_bprefix}${_if}" 301 [ -z "$_bprefix" ] && _bprefix=' ' 302 ;; 303 esac 304 done 305 306 case "$type" in 307 nodhcp) 308 echo $_nodhcplist 309 ;; 310 dhcp) 311 echo $_dhcplist 312 ;; 313 esac 314 return 0 315} 316 317hexdigit() 318{ 319 if [ $1 -lt 10 ]; then 320 echo $1 321 else 322 case $1 in 323 10) echo a ;; 324 11) echo b ;; 325 12) echo c ;; 326 13) echo d ;; 327 14) echo e ;; 328 15) echo f ;; 329 esac 330 fi 331} 332 333hexprint() 334{ 335 val=$1 336 str='' 337 338 dig=`hexdigit $((${val} & 15))` 339 str=${dig}${str} 340 val=$((${val} >> 4)) 341 while [ ${val} -gt 0 ]; do 342 dig=`hexdigit $((${val} & 15))` 343 str=${dig}${str} 344 val=$((${val} >> 4)) 345 done 346 347 echo ${str} 348} 349 350# Setup the interfaces for IPv6 351network6_interface_setup() 352{ 353 interfaces=$* 354 rtsol_interfaces='' 355 case ${ipv6_gateway_enable} in 356 [Yy][Ee][Ss]) 357 rtsol_available=no 358 ;; 359 *) 360 rtsol_available=yes 361 ;; 362 esac 363 for i in $interfaces; do 364 rtsol_interface=yes 365 eval prefix=\$ipv6_prefix_$i 366 if [ -n "${prefix}" ]; then 367 rtsol_available=no 368 rtsol_interface=no 369 laddr=`network6_getladdr $i` 370 hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'` 371 for j in ${prefix}; do 372 address=$j\:${hostid} 373 ifconfig $i inet6 ${address} prefixlen 64 alias 374 375 case ${ipv6_gateway_enable} in 376 [Yy][Ee][Ss]) 377 # subnet-router anycast address 378 # (rfc2373) 379 ifconfig $i inet6 $j:: prefixlen 64 \ 380 alias anycast 381 ;; 382 esac 383 done 384 fi 385 eval ipv6_ifconfig=\$ipv6_ifconfig_$i 386 if [ -n "${ipv6_ifconfig}" ]; then 387 rtsol_available=no 388 rtsol_interface=no 389 ifconfig $i inet6 ${ipv6_ifconfig} alias 390 fi 391 392 if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ] 393 then 394 case ${i} in 395 lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*) 396 ;; 397 *) 398 rtsol_interfaces="${rtsol_interfaces} ${i}" 399 ;; 400 esac 401 else 402 ifconfig $i inet6 403 fi 404 done 405 406 if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then 407 # Act as endhost - automatically configured. 408 # You can configure only single interface, as 409 # specification assumes that autoconfigured host has 410 # single interface only. 411 sysctl net.inet6.ip6.accept_rtadv=1 412 set ${rtsol_interfaces} 413 ifconfig $1 up 414 rtsol $1 415 fi 416 417 for i in $interfaces; do 418 alias=0 419 while : ; do 420 eval ipv6_ifconfig=\$ipv6_ifconfig_${i}_alias${alias} 421 if [ -z "${ipv6_ifconfig}" ]; then 422 break; 423 fi 424 ifconfig $i inet6 ${ipv6_ifconfig} alias 425 alias=$((${alias} + 1)) 426 done 427 done 428} 429 430# Setup IPv6 to IPv4 mapping 431network6_stf_setup() 432{ 433 case ${stf_interface_ipv4addr} in 434 [Nn][Oo] | '') 435 ;; 436 *) 437 # assign IPv6 addr and interface route for 6to4 interface 438 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0})) 439 OIFS="$IFS" 440 IFS=".$IFS" 441 set ${stf_interface_ipv4addr} 442 IFS="$OIFS" 443 hexfrag1=`hexprint $(($1*256 + $2))` 444 hexfrag2=`hexprint $(($3*256 + $4))` 445 ipv4_in_hexformat="${hexfrag1}:${hexfrag2}" 446 case ${stf_interface_ipv6_ifid} in 447 [Aa][Uu][Tt][Oo] | '') 448 for i in ${ipv6_network_interfaces}; do 449 laddr=`network6_getladdr ${i}` 450 case ${laddr} in 451 '') 452 ;; 453 *) 454 break 455 ;; 456 esac 457 done 458 stf_interface_ipv6_ifid=`expr "${laddr}" : \ 459 'fe80::\(.*\)%\(.*\)'` 460 case ${stf_interface_ipv6_ifid} in 461 '') 462 stf_interface_ipv6_ifid=0:0:0:1 463 ;; 464 esac 465 ;; 466 esac 467 ifconfig stf0 create >/dev/null 2>&1 468 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ 469 prefixlen ${stf_prefixlen} 470 # disallow packets to malicious 6to4 prefix 471 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 472 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 473 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 474 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 475 ;; 476 esac 477} 478 479# Setup static routes 480network6_static_routes_setup() 481{ 482 # Set up any static routes. 483 case ${ipv6_defaultrouter} in 484 [Nn][Oo] | '') 485 ;; 486 *) 487 ipv6_static_routes="default ${ipv6_static_routes}" 488 ipv6_route_default="default ${ipv6_defaultrouter}" 489 ;; 490 esac 491 case ${ipv6_static_routes} in 492 [Nn][Oo] | '') 493 ;; 494 *) 495 for i in ${ipv6_static_routes}; do 496 eval ipv6_route_args=\$ipv6_route_${i} 497 route add -inet6 ${ipv6_route_args} 498 done 499 ;; 500 esac 501} 502 503# Setup faith 504network6_faith_setup() 505{ 506 case ${ipv6_faith_prefix} in 507 [Nn][Oo] | '') 508 ;; 509 *) 510 sysctl net.inet6.ip6.keepfaith=1 511 ifconfig faith0 create >/dev/null 2>&1 512 ifconfig faith0 up 513 for prefix in ${ipv6_faith_prefix}; do 514 prefixlen=`expr "${prefix}" : ".*/\(.*\)"` 515 case ${prefixlen} in 516 '') 517 prefixlen=96 518 ;; 519 *) 520 prefix=`expr "${prefix}" : \ 521 "\(.*\)/${prefixlen}"` 522 ;; 523 esac 524 route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1 525 route change -inet6 ${prefix} -prefixlen ${prefixlen} \ 526 -ifp faith0 527 done 528 ;; 529 esac 530} 531 532# Install the "default interface" to kernel, which will be used 533# as the default route when there's no router. 534network6_default_interface_setup() 535{ 536 # Choose IPv6 default interface if it is not clearly specified. 537 case ${ipv6_default_interface} in 538 '') 539 for i in ${ipv6_network_interfaces}; do 540 case $i in 541 lo0|faith[0-9]*) 542 continue 543 ;; 544 esac 545 laddr=`network6_getladdr $i exclude_tentative` 546 case ${laddr} in 547 '') 548 ;; 549 *) 550 ipv6_default_interface=$i 551 break 552 ;; 553 esac 554 done 555 ;; 556 esac 557 558 # Disallow unicast packets without outgoing scope identifiers, 559 # or route such packets to a "default" interface, if it is specified. 560 route add -inet6 fe80:: -prefixlen 10 ::1 -reject 561 case ${ipv6_default_interface} in 562 [Nn][Oo] | '') 563 route add -inet6 ff02:: -prefixlen 16 ::1 -reject 564 ;; 565 *) 566 laddr=`network6_getladdr ${ipv6_default_interface}` 567 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \ 568 -cloning 569 570 # Disable installing the default interface with the 571 # case net.inet6.ip6.forwarding=0 and 572 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict 573 # between the default router list and the manual 574 # configured default route. 575 case ${ipv6_gateway_enable} in 576 [Yy][Ee][Ss]) 577 ;; 578 *) 579 if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ] 580 then 581 ndp -I ${ipv6_default_interface} 582 fi 583 ;; 584 esac 585 ;; 586 esac 587} 588 589network6_getladdr() 590{ 591 ifconfig $1 2>/dev/null | while read proto addr rest; do 592 case ${proto} in 593 inet6) 594 case ${addr} in 595 fe80::*) 596 if [ -z "$2" ]; then 597 echo ${addr} 598 return 599 fi 600 case ${rest} in 601 *tentative*) 602 continue 603 ;; 604 *) 605 echo ${addr} 606 return 607 esac 608 esac 609 esac 610 done 611} 612