--- a/usr/src/cmd/auto-install/ai_get_manifest.py Mon Apr 23 13:28:43 2012 -0700
+++ b/usr/src/cmd/auto-install/ai_get_manifest.py Mon Apr 23 21:42:14 2012 -0600
@@ -37,6 +37,7 @@
from subprocess import Popen, PIPE
import re
import sys
+from struct import pack
import tempfile
import time
import traceback
@@ -52,6 +53,10 @@
AI_MANIFEST_ATTACHMENT_NAME = 'manifest.xml' # named as MIME attachment
+# Network commands
+IPADM = "/usr/sbin/ipadm"
+DLADM = "/usr/sbin/dladm"
+
class AILog:
"""
@@ -368,44 +373,31 @@
#
# Obtain network interface name, which will be queried in next
# step in order to obtain required network parameters
- #
- # Search for the first interface, which is UP - omit loopback
- # interfaces. Then use ifconfig for query the information about
- # that interface and store the result.
- #
- cmd = "/usr/sbin/ifconfig -au | /usr/bin/grep '[0-9]:' " \
- "| /usr/bin/grep -v 'LOOPBACK'"
- AICriteriaNetworkInterface.network_iface, ret = ai_exec_cmd(cmd)
+ #
+ # get name, class and active property of all network interfaces
+ # Select the 1st interface whose class is 'ip' and is active.
+ cmd = IPADM + " show-if -o ifname,class,active -p"
+
+ output, ret = ai_exec_cmd(cmd)
- if ret != 0:
- AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
- "Could not obtain name of valid network interface")
- AICriteriaNetworkInterface.network_iface = None
- else:
- AICriteriaNetworkInterface.network_iface = \
- AICriteriaNetworkInterface.network_iface.split(':')[0]
+ if not ret:
+ for ifprop in output.splitlines():
+ # check for presence of all values
+ if ifprop.count(":") != 2:
+ continue
+ ifname, ifclass, ifstate = ifprop.split(":")
+ if ifclass == 'ip' and ifstate == 'yes':
+ AICriteriaNetworkInterface.network_iface = ifname
+ break
+ if AICriteriaNetworkInterface.network_iface:
AIGM_LOG.post(AILog.AI_DBGLVL_INFO,
"Network interface obtained: %s",
AICriteriaNetworkInterface.network_iface)
-
- #
- # Collect all available information about network interface
- #
- cmd = "/usr/sbin/ifconfig %s" % \
- AICriteriaNetworkInterface.network_iface
-
- AICriteriaNetworkInterface.ifconfig_iface_info, ret = \
- ai_exec_cmd(cmd)
-
- if ret != 0 or \
- AICriteriaNetworkInterface.ifconfig_iface_info == "":
- AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
- "Could not obtain information about "
- "network interface %s",
- AICriteriaNetworkInterface.network_iface)
-
- AICriteriaNetworkInterface.ifconfig_iface_info = None
+ else:
+ AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
+ "Could not obtain name of valid network interface "
+ "name")
class AICriteriaMAC(AICriteriaNetworkInterface):
@@ -426,49 +418,27 @@
AICriteriaMAC.client_mac_initialized = True
- if AICriteriaNetworkInterface.ifconfig_iface_info is None:
- AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
- "Could not obtain MAC address")
- else:
- AICriteriaMAC.client_mac = AICriteriaNetworkInterface. \
- ifconfig_iface_info.split("ether", 1)
+ if AICriteriaNetworkInterface.network_iface:
- if len(AICriteriaMAC.client_mac) < 2:
- AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
- "Could not obtain client MAC address")
- AICriteriaMAC.client_mac = None
- else:
- AICriteriaMAC.client_mac = AICriteriaMAC.\
- client_mac[1].strip().split()[0].strip()
+ # use dladm to get the mac information
+ cmd = (DLADM + " show-linkprop -p mac-address -co value " +
+ AICriteriaNetworkInterface.network_iface)
+
+ output, ret = ai_exec_cmd(cmd)
- #
- # remove ':' and pad with '0's
- #
- # This step makes sure that the criteria are
- # passed to the server in the format which
- # server can understand. This is just an interim
- # solution.
- #
- # For longer term, all criteria should be
- # passed to the server in native format letting
- # the server side control the process of
- # conversion.
- #
+ if not ret:
+ parts = output.strip("\n").split(":")
+ # set mac address if it is formatted properly
+ if len(parts) == 6:
+ AICriteriaMAC.client_mac = ''.join([val.zfill(2)
+ for val in parts])
+ AIGM_LOG.post(AILog.AI_DBGLVL_INFO,
+ "Client MAC address: %s",
+ AICriteriaMAC.client_mac)
- client_mac_parts = \
- AICriteriaMAC.client_mac.split(":")
-
- AICriteriaMAC.client_mac = "%s%s%s%s%s%s" % \
- (client_mac_parts[0].zfill(2),
- client_mac_parts[1].zfill(2),
- client_mac_parts[2].zfill(2),
- client_mac_parts[3].zfill(2),
- client_mac_parts[4].zfill(2),
- client_mac_parts[5].zfill(2))
-
- AIGM_LOG.post(AILog.AI_DBGLVL_INFO,
- "Client MAC address: %s",
- AICriteriaMAC.client_mac)
+ if not AICriteriaMAC.client_mac:
+ AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
+ "Could not obtain client MAC address")
AICriteria.__init__(self, AICriteriaMAC.client_mac)
@@ -479,6 +449,7 @@
"""
client_ip = None
+ client_ip_prefix = None
client_ip_string = None
client_ip_initialized = False
@@ -491,23 +462,31 @@
return
AICriteriaIP.client_ip_initialized = True
- if AICriteriaNetworkInterface.ifconfig_iface_info == None:
- AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
- "Could not obtain IP address")
- else:
- AICriteriaIP.client_ip = AICriteriaNetworkInterface. \
- ifconfig_iface_info.split("inet", 1)[1].strip().\
- split()[0].strip()
+
+ if AICriteriaNetworkInterface.network_iface:
+ cmd = (IPADM + " show-addr -o ADDR -p " +
+ AICriteriaNetworkInterface.network_iface)
+
+ output, ret = ai_exec_cmd(cmd)
+
+ if not ret:
+ if '/' in output:
+ AICriteriaIP.client_ip, AICriteriaIP.client_ip_prefix = \
+ output.strip("\n").split("/")
- # remove '.'
- ip_split = AICriteriaIP.client_ip.split('.')
- AICriteriaIP.client_ip_string = "%03d%03d%03d%03d" % \
- (int(ip_split[0]), int(ip_split[1]),
- int(ip_split[2]), int(ip_split[3]))
+ ip_split = AICriteriaIP.client_ip.split(".")
+ AICriteriaIP.client_ip_string = ''.join([val.zfill(3)
+ for val in ip_split])
+ AIGM_LOG.post(AILog.AI_DBGLVL_INFO, "Client IP address: "
+ "%s", AICriteriaIP.client_ip_string)
+ AIGM_LOG.post(AILog.AI_DBGLVL_INFO, "Network prefix: %s",
+ AICriteriaIP.client_ip_prefix)
- AIGM_LOG.post(AILog.AI_DBGLVL_INFO,
- "Client IP address: %s",
- AICriteriaIP.client_ip_string)
+ if not AICriteriaIP.client_ip_string:
+ AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
+ "Could not obtain network address")
+ AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
+ "Could not obtain network prefix")
AICriteria.__init__(self, AICriteriaIP.client_ip_string)
@@ -531,47 +510,21 @@
AICriteriaNetwork.client_net_initialized = True
- if AICriteriaNetworkInterface.ifconfig_iface_info == None or \
- AICriteriaIP.client_ip == None:
- AIGM_LOG.post(AILog.AI_DBGLVL_ERR,
- "Could not obtain network address")
- else:
- # extract network mask
- client_netmask = \
- long(AICriteriaNetworkInterface.ifconfig_iface_info.
- split("netmask", 1)[1].strip().split()[0].strip(), 16)
+ if AICriteriaIP.client_ip_string and \
+ AICriteriaIP.client_ip_prefix:
- # Translate IP address in string format to long
- ip_part = AICriteriaIP.client_ip.split('.')
- ip_long = long(ip_part[0]) << 24 | long(ip_part[1]) << \
- 16 | long(ip_part[2]) << 8 | long(ip_part[3])
-
- client_network_long = ip_long & client_netmask
-
- AIGM_LOG.post(AILog.AI_DBGLVL_INFO,
- "Mask: %08lX, IP: %08lX, Network: %08lX",
- client_netmask, ip_long, client_network_long)
+ # calculate netmask from ip prefix
+ bits = 0xffffffff ^ (1 << 32 -
+ int(AICriteriaIP.client_ip_prefix)) - 1
+ dotted_netmask = socket.inet_ntoa(pack('>I', bits))
- AICriteriaNetwork.client_net_string = \
- "%03ld%03ld%03ld%03ld" % \
- (client_network_long >> 24,
- client_network_long >> 16 & 0xff,
- client_network_long >> 8 & 0xff,
- client_network_long & 0xff)
+ ip_parts = AICriteriaIP.client_ip.split(".")
+ netmask_parts = dotted_netmask.split(".")
+ AICriteriaNetwork.client_net = ".".join([str(int(i) & int(n))
+ for i, n in zip(ip_parts, netmask_parts)])
- maskbits = 0
- for shift in range(32):
- if ((client_netmask >> shift) & 1):
- maskbits = 32 - shift
- break
-
- AICriteriaNetwork.client_net = \
- "%ld.%ld.%ld.%ld/%d" % \
- (client_network_long >> 24,
- client_network_long >> 16 & 0xff,
- client_network_long >> 8 & 0xff,
- client_network_long & 0xff,
- maskbits)
+ AICriteriaNetwork.client_net_string = "".join([val.zfill(3)
+ for val in AICriteriaNetwork.client_net.split(".")])
AIGM_LOG.post(AILog.AI_DBGLVL_INFO, "Client net: %s",
AICriteriaNetwork.client_net_string)
--- a/usr/src/cmd/installadm/installadm-common.sh Mon Apr 23 13:28:43 2012 -0700
+++ b/usr/src/cmd/installadm/installadm-common.sh Mon Apr 23 21:42:14 2012 -0600
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
#
# Description:
# It contains common functions used by installadm subcommands
@@ -42,7 +42,7 @@
GREP=/bin/grep
HEAD=/bin/head
HOSTNAME=/bin/hostname
-IFCONFIG=/usr/sbin/ifconfig
+IPADM=/usr/sbin/ipadm
LN=/bin/ln
MKDIR=/bin/mkdir
MOUNT=/usr/sbin/mount
@@ -191,7 +191,7 @@
# Find the IP address(es) for the interface route(1) provided. Use
# ipadm(1) to look up interface addresses;
- server_ip=$(/usr/sbin/ipadm show-addr -p -o ADDR ${interface}/ | \
+ server_ip=$($IPADM show-addr -p -o ADDR ${interface}/ | \
$EGREP -v -- "$IPADM_GREP_STRING")
# see if interface has multiple VLANs
@@ -224,34 +224,6 @@
}
#
-# get_ip_netmask
-#
-# Purpose : Get the netmask set for the given IP address on the current host.
-# Assumes IP address is currently set on an interface.
-#
-# Arguments :
-# $1 - IP address
-#
-# Returns netmask in hexidecimal notation (e.g. ffffff00)
-#
-get_ip_netmask()
-{
- ipaddr=$1
-
- if [[ -z "$ipaddr" ]]; then
- return
- fi
-
- $IFCONFIG -a | $GREP broadcast | $AWK '{print $2, $4}' | \
- while read t_ipaddr t_netmask ; do
- if [ "$t_ipaddr" = "$ipaddr" ]; then
- print "$t_netmask"
- break
- fi
- done
-}
-
-#
# get_grub_title
#
# Purpose: Get the line used in the title line of the grub menu.
@@ -552,7 +524,7 @@
# get all addresses and
# remove <IPv6 | 127.0.0.1 | unconfigured DHCP interfaces>
- interfaces=$(/usr/sbin/ipadm show-addr -p -o ADDR,STATE | \
+ interfaces=$($IPADM show-addr -p -o ADDR,STATE | \
$EGREP -v "${IPADM_GREP_STRING}|^127.0.0.1" | \
$EGREP -e ':ok$|:tentative$' | \
$SED 's/:ok$//;s/:tentative$//')
@@ -888,128 +860,3 @@
print "${s_addr[0]}.${s_addr[1]}.${s_addr[2]}.${s_addr[3]}"
return
}
-
-
-#
-# find_network_attr
-#
-# Purpose : Given an IP address, figure out which network on this
-# server it belongs to, or its netmask, depending on $2.
-# Workhorse function for find_network(), find_network_nmask() and
-# find_network_baseIP()
-#
-# Parameters :
-# $1 - IP address
-# $2 - what gets returned: one of "network", "netmask" or "netIPaddr"
-# - "network" specifies that this function returns the network
-# corresponding to the IP address (IP addr & netmask)
-# - "netmask" specifies that this function returns the netmask
-# of the network corresponding to the IP address
-# - "netIPaddr" specifies that this function returns the base IP
-# address of the network corresponding to the IP address
-# Returns :
-# Network for IP address passed in.
-#
-find_network_attr()
-{
- typeset ipaddr=$1
- typeset attr=$2
-
- if [[ -z "$ipaddr" ]] ; then
- return
- fi
-
- # Iterate through the interfaces to figure what the possible
- # networks are (in case this is a multi-homed server).
- # For each network, use its netmask with the given IP address
- # to see if resulting network matches.
- $IFCONFIG -a | $GREP broadcast | $AWK '{print $2, $4}' | \
- while read t_ipaddr t_netmask ; do
-
- # convert hex netmask into bits for CIDR notation
- typeset bits
- # 32 bits minus however many are masked out for hosts
- ((bits=32-log2(2**32-16#$t_netmask)))
-
- # get network of this interface
- if_network=$(calculate_net_addr ${t_ipaddr}/$bits)
- if [[ -z $if_network ]]; then
- continue
- fi
-
- # get network for passed in ipaddr based
- # on this interfaces's netmask
- ip_network=$(calculate_net_addr ${ipaddr}/$bits)
- if [[ -z $ip_network ]]; then
- continue
- fi
-
- # if networks match, this is the network that
- # the passed in ipaddr belongs to.
- if [ "$if_network" = "$ip_network" ] ; then
- case $attr in
- "network" )
- print "$if_network"
- ;;
- "netmask" )
- print "$t_netmask"
- ;;
- "netIPaddr" )
- print "$t_ipaddr"
- ;;
- esac
- break
- fi
- done
-}
-
-#
-# find_network
-#
-# Purpose : Given an IP address, figure out which network on this
-# server it belongs to.
-#
-# Parameters :
-# $1 - IP address
-#
-# Returns :
-# Network for IP address passed in.
-#
-find_network()
-{
- print $(find_network_attr $1 "network")
-}
-
-#
-# find_network_nmask()
-#
-# Purpose : Given an IP address, figure out which network on this server it
-# belongs to, and return that network's netmask.
-#
-# Parameters :
-# $1 - IP address
-#
-# Returns :
-# Netmask for IP address passed in.
-#
-find_network_nmask()
-{
- print $(find_network_attr $1 "netmask")
-}
-
-#
-# find_network_baseIP()
-#
-# Purpose : Given an IP address, figure out which network on this server it
-# belongs to, and return that network's base IP address.
-#
-# Parameters :
-# $1 - IP address
-#
-# Returns :
-# Netmask for IP address passed in.
-#
-find_network_baseIP()
-{
- print $(find_network_attr $1 "netIPaddr")
-}