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