系统管理指南:IP 服务

DHCP 命令

下表列出了可用于在网络中管理 DHCP 的命令。

表 18–1 用于 DHCP 的命令

命令 

说明 

手册页 

dhtadm

用于对 dhcptab 中的选项和宏进行更改。此命令最适用于在创建的脚本中自动更改 DHCP 信息。使用带有 -P 选项的 dhtadm,并通过 grep 命令传输输出,可以在 dhcptab 表中快速搜索特定的选项值。

dhtadm(1M)

pntadm

用于更改将客户机 ID 映射到 IP 地址的 DHCP 网络表,还可选择将配置信息与 IP 地址进行关联。

pntadm(1M)

dhcpconfig

用于配置和取消配置 DHCP 服务器及 BOOTP 中继代理。另外,还可用于转换为另一种数据存储格式,以及导入和导出 DHCP 配置数据。

dhcpconfig(1M)

in.dhcpd

DHCP 服务器守护进程。该守护进程在启动系统时启动。请勿直接启动服务器守护进程。使用 DHCP 管理程序、svcadm 命令或 dhcpconfig 可启动和停止该守护进程。仅当以调试模式运行服务器来解决问题时,才可以直接调用该守护进程。

in.dhcpd(1M)

dhcpmgr

DHCP 管理程序,一种用于配置和管理 DHCP 服务的图形用户界面 (graphical user interface, GUI) 工具。推荐将 DHCP 管理程序作为 Oracle Solaris : DHCP 管理工具。

dhcpmgr(1M)

ifconfig

在系统引导时用于为网络接口指定 IP 地址或配置网络接口参数,或者同时执行这两种操作。在 Oracle Solaris : DHCP 客户机上,ifconfig 可启动 DHCP 以获取配置网络接口所需的参数(包括 IP 地址)。

ifconfig(1M)

dhcpinfo

由 Oracle Solaris : 客户机系统的系统启动脚本用于从 DHCP 客户机守护进程 dhcpagent 中获取信息(如主机名)。您也可以在脚本或命令行中使用 dhcpinfo 来获取指定的参数值。

dhcpinfo(1)

snoop

用于捕获和显示在网络中传送的包的内容。snoop 在解决 DHCP 服务问题时非常有用。

snoop(1M)

dhcpagent

DHCP 客户机守护进程,用于实现 DHCP 协议的客户端。 

dhcpagent(1M)

在脚本中运行 DHCP 命令

dhcpconfigdhtadmpntadm 命令为便于在脚本中使用进行了优化。特别是,pntadm 命令对于在 DHCP 网络表中创建大量 IP 地址项非常有用。以下样例脚本在批处理模式下使用 pntadm 来创建 IP 地址。


示例 18–1 使用 pntadm 命令的 addclient.ksh 脚本

#! /usr/bin/ksh
#
# This script utilizes the pntadm batch facility to add client entries
# to a DHCP network table. It assumes that the user has the rights to
# run pntadm to add entries to DHCP network tables.

#
# Based on the nsswitch setting, query the netmasks table for a netmask.
# Accepts one argument, a dotted IP address.
#
get_netmask()
{
	MTMP=`getent netmasks ${1} | awk '{ print $2 }'`
	if [ ! -z "${MTMP}" ]
	then
		print - ${MTMP}
	fi
}

#
# Based on the network specification, determine whether or not network is 
# subnetted or supernetted.
# Given a dotted IP network number, convert it to the default class
# network.(used to detect subnetting). Requires one argument, the
# network number. (e.g. 10.0.0.0) Echos the default network and default
# mask for success, null if error.
#
get_default_class()
{
	NN01=${1%%.*}
	tmp=${1#*.}
	NN02=${tmp%%.*}
	tmp=${tmp#*.}
	NN03=${tmp%%.*}
	tmp=${tmp#*.}
	NN04=${tmp%%.*}
	RETNET=""
	RETMASK=""

	typeset -i16 ONE=10#${1%%.*}
	typeset -i10 X=$((${ONE}&16#f0))
	if [ ${X} -eq 224 ]
	then
		# Multicast
		typeset -i10 TMP=$((${ONE}&16#f0))
		RETNET="${TMP}.0.0.0"
		RETMASK="240.0.0.0"
	fi
	typeset -i10 X=$((${ONE}&16#80))
	if [ -z "${RETNET}" -a ${X} -eq 0 ]
	then
		# Class A
		RETNET="${NN01}.0.0.0"
		RETMASK="255.0.0.0"
	fi
	typeset -i10 X=$((${ONE}&16#c0))
	if [ -z "${RETNET}" -a ${X} -eq 128 ]
	then
		# Class B
		RETNET="${NN01}.${NN02}.0.0"
		RETMASK="255.255.0.0"
	fi
	typeset -i10 X=$((${ONE}&16#e0))
	if [ -z "${RETNET}" -a ${X} -eq 192 ]
	then
		# Class C
		RETNET="${NN01}.${NN02}.${NN03}.0"
		RETMASK="255.255.255.0"
	fi
	print - ${RETNET} ${RETMASK}
	unset NNO1 NNO2 NNO3 NNO4 RETNET RETMASK X ONE
}

#
# Given a dotted form of an IP address, convert it to its hex equivalent.
#
convert_dotted_to_hex()
{
	typeset -i10 one=${1%%.*}
	typeset -i16 one=${one}
	typeset -Z2 one=${one}
	tmp=${1#*.}

	typeset -i10 two=${tmp%%.*}
	typeset -i16 two=${two}
	typeset -Z2 two=${two}
	tmp=${tmp#*.}

	typeset -i10 three=${tmp%%.*}
	typeset -i16 three=${three}
	typeset -Z2 three=${three}
	tmp=${tmp#*.}

	typeset -i10 four=${tmp%%.*}
	typeset -i16 four=${four}
	typeset -Z2 four=${four}

	 hex=`print - ${one}${two}${three}${four} | sed -e 's/#/0/g'`
	 print - 16#${hex}
	 unset one two three four tmp
}

#
# Generate an IP address given the network address, mask, increment.
# 
get_addr()
{
	typeset -i16 net=`convert_dotted_to_hex ${1}`
	typeset -i16 mask=`convert_dotted_to_hex ${2}`
	typeset -i16 incr=10#${3}

	# Maximum legal value - invert the mask, add to net.
	typeset -i16 mhosts=~${mask}
	typeset -i16 maxnet=${net}+${mhosts}

	# Add the incr value.
	let net=${net}+${incr}

	if [ $((${net} < ${maxnet})) -eq 1 ]
	then
		typeset -i16 a=${net}\&16#ff000000
		typeset -i10 a="${a}>>24"

		typeset -i16 b=${net}\&16#ff0000
		typeset -i10 b="${b}>>16"

		typeset -i16 c=${net}\&16#ff00
		typeset -i10 c="${c}>>8"

		typeset -i10 d=${net}\&16#ff
		print - "${a}.${b}.${c}.${d}"
	fi
	unset net mask incr mhosts maxnet a b c d
}

# Given a network address and client address, return the index.
client_index()
{
	typeset -i NNO1=${1%%.*}
	tmp=${1#*.}
	typeset -i NNO2=${tmp%%.*}
	tmp=${tmp#*.}
	typeset -i NNO3=${tmp%%.*}
	tmp=${tmp#*.}
	typeset -i NNO4=${tmp%%.*}

	typeset -i16 NNF1
	let NNF1=${NNO1}
	typeset -i16 NNF2
	let NNF2=${NNO2}
	typeset -i16 NNF3
	let NNF3=${NNO3}
	typeset -i16 NNF4
	let NNF4=${NNO4}
	typeset +i16 NNF1
	typeset +i16 NNF2
	typeset +i16 NNF3
	typeset +i16 NNF4
	NNF1=${NNF1#16\#}
	NNF2=${NNF2#16\#}
	NNF3=${NNF3#16\#}
	NNF4=${NNF4#16\#}
	if [ ${#NNF1} -eq 1 ]
	then
		NNF1="0${NNF1}"
	fi
	if [ ${#NNF2} -eq 1 ]
	then
		NNF2="0${NNF2}"
	fi
	if [ ${#NNF3} -eq 1 ]
	then
		NNF3="0${NNF3}"
	fi
	if [ ${#NNF4} -eq 1 ]
	then
		NNF4="0${NNF4}"
	fi
	typeset -i16 NN
	let NN=16#${NNF1}${NNF2}${NNF3}${NNF4}
	unset NNF1 NNF2 NNF3 NNF4

	typeset -i NNO1=${2%%.*}
	tmp=${2#*.}
	typeset -i NNO2=${tmp%%.*}
	tmp=${tmp#*.}
	typeset -i NNO3=${tmp%%.*}
	tmp=${tmp#*.}
	typeset -i NNO4=${tmp%%.*}
	typeset -i16 NNF1
	let NNF1=${NNO1}
	typeset -i16 NNF2
	let NNF2=${NNO2}
	typeset -i16 NNF3
	let NNF3=${NNO3}
	typeset -i16 NNF4
	let NNF4=${NNO4}
	typeset +i16 NNF1
	typeset +i16 NNF2
	typeset +i16 NNF3
	typeset +i16 NNF4
	NNF1=${NNF1#16\#}
	NNF2=${NNF2#16\#}
	NNF3=${NNF3#16\#}
	NNF4=${NNF4#16\#}
	if [ ${#NNF1} -eq 1 ]
	then
		NNF1="0${NNF1}"
	fi
	if [ ${#NNF2} -eq 1 ]
	then
		NNF2="0${NNF2}"
	fi
	if [ ${#NNF3} -eq 1 ]
	then
		NNF3="0${NNF3}"
	fi
	if [ ${#NNF4} -eq 1 ]
	then
		NNF4="0${NNF4}"
	fi
	typeset -i16 NC
	let NC=16#${NNF1}${NNF2}${NNF3}${NNF4}
	typeset -i10 ANS
	let ANS=${NC}-${NN}
	print - $ANS
}

#
# Check usage.
#
if [ "$#" != 3 ]
then
	print "This script is used to add client entries to a DHCP network"
	print "table by utilizing the pntadm batch facilty.\n"
	print "usage: $0 network start_ip entries\n"
	print "where: network is the IP address of the network"
        print "       start_ip is the starting IP address \n"
        print "       entries is the number of the entries to add\n"
	print "example: $0 10.148.174.0 10.148.174.1 254\n"
	return
fi

#
# Use input arguments to set script variables.
#
NETWORK=$1
START_IP=$2
typeset -i STRTNUM=`client_index ${NETWORK} ${START_IP}`
let ENDNUM=${STRTNUM}+$3
let ENTRYNUM=${STRTNUM}
BATCHFILE=/tmp/batchfile.$$
MACRO=`uname -n`

#
# Check if mask in netmasks table. First try
# for network address as given, in case VLSM
# is in use.
#
NETMASK=`get_netmask ${NETWORK}`
if [ -z "${NETMASK}" ]
then
	get_default_class ${NETWORK} | read DEFNET DEFMASK
	# use the default.
	if [ "${DEFNET}" != "${NETWORK}" ]
	then
		# likely subnetted/supernetted.
		print - "\n\n###\tWarning\t###\n"
		print - "Network ${NETWORK} is netmasked, but no entry was found  \n
              in the 'netmasks' table; please update the 'netmasks'  \n
              table in the appropriate nameservice before continuing. \n 
              (See /etc/nsswitch.conf.) \n" >&2
		return 1
	else
		# use the default.
		NETMASK="${DEFMASK}"
	fi
fi

#
# Create a batch file.
#
print -n "Creating batch file "
while [ ${ENTRYNUM} -lt ${ENDNUM} ]
do
	if [ $((${ENTRYNUM}-${STRTNUM}))%50 -eq 0 ]
	then
		print -n "."
	fi

	CLIENTIP=`get_addr ${NETWORK} ${NETMASK} ${ENTRYNUM}`
	print "pntadm -A ${CLIENTIP} -m ${MACRO} ${NETWORK}" >> ${BATCHFILE}
	let ENTRYNUM=${ENTRYNUM}+1
done
print " done.\n"

#
# Run pntadm in batch mode and redirect output to a temporary file.
# Progress can be monitored by using the output file.
#
print "Batch processing output redirected to ${BATCHFILE}"
print "Batch processing started."

pntadm -B ${BATCHFILE} -v > /tmp/batch.out 2 >&1

print "Batch processing completed."