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