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