10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*3431Scarlsonj * Common Development and Distribution License (the "License"). 6*3431Scarlsonj * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*3431Scarlsonj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*3431Scarlsonj * Use is subject to license terms. 240Sstevel@tonic-gate * 250Sstevel@tonic-gate * INFORM_SENT state of the client state machine. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <sys/types.h> 310Sstevel@tonic-gate #include <time.h> 320Sstevel@tonic-gate #include <sys/socket.h> 330Sstevel@tonic-gate #include <netinet/in.h> 340Sstevel@tonic-gate #include <netinet/udp.h> 350Sstevel@tonic-gate #include <netinet/ip_var.h> 360Sstevel@tonic-gate #include <netinet/udp_var.h> 370Sstevel@tonic-gate #include <dhcpmsg.h> 380Sstevel@tonic-gate 39*3431Scarlsonj #include "agent.h" 40*3431Scarlsonj #include "states.h" 41*3431Scarlsonj #include "interface.h" 420Sstevel@tonic-gate #include "packet.h" 43*3431Scarlsonj 44*3431Scarlsonj static boolean_t stop_informing(dhcp_smach_t *, unsigned int); 450Sstevel@tonic-gate 460Sstevel@tonic-gate /* 470Sstevel@tonic-gate * dhcp_inform(): sends an INFORM packet and sets up reception for an ACK 480Sstevel@tonic-gate * 49*3431Scarlsonj * input: dhcp_smach_t *: the state machine to use 500Sstevel@tonic-gate * output: void 510Sstevel@tonic-gate * note: the INFORM cannot be sent successfully if the interface 52*3431Scarlsonj * does not have an IP address (this is mostly an issue for IPv4). 530Sstevel@tonic-gate */ 540Sstevel@tonic-gate 550Sstevel@tonic-gate void 56*3431Scarlsonj dhcp_inform(dhcp_smach_t *dsmp) 570Sstevel@tonic-gate { 580Sstevel@tonic-gate dhcp_pkt_t *dpkt; 590Sstevel@tonic-gate 60*3431Scarlsonj if (!set_smach_state(dsmp, INIT)) 61*3431Scarlsonj goto failed; 62*3431Scarlsonj 63*3431Scarlsonj if (dsmp->dsm_isv6) { 64*3431Scarlsonj dpkt = init_pkt(dsmp, DHCPV6_MSG_INFO_REQ); 650Sstevel@tonic-gate 66*3431Scarlsonj /* Add required Option Request option */ 67*3431Scarlsonj (void) add_pkt_prl(dpkt, dsmp); 68*3431Scarlsonj dsmp->dsm_server = ipv6_all_dhcp_relay_and_servers; 69*3431Scarlsonj (void) send_pkt_v6(dsmp, dpkt, dsmp->dsm_server, 70*3431Scarlsonj stop_informing, DHCPV6_INF_TIMEOUT, DHCPV6_INF_MAX_RT); 71*3431Scarlsonj } else { 72*3431Scarlsonj ipaddr_t server; 730Sstevel@tonic-gate 74*3431Scarlsonj /* 75*3431Scarlsonj * Assemble a DHCPREQUEST packet, without the Server ID option. 76*3431Scarlsonj * Fill in ciaddr, since we know this. dsm_server will be set 77*3431Scarlsonj * to the server's IP address, which will be the broadcast 78*3431Scarlsonj * address if we don't know it. The max DHCP message size 79*3431Scarlsonj * option is set to the interface max, minus the size of the 80*3431Scarlsonj * UDP and IP headers. 81*3431Scarlsonj */ 82*3431Scarlsonj 83*3431Scarlsonj dpkt = init_pkt(dsmp, INFORM); 84*3431Scarlsonj IN6_V4MAPPED_TO_INADDR(&dsmp->dsm_lif->lif_v6addr, 85*3431Scarlsonj &dpkt->pkt->ciaddr); 860Sstevel@tonic-gate 87*3431Scarlsonj (void) add_pkt_opt16(dpkt, CD_MAX_DHCP_SIZE, 88*3431Scarlsonj htons(dsmp->dsm_lif->lif_pif->pif_max - 89*3431Scarlsonj sizeof (struct udpiphdr))); 90*3431Scarlsonj (void) add_pkt_opt(dpkt, CD_CLASS_ID, class_id, class_id_len); 91*3431Scarlsonj (void) add_pkt_prl(dpkt, dsmp); 92*3431Scarlsonj (void) add_pkt_opt(dpkt, CD_END, NULL, 0); 930Sstevel@tonic-gate 94*3431Scarlsonj IN6_V4MAPPED_TO_IPADDR(&dsmp->dsm_server, server); 95*3431Scarlsonj if (!send_pkt(dsmp, dpkt, server, NULL)) { 96*3431Scarlsonj dhcpmsg(MSG_ERROR, "dhcp_inform: send_pkt failed"); 97*3431Scarlsonj goto failed; 98*3431Scarlsonj } 990Sstevel@tonic-gate } 1000Sstevel@tonic-gate 101*3431Scarlsonj if (!set_smach_state(dsmp, INFORM_SENT)) 102*3431Scarlsonj goto failed; 103*3431Scarlsonj 104*3431Scarlsonj return; 1050Sstevel@tonic-gate 106*3431Scarlsonj failed: 107*3431Scarlsonj dsmp->dsm_dflags |= DHCP_IF_FAILED; 108*3431Scarlsonj ipc_action_finish(dsmp, DHCP_IPC_E_INT); 109*3431Scarlsonj } 1100Sstevel@tonic-gate 111*3431Scarlsonj /* 112*3431Scarlsonj * stop_informing(): decides when to stop retransmitting Information-Requests 113*3431Scarlsonj * 114*3431Scarlsonj * input: dhcp_smach_t *: the state machine Info-Reqs are being sent from 115*3431Scarlsonj * unsigned int: the number of requests sent so far 116*3431Scarlsonj * output: boolean_t: B_TRUE if retransmissions should stop 117*3431Scarlsonj */ 1180Sstevel@tonic-gate 119*3431Scarlsonj /* ARGSUSED */ 120*3431Scarlsonj static boolean_t 121*3431Scarlsonj stop_informing(dhcp_smach_t *dsmp, unsigned int n_requests) 122*3431Scarlsonj { 123*3431Scarlsonj return (B_FALSE); 1240Sstevel@tonic-gate } 125