4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * REQUESTING state of the client state machine.
26 */
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <search.h>
31 #include <sys/types.h>
32 #include <netinet/in.h>
33 #include <netinet/dhcp.h>
34 #include <netinet/udp.h>
35 #include <netinet/ip_var.h>
36 #include <netinet/udp_var.h>
37 #include <arpa/inet.h>
38 #include <dhcp_hostconf.h>
39 #include <dhcpagent_util.h>
40 #include <dhcpmsg.h>
41
42 #include "states.h"
43 #include "util.h"
62 send_v6_request(dhcp_smach_t *dsmp)
63 {
64 dhcp_pkt_t *dpkt;
65 dhcpv6_ia_na_t d6in;
66
67 dpkt = init_pkt(dsmp, DHCPV6_MSG_REQUEST);
68 (void) add_pkt_opt(dpkt, DHCPV6_OPT_SERVERID, dsmp->dsm_serverid,
69 dsmp->dsm_serveridlen);
70
71 /* Add an IA_NA option for our controlling LIF */
72 d6in.d6in_iaid = htonl(dsmp->dsm_lif->lif_iaid);
73 d6in.d6in_t1 = htonl(0);
74 d6in.d6in_t2 = htonl(0);
75 (void) add_pkt_opt(dpkt, DHCPV6_OPT_IA_NA,
76 (dhcpv6_option_t *)&d6in + 1,
77 sizeof (d6in) - sizeof (dhcpv6_option_t));
78
79 /* Add required Option Request option */
80 (void) add_pkt_prl(dpkt, dsmp);
81
82 (void) send_pkt_v6(dsmp, dpkt, dsmp->dsm_server, stop_requesting,
83 DHCPV6_REQ_TIMEOUT, DHCPV6_REQ_MAX_RT);
84
85 /* For DHCPv6, state switch cannot fail */
86 (void) set_smach_state(dsmp, REQUESTING);
87 }
88
89 /*
90 * server_unicast_option(): determines the server address to use based on the
91 * DHCPv6 Server Unicast option present in the given
92 * packet.
93 *
94 * input: dhcp_smach_t *: the state machine
95 * PKT_LIST *: received packet (Advertisement or Reply)
96 * output: none
97 */
98
99 void
100 server_unicast_option(dhcp_smach_t *dsmp, PKT_LIST *plp)
101 {
296 (void) add_pkt_opt32(dpkt, CD_LEASE_TIME, lease);
297 (void) add_pkt_opt16(dpkt, CD_MAX_DHCP_SIZE,
298 htons(dsmp->dsm_lif->lif_max - sizeof (struct udpiphdr)));
299 (void) add_pkt_opt32(dpkt, CD_REQUESTED_IP_ADDR,
300 offer->pkt->yiaddr.s_addr);
301 (void) add_pkt_opt(dpkt, CD_SERVER_ID,
302 offer->opts[CD_SERVER_ID]->value,
303 offer->opts[CD_SERVER_ID]->len);
304
305 if (class_id_len != 0) {
306 (void) add_pkt_opt(dpkt, CD_CLASS_ID, class_id,
307 class_id_len);
308 }
309 (void) add_pkt_prl(dpkt, dsmp);
310
311 /*
312 * dsm_reqhost was set for this state machine in
313 * dhcp_selecting() if the DF_REQUEST_HOSTNAME option set and a
314 * host name was found
315 */
316 if (dsmp->dsm_reqhost != NULL) {
317 (void) add_pkt_opt(dpkt, CD_HOSTNAME, dsmp->dsm_reqhost,
318 strlen(dsmp->dsm_reqhost));
319 }
320 (void) add_pkt_opt(dpkt, CD_END, NULL, 0);
321
322 /*
323 * send out the REQUEST, trying retransmissions. either a NAK
324 * or too many REQUEST attempts will revert us to SELECTING.
325 */
326
327 if (!set_smach_state(dsmp, REQUESTING)) {
328 dhcpmsg(MSG_ERROR, "dhcp_requesting: cannot switch to "
329 "REQUESTING state; reverting to INIT on %s",
330 dsmp->dsm_name);
331 goto failure;
332 }
333
334 (void) send_pkt(dsmp, dpkt, htonl(INADDR_BROADCAST),
335 stop_requesting);
336 }
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
25 *
26 * REQUESTING state of the client state machine.
27 */
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <search.h>
32 #include <sys/types.h>
33 #include <netinet/in.h>
34 #include <netinet/dhcp.h>
35 #include <netinet/udp.h>
36 #include <netinet/ip_var.h>
37 #include <netinet/udp_var.h>
38 #include <arpa/inet.h>
39 #include <dhcp_hostconf.h>
40 #include <dhcpagent_util.h>
41 #include <dhcpmsg.h>
42
43 #include "states.h"
44 #include "util.h"
63 send_v6_request(dhcp_smach_t *dsmp)
64 {
65 dhcp_pkt_t *dpkt;
66 dhcpv6_ia_na_t d6in;
67
68 dpkt = init_pkt(dsmp, DHCPV6_MSG_REQUEST);
69 (void) add_pkt_opt(dpkt, DHCPV6_OPT_SERVERID, dsmp->dsm_serverid,
70 dsmp->dsm_serveridlen);
71
72 /* Add an IA_NA option for our controlling LIF */
73 d6in.d6in_iaid = htonl(dsmp->dsm_lif->lif_iaid);
74 d6in.d6in_t1 = htonl(0);
75 d6in.d6in_t2 = htonl(0);
76 (void) add_pkt_opt(dpkt, DHCPV6_OPT_IA_NA,
77 (dhcpv6_option_t *)&d6in + 1,
78 sizeof (d6in) - sizeof (dhcpv6_option_t));
79
80 /* Add required Option Request option */
81 (void) add_pkt_prl(dpkt, dsmp);
82
83 /* Add FQDN if configured */
84 (void) dhcp_add_fqdn_opt(dpkt, dsmp);
85
86 (void) send_pkt_v6(dsmp, dpkt, dsmp->dsm_server, stop_requesting,
87 DHCPV6_REQ_TIMEOUT, DHCPV6_REQ_MAX_RT);
88
89 /* For DHCPv6, state switch cannot fail */
90 (void) set_smach_state(dsmp, REQUESTING);
91 }
92
93 /*
94 * server_unicast_option(): determines the server address to use based on the
95 * DHCPv6 Server Unicast option present in the given
96 * packet.
97 *
98 * input: dhcp_smach_t *: the state machine
99 * PKT_LIST *: received packet (Advertisement or Reply)
100 * output: none
101 */
102
103 void
104 server_unicast_option(dhcp_smach_t *dsmp, PKT_LIST *plp)
105 {
300 (void) add_pkt_opt32(dpkt, CD_LEASE_TIME, lease);
301 (void) add_pkt_opt16(dpkt, CD_MAX_DHCP_SIZE,
302 htons(dsmp->dsm_lif->lif_max - sizeof (struct udpiphdr)));
303 (void) add_pkt_opt32(dpkt, CD_REQUESTED_IP_ADDR,
304 offer->pkt->yiaddr.s_addr);
305 (void) add_pkt_opt(dpkt, CD_SERVER_ID,
306 offer->opts[CD_SERVER_ID]->value,
307 offer->opts[CD_SERVER_ID]->len);
308
309 if (class_id_len != 0) {
310 (void) add_pkt_opt(dpkt, CD_CLASS_ID, class_id,
311 class_id_len);
312 }
313 (void) add_pkt_prl(dpkt, dsmp);
314
315 /*
316 * dsm_reqhost was set for this state machine in
317 * dhcp_selecting() if the DF_REQUEST_HOSTNAME option set and a
318 * host name was found
319 */
320 if (dhcp_add_fqdn_opt(dpkt, dsmp) != 0 &&
321 dsmp->dsm_reqhost != NULL) {
322 (void) add_pkt_opt(dpkt, CD_HOSTNAME, dsmp->dsm_reqhost,
323 strlen(dsmp->dsm_reqhost));
324 }
325 (void) add_pkt_opt(dpkt, CD_END, NULL, 0);
326
327 /*
328 * send out the REQUEST, trying retransmissions. either a NAK
329 * or too many REQUEST attempts will revert us to SELECTING.
330 */
331
332 if (!set_smach_state(dsmp, REQUESTING)) {
333 dhcpmsg(MSG_ERROR, "dhcp_requesting: cannot switch to "
334 "REQUESTING state; reverting to INIT on %s",
335 dsmp->dsm_name);
336 goto failure;
337 }
338
339 (void) send_pkt(dsmp, dpkt, htonl(INADDR_BROADCAST),
340 stop_requesting);
341 }
|