本章介绍了 DHCP 命令和 DHCP 文件之间的关系,但并未介绍如何使用这些命令。
本章包含以下信息:
下表列出了可用于在网络中管理 DHCP 的命令。
表 18–1 用于 DHCP 的命令
dhcpconfig、dhtadm 和 pntadm 命令为便于在脚本中使用进行了优化。特别是,pntadm 命令对于在 DHCP 网络表中创建大量 IP 地址项非常有用。以下样例脚本在批处理模式下使用 pntadm 来创建 IP 地址。
#! /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."
|
下表列出了与 Oracle Solaris : DHCP 关联的文件。
表 18–2 DHCP 守护进程和命令使用的文件和表|
文件名或表名 |
说明 |
手册页 |
|---|---|---|
|
dhcptab |
DHCP 配置信息表的通称,这些配置信息以选项及指定值的形式进行记录,而这些选项及指定值随后会组合为宏。dhcptab 表的名称及其地址由用于 DHCP 信息的数据存储确定。 | |
|
DHCP 网络表 |
将 IP 地址映射为客户机 ID 和配置选项。DHCP 网络表根据网络的 IP 地址(如 10.21.32.0)来命名。不存在名为 dhcp_network 的文件。DHCP 网络表的名称和地址由用于 DHCP 信息的数据存储确定。 | |
|
dhcpsvc.conf |
存储 DHCP 守护进程的启动选项以及数据存储信息。此文件决不能手动编辑。使用 dhcpconfig 命令可更改启动选项。 | |
|
nsswitch.conf |
指定名称服务数据库的地址以及搜索名称服务以查找各种信息的顺序。配置 DHCP 服务器时,会读取 nsswitch.conf 文件以获取准确的配置信息。此文件位于 /etc 目录中。 | |
|
resolv.conf |
包含用于解析 DNS 查询的信息。在 DHCP 服务器配置过程中,会查看此文件以获取有关 DNS 域和 DNS 服务器的信息。此文件位于 /etc 目录中。 | |
|
dhcp.interface |
表示将在 dhcp.interface 文件名中指定的客户机网络接口上使用 DHCP。例如,存在名为 dhcp.qe0 的文件表示将在 qe0 接口上使用 DHCP。dhcp.interface 文件可能包含一些命令,这些命令将作为选项传递给用于在客户机上启动 DHCP 的 ifconfig 命令。此文件位于 Oracle Solaris : DHCP 客户机系统上的 /etc 目录中。 |
没有特定的手册页,请参见 dhcp(5) |
|
interface.dhc |
包含从 DHCP 中为给定网络接口获取的配置参数。当删除此接口的 IP 地址租用时,客户机会将当前配置信息高速缓存至 /etc/dhcp/interface.dhc 中。例如,如果在 qe0 接口上使用 DHCP,则 dhcpagent 会将配置信息高速缓存至 /etc/dhcp/qe0.dhc 中。下次在此接口上启动 DHCP 时,如果租用未过期,客户机会请求使用高速缓存的配置。如果 DHCP 服务器拒绝此请求,则客户机会启动标准的 DHCP 租用协商进程。 |
没有特定的手册页,请参见 dhcpagent(1M) |
|
dhcpagent |
设置 dhcpagent 客户机守护进程的参数值。此文件的路径为 /etc/default/dhcpagent。有关参数的信息,请参见 /etc/default/dhcpagent 文件或 dhcpagent(1M) 手册页。 | |
|
DHCP inittab |
定义 DHCP 选项代码的各个方面(如数据类型),并指定助记标签。有关此文件语法的更多信息,请参见 dhcp_inittab(4) 手册页。 在客户机上,dhcpinfo 会使用 /etc/dhcp/inittab 文件中的信息来为此信息的读者提供更多有意义的信息。在 DHCP 服务器系统上,DHCP 守护进程和管理工具会使用此文件来获取 DHCP 选项信息。 /etc/dhcp/inittab 文件将替换在先前的发行版中使用的 /etc/dhcp/dhcptags 文件。DHCP 选项信息提供了有关这种替换的更多信息。 |
过去,DHCP 选项信息存储在多个位置,包括服务器的 dhcptab 表、客户机的 dhcptags 文件和各种程序的内部表。在 Solaris 8 发行版以及更高发行版中,选项信息合并在 /etc/dhcp/inittab 文件中。有关此文件的详细信息,请参见 dhcp_inittab(4) 手册页。
Oracle Solaris : DHCP 客户机使用 DHCP inittab 文件代替 dhcptags 文件。客户机使用此文件可获取有关在 DHCP 包中收到的选项代码的信息。DHCP 服务器上的 in.dhcpd、snoop 和 dhcpmgr 程序也将使用 inittab 文件。
大多数使用 Oracle Solaris : DHCP 的站点不会受到转换为 /etc/dhcp/inittab 文件这一操作的影响。如果满足以下所有条件,则站点将会受到影响:
计划从 Solaris 8 发行版之前的 Oracle Solaris : 发行版进行升级。
之前已创建了新的 DHCP 选项。
修改了 /etc/dhcp/dhcptags 文件并希望保留更改。
升级时,升级日志会通知您 dhcptags 文件已经修改,因此应对 DHCP inittab 文件进行更改。
inittab 文件比 dhcptags 文件包含更多的信息。inittab 文件使用的语法也不同。
以下是 dhcptags 项的一个样例:
33 StaticRt - IPList Static_Routes
33 为在 DHCP 包中传送的数字代码。StaticRt 为选项名。IPList 表示 StaticRt 的数据类型必须为 IP 地址列表。Static_Routes 是一个描述性更强的名称。
inittab 文件由说明每个选项的单行记录组成。其格式类似于在 dhcptab 中定义符号的格式。下表说明了 inittab 文件的语法。
说明
选项名。选项名在其选项类别中必须是唯一的,不可与标准选项、站点选项和供应商选项等类别中的其他选项重名。例如,不能有两个同名的站点选项,不能创建与标准选项名称相同的站点选项。
标识选项所属的名称空间。必须为以下名称空间之一: 标准、站点、供应商、字段或内部。
当选项在网络中发送时标识此选项。大多数情况下,代码唯一标识选项,与类别无关。但是,在涉及内部类别(如字段选项或内部选项)的情况下,代码可能会用于其他目的。代码可能不是全局唯一的。代码在选项类别中应是唯一的,并且不会与标准字段和站点字段中的代码重名。
说明与此选项关联的数据。有效类型为 IP、ASCII、Octet、Boolean、Unumber8、Unumber16、Unumber32、Unumber64、Snumber8、Snumber16、Snumber32 和 Snumber64 等。对数字来说,首字母 U 或 S 表示该数字为无符号或带符号的数字。末尾数字指明数字中的二进制位数。例如,Unumber8 即为无符号的 8 位二进制数字。类型不区分大小写。
说明组成此选项的完整值的数据单元的数量。
说明此选项允许使用的完整值的数量。0 表示一个无穷大的数字。
说明可使用此信息的程序。使用者应设置为 sdmi,其中:
snoop
in.dhcpd
dhcpmgr
dhcpinfo
以下是 inittab 项的一个样例:
StaticRt - Standard, 33, IP, 2, 0, sdmi
该项介绍了名为 StaticRt 的选项。此选项属于标准类别,选项代码为 33。由于类型为 IP、粒度为 2、最大值为无穷大 (0),因此预期的数据是一个可能为无穷大的 IP 地址对数量。此选项的使用者为 sdmi: snoop、in.dhcpd、dhcpmgr 和 dhcpinfo。
如果之前向 dhcptags 文件中添加了项,则必须向新的 inittab 文件中添加对应的项,这样才能继续使用添加到站点中的选项。以下示例说明如何以 inittab 格式表示 dhcptags 项的一个样例。
假定已经为连接到网络的传真机添加了以下 dhcptags 项:
128 FaxMchn - IP Fax_Machine
代码 128 意味着此选项一定属于站点类别。选项名为 FaxMchn,数据类型为 IP。
对应的 inittab 项可能是:
FaxMchn SITE, 128, IP, 1, 1, sdmi
粒度 1 和最大值 1 表示此选项应有一个 IP 地址。