系统管理指南:IP 服务

DHCP 客户机事件脚本

您可以将 Oracle Solaris : DHCP 客户机设置为运行可执行程序或脚本,这些程序或脚本可执行任何适用于客户机系统的操作。出现特定的 DHCP 租用事件之后,便会自动执行称为事件脚本的程序或脚本。可以使用事件脚本来运行其他命令、程序或者脚本以响应特定的租用事件。您必须提供自己的事件脚本以使用此功能。

dhcpagent 使用以下事件关键字来标识 DHCP 租用事件:

事件关键字

说明

BOUNDBOUND6

将接口配置为用于 DHCP。客户机从 DHCP 服务器接收确认消息 (DHCPv4 ACK) 或 (DHCPv6 Reply),此消息同意租用 IP 地址的请求。成功配置接口之后,便会立即调用事件脚本。

EXTENDEXTEND6

客户机成功地延长了租用期。当客户机从 DHCP 服务器接收续订请求的确认消息之后,便会立即调用事件脚本。

EXPIREEXPIRE6

租用时间结束时租用即到期。对于 DHCPv4,将在从接口中删除租用地址,并将接口标记为关闭之前的瞬间调用事件脚本。对于 DHCPv6,将在从接口中删除最后剩余的租用地址之前调用事件脚本。

DROPDROP6

客户机结束租用,将接口从 DHCP 控制中删除。系统会在将接口从 DHCP 控制中删除之前的瞬间调用事件脚本。

RELEASERELEASE6

客户机放弃 IP 地址。在客户机释放接口上的地址并将 DHCPv4 RELEASE 或 DHCPv6 Release 包发送到 DHCP 服务器之前的瞬间调用事件脚本。

INFORMINFORM6

接口通过 DHCPv4 INFORM 或 DHCPv6 Information-Request 消息从 DHCP 服务器获取新的或更新的配置信息。当 DHCP 客户机从服务器仅获取配置参数而不获取 IP 地址租用时,将出现这些事件。

LOSS6

在租用失效期间,如果仍然存在一个或多个有效租用,则在删除失效地址之前将调用该事件脚本。被删除的那些地址标记有 IFF_DEPRECATED 标志。

如果出现以上任意一种事件,dhcpagent 都会调用以下命令:


/etc/dhcp/eventhook interface event

其中,interface 是使用 DHCP 的接口,而 event 是前面所述的事件关键字之一。例如,当 ce0 接口首次配置为用于 DHCP 时,dhcpagent 会按如下方式调用事件脚本:


/etc/dhcp/eventhook ce0 BOUND

要使用事件脚本功能,您必须执行以下操作:

事件脚本从 dhcpagent 继承其程序环境,并以 root 权限运行。如有必要,脚本可以使用 dhcpinfo 实用程序来获取有关接口的更多信息。有关更多信息,请参见 dhcpinfo(1) 手册页。

dhcpagent 守护进程将等待事件脚本在所有事件上退出。如果事件脚本在 55 秒内没有退出,则 dhcpagent 会向脚本进程发送 SIGTERM 信号。如果又经过 3 秒之后进程仍没有退出,则守护进程会发送 SIGKILL 信号以中止此进程。

dhcpagent(1M) 手册页包含一个事件脚本的示例。

示例 16–3 显示了如何使用 DHCP 事件脚本使 /etc/resolv.conf 文件的内容保持最新。当出现 BOUNDEXTEND 事件时,脚本便会替换域服务器和名称服务器的名称。当出现 EXPIREDROPRELEASE 事件时,该脚本便会从文件中删除域服务器和名称服务器的名称。


注 –

此脚本示例假设 DHCP 是域服务器名称和名称服务器名称的授权源。此脚本还假设 DHCP 控制之下的所有接口都返回相同且最新的信息。以上假设也许并不能反映您系统的具体情况。



示例 16–3 用于更新 /etc/resolv.conf 文件的事件脚本

#!/bin/ksh -p

PATH=/bin:/sbin export PATH
umask 0222

# Refresh the domain and name servers on /etc/resolv.conf

insert ()
{
	dnsservers=`dhcpinfo -i $1 DNSserv`
	if [ -n "$dnsservers" ]; then
		# remove the old domain and name servers
		if [ -f /etc/resolv.conf ]; then
			rm -f /tmp/resolv.conf.$$
			sed -e '/^domain/d' -e '/^nameserver/d' \
			    /etc/resolv.conf > /tmp/resolv.conf.$$
		fi

		# add the new domain
		dnsdomain=`dhcpinfo -i $1 DNSdmain`
		if [ -n "$dnsdomain" ]; then
			echo "domain $dnsdomain" >> /tmp/resolv.conf.$$
		fi

		# add new name servers
		for name in $dnsservers; do
			echo nameserver $name >> /tmp/resolv.conf.$$
		done
		mv -f /tmp/resolv.conf.$$ /etc/resolv.conf
	fi
}

# Remove the domain and name servers from /etc/resolv.conf

remove ()
{
	if [ -f /etc/resolv.conf ]; then
		rm -f /tmp/resolv.conf.$$
		sed -e '/^domain/d' -e '/^nameserver/d' \
		    /etc/resolv.conf > /tmp/resolv.conf.$$
		mv -f /tmp/resolv.conf.$$ /etc/resolv.conf
	fi
}

case $2 in
BOUND | EXTEND)
	insert $1
	exit 0
	;;
EXPIRE | DROP | RELEASE)
	remove
	exit 0
	;;
*)
	exit 0
	;;
esac