xref: /onnv-gate/usr/src/cmd/cmd-inet/sbin/dhcpagent/release.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  *
26*0Sstevel@tonic-gate  * DECLINE/RELEASE configuration functionality for the DHCP client.
27*0Sstevel@tonic-gate  */
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #include <sys/types.h>
32*0Sstevel@tonic-gate #include <string.h>
33*0Sstevel@tonic-gate #include <netinet/in.h>
34*0Sstevel@tonic-gate #include <sys/socket.h>
35*0Sstevel@tonic-gate #include <net/if.h>
36*0Sstevel@tonic-gate #include <netinet/dhcp.h>
37*0Sstevel@tonic-gate #include <dhcpmsg.h>
38*0Sstevel@tonic-gate #include <dhcp_hostconf.h>
39*0Sstevel@tonic-gate #include <unistd.h>
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate #include "packet.h"
42*0Sstevel@tonic-gate #include "interface.h"
43*0Sstevel@tonic-gate #include "states.h"
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate /*
46*0Sstevel@tonic-gate  * send_decline(): sends a DECLINE message (broadcasted)
47*0Sstevel@tonic-gate  *
48*0Sstevel@tonic-gate  *   input: struct ifslist *: the interface to send the DECLINE on
49*0Sstevel@tonic-gate  *	    char *: an optional text explanation to send with the message
50*0Sstevel@tonic-gate  *	    struct in_addr *: the IP address being declined
51*0Sstevel@tonic-gate  *  output: void
52*0Sstevel@tonic-gate  */
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate void
55*0Sstevel@tonic-gate send_decline(struct ifslist *ifsp, char *msg, struct in_addr *declined_ip)
56*0Sstevel@tonic-gate {
57*0Sstevel@tonic-gate 	dhcp_pkt_t	*dpkt;
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate 	dpkt = init_pkt(ifsp, DECLINE);
60*0Sstevel@tonic-gate 	add_pkt_opt32(dpkt, CD_SERVER_ID, ifsp->if_server.s_addr);
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate 	if (msg != NULL)
63*0Sstevel@tonic-gate 		add_pkt_opt(dpkt, CD_MESSAGE, msg, strlen(msg) + 1);
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	add_pkt_opt32(dpkt, CD_REQUESTED_IP_ADDR, declined_ip->s_addr);
66*0Sstevel@tonic-gate 	add_pkt_opt(dpkt, CD_END, NULL, 0);
67*0Sstevel@tonic-gate 
68*0Sstevel@tonic-gate 	(void) send_pkt(ifsp, dpkt, htonl(INADDR_BROADCAST), NULL);
69*0Sstevel@tonic-gate }
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate /*
72*0Sstevel@tonic-gate  * dhcp_release(): sends a RELEASE message to a DHCP server and removes
73*0Sstevel@tonic-gate  *		   the interface from DHCP control
74*0Sstevel@tonic-gate  *
75*0Sstevel@tonic-gate  *   input: struct ifslist *: the interface to send the RELEASE on and remove
76*0Sstevel@tonic-gate  *	    const char *: an optional text explanation to send with the message
77*0Sstevel@tonic-gate  *  output: int: 1 on success, 0 on failure
78*0Sstevel@tonic-gate  */
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate int
81*0Sstevel@tonic-gate dhcp_release(struct ifslist *ifsp, const char *msg)
82*0Sstevel@tonic-gate {
83*0Sstevel@tonic-gate 	int		retval = 0;
84*0Sstevel@tonic-gate 	int		error = DHCP_IPC_E_INT;
85*0Sstevel@tonic-gate 	dhcp_pkt_t	*dpkt;
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate 	if (ifsp->if_dflags & DHCP_IF_BOOTP)
88*0Sstevel@tonic-gate 		goto out;
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 	if (ifsp->if_state != BOUND && ifsp->if_state != RENEWING &&
91*0Sstevel@tonic-gate 	    ifsp->if_state != REBINDING)
92*0Sstevel@tonic-gate 		goto out;
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate 	dhcpmsg(MSG_INFO, "releasing interface %s", ifsp->if_name);
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 	dpkt = init_pkt(ifsp, RELEASE);
97*0Sstevel@tonic-gate 	dpkt->pkt->ciaddr.s_addr = ifsp->if_addr.s_addr;
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate 	if (msg != NULL)
100*0Sstevel@tonic-gate 		add_pkt_opt(dpkt, CD_MESSAGE, msg, strlen(msg) + 1);
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	add_pkt_opt32(dpkt, CD_SERVER_ID, ifsp->if_server.s_addr);
103*0Sstevel@tonic-gate 	add_pkt_opt(dpkt, CD_END, NULL, 0);
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	(void) send_pkt(ifsp, dpkt, ifsp->if_server.s_addr, NULL);
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate 	/*
108*0Sstevel@tonic-gate 	 * XXX this totally sucks, but since udp is best-effort,
109*0Sstevel@tonic-gate 	 * without this delay, there's a good chance that the packet
110*0Sstevel@tonic-gate 	 * that we just enqueued for sending will get pitched
111*0Sstevel@tonic-gate 	 * when we canonize the interface below.
112*0Sstevel@tonic-gate 	 */
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate 	(void) usleep(500);
115*0Sstevel@tonic-gate 	(void) canonize_ifs(ifsp);
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate 	remove_ifs(ifsp);
118*0Sstevel@tonic-gate 	error = DHCP_IPC_SUCCESS;
119*0Sstevel@tonic-gate 	retval = 1;
120*0Sstevel@tonic-gate out:
121*0Sstevel@tonic-gate 	ipc_action_finish(ifsp, error);
122*0Sstevel@tonic-gate 	async_finish(ifsp);
123*0Sstevel@tonic-gate 	return (retval);
124*0Sstevel@tonic-gate }
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate /*
127*0Sstevel@tonic-gate  * dhcp_drop(): drops the interface from DHCP control
128*0Sstevel@tonic-gate  *
129*0Sstevel@tonic-gate  *   input: struct ifslist *: the interface to drop
130*0Sstevel@tonic-gate  *	    const char *: unused
131*0Sstevel@tonic-gate  *  output: int: always 1
132*0Sstevel@tonic-gate  */
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate /* ARGSUSED */
135*0Sstevel@tonic-gate int
136*0Sstevel@tonic-gate dhcp_drop(struct ifslist *ifsp, const char *msg)
137*0Sstevel@tonic-gate {
138*0Sstevel@tonic-gate 	PKT_LIST *plp[2];
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	dhcpmsg(MSG_INFO, "dropping interface %s", ifsp->if_name);
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate 	if (ifsp->if_state == BOUND || ifsp->if_state == RENEWING ||
143*0Sstevel@tonic-gate 	    ifsp->if_state == REBINDING) {
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate 		if ((ifsp->if_dflags & DHCP_IF_BOOTP) == 0) {
146*0Sstevel@tonic-gate 			plp[0] = ifsp->if_ack;
147*0Sstevel@tonic-gate 			plp[1] = ifsp->if_orig_ack;
148*0Sstevel@tonic-gate 			if (write_hostconf(ifsp->if_name, plp, 2,
149*0Sstevel@tonic-gate 			    monosec_to_time(ifsp->if_curstart_monosec)) == -1)
150*0Sstevel@tonic-gate 				dhcpmsg(MSG_ERR, "cannot write %s (reboot will "
151*0Sstevel@tonic-gate 				    "not use cached configuration)",
152*0Sstevel@tonic-gate 				    ifname_to_hostconf(ifsp->if_name));
153*0Sstevel@tonic-gate 		}
154*0Sstevel@tonic-gate 		(void) canonize_ifs(ifsp);
155*0Sstevel@tonic-gate 	}
156*0Sstevel@tonic-gate 	remove_ifs(ifsp);
157*0Sstevel@tonic-gate 	ipc_action_finish(ifsp, DHCP_IPC_SUCCESS);
158*0Sstevel@tonic-gate 	async_finish(ifsp);
159*0Sstevel@tonic-gate 	return (1);
160*0Sstevel@tonic-gate }
161