xref: /dflybsd-src/sbin/dhclient/dhclient-script (revision 6bdc8b4312eb853c44dc9a5fd6a2874a79c29ad4)
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	if [ -n "$old_classless_routes" ]; then
30		fill_classless_routes "$old_classless_routes"
31		set $classless_routes
32		while [ $# -gt 1 ]; do
33			route delete "$1" "$2"
34			shift; shift
35		done
36		return 0;
37	fi
38}
39
40add_new_address() {
41	ifconfig $interface \
42		inet $new_ip_address \
43		netmask $new_subnet_mask \
44		broadcast $new_broadcast_address
45
46	# XXX Original TIMEOUT code did not do this unless $new_routers was set?
47	#route add $new_ip_address 127.0.0.1 >/dev/null 2>&1
48}
49
50fill_classless_routes() {
51	set $1
52	while [ $# -ge 5 ]; do
53		if [ $1 -eq 0 ]; then
54			route="default"
55		elif [ $1 -le 8 ]; then
56			route="$2.0.0.0/$1"
57			shift
58		elif [ $1 -le 16 ]; then
59			route="$2.$3.0.0/$1"
60			shift; shift
61		elif [ $1 -le 24 ]; then
62			route="$2.$3.$4.0/$1"
63			shift; shift; shift
64		else
65			route="$2.$3.$4.$5/$1"
66			shift; shift; shift; shift
67		fi
68		shift
69		router="$1.$2.$3.$4"
70		classless_routes="$classless_routes $route $router"
71		shift; shift; shift; shift
72	done
73}
74
75delete_old_routes() {
76	arp -dan
77}
78
79add_new_routes() {
80	# RFC 3442: If the DHCP server returns both a Classless Static
81	# Routes option and a Router option, the DHCP client MUST ignore
82	# the Router option.
83	#
84	# DHCP clients that support this option (Classless Static Routes)
85	# MUST NOT install the routes specified in the Static Routes
86	# option (option code 33) if both a Static Routes option and the
87	# Classless Static Routes option are provided.
88
89	if [ -n "$new_classless_routes" ]; then
90		fill_classless_routes "$new_classless_routes"
91		$LOGGER "New Classless Static Routes ($interface): $classless_routes"
92		set $classless_routes
93		while [ $# -gt 1 ]; do
94			if [ "0.0.0.0" = "$2" ]; then
95				route add "$1" -iface "$interface"
96			else
97				route add "$1" "$2"
98			fi
99			shift; shift
100		done
101		return
102	fi
103
104	for router in $new_routers; do
105		route -q delete default
106		if [ "$new_ip_address" = "$router" ]; then
107			route -q add default -iface $router
108		else
109			route -q add default $router
110		fi
111		# 2nd and subsequent default routers error out, so explicitly
112		# stop processing the list after the first one.
113		break
114	done
115}
116
117add_new_resolv_conf() {
118	# Create resolv.conf when either $new_domain_name_servers or
119	# $new_domain_name are provided. As reported in PR#3135, some ISPs
120	# provide only $new_domain_name_servers.
121
122	rm -f /etc/resolv.conf.std
123
124	if [ -n "$new_domain_name" ]; then
125		echo "search $new_domain_name" >>/etc/resolv.conf.std
126	fi
127
128	if [ -n "$new_domain_name_servers" ]; then
129		for nameserver in $new_domain_name_servers; do
130			echo "nameserver $nameserver" >>/etc/resolv.conf.std
131		done
132	fi
133
134	if [ -f /etc/resolv.conf.std ]; then
135		if [ -f /etc/resolv.conf.tail ]; then
136			cat /etc/resolv.conf.tail >>/etc/resolv.conf.std
137		fi
138
139		# In case (e.g. during OpenBSD installs) /etc/resolv.conf
140		# is a symbolic link, take care to preserve the link and write
141		# the new data in the correct location.
142
143		if [ -f /etc/resolv.conf ]; then
144			cat /etc/resolv.conf > /etc/resolv.conf.save
145		fi
146		cat /etc/resolv.conf.std > /etc/resolv.conf
147		rm -f /etc/resolv.conf.std
148
149		# Try to ensure correct ownership and permissions.
150		chown -RL root:wheel /etc/resolv.conf
151		chmod -RL 644 /etc/resolv.conf
152
153		return 0
154	fi
155
156	return 1
157}
158
159#
160# Start of active code.
161#
162
163case $reason in
164MEDIUM)
165	# Not called by OpenBSD dhclient(8).
166	;;
167
168PREINIT)
169	# Not called by OpenBSD dhclient(8).
170	;;
171
172ARPSEND)
173	# Not called by OpenBSD dhclient(8).
174	exit 1
175	;;
176
177ARPCHECK)
178	# Not called by OpenBSD dhclient(8).
179	# Always succeed. i.e. accept lease.
180	;;
181
182BOUND|RENEW|REBIND|REBOOT)
183	if [ -n "$old_ip_address" ]; then
184		if [ "$old_ip_address" != "$new_ip_address" ]; then
185			delete_old_address
186			delete_old_routes
187		fi
188	fi
189	if [ "$reason" = BOUND ] ||
190	   [ "$reason" = REBOOT ] ||
191	   [ -z "$old_ip_address" ] ||
192	   [ "$old_ip_address" != "$new_ip_address" ]; then
193		add_new_address
194		add_new_routes
195	fi
196	add_new_resolv_conf
197	;;
198
199EXPIRE|FAIL)
200	if [ -n "$old_ip_address" ]; then
201		delete_old_address
202		delete_old_routes
203	fi
204	if [ -f /etc/resolv.conf.save ]; then
205		cat /etc/resolv.conf.save > /etc/resolv.conf
206		rm -f /etc/resolv.conf.save
207	fi
208	;;
209
210TIMEOUT)
211	add_new_address
212	sleep 1
213	if [ -n "$new_routers" ]; then
214		set "$new_routers"
215		if ping -q -c 1 -w 1 "$1"; then
216			add_new_routes
217			if add_new_resolv_conf; then
218				exit 0
219			fi
220		fi
221	fi
222	ifconfig $interface inet $new_ip_address delete
223	# XXX Why not a delete_old_address as before all other invocations of
224	#     delete_old_routes?
225	delete_old_routes
226	exit 1
227	;;
228esac
229
230exit 0
231