10Sstevel@tonic-gate#!/bin/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 64121Samaguire# Common Development and Distribution License (the "License"). 74121Samaguire# 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*11767SAnurag.Maskey@Sun.COM# Copyright 2010 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate# Use is subject to license terms. 250Sstevel@tonic-gate# 260Sstevel@tonic-gate# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T. 270Sstevel@tonic-gate# All rights reserved. 280Sstevel@tonic-gate# 290Sstevel@tonic-gate 308485SPeter.Memishian@Sun.COM# Print warnings to console 318485SPeter.Memishian@Sun.COMwarn_failed_ifs() { 328485SPeter.Memishian@Sun.COM echo "Failed to $1 interface(s):$2" >/dev/msglog 338485SPeter.Memishian@Sun.COM} 348485SPeter.Memishian@Sun.COM 350Sstevel@tonic-gate# 360Sstevel@tonic-gate# shcat file 370Sstevel@tonic-gate# Simulates cat in sh so it doesn't need to be on the root filesystem. 380Sstevel@tonic-gate# 390Sstevel@tonic-gateshcat() { 400Sstevel@tonic-gate while [ $# -ge 1 ]; do 410Sstevel@tonic-gate while read i; do 420Sstevel@tonic-gate echo "$i" 430Sstevel@tonic-gate done < $1 440Sstevel@tonic-gate shift 450Sstevel@tonic-gate done 460Sstevel@tonic-gate} 470Sstevel@tonic-gate 480Sstevel@tonic-gate# 498485SPeter.Memishian@Sun.COM# inet_list list of IPv4 interfaces. 508485SPeter.Memishian@Sun.COM# inet6_list list of IPv6 interfaces. 518485SPeter.Memishian@Sun.COM# ipmp_list list of IPMP IPv4 interfaces. 528485SPeter.Memishian@Sun.COM# ipmp6_list list of IPMP IPv6 interfaces. 538485SPeter.Memishian@Sun.COM# inet_plumbed list of plumbed IPv4 interfaces. 548485SPeter.Memishian@Sun.COM# inet6_plumbed list of plumbed IPv6 interfaces. 558485SPeter.Memishian@Sun.COM# ipmp_created list of created IPMP IPv4 interfaces. 568485SPeter.Memishian@Sun.COM# ipmp6_created list of created IPMP IPv6 interfaces. 578485SPeter.Memishian@Sun.COM# inet_failed list of IPv4 interfaces that failed to plumb. 588485SPeter.Memishian@Sun.COM# inet6_failed list of IPv6 interfaces that failed to plumb. 598485SPeter.Memishian@Sun.COM# ipmp_failed list of IPMP IPv4 interfaces that failed to be created. 608485SPeter.Memishian@Sun.COM# ipmp6_failed list of IPMP IPv6 interfaces that failed to be created. 610Sstevel@tonic-gate# 620Sstevel@tonic-gateunset inet_list inet_plumbed inet_failed \ 638485SPeter.Memishian@Sun.COM inet6_list inet6_plumbed inet6_failed \ 648485SPeter.Memishian@Sun.COM ipmp_list ipmp_created ipmp_failed \ 658485SPeter.Memishian@Sun.COM ipmp6_list ipmp6_created ipmp6_failed 668485SPeter.Memishian@Sun.COM 670Sstevel@tonic-gate# 680Sstevel@tonic-gate# get_physical interface 690Sstevel@tonic-gate# 708485SPeter.Memishian@Sun.COM# Return physical interface corresponding to the given interface. 710Sstevel@tonic-gate# 720Sstevel@tonic-gateget_physical() 730Sstevel@tonic-gate{ 740Sstevel@tonic-gate ORIGIFS="$IFS" 750Sstevel@tonic-gate IFS="${IFS}:" 760Sstevel@tonic-gate set -- $1 770Sstevel@tonic-gate IFS="$ORIGIFS" 780Sstevel@tonic-gate 790Sstevel@tonic-gate echo $1 800Sstevel@tonic-gate} 810Sstevel@tonic-gate 820Sstevel@tonic-gate# 830Sstevel@tonic-gate# get_logical interface 840Sstevel@tonic-gate# 850Sstevel@tonic-gate# Return logical interface number. Zero will be returned 868485SPeter.Memishian@Sun.COM# if there is no explicit logical number. 870Sstevel@tonic-gate# 880Sstevel@tonic-gateget_logical() 890Sstevel@tonic-gate{ 900Sstevel@tonic-gate ORIGIFS="$IFS" 910Sstevel@tonic-gate IFS="${IFS}:" 920Sstevel@tonic-gate set -- $1 930Sstevel@tonic-gate IFS="$ORIGIFS" 940Sstevel@tonic-gate 950Sstevel@tonic-gate if [ -z "$2" ]; then 960Sstevel@tonic-gate echo 0 970Sstevel@tonic-gate else 980Sstevel@tonic-gate echo $2 990Sstevel@tonic-gate fi 1000Sstevel@tonic-gate} 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate# 1030Sstevel@tonic-gate# if_comp if1 if2 1040Sstevel@tonic-gate# 1058485SPeter.Memishian@Sun.COM# Compare interfaces. Do the physical interface names and logical interface 1060Sstevel@tonic-gate# numbers match? 1070Sstevel@tonic-gate# 1080Sstevel@tonic-gateif_comp() 1090Sstevel@tonic-gate{ 1108485SPeter.Memishian@Sun.COM physical_comp $1 $2 && [ `get_logical $1` -eq `get_logical $2` ] 1110Sstevel@tonic-gate} 1128485SPeter.Memishian@Sun.COM 1130Sstevel@tonic-gate# 1140Sstevel@tonic-gate# physical_comp if1 if2 1150Sstevel@tonic-gate# 1168485SPeter.Memishian@Sun.COM# Do the two interfaces share a physical interface? 1170Sstevel@tonic-gate# 1180Sstevel@tonic-gatephysical_comp() 1190Sstevel@tonic-gate{ 1200Sstevel@tonic-gate [ "`get_physical $1`" = "`get_physical $2`" ] 1210Sstevel@tonic-gate} 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate# 1240Sstevel@tonic-gate# in_list op item list 1250Sstevel@tonic-gate# 1260Sstevel@tonic-gate# Is "item" in the given list? Use "op" to do the test, applying it to 1270Sstevel@tonic-gate# "item" and each member of the list in turn until it returns success. 1280Sstevel@tonic-gate# 1290Sstevel@tonic-gatein_list() 1300Sstevel@tonic-gate{ 1310Sstevel@tonic-gate op=$1 1320Sstevel@tonic-gate item=$2 1330Sstevel@tonic-gate shift 2 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate while [ $# -gt 0 ]; do 1360Sstevel@tonic-gate $op $item $1 && return 0 1370Sstevel@tonic-gate shift 1380Sstevel@tonic-gate done 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate return 1 1410Sstevel@tonic-gate} 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate# 1448485SPeter.Memishian@Sun.COM# get_groupifname groupname 1458485SPeter.Memishian@Sun.COM# 1468485SPeter.Memishian@Sun.COM# Return the IPMP meta-interface name for the group, if it exists. 1470Sstevel@tonic-gate# 1488485SPeter.Memishian@Sun.COMget_groupifname() 1498485SPeter.Memishian@Sun.COM{ 1508485SPeter.Memishian@Sun.COM /sbin/ipmpstat -gP -o groupname,group | while IFS=: read name ifname; do 1518485SPeter.Memishian@Sun.COM if [ "$name" = "$1" ]; then 1528485SPeter.Memishian@Sun.COM echo "$ifname" 1538485SPeter.Memishian@Sun.COM return 1548485SPeter.Memishian@Sun.COM fi 1558485SPeter.Memishian@Sun.COM done 1568485SPeter.Memishian@Sun.COM} 1578485SPeter.Memishian@Sun.COM 1588485SPeter.Memishian@Sun.COM# 1598485SPeter.Memishian@Sun.COM# create_ipmp ifname groupname type 1608485SPeter.Memishian@Sun.COM# 1618485SPeter.Memishian@Sun.COM# Helper function for create_groupifname() that returns zero if it's able 1628485SPeter.Memishian@Sun.COM# to create an IPMP interface of the specified type and place it in the 1638485SPeter.Memishian@Sun.COM# specified group, or non-zero otherwise. 1648485SPeter.Memishian@Sun.COM# 1658485SPeter.Memishian@Sun.COMcreate_ipmp() 1668485SPeter.Memishian@Sun.COM{ 1678485SPeter.Memishian@Sun.COM /sbin/ifconfig $1 >/dev/null 2>&1 && return 1 1688485SPeter.Memishian@Sun.COM /sbin/ifconfig $1 inet6 >/dev/null 2>&1 && return 1 1698485SPeter.Memishian@Sun.COM /sbin/ifconfig $1 $3 ipmp group $2 2>/dev/null 1708485SPeter.Memishian@Sun.COM} 1718485SPeter.Memishian@Sun.COM 1728485SPeter.Memishian@Sun.COM# 1738485SPeter.Memishian@Sun.COM# create_groupifname groupname type 1748485SPeter.Memishian@Sun.COM# 1758485SPeter.Memishian@Sun.COM# Create an IPMP meta-interface name for the group. We only use this 1768485SPeter.Memishian@Sun.COM# function if all of the interfaces in the group failed at boot and there 1778485SPeter.Memishian@Sun.COM# were no /etc/hostname[6].<if> files for the IPMP meta-interface. 1788485SPeter.Memishian@Sun.COM# 1798485SPeter.Memishian@Sun.COMcreate_groupifname() 1808485SPeter.Memishian@Sun.COM{ 1818485SPeter.Memishian@Sun.COM # 1828485SPeter.Memishian@Sun.COM # This is a horrible way to count from 0 to 999, but in sh and 1838485SPeter.Memishian@Sun.COM # without necessarily having /usr mounted, what else can we do? 1848485SPeter.Memishian@Sun.COM # 1858485SPeter.Memishian@Sun.COM for a in "" 1 2 3 4 5 6 7 8 9; do 1868485SPeter.Memishian@Sun.COM for b in 0 1 2 3 4 5 6 7 8 9; do 1878485SPeter.Memishian@Sun.COM for c in 0 1 2 3 4 5 6 7 8 9; do 1888485SPeter.Memishian@Sun.COM # strip leading zeroes 1898485SPeter.Memishian@Sun.COM [ "$a" = "" ] && [ "$b" = 0 ] && b="" 1908485SPeter.Memishian@Sun.COM if create_ipmp ipmp$a$b$c $1 $2; then 1918485SPeter.Memishian@Sun.COM echo ipmp$a$b$c 1928485SPeter.Memishian@Sun.COM return 1938485SPeter.Memishian@Sun.COM fi 1948485SPeter.Memishian@Sun.COM done 1958485SPeter.Memishian@Sun.COM done 1968485SPeter.Memishian@Sun.COM done 1978485SPeter.Memishian@Sun.COM} 1988485SPeter.Memishian@Sun.COM 1998485SPeter.Memishian@Sun.COM# 2008485SPeter.Memishian@Sun.COM# get_hostname_ipmpinfo interface type 2018485SPeter.Memishian@Sun.COM# 2028485SPeter.Memishian@Sun.COM# Return all requested IPMP keywords from hostname file for a given interface. 2030Sstevel@tonic-gate# 2040Sstevel@tonic-gate# Example: 2058485SPeter.Memishian@Sun.COM# get_hostname_ipmpinfo hme0 inet keyword [ keyword ... ] 2060Sstevel@tonic-gate# 2078485SPeter.Memishian@Sun.COMget_hostname_ipmpinfo() 2080Sstevel@tonic-gate{ 2090Sstevel@tonic-gate case "$2" in 2108485SPeter.Memishian@Sun.COM inet) file=/etc/hostname.$1 2110Sstevel@tonic-gate ;; 2128485SPeter.Memishian@Sun.COM inet6) file=/etc/hostname6.$1 2130Sstevel@tonic-gate ;; 2140Sstevel@tonic-gate *) 2150Sstevel@tonic-gate return 2160Sstevel@tonic-gate ;; 2170Sstevel@tonic-gate esac 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate [ -r "$file" ] || return 2200Sstevel@tonic-gate 2218485SPeter.Memishian@Sun.COM type=$2 2228485SPeter.Memishian@Sun.COM shift 2 2238485SPeter.Memishian@Sun.COM 2240Sstevel@tonic-gate # 2258485SPeter.Memishian@Sun.COM # Read through the hostname file looking for the specified 2268485SPeter.Memishian@Sun.COM # keywords. Since there may be several keywords that cancel 2278485SPeter.Memishian@Sun.COM # each other out, the caller must post-process as appropriate. 2280Sstevel@tonic-gate # 2290Sstevel@tonic-gate while read line; do 2300Sstevel@tonic-gate [ -z "$line" ] && continue 2318485SPeter.Memishian@Sun.COM /sbin/ifparse -s "$type" $line 2328485SPeter.Memishian@Sun.COM done < "$file" | while read one two; do 2338485SPeter.Memishian@Sun.COM for keyword in "$@"; do 2348485SPeter.Memishian@Sun.COM [ "$one" = "$keyword" ] && echo "$one $two" 2358485SPeter.Memishian@Sun.COM done 2360Sstevel@tonic-gate done 2370Sstevel@tonic-gate} 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate# 2400Sstevel@tonic-gate# get_group_for_type interface type list 2410Sstevel@tonic-gate# 2420Sstevel@tonic-gate# Look through the set of hostname files associated with the same physical 2430Sstevel@tonic-gate# interface as "interface", and determine which group they would configure. 2440Sstevel@tonic-gate# Only hostname files associated with the physical interface or logical 2450Sstevel@tonic-gate# interface zero are allowed to set the group. 2460Sstevel@tonic-gate# 2470Sstevel@tonic-gateget_group_for_type() 2480Sstevel@tonic-gate{ 2490Sstevel@tonic-gate physical=`get_physical $1` 2500Sstevel@tonic-gate type=$2 2510Sstevel@tonic-gate group="" 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate # 2540Sstevel@tonic-gate # The last setting of the group is the one that counts, which is 2550Sstevel@tonic-gate # the reason for the second while loop. 2560Sstevel@tonic-gate # 2570Sstevel@tonic-gate shift 2 2588485SPeter.Memishian@Sun.COM for ifname in "$@"; do 2598485SPeter.Memishian@Sun.COM if if_comp "$physical" $ifname; then 2608485SPeter.Memishian@Sun.COM get_hostname_ipmpinfo $ifname $type group 2610Sstevel@tonic-gate fi 2620Sstevel@tonic-gate done | while :; do 2638485SPeter.Memishian@Sun.COM read keyword grname || { 2640Sstevel@tonic-gate echo "$group" 2650Sstevel@tonic-gate break 2660Sstevel@tonic-gate } 2678485SPeter.Memishian@Sun.COM group="$grname" 2680Sstevel@tonic-gate done 2690Sstevel@tonic-gate} 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate# 2728485SPeter.Memishian@Sun.COM# get_group interface 2730Sstevel@tonic-gate# 2748485SPeter.Memishian@Sun.COM# If there is both an inet and inet6 version of an interface, the group 2758485SPeter.Memishian@Sun.COM# could be set in either set of hostname files. Since inet6 is configured 2768485SPeter.Memishian@Sun.COM# after inet, if there's a setting in both files, inet6 wins. 2770Sstevel@tonic-gate# 2788485SPeter.Memishian@Sun.COMget_group() 2790Sstevel@tonic-gate{ 2808485SPeter.Memishian@Sun.COM group=`get_group_for_type $1 inet6 $inet6_list` 2818485SPeter.Memishian@Sun.COM [ -z "$group" ] && group=`get_group_for_type $1 inet $inet_list` 2828485SPeter.Memishian@Sun.COM echo $group 2830Sstevel@tonic-gate} 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate# 28611076SCathy.Zhou@Sun.COM# Given the interface name and the address family (inet or inet6), determine 28711076SCathy.Zhou@Sun.COM# whether this is a VRRP VNIC. 28811076SCathy.Zhou@Sun.COM# 28911076SCathy.Zhou@Sun.COM# This is used to determine whether to bring the interface up 29011076SCathy.Zhou@Sun.COM# 29111076SCathy.Zhou@Sun.COMnot_vrrp_interface() { 29211076SCathy.Zhou@Sun.COM macaddrtype=`/sbin/dladm show-vnic $1 -o MACADDRTYPE -p 2>/dev/null` 29311076SCathy.Zhou@Sun.COM 29411076SCathy.Zhou@Sun.COM case "$macaddrtype" in 29511076SCathy.Zhou@Sun.COM 'vrrp'*''$2'') vrrp=1 29611076SCathy.Zhou@Sun.COM ;; 29711076SCathy.Zhou@Sun.COM *) vrrp=0 29811076SCathy.Zhou@Sun.COM ;; 29911076SCathy.Zhou@Sun.COM esac 30011076SCathy.Zhou@Sun.COM return $vrrp 30111076SCathy.Zhou@Sun.COM} 30211076SCathy.Zhou@Sun.COM 3030Sstevel@tonic-gate# doDHCPhostname interface 3040Sstevel@tonic-gate# Pass to this function the name of an interface. It will return 3050Sstevel@tonic-gate# true if one should enable the use of DHCP client-side host name 3060Sstevel@tonic-gate# requests on the interface, and false otherwise. 3070Sstevel@tonic-gate# 3080Sstevel@tonic-gatedoDHCPhostname() 3090Sstevel@tonic-gate{ 3100Sstevel@tonic-gate if [ -f /etc/dhcp.$1 ] && [ -f /etc/hostname.$1 ]; then 3110Sstevel@tonic-gate set -- `shcat /etc/hostname.$1` 3120Sstevel@tonic-gate [ $# -eq 2 -a "$1" = "inet" ] 3130Sstevel@tonic-gate return $? 3140Sstevel@tonic-gate fi 3150Sstevel@tonic-gate return 1 3160Sstevel@tonic-gate} 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate# 3190Sstevel@tonic-gate# inet_process_hostname processor [ args ] 3200Sstevel@tonic-gate# 3210Sstevel@tonic-gate# Process an inet hostname file. The contents of the file 3220Sstevel@tonic-gate# are taken from standard input. Each line is passed 3230Sstevel@tonic-gate# on the command line to the "processor" command. 3240Sstevel@tonic-gate# Command line arguments can be passed to the processor. 3250Sstevel@tonic-gate# 3260Sstevel@tonic-gate# Examples: 3270Sstevel@tonic-gate# inet_process_hostname /sbin/ifconfig hme0 < /etc/hostname.hme0 3280Sstevel@tonic-gate# 3290Sstevel@tonic-gate# inet_process_hostname /sbin/ifparse -f < /etc/hostname.hme0 3300Sstevel@tonic-gate# 3310Sstevel@tonic-gate# If there is only line in an hostname file we assume it contains 3320Sstevel@tonic-gate# the old style address which results in the interface being brought up 3338485SPeter.Memishian@Sun.COM# and the netmask and broadcast address being set ($inet_oneline_epilogue). 3340Sstevel@tonic-gate# 33511076SCathy.Zhou@Sun.COM# Note that if the interface is a VRRP interface, do not bring the address 33611076SCathy.Zhou@Sun.COM# up ($inet_oneline_epilogue_no_up). 33711076SCathy.Zhou@Sun.COM# 3380Sstevel@tonic-gate# If there are multiple lines we assume the file contains a list of 3390Sstevel@tonic-gate# commands to the processor with neither the implied bringing up of the 3400Sstevel@tonic-gate# interface nor the setting of the default netmask and broadcast address. 3410Sstevel@tonic-gate# 3420Sstevel@tonic-gate# Return non-zero if any command fails so that the caller may alert 3430Sstevel@tonic-gate# users to errors in the configuration. 3440Sstevel@tonic-gate# 34511076SCathy.Zhou@Sun.COMinet_oneline_epilogue_no_up="netmask + broadcast +" 3468485SPeter.Memishian@Sun.COMinet_oneline_epilogue="netmask + broadcast + up" 3478485SPeter.Memishian@Sun.COM 3480Sstevel@tonic-gateinet_process_hostname() 3490Sstevel@tonic-gate{ 3500Sstevel@tonic-gate if doDHCPhostname $2; then 3510Sstevel@tonic-gate : 3520Sstevel@tonic-gate else 3530Sstevel@tonic-gate # 3540Sstevel@tonic-gate # Redirecting input from a file results in a sub-shell being 3550Sstevel@tonic-gate # used, hence this outer loop surrounding the "multiple_lines" 3560Sstevel@tonic-gate # and "ifcmds" variables. 3570Sstevel@tonic-gate # 3580Sstevel@tonic-gate while :; do 3590Sstevel@tonic-gate multiple_lines=false 3600Sstevel@tonic-gate ifcmds="" 3610Sstevel@tonic-gate retval=0 3620Sstevel@tonic-gate 3638485SPeter.Memishian@Sun.COM while read one rest; do 3640Sstevel@tonic-gate if [ -n "$ifcmds" ]; then 3650Sstevel@tonic-gate # 3660Sstevel@tonic-gate # This handles the first N-1 3670Sstevel@tonic-gate # lines of a N-line hostname file. 3680Sstevel@tonic-gate # 3690Sstevel@tonic-gate $* $ifcmds || retval=$? 3700Sstevel@tonic-gate multiple_lines=true 3710Sstevel@tonic-gate fi 3728485SPeter.Memishian@Sun.COM 3738485SPeter.Memishian@Sun.COM # 3748485SPeter.Memishian@Sun.COM # Strip out the "ipmp" keyword if it's the 3758485SPeter.Memishian@Sun.COM # first token, since it's used to control 3768485SPeter.Memishian@Sun.COM # interface creation, not configuration. 3778485SPeter.Memishian@Sun.COM # 3788485SPeter.Memishian@Sun.COM [ "$one" = ipmp ] && one= 3798485SPeter.Memishian@Sun.COM ifcmds="$one $rest" 3800Sstevel@tonic-gate done 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate # 3830Sstevel@tonic-gate # If the hostname file is empty or consists of only 3840Sstevel@tonic-gate # blank lines, break out of the outer loop without 3850Sstevel@tonic-gate # configuring the newly plumbed interface. 3860Sstevel@tonic-gate # 3870Sstevel@tonic-gate [ -z "$ifcmds" ] && return $retval 3880Sstevel@tonic-gate if [ $multiple_lines = false ]; then 38911076SCathy.Zhou@Sun.COM # 3908485SPeter.Memishian@Sun.COM # The traditional one-line hostname file. 39111076SCathy.Zhou@Sun.COM # Note that we only bring it up if the 39211076SCathy.Zhou@Sun.COM # interface is not a VRRP VNIC. 39311076SCathy.Zhou@Sun.COM # 39411076SCathy.Zhou@Sun.COM if not_vrrp_interface $2 $3; then 39511076SCathy.Zhou@Sun.COM estr="$inet_oneline_epilogue" 39611076SCathy.Zhou@Sun.COM else 39711076SCathy.Zhou@Sun.COM estr="$inet_oneline_epilogue_no_up" 39811076SCathy.Zhou@Sun.COM fi 39911076SCathy.Zhou@Sun.COM ifcmds="$ifcmds $estr" 4000Sstevel@tonic-gate fi 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate # 4030Sstevel@tonic-gate # This handles either the single-line case or 4040Sstevel@tonic-gate # the last line of the N-line case. 4050Sstevel@tonic-gate # 4060Sstevel@tonic-gate $* $ifcmds || return $? 4070Sstevel@tonic-gate return $retval 4080Sstevel@tonic-gate done 4090Sstevel@tonic-gate fi 4100Sstevel@tonic-gate} 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate# 4130Sstevel@tonic-gate# inet6_process_hostname processor [ args ] 4140Sstevel@tonic-gate# 4150Sstevel@tonic-gate# Process an inet6 hostname file. The contents of the file 4160Sstevel@tonic-gate# are taken from standard input. Each line is passed 4170Sstevel@tonic-gate# on the command line to the "processor" command. 4180Sstevel@tonic-gate# Command line arguments can be passed to the processor. 4190Sstevel@tonic-gate# 4200Sstevel@tonic-gate# Examples: 4210Sstevel@tonic-gate# inet6_process_hostname /sbin/ifconfig hme0 inet6 < /etc/hostname6.hme0 4220Sstevel@tonic-gate# 4230Sstevel@tonic-gate# inet6_process_hostname /sbin/ifparse -f inet6 < /etc/hostname6.hme0 4240Sstevel@tonic-gate# 4250Sstevel@tonic-gate# Return non-zero if any of the commands fail so that the caller may alert 4260Sstevel@tonic-gate# users to errors in the configuration. 4270Sstevel@tonic-gate# 4280Sstevel@tonic-gateinet6_process_hostname() 4290Sstevel@tonic-gate{ 4300Sstevel@tonic-gate retval=0 4318485SPeter.Memishian@Sun.COM while read one rest; do 4328485SPeter.Memishian@Sun.COM # 4338485SPeter.Memishian@Sun.COM # See comment in inet_process_hostname for details. 4348485SPeter.Memishian@Sun.COM # 4358485SPeter.Memishian@Sun.COM [ "$one" = ipmp ] && one= 4368485SPeter.Memishian@Sun.COM ifcmds="$one $rest" 4378485SPeter.Memishian@Sun.COM 4380Sstevel@tonic-gate if [ -n "$ifcmds" ]; then 4390Sstevel@tonic-gate $* $ifcmds || retval=$? 4400Sstevel@tonic-gate fi 4410Sstevel@tonic-gate done 4420Sstevel@tonic-gate return $retval 4430Sstevel@tonic-gate} 4440Sstevel@tonic-gate 4450Sstevel@tonic-gate# 4468485SPeter.Memishian@Sun.COM# Process interfaces that failed to plumb. Find the IPMP meta-interface 4478485SPeter.Memishian@Sun.COM# that should host the addresses. For IPv6, only static addresses defined 4488485SPeter.Memishian@Sun.COM# in hostname6 files are moved, autoconfigured addresses are not moved. 4490Sstevel@tonic-gate# 4500Sstevel@tonic-gate# Example: 4510Sstevel@tonic-gate# move_addresses inet6 4520Sstevel@tonic-gate# 4530Sstevel@tonic-gatemove_addresses() 4540Sstevel@tonic-gate{ 4550Sstevel@tonic-gate type="$1" 4560Sstevel@tonic-gate eval "failed=\"\$${type}_failed\"" 4570Sstevel@tonic-gate eval "list=\"\$${type}_list\"" 4588485SPeter.Memishian@Sun.COM process_func="${type}_process_hostname" 4590Sstevel@tonic-gate processed="" 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate if [ "$type" = inet ]; then 4628485SPeter.Memishian@Sun.COM typedesc="IPv4" 4630Sstevel@tonic-gate zaddr="0.0.0.0" 4640Sstevel@tonic-gate hostpfx="/etc/hostname" 4650Sstevel@tonic-gate else 4668485SPeter.Memishian@Sun.COM typedesc="IPv6" 4670Sstevel@tonic-gate zaddr="::" 4680Sstevel@tonic-gate hostpfx="/etc/hostname6" 4690Sstevel@tonic-gate fi 4700Sstevel@tonic-gate 4718485SPeter.Memishian@Sun.COM echo "Moving addresses from missing ${typedesc} interface(s):\c" \ 4728485SPeter.Memishian@Sun.COM >/dev/msglog 4738485SPeter.Memishian@Sun.COM 4748485SPeter.Memishian@Sun.COM for ifname in $failed; do 4758485SPeter.Memishian@Sun.COM in_list if_comp $ifname $processed && continue 4760Sstevel@tonic-gate 4778485SPeter.Memishian@Sun.COM group=`get_group $ifname` 4788485SPeter.Memishian@Sun.COM if [ -z "$group" ]; then 4798485SPeter.Memishian@Sun.COM in_list physical_comp $ifname $processed || { 4808485SPeter.Memishian@Sun.COM echo " $ifname (not moved -- not" \ 4818485SPeter.Memishian@Sun.COM "in an IPMP group)\c" >/dev/msglog 4828485SPeter.Memishian@Sun.COM processed="$processed $ifname" 4830Sstevel@tonic-gate } 4840Sstevel@tonic-gate continue 4850Sstevel@tonic-gate fi 4868485SPeter.Memishian@Sun.COM 4878485SPeter.Memishian@Sun.COM # 4888485SPeter.Memishian@Sun.COM # Lookup the IPMP meta-interface name. If one doesn't exist, 4898485SPeter.Memishian@Sun.COM # create it. 4908485SPeter.Memishian@Sun.COM # 4918485SPeter.Memishian@Sun.COM grifname=`get_groupifname $group` 4928485SPeter.Memishian@Sun.COM [ -z "$grifname" ] && grifname=`create_groupifname $group $type` 4938485SPeter.Memishian@Sun.COM 4940Sstevel@tonic-gate # 4950Sstevel@tonic-gate # The hostname files are processed twice. In the first 49610649SPeter.Memishian@Sun.COM # pass, we are looking for all commands that apply to the 49710649SPeter.Memishian@Sun.COM # non-additional interface address. These may be 49810649SPeter.Memishian@Sun.COM # scattered over several files. We won't know whether the 49910649SPeter.Memishian@Sun.COM # address represents a failover address or not until we've 50010649SPeter.Memishian@Sun.COM # read all the files associated with the interface. 5018485SPeter.Memishian@Sun.COM # 5020Sstevel@tonic-gate # In the first pass through the hostname files, all 50310649SPeter.Memishian@Sun.COM # additional logical interface commands are removed. The 50410649SPeter.Memishian@Sun.COM # remaining commands are concatenated together and passed 50510649SPeter.Memishian@Sun.COM # to ifparse to determine whether the non-additional 50610649SPeter.Memishian@Sun.COM # logical interface address is a failover address. If it 50710649SPeter.Memishian@Sun.COM # as a failover address, the address may not be the first 50810649SPeter.Memishian@Sun.COM # item on the line, so we can't just substitute "addif" 50910649SPeter.Memishian@Sun.COM # for "set". We prepend an "addif $zaddr" command, and 51010649SPeter.Memishian@Sun.COM # let the embedded "set" command set the address later. 5110Sstevel@tonic-gate # 5120Sstevel@tonic-gate /sbin/ifparse -f $type ` 5138485SPeter.Memishian@Sun.COM for item in $list; do 5148485SPeter.Memishian@Sun.COM if_comp $ifname $item && $process_func \ 5158485SPeter.Memishian@Sun.COM /sbin/ifparse $type < $hostpfx.$item 5168485SPeter.Memishian@Sun.COM done | while read three four; do 5178485SPeter.Memishian@Sun.COM [ "$three" != addif ] && echo "$three $four \c" 5188485SPeter.Memishian@Sun.COM done` | while read one two; do 5198485SPeter.Memishian@Sun.COM [ -z "$one" ] && continue 5208485SPeter.Memishian@Sun.COM [ "$one $two" = "$inet_oneline_epilogue" ] && \ 5218485SPeter.Memishian@Sun.COM continue 5228485SPeter.Memishian@Sun.COM line="addif $zaddr $one $two" 5238485SPeter.Memishian@Sun.COM /sbin/ifconfig $grifname $type $line >/dev/null 5248485SPeter.Memishian@Sun.COM done 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate # 5270Sstevel@tonic-gate # In the second pass, look for the the "addif" commands 5280Sstevel@tonic-gate # that configure additional failover addresses. Addif 5290Sstevel@tonic-gate # commands are not valid in logical interface hostname 5300Sstevel@tonic-gate # files. 5310Sstevel@tonic-gate # 5328485SPeter.Memishian@Sun.COM if [ "$ifname" = "`get_physical $ifname`" ]; then 5338485SPeter.Memishian@Sun.COM $process_func /sbin/ifparse -f $type < $hostpfx.$ifname \ 5348485SPeter.Memishian@Sun.COM | while read one two; do 5358485SPeter.Memishian@Sun.COM [ "$one" = addif ] && \ 5368485SPeter.Memishian@Sun.COM /sbin/ifconfig $grifname $type \ 5378485SPeter.Memishian@Sun.COM addif $two >/dev/null 5380Sstevel@tonic-gate done 5390Sstevel@tonic-gate fi 5400Sstevel@tonic-gate 5418485SPeter.Memishian@Sun.COM in_list physical_comp $ifname $processed || { 5428485SPeter.Memishian@Sun.COM processed="$processed $ifname" 54310649SPeter.Memishian@Sun.COM echo " $ifname (moved to $grifname)\c" > /dev/msglog 5440Sstevel@tonic-gate } 5458485SPeter.Memishian@Sun.COM done 5468485SPeter.Memishian@Sun.COM echo "." >/dev/msglog 5478485SPeter.Memishian@Sun.COM} 5488485SPeter.Memishian@Sun.COM 5498485SPeter.Memishian@Sun.COM# 5508485SPeter.Memishian@Sun.COM# if_configure type class interface_list 5518485SPeter.Memishian@Sun.COM# 5528485SPeter.Memishian@Sun.COM# Configure all of the interfaces of type `type' (e.g., "inet6") in 5538485SPeter.Memishian@Sun.COM# `interface_list' according to their /etc/hostname[6].* files. `class' 5548485SPeter.Memishian@Sun.COM# describes the class of interface (e.g., "IPMP"), as a diagnostic aid. 5558485SPeter.Memishian@Sun.COM# For inet6 interfaces, the interface is also brought up. 5568485SPeter.Memishian@Sun.COM# 5578485SPeter.Memishian@Sun.COMif_configure() 5588485SPeter.Memishian@Sun.COM{ 5598485SPeter.Memishian@Sun.COM fail= 5608485SPeter.Memishian@Sun.COM type=$1 5618485SPeter.Memishian@Sun.COM class=$2 5628485SPeter.Memishian@Sun.COM process_func=${type}_process_hostname 5638485SPeter.Memishian@Sun.COM shift 2 5648485SPeter.Memishian@Sun.COM 5658485SPeter.Memishian@Sun.COM if [ "$type" = inet ]; then 5668485SPeter.Memishian@Sun.COM desc="IPv4" 5678485SPeter.Memishian@Sun.COM hostpfx="/etc/hostname" 5688485SPeter.Memishian@Sun.COM else 5698485SPeter.Memishian@Sun.COM desc="IPv6" 5708485SPeter.Memishian@Sun.COM hostpfx="/etc/hostname6" 5718485SPeter.Memishian@Sun.COM fi 5728485SPeter.Memishian@Sun.COM [ -n "$class" ] && desc="$class $desc" 5738485SPeter.Memishian@Sun.COM 5748485SPeter.Memishian@Sun.COM echo "configuring $desc interfaces:\c" 5758485SPeter.Memishian@Sun.COM while [ $# -gt 0 ]; do 5768485SPeter.Memishian@Sun.COM $process_func /sbin/ifconfig $1 $type < $hostpfx.$1 >/dev/null 5778485SPeter.Memishian@Sun.COM if [ $? != 0 ]; then 5788485SPeter.Memishian@Sun.COM fail="$fail $1" 5798485SPeter.Memishian@Sun.COM elif [ "$type" = inet6 ]; then 58011076SCathy.Zhou@Sun.COM # 58111076SCathy.Zhou@Sun.COM # only bring the interface up if it is not a 58211076SCathy.Zhou@Sun.COM # VRRP VNIC 58311076SCathy.Zhou@Sun.COM # 58411076SCathy.Zhou@Sun.COM if not_vrrp_interface $1 $type; then 58511076SCathy.Zhou@Sun.COM /sbin/ifconfig $1 inet6 up || fail="$fail $1" 58611076SCathy.Zhou@Sun.COM fi 5878485SPeter.Memishian@Sun.COM fi 5888485SPeter.Memishian@Sun.COM echo " $1\c" 5890Sstevel@tonic-gate shift 5900Sstevel@tonic-gate done 5910Sstevel@tonic-gate echo "." 5928485SPeter.Memishian@Sun.COM 5938485SPeter.Memishian@Sun.COM [ -n "$fail" ] && warn_failed_ifs "configure $desc" "$fail" 5940Sstevel@tonic-gate} 5955895Syz147064 5965895Syz147064# 5975895Syz147064# net_reconfigure is called from the network/physical service (by the 5985895Syz147064# net-physical and net-nwam method scripts) to perform tasks that only 5995895Syz147064# need to be done during a reconfigure boot. This needs to be 6005895Syz147064# isolated in a function since network/physical has two instances 6015895Syz147064# (default and nwam) that have distinct method scripts that each need 6025895Syz147064# to do these things. 6035895Syz147064# 6045895Syz147064net_reconfigure () 6055895Syz147064{ 6065895Syz147064 # 6075895Syz147064 # Is this a reconfigure boot? If not, then there's nothing 6085895Syz147064 # for us to do. 6095895Syz147064 # 6109682SCathy.Zhou@Sun.COM reconfig=`svcprop -c -p system/reconfigure \ 6119682SCathy.Zhou@Sun.COM system/svc/restarter:default 2>/dev/null` 6127645Sjames.d.carlson@sun.com if [ $? -ne 0 -o "$reconfig" = false ]; then 6135895Syz147064 return 0 6145895Syz147064 fi 6155895Syz147064 6165895Syz147064 # 6175895Syz147064 # Ensure that the datalink-management service is running since 6185895Syz147064 # manifest-import has not yet run for a first boot after 6195895Syz147064 # upgrade. We wouldn't need to do that if manifest-import ran 6205895Syz147064 # earlier in boot, since there is an explicit dependency 6215895Syz147064 # between datalink-management and network/physical. 6225895Syz147064 # 6235895Syz147064 svcadm enable -ts network/datalink-management:default 6245895Syz147064 6255895Syz147064 # 6265895Syz147064 # There is a bug in SMF which causes the svcadm command above 6275895Syz147064 # to exit prematurely (with an error code of 3) before having 6285895Syz147064 # waited for the service to come online after having enabled 6295895Syz147064 # it. Until that bug is fixed, we need to have the following 6305895Syz147064 # loop to explicitly wait for the service to come online. 6315895Syz147064 # 6325895Syz147064 i=0 6335895Syz147064 while [ $i -lt 30 ]; do 6345895Syz147064 i=`expr $i + 1` 6355895Syz147064 sleep 1 6365895Syz147064 state=`svcprop -p restarter/state \ 6375895Syz147064 network/datalink-management:default 2>/dev/null` 6385895Syz147064 if [ $? -ne 0 ]; then 6395895Syz147064 continue 6405895Syz147064 elif [ "$state" = "online" ]; then 6415895Syz147064 break 6425895Syz147064 fi 6435895Syz147064 done 6445895Syz147064 if [ "$state" != "online" ]; then 6455895Syz147064 echo "The network/datalink-management service \c" 6465895Syz147064 echo "did not come online." 6475895Syz147064 return 1 6485895Syz147064 fi 6495895Syz147064 6505895Syz147064 # 6515895Syz147064 # Initialize the set of physical links, and validate and 6525895Syz147064 # remove all the physical links which were removed during the 6535895Syz147064 # system shutdown. 6545895Syz147064 # 6555895Syz147064 /sbin/dladm init-phys 6565895Syz147064 return 0 6575895Syz147064} 65810491SRishi.Srivatsavai@Sun.COM 65910491SRishi.Srivatsavai@Sun.COM# 66010491SRishi.Srivatsavai@Sun.COM# Check for use of the default "Port VLAN Identifier" (PVID) -- VLAN 1. 66110491SRishi.Srivatsavai@Sun.COM# If there is one for a given interface, then warn the user and force the 66210491SRishi.Srivatsavai@Sun.COM# PVID to zero (if it's not already set). We do this by generating a list 66310491SRishi.Srivatsavai@Sun.COM# of interfaces with VLAN 1 in use first, and then parsing out the 66410491SRishi.Srivatsavai@Sun.COM# corresponding base datalink entries to check for ones without a 66510491SRishi.Srivatsavai@Sun.COM# "default_tag" property. 66610491SRishi.Srivatsavai@Sun.COM# 66710491SRishi.Srivatsavai@Sun.COMupdate_pvid() 66810491SRishi.Srivatsavai@Sun.COM{ 66910491SRishi.Srivatsavai@Sun.COM datalink=/etc/dladm/datalink.conf 67010491SRishi.Srivatsavai@Sun.COM 67110491SRishi.Srivatsavai@Sun.COM ( 67210491SRishi.Srivatsavai@Sun.COM # Find datalinks using VLAN 1 explicitly 67310491SRishi.Srivatsavai@Sun.COM # configured by dladm 67410491SRishi.Srivatsavai@Sun.COM /usr/bin/nawk ' 67510491SRishi.Srivatsavai@Sun.COM /^#/ || NF < 2 { next } 67610491SRishi.Srivatsavai@Sun.COM { linkdata[$1]=$2; } 67710491SRishi.Srivatsavai@Sun.COM /;vid=int,1;/ { 67810491SRishi.Srivatsavai@Sun.COM sub(/.*;linkover=int,/, "", $2); 67910491SRishi.Srivatsavai@Sun.COM sub(/;.*/, "", $2); 68010491SRishi.Srivatsavai@Sun.COM link=linkdata[$2]; 68110491SRishi.Srivatsavai@Sun.COM sub(/name=string,/, "", link); 68210491SRishi.Srivatsavai@Sun.COM sub(/;.*/, "", link); 68310491SRishi.Srivatsavai@Sun.COM print link; 68410491SRishi.Srivatsavai@Sun.COM }' $datalink 68510491SRishi.Srivatsavai@Sun.COM ) | ( /usr/bin/sort -u; echo END; cat $datalink ) | /usr/bin/nawk ' 68610491SRishi.Srivatsavai@Sun.COM /^END$/ { state=1; } 68710491SRishi.Srivatsavai@Sun.COM state == 0 { usingpvid[++nusingpvid]=$1; next; } 68810491SRishi.Srivatsavai@Sun.COM /^#/ || NF < 2 { next; } 68910491SRishi.Srivatsavai@Sun.COM { 69010491SRishi.Srivatsavai@Sun.COM # If it is already present and has a tag set, 69110491SRishi.Srivatsavai@Sun.COM # then believe it. 69210491SRishi.Srivatsavai@Sun.COM if (!match($2, /;default_tag=/)) 69310491SRishi.Srivatsavai@Sun.COM next; 69410491SRishi.Srivatsavai@Sun.COM sub(/name=string,/, "", $2); 69510491SRishi.Srivatsavai@Sun.COM sub(/;.*/, "", $2); 69610491SRishi.Srivatsavai@Sun.COM for (i = 1; i <= nusingpvid; i++) { 69710491SRishi.Srivatsavai@Sun.COM if (usingpvid[i] == $2) 69810491SRishi.Srivatsavai@Sun.COM usingpvid[i]=""; 69910491SRishi.Srivatsavai@Sun.COM } 70010491SRishi.Srivatsavai@Sun.COM } 70110491SRishi.Srivatsavai@Sun.COM END { 70210491SRishi.Srivatsavai@Sun.COM for (i = 1; i <= nusingpvid; i++) { 70310491SRishi.Srivatsavai@Sun.COM if (usingpvid[i] != "") { 70410491SRishi.Srivatsavai@Sun.COM printf("Warning: default VLAN tag set to 0" \ 70510491SRishi.Srivatsavai@Sun.COM " on %s\n", usingpvid[i]); 70610491SRishi.Srivatsavai@Sun.COM cmd=sprintf("dladm set-linkprop -p " \ 70710491SRishi.Srivatsavai@Sun.COM "default_tag=0 %s\n", usingpvid[i]); 70810491SRishi.Srivatsavai@Sun.COM system(cmd); 70910491SRishi.Srivatsavai@Sun.COM } 71010491SRishi.Srivatsavai@Sun.COM } 71110491SRishi.Srivatsavai@Sun.COM }' 71210491SRishi.Srivatsavai@Sun.COM} 713*11767SAnurag.Maskey@Sun.COM 714*11767SAnurag.Maskey@Sun.COM# 715*11767SAnurag.Maskey@Sun.COM# service_exists fmri 716*11767SAnurag.Maskey@Sun.COM# 717*11767SAnurag.Maskey@Sun.COM# returns success (0) if the service exists, 1 otherwise. 718*11767SAnurag.Maskey@Sun.COM# 719*11767SAnurag.Maskey@Sun.COMservice_exists() 720*11767SAnurag.Maskey@Sun.COM{ 721*11767SAnurag.Maskey@Sun.COM /usr/sbin/svccfg -s $1 listpg > /dev/null 2>&1 722*11767SAnurag.Maskey@Sun.COM if [ $? -eq 0 ]; then 723*11767SAnurag.Maskey@Sun.COM return 0; 724*11767SAnurag.Maskey@Sun.COM fi 725*11767SAnurag.Maskey@Sun.COM return 1; 726*11767SAnurag.Maskey@Sun.COM} 727*11767SAnurag.Maskey@Sun.COM 728*11767SAnurag.Maskey@Sun.COM# 729*11767SAnurag.Maskey@Sun.COM# service_is_enabled fmri 730*11767SAnurag.Maskey@Sun.COM# 731*11767SAnurag.Maskey@Sun.COM# returns success (0) if the service is enabled (permanently or 732*11767SAnurag.Maskey@Sun.COM# temporarily), 1 otherwise. 733*11767SAnurag.Maskey@Sun.COM# 734*11767SAnurag.Maskey@Sun.COMservice_is_enabled() 735*11767SAnurag.Maskey@Sun.COM{ 736*11767SAnurag.Maskey@Sun.COM # 737*11767SAnurag.Maskey@Sun.COM # The -c option must be specified to use the composed view 738*11767SAnurag.Maskey@Sun.COM # because the general/enabled property takes immediate effect. 739*11767SAnurag.Maskey@Sun.COM # See Example 2 in svcprop(1). 740*11767SAnurag.Maskey@Sun.COM # 741*11767SAnurag.Maskey@Sun.COM # Look at the general_ovr/enabled (if it is present) first to 742*11767SAnurag.Maskey@Sun.COM # determine the temporarily enabled state. 743*11767SAnurag.Maskey@Sun.COM # 744*11767SAnurag.Maskey@Sun.COM tstate=`/usr/bin/svcprop -c -p general_ovr/enabled $1 2>/dev/null` 745*11767SAnurag.Maskey@Sun.COM if [ $? -eq 0 ]; then 746*11767SAnurag.Maskey@Sun.COM [ "$tstate" = "true" ] && return 0 747*11767SAnurag.Maskey@Sun.COM return 1 748*11767SAnurag.Maskey@Sun.COM fi 749*11767SAnurag.Maskey@Sun.COM 750*11767SAnurag.Maskey@Sun.COM state=`/usr/bin/svcprop -c -p general/enabled $1 2>/dev/null` 751*11767SAnurag.Maskey@Sun.COM [ "$state" = "true" ] && return 0 752*11767SAnurag.Maskey@Sun.COM return 1 753*11767SAnurag.Maskey@Sun.COM} 754*11767SAnurag.Maskey@Sun.COM 755*11767SAnurag.Maskey@Sun.COM# 756*11767SAnurag.Maskey@Sun.COM# is_valid_v4addr addr 757*11767SAnurag.Maskey@Sun.COM# 758*11767SAnurag.Maskey@Sun.COM# Returns 0 if a valid IPv4 address is given, 1 otherwise. 759*11767SAnurag.Maskey@Sun.COM# 760*11767SAnurag.Maskey@Sun.COMis_valid_v4addr() 761*11767SAnurag.Maskey@Sun.COM{ 762*11767SAnurag.Maskey@Sun.COM echo $1 | /usr/xpg4/bin/awk 'NF != 1 { exit 1 } \ 763*11767SAnurag.Maskey@Sun.COM $1 !~ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\ 764*11767SAnurag.Maskey@Sun.COM (25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ \ 765*11767SAnurag.Maskey@Sun.COM { exit 1 }' 766*11767SAnurag.Maskey@Sun.COM return $? 767*11767SAnurag.Maskey@Sun.COM} 768*11767SAnurag.Maskey@Sun.COM 769*11767SAnurag.Maskey@Sun.COM# 770*11767SAnurag.Maskey@Sun.COM# is_valid_v6addr addr 771*11767SAnurag.Maskey@Sun.COM# 772*11767SAnurag.Maskey@Sun.COM# Returns 0 if a valid IPv6 address is given, 1 otherwise. 773*11767SAnurag.Maskey@Sun.COM# 774*11767SAnurag.Maskey@Sun.COMis_valid_v6addr() 775*11767SAnurag.Maskey@Sun.COM{ 776*11767SAnurag.Maskey@Sun.COM echo $1 | /usr/xpg4/bin/awk 'NF != 1 { exit 1 } \ 777*11767SAnurag.Maskey@Sun.COM # 1:2:3:4:5:6:7:8 778*11767SAnurag.Maskey@Sun.COM $1 !~ /^([a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/ && 779*11767SAnurag.Maskey@Sun.COM # 1:2:3::6:7:8 780*11767SAnurag.Maskey@Sun.COM $1 !~ /^([a-fA-F0-9]{1,4}:){0,6}:([a-fA-F0-9]{1,4}:){0,6}\ 781*11767SAnurag.Maskey@Sun.COM [a-fA-F0-9]{1,4}$/ && 782*11767SAnurag.Maskey@Sun.COM # 1:2:3:: 783*11767SAnurag.Maskey@Sun.COM $1 !~ /^([a-fA-F0-9]{1,4}:){0,7}:$/ && 784*11767SAnurag.Maskey@Sun.COM # ::7:8 785*11767SAnurag.Maskey@Sun.COM $1 !~ /^:(:[a-fA-F0-9]{1,4}){0,6}:[a-fA-F0-9]{1,4}$/ && 786*11767SAnurag.Maskey@Sun.COM # ::f:1.2.3.4 787*11767SAnurag.Maskey@Sun.COM $1 !~ /^:(:[a-fA-F0-9]{1,4}){0,5}:\ 788*11767SAnurag.Maskey@Sun.COM ((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\ 789*11767SAnurag.Maskey@Sun.COM (25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ && 790*11767SAnurag.Maskey@Sun.COM # a:b:c:d:e:f:1.2.3.4 791*11767SAnurag.Maskey@Sun.COM $1 !~ /^([a-fA-F0-9]{1,4}:){6}\ 792*11767SAnurag.Maskey@Sun.COM ((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\ 793*11767SAnurag.Maskey@Sun.COM (25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ \ 794*11767SAnurag.Maskey@Sun.COM { exit 1 }' 795*11767SAnurag.Maskey@Sun.COM return $? 796*11767SAnurag.Maskey@Sun.COM} 797*11767SAnurag.Maskey@Sun.COM 798*11767SAnurag.Maskey@Sun.COM# 799*11767SAnurag.Maskey@Sun.COM# is_valid_addr addr 800*11767SAnurag.Maskey@Sun.COM# 801*11767SAnurag.Maskey@Sun.COM# Returns 0 if a valid IPv4 or IPv6 address is given, 1 otherwise. 802*11767SAnurag.Maskey@Sun.COM# 803*11767SAnurag.Maskey@Sun.COMis_valid_addr() 804*11767SAnurag.Maskey@Sun.COM{ 805*11767SAnurag.Maskey@Sun.COM is_valid_v4addr $1 || is_valid_v6addr $1 806*11767SAnurag.Maskey@Sun.COM} 807*11767SAnurag.Maskey@Sun.COM 808*11767SAnurag.Maskey@Sun.COM# 809*11767SAnurag.Maskey@Sun.COM# nwam_get_loc_prop location property 810*11767SAnurag.Maskey@Sun.COM# 811*11767SAnurag.Maskey@Sun.COM# echoes the value of the property for the given location 812*11767SAnurag.Maskey@Sun.COM# return: 813*11767SAnurag.Maskey@Sun.COM# 0 => property is set 814*11767SAnurag.Maskey@Sun.COM# 1 => property is not set 815*11767SAnurag.Maskey@Sun.COM# 816*11767SAnurag.Maskey@Sun.COMnwam_get_loc_prop() 817*11767SAnurag.Maskey@Sun.COM{ 818*11767SAnurag.Maskey@Sun.COM value=`/usr/sbin/nwamcfg "select loc $1; get -V $2" 2>/dev/null` 819*11767SAnurag.Maskey@Sun.COM rtn=$? 820*11767SAnurag.Maskey@Sun.COM echo $value 821*11767SAnurag.Maskey@Sun.COM return $rtn 822*11767SAnurag.Maskey@Sun.COM} 823