Solaris のシステム管理 (IP サービス)

第 18 章 DHCP コマンドと DHCP ファイル (リファレンス)

この章では、DHCP コマンドと DHCP ファイルの関連について説明します。ただし、この章にはコマンドの使い方は含まれていません。

この章では、次の内容について説明します。

DHCP のコマンド

次の表に、ネットワーク上で DHCP を管理するために使用できるコマンドを示します。

表 18–1 DHCP で使用されるコマンド

コマンド 

説明 

マニュアルページ 

dhtadm

dhcptab 内のオプションやマクロを変更するときに使用します。このコマンドは、DHCP 情報を自動的に変更するために作成するスクリプトでもっとも役立ちます。dhtadm-P オプションを指定し、その結果を grep コマンドに渡すと、dhcptab テーブル内の特定のオプション値をすばやく検索できます。

dhtadm(1M)

pntadm

DHCP ネットワークテーブルを変更するときに使用します。このテーブルでは、クライアント ID と IP アドレスが対応付けられ、オプションとして構成情報と IP アドレスが関連付けられています。

pntadm(1M)

dhcpconfig

DHCP サーバーや BOOTP リレーエージェントの構成や構成解除を行うときに使用します。さらに、データストアを別のデータストアへ変換したり、DHCP 構成データのインポートやエクスポートを行うときにも使用します。

dhcpconfig(1M)

in.dhcpd

DHCP サーバーデーモン。デーモンはシステムの起動時に起動されます。したがって、サーバーデーモンを直接起動すべきではありません。デーモンの起動や停止には、DHCP マネージャ、 svcadm コマンド、または dhcpconfig を使用できます。問題を解決するためにデーモンをデバッグモードで実行する場合にのみデーモンを直接起動します。

in.dhcpd(1M)

dhcpmgr

DHCP マネージャ。DHCP サービスの構成や管理に使用するグラフィカルユーザーインタフェース (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 コマンドは大量の IP アドレスエントリを DHCP ネットワークテーブルに作成するときに便利です。次のサンプルスクリプトでは、バッチモードで pntadm を使って、IP アドレスを作成しています。


例 18–1 addclient.ksh スクリプトで pntadm コマンドを使用する

#! /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."

DHCP サービスによって使用されるファイル

次の表に、Oracle Solaris DHCP に関連するファイルを示します。

表 18–2 DHCP デーモンや DHCP コマンドで使用されるファイル

ファイルまたはテーブル名 

説明 

マニュアルページ 

dhcptab

オプションとその値の組み合わせからなる DHCP 構成情報のテーブルを表す総称的な用語。構成情報はさらにマクロとしてグループ化されます。dhcptab テーブルの名前と位置は、DHCP 情報の格納にどのデータストアを使用するかによって異なります。

dhcptab(4)

DHCP ネットワークテーブル 

IP アドレスをクライアント ID と構成オプションに割り当てます。DHCP ネットワークテーブルの名前は、10.21.32.0 など、ネットワークの IP アドレスに基づいて付けられます。dhcp_network というファイルはありません。DHCP ネットワークテーブルの名前と位置は、DHCP 情報の格納にどのデータストアを使用するかによって異なります。

dhcp_network(4)

dhcpsvc.conf

DHCP デーモンの起動オプションと、データストア情報を格納しています。このファイルを手動で編集してはいけません。起動オプションの変更には dhcpconfig コマンドを使用します。

dhcpsvc.conf(4)

nsswitch.conf

ネームサービスデータベースの場所と、それらのデータベースをどのような順序で検索してさまざまな情報を入手するかを指定します。nsswitch.conf ファイルは、DHCP サーバーを構成する際に正確な構成情報を入手するために使用されます。このファイルは、/etc ディレクトリに存在します。

nsswitch.conf(4)

resolv.conf

DNS クエリーを解決するための情報が含まれています。DHCP サーバーの構成中に、このファイルで、DNS ドメインと DNS サーバーに関する情報が調べられます。このファイルは、/etc ディレクトリに存在します。

resolv.conf(4)

dhcp.interface

ファイル名 dhcp.interface で指定されたクライアントネットワークインタフェースで DHCP が使用されることを示します。たとえば、dhcp.qe0 という名前のファイルが存在する場合、DHCP は qe0 インタフェースで使用されることを表します。その場合、 dhcp.interface ファイルには、ifconfig コマンド (DHCP をそのインタフェースで起動するために使用される) にオプションとして渡されるコマンドが含まれていることがあります。このファイルは、Oracle Solaris DHCP クライアントシステムの /etc ディレクトリに存在します。

特定のマニュアルページはありません。dhcp(5) を参照してください。

interface.dhc

DHCP から得られた特定のネットワークインタフェースの構成パラメータが含まれています。インタフェースの IP アドレスのリースが停止されると、このクライアントは、/etc/dhcp/ interface.dhc にある現在の設定情報をキャッシュします。たとえば、DHCP が qe0 インタフェースで使用されている場合、dhcpagent は、構成情報を /etc/dhcp/qe0.dhc にキャッシュします。DHCP が次にこのインタフェースで起動するときに、リースの有効期限内であれば、このクライアントはキャッシュされた情報を使用するように要求します。DHCP サーバーがこの要求を拒否すると、クライアントは標準の DHCP リースネゴシエーション手順を開始します。

特定のマニュアルページはありません。dhcpagent(1M) を参照してくささい。

dhcpagent

dhcpagent クライアントデーモンのパラメータ値を設定します。このファイルへのパスは /etc/default/dhcpagent です。パラメータについては、/etc/default/dhcpagent ファイルか、 dhcpagent(1M) のマニュアルページを参照してください。

dhcpagent(1M)

DHCP inittab

データタイプなど、DHCP オプションコードのさまざまな要素を定義するとともに、ニーモニックラベルを割り当てます。ファイルの構文については、dhcp_inittab(4) のマニュアルページを参照してください。

クライアント側では、 dhcpinfo/etc/dhcp/inittab ファイル中の情報を人が判読可能な情報として提供します。DHCP サーバーシステムでは、DHCP デーモンと管理ツールがこのファイルから DHCP オプション情報を入手します。

以前のリリースで使用されていた /etc/dhcp/dhcptags ファイルは /etc/dhcp/inittab ファイルで置き換えられている。これについては、 「DHCP のオプション」を参照してください。

dhcp_inittab(4)

DHCP のオプション

従来、DHCP のオプション情報は、サーバーの dhcptab テーブルやクライアントの dhcptags ファイル、さらにさまざまなプログラムの内部テーブルなど、複数の場所に格納されてきました。そのため、Solaris 8 以降のリリースでは、すべてのオプション情報が /etc/dhcp/inittab ファイルに統合されています。ファイルの詳細については、dhcp_inittab(4) のマニュアルページを参照してください。

Oracle Solaris DHCP クライアントでは、dhcptags ファイルの代わりに DHCP の inittab ファイルを使用します。クライアントは、DHCP パケットの一部としてオプションコードを受け取ると、その情報をこのファイルから取得します。DHCP サーバーの in.dhcpdsnoopdhcpmgr プログラムでもこの inittab ファイルを使用します。

サイトが影響を受けるかどうかの判別

Oracle Solaris DHCP を使用するほとんどのサイトは、/etc/dhcp/inittab ファイルへの切り替えによる影響を受けません。影響を受けるのは、次の条件がすべて当てはまるサイトだけです。

アップグレードを行うと、dhcptags ファイルが変更されたために DHCP inittab ファイルを変更する必要があることを示すメッセージがアップグレードログに書き込まれます。

dhcptags ファイルと inittab ファイルの違い

inittab ファイルには、dhcptags ファイルよりも多くの情報が含まれています。さらに、inittab ファイルでは、異なる構文が使用されます。

次に、dhcptags のエントリ例を示します。

33 StaticRt - IPList Static_Routes

33 は DHCP パケットで渡される数値コードです。StaticRt はオプション名です。IPList は、StaticRt のデータタイプが一連の IP アドレスでなければならないことを示します。Static_Routes は記述名です。

inittab ファイルは、これらのオプションを 1 行で表した複数のレコードから構成されています。形式は、dhcptab のシンボルを定義する形式と似ています。次の表に、inittab ファイルの構文について説明します。

オプション

説明

option-name

オプションの名前。オプション名は、そのオプションのカテゴリ内部で一意である必要があります。また、Standard、Site、Vendor のカテゴリにある、ほかのオプション名と重複できません。たとえば、同じ名前を持つ Site オプションを 2 つ持つことはできず、Standard のオプションと同じ名前の Site のオプションは作成できません。

category

オプションが所属する名前空間を特定します。次のいずれかである必要があります。 Standard、Site、Vendor、Field、または Internal。

code

オプションがネットワーク経由で送信されたときにそのオプションを特定します。多くの場合、カテゴリがなくてもコードはオプションを一意に特定します。ただし、Field や Internal などの内部カテゴリの場合は、コードがほかの目的に使用される場合があります。コードは、広域的に一意でない場合があります。コードは、オプションのカテゴリ内部では一意であることが必要で、Standard と Site のフィールドにあるコードと重複することはできません。

type

このオプションと関連するデータを記述します。有効なタイプは、IP、ASCII、Octet、Boolean、Unumber8、Unumber16、Unumber32、Unumber64、Snumber8、Snumber16、Snumber32、および Snumber64 です。数値の場合、先頭の U や S は、数値が符号なしか符号ありかを示します。終わりの数字は、数値にいくつのビットが含まれているかを表します。たとえば、Unumber8 は無符号の 8 ビット数値を表します。タイプには、大文字小文字の区別はありません。

granularity

このオプションの値を構成するデータ単位数を記述します。

maximum

このオプションに指定可能な値の個数を記述します。0 は、無限大の数を表します。

consumers

この情報を使用できるプログラムを記述します。これには次の sdmi を指定します。

s

snoop

d

in.dhcpd

m

dhcpmgr

i

dhcpinfo

次に inittab エントリの例を示します。

StaticRt - Standard, 33, IP, 2, 0, sdmi

このエントリは、オプションが StaticRt という名前で、Standard カテゴリに属し、オプションコード 33 であることを示します。これで表されるデータは、理論上無数の IP アドレスの組です。なぜなら、タイプが IP、データ単位が 2、最大が無限 (0) だからです。このオプションを利用するのは sdmi: snoopin.dhcpddhcpmgrdhcpinfo です。

dhcptags エントリの inittab エントリへの変換

以前に dhcptags ファイルにエントリを追加している場合は、対応するエントリを新しい inittab ファイルにも追加する必要があります。ただし、以前に追加したオプションを使用しない場合は不要です。次の例では、dhcptags エントリの例を inittab フォーマットで表す方法を示しています。

ネットワークに接続されたファックスについて、次の dhcptags エントリを追加したと想定してください。

128 FaxMchn - IP Fax_Machine

コード 128 は、オプションが Site カテゴリに属していなければならないことを示します。オプション名は FaxMchn、データタイプは IP です。

対応する inittab エントリは次のとおりです。

FaxMchn SITE, 128, IP, 1, 1, sdmi

データ単位数が 1、指定可能な値の数が 1 なので、このオプションには 1 つの IP アドレスを指定することを表しています。