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