10Sstevel@tonic-gate#!/sbin/sh 20Sstevel@tonic-gate# 30Sstevel@tonic-gate# CDDL HEADER START 40Sstevel@tonic-gate# 50Sstevel@tonic-gate# The contents of this file are subject to the terms of the 61573Sdp# Common Development and Distribution License (the "License"). 71573Sdp# You may not use this file except in compliance with the License. 80Sstevel@tonic-gate# 90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate# See the License for the specific language governing permissions 120Sstevel@tonic-gate# and limitations under the License. 130Sstevel@tonic-gate# 140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate# 200Sstevel@tonic-gate# CDDL HEADER END 210Sstevel@tonic-gate# 220Sstevel@tonic-gate# 23*11262SRajagopal.Andra@Sun.COM# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate# Use is subject to license terms. 250Sstevel@tonic-gate# 260Sstevel@tonic-gate 270Sstevel@tonic-gate# 280Sstevel@tonic-gate# This is third phase of TCP/IP startup/configuration. This script 29*11262SRajagopal.Andra@Sun.COM# runs after the NIS startup script. We run things here that may 30*11262SRajagopal.Andra@Sun.COM# depend on NIS maps. 310Sstevel@tonic-gate# 320Sstevel@tonic-gate 331573Sdp. /lib/svc/share/smf_include.sh 341573Sdp 350Sstevel@tonic-gatecase "$1" in 360Sstevel@tonic-gate'start') 370Sstevel@tonic-gate # 383448Sdh155122 # In a shared-IP zone we need this service to be up, but all of the 393448Sdh155122 # work it tries to do is irrelevant (and will actually lead to the 403448Sdh155122 # service failing if we try to do it), so just bail out. 413448Sdh155122 # In the global zone and exclusive-IP zones we proceed. 420Sstevel@tonic-gate # 433448Sdh155122 smf_configure_ip || exit 0 440Sstevel@tonic-gate ;; # Fall through -- rest of script is the initialization code 450Sstevel@tonic-gate 460Sstevel@tonic-gate'stop') 470Sstevel@tonic-gate exit 0 480Sstevel@tonic-gate ;; 490Sstevel@tonic-gate 500Sstevel@tonic-gate*) 510Sstevel@tonic-gate echo "Usage: $0 { start | stop }" 520Sstevel@tonic-gate exit 1 530Sstevel@tonic-gate ;; 540Sstevel@tonic-gateesac 550Sstevel@tonic-gate 567045SokieNWAM_FMRI="svc:/network/physical:nwam" 577045SokieNETSVC_FMRI="svc:/network/service:default" 587045Sokie 593938Sjbeckinterface=$2 600Sstevel@tonic-gate 610Sstevel@tonic-gate# If boot variables are not set, set variables we use 620Sstevel@tonic-gate[ -z "$_INIT_UTS_NODENAME" ] && _INIT_UTS_NODENAME=`/usr/bin/uname -n` 630Sstevel@tonic-gate 640Sstevel@tonic-gate# 657045Sokie# This function removes the instance portion of the passed-in FMRI; for 667045Sokie# example, 'svc:/network/service:default' becomes 'svc:/network/service'. 677045Sokie# 687045Sokieremove_fmri_inst () { 697045Sokie echo $1 | awk -F: ' { printf "%s:%s", $1, $2 } ' 707045Sokie} 717045Sokie 727045Sokie# 737045Sokie# This function returns true if this script was *not* invoked 747045Sokie# by an instance of svc:/network/service. 757045Sokie# 767045Sokiefmri_is_not_netsvc () { 777045Sokie FMRI_1=`remove_fmri_inst $SMF_FMRI` 787045Sokie FMRI_2=`remove_fmri_inst $NETSVC_FMRI` 797045Sokie [ "$FMRI_1" = "$FMRI_2" ] && return 1 807045Sokie return 0 817045Sokie} 827045Sokie 837045Sokie# 847045Sokie# This function returns true if this script was *not* invoked 857045Sokie# by the nwam instance of the network/physical service. 867045Sokie# 877045Sokiefmri_is_not_nwam () { 887045Sokie [ "&SMF_FMRI" = "$NWAM_FMRI" ] && return 1 897045Sokie return 0 907045Sokie} 917045Sokie 927045Sokie# 937045Sokie# This function returns true if the nwam service is not running, false 947045Sokie# if it is. "running" is defined as "current state is online or next 957045Sokie# state is online". 967045Sokie# 977045Sokienwam_is_not_running() { 987045Sokie state=`/usr/bin/svcprop -p restarter/state $NWAM_FMRI` 997045Sokie nstate=`/usr/bin/svcprop -p restarter/next_state $NWAM_FMRI` 1007045Sokie 1017045Sokie [ "$state" = "online" -o "$nextstate" = "online" ] && return 1 1027045Sokie return 0 1037045Sokie} 1047045Sokie 1057045Sokie# 1060Sstevel@tonic-gate# wait_nis 1070Sstevel@tonic-gate# Wait up to 5 seconds for ypbind to obtain a binding. 1080Sstevel@tonic-gate# 1090Sstevel@tonic-gatewait_nis () 1100Sstevel@tonic-gate{ 1110Sstevel@tonic-gate for i in 1 2 3 4 5; do 1120Sstevel@tonic-gate server=`/usr/bin/ypwhich 2>/dev/null` 1130Sstevel@tonic-gate [ $? -eq 0 -a -n "$server" ] && return 0 || sleep 1 1140Sstevel@tonic-gate done 1150Sstevel@tonic-gate return 1 1160Sstevel@tonic-gate} 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate# 1190Sstevel@tonic-gate# This function takes two file names and the file mode as input. The two 1200Sstevel@tonic-gate# files are compared for differences (using cmp(1)) and if different, the 1210Sstevel@tonic-gate# second file is over written with the first. A chmod is done with the file 1220Sstevel@tonic-gate# mode passed in. If the files are equal, the first file passed 1230Sstevel@tonic-gate# in (the /tmp file) is deleted. 1240Sstevel@tonic-gate# 1250Sstevel@tonic-gatemv_file () 1260Sstevel@tonic-gate{ 1270Sstevel@tonic-gate /usr/bin/cmp -s $1 $2 1280Sstevel@tonic-gate if [ $? -eq 1 ]; then 1290Sstevel@tonic-gate /usr/bin/mv $1 $2 1300Sstevel@tonic-gate # 1310Sstevel@tonic-gate # The umask during boot is configurable, which requires 1320Sstevel@tonic-gate # explicit setting of file permission modes when we 1330Sstevel@tonic-gate # create files. 1340Sstevel@tonic-gate # 1350Sstevel@tonic-gate /usr/bin/chmod $3 $2 1360Sstevel@tonic-gate else 1370Sstevel@tonic-gate /usr/bin/rm $1 1380Sstevel@tonic-gate fi 1390Sstevel@tonic-gate} 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate# 1427045Sokie# This function takes a DHCP parameter (as defined in /etc/dhcp/inittab) 1437045Sokie# and returns the value for that parameter returned by the DHCP server. 1447045Sokie# If the global 'interface' is defined, it will request the value learned 1457045Sokie# on that interface, else it will request the value learned on the primary 1467045Sokie# interface. 1477045Sokie# 1487045Sokieget_dhcp_var () 1497045Sokie{ 1507045Sokie if [ -n "$interface" ]; then 1517045Sokie /sbin/dhcpinfo -i $interface $1 1527045Sokie else 1537045Sokie /sbin/dhcpinfo $1 1547045Sokie fi 1557045Sokie} 1567045Sokie 1577045Sokie# 1587045Sokie# This function returns true if the string "# Added by DHCP$" occurs in 1597045Sokie# the passed-in file, false otherwise. 1607045Sokie# 1617045Sokiedhcp_edits () 1627045Sokie{ 1637045Sokie /usr/bin/grep '# Added by DHCP$' $1 >/dev/null 2>&1 1647045Sokie return $? 1657045Sokie} 1667045Sokie 1677045Sokie# 1687045Sokie# update_resolv() 1697045Sokie# Go through /etc/resolv.conf and replace any existing domain or 1707045Sokie# nameserver entries with new ones derived from DHCP. Note that 1717045Sokie# it is important to preserve order of domain entries vs. search 1727045Sokie# entries; the search entries are reserved for administrator 1737045Sokie# customization and if placed after the domain entry will override 1747045Sokie# it. See resolv.conf(4). 1757045Sokie# 1767045Sokie# The first arg should be the dns servers string, the second 1777045Sokie# should be the dns domain. 1787045Sokie# 1797045Sokieupdate_resolv () 1807045Sokie{ 1817045Sokie dnsservers=$1 1827045Sokie dnsdomain=$2 1837045Sokie 1847045Sokie if [ ! -f /etc/resolv.conf ]; then 1857045Sokie /usr/bin/touch /etc/resolv.conf 1867045Sokie fi 1877045Sokie export dnsservers dnsdomain 1887045Sokie /usr/bin/nawk </etc/resolv.conf >/tmp/resolv.conf.$$ ' 1897045Sokie function writedomain() { 1907045Sokie if (updated == 0) { 1917045Sokie # Use only first domain, not a search list 1927045Sokie split(ENVIRON["dnsdomain"], d) 1937045Sokie if(length(d[1]) != 0) 1947045Sokie printf("domain %s\n", d[1]) 1957045Sokie } 1967045Sokie ++updated 1977045Sokie } 1987045Sokie $1 == "domain" { writedomain(); next } 1997045Sokie $1 != "nameserver" { print $0 } 2007045Sokie END { 2017045Sokie writedomain() 2027045Sokie n = split(ENVIRON["dnsservers"], s) 2037045Sokie for (i = 1; i <= n; ++i) 2047045Sokie printf("nameserver %s\n", s[i]) 2057045Sokie }' 2067045Sokie unset dnsservers dnsdomain 2077045Sokie mv_file /tmp/resolv.conf.$$ /etc/resolv.conf 644 2087045Sokie} 2097045Sokie 2107045Sokie# 2110Sstevel@tonic-gate# update_nss 2120Sstevel@tonic-gate# This routine takes as a parameter, the name of the respective policy 2130Sstevel@tonic-gate# to change in the nsswitch.conf (hosts or ipnodes) to update with dns. 2140Sstevel@tonic-gate# 2150Sstevel@tonic-gateupdate_nss () 2160Sstevel@tonic-gate{ 2170Sstevel@tonic-gate policy=$1; 2180Sstevel@tonic-gate # Add dns to the nsswitch file, if it isn't already there. 2190Sstevel@tonic-gate /usr/bin/awk ' $1 ~ /^'${policy}':/ { 2200Sstevel@tonic-gate n = split($0, a); 2210Sstevel@tonic-gate newl = a[1]; 2220Sstevel@tonic-gate if ($0 !~ /dns/) { 2230Sstevel@tonic-gate printf("#%s # Commented out by DHCP\n", $0); 2240Sstevel@tonic-gate updated = 0; 2250Sstevel@tonic-gate for (i = 2; i <= n; i++) { 2260Sstevel@tonic-gate if (updated == 0 && index(a[i], "[") == 1) { 2270Sstevel@tonic-gate newl = newl" dns"; 2280Sstevel@tonic-gate updated++; 2290Sstevel@tonic-gate } 2300Sstevel@tonic-gate newl = newl" "a[i]; 2310Sstevel@tonic-gate } 2320Sstevel@tonic-gate if (updated == 0) { 2330Sstevel@tonic-gate newl = newl" dns"; 2340Sstevel@tonic-gate updated++; 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate if (updated != 0) 2370Sstevel@tonic-gate newl = newl" # Added by DHCP"; 2380Sstevel@tonic-gate else 2390Sstevel@tonic-gate newl = $0; 2400Sstevel@tonic-gate printf("%s\n", newl); 2410Sstevel@tonic-gate } else 2420Sstevel@tonic-gate printf("%s\n", $0); 2430Sstevel@tonic-gate } $1 !~ /^'${policy}':/ { printf("%s\n", $0); }' /etc/nsswitch.conf \ 2440Sstevel@tonic-gate >/tmp/nsswitch.conf.$$ 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate mv_file /tmp/nsswitch.conf.$$ /etc/nsswitch.conf 644 2470Sstevel@tonic-gate} 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate# 2507045Sokie# Remove any lines with the "# Added by DHCP" tag from /etc/nsswitch.conf; 2517045Sokie# also uncomment hosts and ipnodes entries which were previously commented 2527045Sokie# out by this script. 2530Sstevel@tonic-gate# 2547045Sokiecleanup_nss () 2557045Sokie{ 2560Sstevel@tonic-gate /usr/bin/sed \ 2570Sstevel@tonic-gate -e '/# Added by DHCP$/d' \ 2580Sstevel@tonic-gate -e 's/^\(#hosts:\)\(.*[^#]\)\(#.*\)$/hosts: \2/' \ 2590Sstevel@tonic-gate -e 's/^\(#ipnodes:\)\(.*[^#]\)\(#.*\)$/ipnodes: \2/' \ 2600Sstevel@tonic-gate /etc/nsswitch.conf >/tmp/nsswitch.conf.$$ 2610Sstevel@tonic-gate 2620Sstevel@tonic-gate mv_file /tmp/nsswitch.conf.$$ /etc/nsswitch.conf 644 2637045Sokie} 2640Sstevel@tonic-gate 2657045Sokie# 2667045Sokie# Remove any lines with the "# Added by DHCP" tag from /etc/inet/hosts. 2677045Sokie# 2687045Sokiecleanup_hosts () 2697045Sokie{ 2703938Sjbeck /usr/bin/nawk '{ 2713938Sjbeck if (index($0, "# Added by DHCP") == 0 || 2723938Sjbeck $1 == "127.0.0.1" || $1 == "::1") { 2733938Sjbeck print $0 2743938Sjbeck } 2753938Sjbeck }' /etc/inet/hosts > /tmp/hosts.$$ 2763938Sjbeck mv_file /tmp/hosts.$$ /etc/inet/hosts 444 2777045Sokie} 2787045Sokie 2797045Sokie# 2807045Sokie# We now need to reset the netmask and broadcast address for our network 2817045Sokie# interfaces. Since this may result in a name service lookup, we want to 2827045Sokie# now wait for NIS to come up if we previously started it. 2837045Sokie# 2847045Sokie# Only do this in the non-nwam case. 2857045Sokie# 2867045Sokieif fmri_is_not_nwam; then 2877045Sokie domain=`/usr/bin/domainname 2>/dev/null` 2887045Sokie 2897045Sokie [ -z "$domain" ] || [ ! -d /var/yp/binding/$domain ] || wait_nis || \ 2907045Sokie echo "WARNING: Timed out waiting for NIS to come up" >& 2 2917045Sokie 2927045Sokie # 2937045Sokie # Re-set the netmask and broadcast addr for all IP interfaces. This 2947045Sokie # ifconfig is run here, after waiting for name services, so that 2957045Sokie # "netmask +" will find the netmask if it lives in a NIS map. The 'D' 2967045Sokie # in -auD tells ifconfig NOT to mess with the interface if it is 2977045Sokie # under DHCP control 2987045Sokie # 2997045Sokie /usr/sbin/ifconfig -auD4 netmask + broadcast + 3003938Sjbeckfi 3010Sstevel@tonic-gate 3027045Sokie# Uncomment these lines to print complete network interface configuration 3037045Sokie# echo "network interface configuration:" 3047045Sokie# /usr/sbin/ifconfig -a 3057045Sokie 3067045Sokie# 3077045Sokie# If our network configuration strategy is DHCP, check for DNS 3087045Sokie# configuration parameters obtained from the DHCP server. 3097045Sokie# 3107045Sokie# If NWAM is enabled, it will invoke this script to do this configuration 3117045Sokie# whenever a DHCP lease is obtained; in that case, this configuration 3127045Sokie# should *not* happen when svc:network/service is starting, as it will 3137045Sokie# interfere with the configuration performed by NWAM. 3147045Sokie# 3157045Sokieif nwam_is_not_running || fmri_is_not_netsvc; then 3167045Sokie 3177045Sokie smf_netstrategy 3187045Sokie 3197045Sokie if [ "$_INIT_NET_STRATEGY" = "dhcp" ]; then 3207045Sokie dnsservers=`get_dhcp_var DNSserv` 3217045Sokie dnsdomain=`get_dhcp_var DNSdmain` 3227045Sokie else 3237045Sokie dnsservers="" 3247045Sokie dnsdomain="" 3257045Sokie fi 3267045Sokie 3277045Sokie if [ -n "$dnsservers" ]; then 3287045Sokie # 3297045Sokie # add settings retrieved from dhcp server to /etc/resolv.conf 3307045Sokie # 3317045Sokie update_resolv "$dnsservers" "$dnsdomain" 3327045Sokie 3337045Sokie # 3347045Sokie # Add dns to the nsswitch file, if it isn't already there. 3357045Sokie # 3367045Sokie update_nss hosts 3377045Sokie update_nss ipnodes 3387045Sokie 3397045Sokie elif dhcp_edits /etc/nsswitch.conf; then 3407045Sokie # If we added DNS to the hosts and ipnodes 3417045Sokie # policy in the nsswitch, remove it. 3427045Sokie cleanup_nss 3437045Sokie fi 3447045Sokiefi 3457045Sokie 3467045Sokieif dhcp_edits /etc/inet/hosts; then 3477045Sokie # Clean up any old DHCP-added entries 3487045Sokie # (except loopback) in the hosts file. 3497045Sokie cleanup_hosts 3507045Sokiefi 3517045Sokie 3527045Sokie# 3537045Sokie# If we were invoked by NWAM, can exit now (skipping the ipqos config) 3547045Sokie# 3557045Sokieif [ -z "$SMF_FMRI" ] || [ "$SMF_FMRI" = "$NWAM_FMRI" ]; then 3564121Samaguire exit 0 3574121Samaguirefi 3584121Samaguire 3594121Samaguire# 3604121Samaguire# Load the IPQoS configuration. 3614121Samaguire# This is backgrounded so that any remote hostname lookups it performs 3624121Samaguire# don't unduely delay startup. Any messages go via syslog. 3634121Samaguire# 3644121Samaguire 3654121Samaguireif [ -f /usr/sbin/ipqosconf -a -f /etc/inet/ipqosinit.conf ]; then 3664121Samaguire /usr/sbin/ipqosconf -s -a /etc/inet/ipqosinit.conf & 3674121Samaguirefi 368