xref: /dragonfly/sbin/dhclient/dhclient-script (revision ad9f8794)
1#!/bin/sh
2#
3# $OpenBSD: dhclient-script,v 1.12 2007/08/11 17:58:55 krw Exp $
4# $DragonFly: src/sbin/dhclient/dhclient-script,v 1.1 2008/08/30 16:07:58 hasso Exp $
5#
6# Copyright (c) 2003 Kenneth R Westerback <krw@openbsd.org>
7#
8# Permission to use, copy, modify, and distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19#
20#
21
22#
23# Helper functions that implement common actions.
24#
25
26delete_old_address() {
27	if [ -n "$old_ip_address" ]; then
28		ifconfig $interface inet $old_ip_address delete $medium
29		route delete "$old_ip_address" 127.0.0.1 >/dev/null 2>&1
30	fi
31}
32
33add_new_address() {
34	ifconfig $interface \
35		inet $new_ip_address \
36		netmask $new_subnet_mask \
37		broadcast $new_broadcast_address \
38		$medium
39
40	# XXX Original TIMEOUT code did not do this unless $new_routers was set?
41	route add $new_ip_address 127.0.0.1 >/dev/null 2>&1
42}
43
44delete_old_alias() {
45	if [ -n "$alias_ip_address" ]; then
46		ifconfig $interface inet $alias_ip_address delete > /dev/null 2>&1
47		route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
48	fi
49}
50
51add_new_alias() {
52	if [ -n "$alias_ip_address" ]; then
53		ifconfig $interface inet $alias_ip_address alias netmask \
54		    $alias_subnet_mask
55		route add $alias_ip_address 127.0.0.1
56	fi
57}
58
59delete_old_routes() {
60	if [ -n "$old_static_routes" ]; then
61		set $old_static_routes
62		while [ $# -gt 1 ]; do
63			route delete "$1" "$2"
64			shift; shift
65		done
66	fi
67
68	arp -dan
69}
70
71add_new_routes() {
72	for router in $new_routers; do
73		route delete default >/dev/null 2>&1
74		if [ "$new_ip_address" = "$router" ]; then
75			route add default -iface $router >/dev/null 2>&1
76		else
77			route add default $router >/dev/null 2>&1
78		fi
79		# 2nd and subsequent default routers error out, so explicitly
80		# stop processing the list after the first one.
81		break
82	done
83
84	if [ -n "$new_static_routes" ]; then
85		set $new_static_routes
86		while [ $# -gt 1 ]; do
87			route add $1 $2
88			shift; shift
89		done
90	fi
91}
92
93add_new_resolv_conf() {
94	# XXX Old code did not create/update resolv.conf unless both
95	# $new_domain_name and $new_domain_name_servers were provided.  PR
96	# #3135 reported some ISPs only provide $new_domain_name_servers and
97	# thus broke the script. This code creates the resolv.conf if either
98	# are provided.
99
100	rm -f /etc/resolv.conf.std
101
102	if [ -n "$new_domain_name" ]; then
103		echo "search $new_domain_name" >>/etc/resolv.conf.std
104	fi
105
106	if [ -n "$new_domain_name_servers" ]; then
107		for nameserver in $new_domain_name_servers; do
108			echo "nameserver $nameserver" >>/etc/resolv.conf.std
109		done
110	fi
111
112	if [ -f /etc/resolv.conf.std ]; then
113		if [ -f /etc/resolv.conf.tail ]; then
114			cat /etc/resolv.conf.tail >>/etc/resolv.conf.std
115		fi
116
117		# In case (e.g. during OpenBSD installs) /etc/resolv.conf
118		# is a symbolic link, take care to preserve the link and write
119		# the new data in the correct location.
120
121		if [ -f /etc/resolv.conf ]; then
122			cat /etc/resolv.conf > /etc/resolv.conf.save
123		fi
124		cat /etc/resolv.conf.std > /etc/resolv.conf
125		rm -f /etc/resolv.conf.std
126
127		# Try to ensure correct ownership and permissions.
128		chown -RL root:wheel /etc/resolv.conf
129		chmod -RL 644 /etc/resolv.conf
130
131		return 0
132	fi
133
134	return 1
135}
136
137#
138# Start of active code.
139#
140
141case $reason in
142MEDIUM)
143	ifconfig $interface $medium
144	sleep 1
145	;;
146
147PREINIT)
148	delete_old_alias
149	ifconfig $interface up
150	;;
151
152ARPCHECK|ARPSEND)
153	;;
154
155BOUND|RENEW|REBIND|REBOOT)
156	if [ -n "$old_ip_address" ]; then
157		if [ "$old_ip_address" != "$alias_ip_address" ]; then
158			delete_old_alias
159		fi
160		if [ "$old_ip_address" != "$new_ip_address" ]; then
161			delete_old_address
162			delete_old_routes
163		fi
164	fi
165	if [ "$reason" = BOUND ] ||
166	   [ "$reason" = REBOOT ] ||
167	   [ -z "$old_ip_address" ] ||
168	   [ "$old_ip_address" != "$new_ip_address" ]; then
169		add_new_address
170		add_new_routes
171	fi
172	if [ "$new_ip_address" != "$alias_ip_address" ]; then
173		add_new_alias
174	fi
175	add_new_resolv_conf
176	;;
177
178EXPIRE|FAIL)
179	delete_old_alias
180	if [ -n "$old_ip_address" ]; then
181		delete_old_address
182		delete_old_routes
183	fi
184	# XXX Why add alias we just deleted above?
185	add_new_alias
186	if [ -f /etc/resolv.conf.save ]; then
187		cat /etc/resolv.conf.save > /etc/resolv.conf
188	fi
189	;;
190
191TIMEOUT)
192	delete_old_alias
193	add_new_address
194	sleep 1
195	if [ -n "$new_routers" ]; then
196		set "$new_routers"
197		if ping -q -c 1 -w 1 "$1"; then
198			if [ "$new_ip_address" != "$alias_ip_address" ]; then
199				add_new_alias
200			fi
201			add_new_routes
202			if add_new_resolv_conf; then
203				exit 0
204			fi
205		fi
206	fi
207	ifconfig $interface inet $new_ip_address delete $medium
208	# XXX Why not a delete_old_address as before all other invocations of
209	#     delete_old_routes?
210	delete_old_routes
211	exit 1
212	;;
213esac
214
215exit 0
216