| 1 | /* | 
| 2 |  * dhcpcd - DHCP client daemon | 
| 3 |  * Copyright (c) 2006-2019 Roy Marples <roy@marples.name> | 
| 4 |  * All rights reserved | 
| 5 |  | 
| 6 |  * Redistribution and use in source and binary forms, with or without | 
| 7 |  * modification, are permitted provided that the following conditions | 
| 8 |  * are met: | 
| 9 |  * 1. Redistributions of source code must retain the above copyright | 
| 10 |  *    notice, this list of conditions and the following disclaimer. | 
| 11 |  * 2. Redistributions in binary form must reproduce the above copyright | 
| 12 |  *    notice, this list of conditions and the following disclaimer in the | 
| 13 |  *    documentation and/or other materials provided with the distribution. | 
| 14 |  * | 
| 15 |  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | 
| 16 |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
| 17 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
| 18 |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 
| 19 |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
| 20 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
| 21 |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
| 22 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
| 23 |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
| 24 |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
| 25 |  * SUCH DAMAGE. | 
| 26 |  */ | 
| 27 |  | 
| 28 | #ifndef DHCP6_H | 
| 29 | #define DHCP6_H | 
| 30 |  | 
| 31 | #include "dhcpcd.h" | 
| 32 |  | 
| 33 | #define IN6ADDR_LINKLOCAL_ALLDHCP_INIT \ | 
| 34 | 	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ | 
| 35 | 	    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 }}} | 
| 36 |  | 
| 37 | /* UDP port numbers for DHCP */ | 
| 38 | #define DHCP6_CLIENT_PORT	546 | 
| 39 | #define DHCP6_SERVER_PORT	547 | 
| 40 |  | 
| 41 | /* DHCP message type */ | 
| 42 | #define DHCP6_SOLICIT		1 | 
| 43 | #define DHCP6_ADVERTISE		2 | 
| 44 | #define DHCP6_REQUEST		3 | 
| 45 | #define DHCP6_CONFIRM		4 | 
| 46 | #define DHCP6_RENEW		5 | 
| 47 | #define DHCP6_REBIND		6 | 
| 48 | #define DHCP6_REPLY		7 | 
| 49 | #define DHCP6_RELEASE		8 | 
| 50 | #define DHCP6_DECLINE		9 | 
| 51 | #define DHCP6_RECONFIGURE	10 | 
| 52 | #define DHCP6_INFORMATION_REQ	11 | 
| 53 | #define DHCP6_RELAY_FLOW	12 | 
| 54 | #define DHCP6_RELAY_REPL	13 | 
| 55 | #define DHCP6_RECONFIGURE_REQ	18 | 
| 56 | #define DHCP6_RECONFIGURE_REPLY	19 | 
| 57 |  | 
| 58 | #ifdef DHCP6 | 
| 59 |  | 
| 60 | #define D6_OPTION_CLIENTID		1 | 
| 61 | #define D6_OPTION_SERVERID		2 | 
| 62 | #define D6_OPTION_IA_NA			3 | 
| 63 | #define D6_OPTION_IA_TA			4 | 
| 64 | #define D6_OPTION_ORO			6 | 
| 65 | #define D6_OPTION_IA_ADDR		5 | 
| 66 | #define D6_OPTION_PREFERENCE		7 | 
| 67 | #define D6_OPTION_ELAPSED		8 | 
| 68 | #define D6_OPTION_AUTH			11 | 
| 69 | #define D6_OPTION_UNICAST		12 | 
| 70 | #define D6_OPTION_STATUS_CODE		13 | 
| 71 | #define D6_OPTION_RAPID_COMMIT		14 | 
| 72 | #define D6_OPTION_USER_CLASS		15 | 
| 73 | #define D6_OPTION_VENDOR_CLASS		16 | 
| 74 | #define D6_OPTION_VENDOR_OPTS		17 | 
| 75 | #define D6_OPTION_INTERFACE_ID		18 | 
| 76 | #define D6_OPTION_RECONF_MSG		19 | 
| 77 | #define D6_OPTION_RECONF_ACCEPT		20 | 
| 78 | #define D6_OPTION_SIP_SERVERS_NAME	21 | 
| 79 | #define D6_OPTION_SIP_SERVERS_ADDRESS	22 | 
| 80 | #define D6_OPTION_DNS_SERVERS		23 | 
| 81 | #define D6_OPTION_DOMAIN_LIST		24 | 
| 82 | #define D6_OPTION_IA_PD			25 | 
| 83 | #define D6_OPTION_IAPREFIX		26 | 
| 84 | #define D6_OPTION_NIS_SERVERS		27 | 
| 85 | #define D6_OPTION_NISP_SERVERS		28 | 
| 86 | #define D6_OPTION_NIS_DOMAIN_NAME	29 | 
| 87 | #define D6_OPTION_NISP_DOMAIN_NAME	30 | 
| 88 | #define D6_OPTION_SNTP_SERVERS		31 | 
| 89 | #define D6_OPTION_INFO_REFRESH_TIME	32 | 
| 90 | #define D6_OPTION_BCMS_SERVER_D		33 | 
| 91 | #define D6_OPTION_BCMS_SERVER_A		34 | 
| 92 | #define D6_OPTION_FQDN			39 | 
| 93 | #define D6_OPTION_POSIX_TIMEZONE	41 | 
| 94 | #define D6_OPTION_TZDB_TIMEZONE		42 | 
| 95 | #define D6_OPTION_PD_EXCLUDE		67 | 
| 96 | #define D6_OPTION_SOL_MAX_RT		82 | 
| 97 | #define D6_OPTION_INF_MAX_RT		83 | 
| 98 | #define	D6_OPTION_MUDURL		112 | 
| 99 |  | 
| 100 | #define D6_FQDN_PTR	0x00 | 
| 101 | #define D6_FQDN_BOTH	0x01 | 
| 102 | #define D6_FQDN_NONE	0x04 | 
| 103 |  | 
| 104 | #include "dhcp.h" | 
| 105 | #include "ipv6.h" | 
| 106 |  | 
| 107 | #define D6_STATUS_OK		0 | 
| 108 | #define D6_STATUS_FAIL		1 | 
| 109 | #define D6_STATUS_NOADDR	2 | 
| 110 | #define D6_STATUS_NOBINDING	3 | 
| 111 | #define D6_STATUS_NOTONLINK	4 | 
| 112 | #define D6_STATUS_USEMULTICAST	5 | 
| 113 |  | 
| 114 | #define	SOL_MAX_DELAY		1 | 
| 115 | #define	SOL_TIMEOUT		1 | 
| 116 | #define	SOL_MAX_RT		3600 /* RFC7083 */ | 
| 117 | #define	SOL_MAX_RC		0 | 
| 118 | #define	REQ_MAX_DELAY		0 | 
| 119 | #define	REQ_TIMEOUT		1 | 
| 120 | #define	REQ_MAX_RT		30 | 
| 121 | #define	REQ_MAX_RC		10 | 
| 122 | #define	CNF_MAX_DELAY		1 | 
| 123 | #define	CNF_TIMEOUT		1 | 
| 124 | #define	CNF_MAX_RT		4 | 
| 125 | #define	CNF_MAX_RC		0 | 
| 126 | #define	CNF_MAX_RD		10 | 
| 127 | #define	REN_MAX_DELAY		0 | 
| 128 | #define	REN_TIMEOUT		10 | 
| 129 | #define	REN_MAX_RT		600 | 
| 130 | #define	REB_MAX_DELAY		0 | 
| 131 | #define	REB_TIMEOUT		10 | 
| 132 | #define	REB_MAX_RT		600 | 
| 133 | #define	INF_MAX_DELAY		1 | 
| 134 | #define	INF_TIMEOUT		1 | 
| 135 | #define	INF_MAX_RD		CNF_MAX_RD /* NOT RFC defined */ | 
| 136 | #define	INF_MAX_RT		3600 /* RFC7083 */ | 
| 137 | #define	REL_MAX_DELAY		0 | 
| 138 | #define	REL_TIMEOUT		1 | 
| 139 | #define	REL_MAX_RT		0 | 
| 140 | #define	REL_MAX_RC		5 | 
| 141 | #define	DEC_MAX_DELAY		0 | 
| 142 | #define	DEC_TIMEOUT		1 | 
| 143 | #define	DEC_MAX_RC		5 | 
| 144 | #define	REC_MAX_DELAY		0 | 
| 145 | #define	REC_TIMEOUT		2 | 
| 146 | #define	REC_MAX_RC		8 | 
| 147 | #define	HOP_COUNT_LIMIT		32 | 
| 148 |  | 
| 149 | /* RFC4242 3.1 */ | 
| 150 | #define IRT_DEFAULT		86400 | 
| 151 | #define IRT_MINIMUM		600 | 
| 152 |  | 
| 153 | #define DHCP6_RAND_MIN		-100 | 
| 154 | #define DHCP6_RAND_MAX		100 | 
| 155 |  | 
| 156 | enum DH6S { | 
| 157 | 	DH6S_INIT, | 
| 158 | 	DH6S_DISCOVER, | 
| 159 | 	DH6S_REQUEST, | 
| 160 | 	DH6S_BOUND, | 
| 161 | 	DH6S_RENEW, | 
| 162 | 	DH6S_REBIND, | 
| 163 | 	DH6S_CONFIRM, | 
| 164 | 	DH6S_INFORM, | 
| 165 | 	DH6S_INFORMED, | 
| 166 | 	DH6S_RENEW_REQUESTED, | 
| 167 | 	DH6S_PROBE, | 
| 168 | 	DH6S_DELEGATED, | 
| 169 | 	DH6S_TIMEDOUT, | 
| 170 | 	DH6S_ITIMEDOUT, | 
| 171 | 	DH6S_RELEASE, | 
| 172 | 	DH6S_RELEASED | 
| 173 | }; | 
| 174 |  | 
| 175 | struct dhcp6_state { | 
| 176 | 	enum DH6S state; | 
| 177 | 	struct timespec started; | 
| 178 |  | 
| 179 | 	/* Message retransmission timings */ | 
| 180 | 	struct timespec RT; | 
| 181 | 	unsigned int IMD; | 
| 182 | 	unsigned int RTC; | 
| 183 | 	time_t IRT; | 
| 184 | 	unsigned int MRC; | 
| 185 | 	time_t MRT; | 
| 186 | 	void (*MRCcallback)(void *); | 
| 187 | 	time_t sol_max_rt; | 
| 188 | 	time_t inf_max_rt; | 
| 189 |  | 
| 190 | 	struct dhcp6_message *send; | 
| 191 | 	size_t send_len; | 
| 192 | 	struct dhcp6_message *recv; | 
| 193 | 	size_t recv_len; | 
| 194 | 	struct dhcp6_message *new; | 
| 195 | 	size_t new_len; | 
| 196 | 	struct dhcp6_message *old; | 
| 197 | 	size_t old_len; | 
| 198 |  | 
| 199 | 	struct timespec acquired; | 
| 200 | 	uint32_t renew; | 
| 201 | 	uint32_t rebind; | 
| 202 | 	uint32_t expire; | 
| 203 | 	struct in6_addr unicast; | 
| 204 | 	struct ipv6_addrhead addrs; | 
| 205 | 	uint32_t lowpl; | 
| 206 | 	/* The +3 is for the possible .pd extension for prefix delegation */ | 
| 207 | 	char leasefile[sizeof(LEASEFILE6) + IF_NAMESIZE + (IF_SSIDLEN * 4) +3]; | 
| 208 | 	const char *reason; | 
| 209 | 	uint16_t lerror; /* Last error received from DHCPv6 reply. */ | 
| 210 | 	struct authstate auth; | 
| 211 | }; | 
| 212 |  | 
| 213 | #define D6_STATE(ifp)							       \ | 
| 214 | 	((struct dhcp6_state *)(ifp)->if_data[IF_DATA_DHCP6]) | 
| 215 | #define D6_CSTATE(ifp)							       \ | 
| 216 | 	((const struct dhcp6_state *)(ifp)->if_data[IF_DATA_DHCP6]) | 
| 217 | #define D6_STATE_RUNNING(ifp)						       \ | 
| 218 | 	(D6_CSTATE((ifp)) &&						       \ | 
| 219 | 	D6_CSTATE((ifp))->reason && dhcp6_dadcompleted((ifp))) | 
| 220 |  | 
| 221 | void dhcp6_printoptions(const struct dhcpcd_ctx *, | 
| 222 |     const struct dhcp_opt *, size_t); | 
| 223 | const struct ipv6_addr *dhcp6_iffindaddr(const struct interface *ifp, | 
| 224 |     const struct in6_addr *addr, unsigned int flags); | 
| 225 | struct ipv6_addr *dhcp6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *, | 
| 226 |     unsigned int); | 
| 227 | size_t dhcp6_find_delegates(struct interface *); | 
| 228 | int dhcp6_start(struct interface *, enum DH6S); | 
| 229 | void dhcp6_reboot(struct interface *); | 
| 230 | void dhcp6_renew(struct interface *); | 
| 231 | ssize_t dhcp6_env(char **, const char *, const struct interface *, | 
| 232 |     const struct dhcp6_message *, size_t); | 
| 233 | void dhcp6_free(struct interface *); | 
| 234 | void dhcp6_handleifa(int, struct ipv6_addr *, pid_t); | 
| 235 | int dhcp6_dadcompleted(const struct interface *); | 
| 236 | void dhcp6_abort(struct interface *); | 
| 237 | void dhcp6_drop(struct interface *, const char *); | 
| 238 | int dhcp6_dump(struct interface *); | 
| 239 | #endif /* DHCP6 */ | 
| 240 |  | 
| 241 | #endif /* DHCP6_H */ | 
| 242 |  |