Home | History | Annotate | Line # | Download | only in src
      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 DHCPCD_H
     30 #define DHCPCD_H
     31 
     32 #include <sys/socket.h>
     33 
     34 #include <net/if.h>
     35 
     36 #include <stdio.h>
     37 
     38 #include "config.h"
     39 #include "control.h"
     40 #include "defs.h"
     41 #include "if-options.h"
     42 #include "queue.h"
     43 
     44 #define HWADDR_LEN     20
     45 #define IF_SSIDLEN     32
     46 #define PROFILE_LEN    64
     47 #define SECRET_LEN     64
     48 
     49 #define IF_INACTIVE    0
     50 #define IF_ACTIVE      1
     51 #define IF_ACTIVE_USER 2
     52 
     53 #define LINK_UP	       1
     54 #define LINK_UNKNOWN   0
     55 #define LINK_DOWN      -1
     56 
     57 #define IF_DATA_IPV4   0
     58 #define IF_DATA_ARP    1
     59 #define IF_DATA_IPV4LL 2
     60 #define IF_DATA_DHCP   3
     61 #define IF_DATA_IPV6   4
     62 #define IF_DATA_IPV6ND 5
     63 #define IF_DATA_DHCP6  6
     64 #define IF_DATA_MAX    7
     65 
     66 #ifdef __QNX__
     67 /* QNX carries defines for, but does not actually support PF_LINK */
     68 #undef IFLR_ACTIVE
     69 #endif
     70 
     71 struct interface {
     72 	struct dhcpcd_ctx *ctx;
     73 	TAILQ_ENTRY(interface) next;
     74 	char name[IF_NAMESIZE];
     75 	unsigned int index;
     76 	unsigned int active;
     77 	unsigned int flags;
     78 	uint16_t hwtype; /* ARPHRD_ETHER for example */
     79 	unsigned char hwaddr[HWADDR_LEN];
     80 	uint8_t hwlen;
     81 	int mtu;
     82 	unsigned short vlanid;
     83 	unsigned int metric;
     84 	int carrier;
     85 	bool wireless;
     86 	uint8_t ssid[IF_SSIDLEN];
     87 	unsigned int ssid_len;
     88 
     89 	int argc;
     90 	char **argv;
     91 
     92 	char profile[PROFILE_LEN];
     93 	struct if_options *options;
     94 	void *if_data[IF_DATA_MAX];
     95 };
     96 TAILQ_HEAD(if_head, interface);
     97 
     98 #include "privsep.h"
     99 
    100 /* dhcpcd requires CMSG_SPACE to evaluate to a compile time constant. */
    101 #if defined(__QNX) || \
    102     (defined(__NetBSD_Version__) && __NetBSD_Version__ < 600000000)
    103 #undef CMSG_SPACE
    104 #endif
    105 
    106 #ifndef ALIGNBYTES
    107 #define ALIGNBYTES (sizeof(int) - 1)
    108 #endif
    109 #ifndef ALIGN
    110 #define ALIGN(p) (((unsigned int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
    111 #endif
    112 #ifndef CMSG_SPACE
    113 #define CMSG_SPACE(len) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(len))
    114 #endif
    115 
    116 struct passwd;
    117 
    118 struct dhcpcd_ctx {
    119 	char *pidfile;
    120 	char vendor[256];
    121 	int fork_fd; /* FD for the fork init signal pipe */
    122 	const char *cffile;
    123 	unsigned long long options;
    124 	char *logfile;
    125 	int argc;
    126 	char **argv;
    127 	int ifac;    /* allowed interfaces */
    128 	char **ifav; /* allowed interfaces */
    129 	int ifdc;    /* denied interfaces */
    130 	char **ifdv; /* denied interfaces */
    131 	int ifc;     /* listed interfaces */
    132 	char **ifv;  /* listed interfaces */
    133 	int ifcc;    /* configured interfaces */
    134 	char **ifcv; /* configured interfaces */
    135 	uint8_t duid_type;
    136 	unsigned char *duid;
    137 	size_t duid_len;
    138 	struct if_head *ifaces;
    139 
    140 	char *ctl_buf;
    141 	size_t ctl_buflen;
    142 	size_t ctl_bufpos;
    143 	size_t ctl_extra;
    144 
    145 	rb_tree_t routes; /* our routes */
    146 #ifdef RT_FREE_ROUTE_TABLE
    147 	rb_tree_t froutes; /* free routes for re-use */
    148 #endif
    149 	size_t rt_order; /* route order storage */
    150 
    151 	int pf_inet_fd;
    152 #ifdef PF_LINK
    153 	int pf_link_fd;
    154 #endif
    155 	void *priv;
    156 	int link_fd;
    157 #ifndef SMALL
    158 	int link_rcvbuf;
    159 #endif
    160 	int seq;  /* route message sequence no */
    161 	int sseq; /* successful seq no sent */
    162 
    163 	struct eloop *eloop;
    164 
    165 	char *script;
    166 #ifdef HAVE_OPEN_MEMSTREAM
    167 	FILE *script_fp;
    168 #endif
    169 	char *script_buf;
    170 	size_t script_buflen;
    171 	char **script_env;
    172 	size_t script_envlen;
    173 	void *io_buf;
    174 	size_t io_buflen;
    175 
    176 	int control_fd;
    177 	struct fd_list_head control_fds;
    178 	char control_sock[sizeof(CONTROLSOCKET) + IF_NAMESIZE];
    179 	gid_t read_group;
    180 	gid_t control_group;
    181 
    182 	/* DHCP Enterprise options, RFC3925 */
    183 	struct dhcp_opt *vivso;
    184 	size_t vivso_len;
    185 
    186 	char *randomstate; /* original state */
    187 
    188 	/* For filtering RTM_MISS messages per router */
    189 #ifdef BSD
    190 	uint8_t *rt_missfilter;
    191 	size_t rt_missfilterlen;
    192 	size_t rt_missfiltersize;
    193 #endif
    194 
    195 #ifdef PRIVSEP
    196 	struct passwd *ps_user; /* struct passwd for privsep user */
    197 	struct ps_process_head ps_processes; /* List of spawned processes */
    198 	struct ps_process *ps_root;
    199 	struct ps_process *ps_inet;
    200 	struct ps_process *ps_ctl;
    201 	int ps_data_fd;		    /* data returned from processes */
    202 	int ps_log_fd;		    /* chroot logging */
    203 	int ps_log_root_fd;	    /* outside chroot log reader */
    204 	struct fd_list *ps_control; /* Queue for the above */
    205 	void *ps_buf;		    /* IPC buffer */
    206 	size_t ps_buflen;	    /* IPC buffer length */
    207 	unsigned int ps_control_id; /* Unique monotonic control ID */
    208 #endif
    209 
    210 #ifdef INET
    211 	struct dhcp_opt *dhcp_opts;
    212 	size_t dhcp_opts_len;
    213 
    214 	int udp_rfd;
    215 	int udp_wfd;
    216 
    217 	/* Our aggregate option buffer.
    218 	 * We ONLY use this when options are split, which for most purposes is
    219 	 * practically never. See RFC3396 for details. */
    220 	uint8_t *opt_buffer;
    221 	size_t opt_buffer_len;
    222 #endif
    223 #ifdef INET6
    224 	uint8_t *secret;
    225 	size_t secret_len;
    226 
    227 #ifndef __sun
    228 	int nd_fd;
    229 #endif
    230 	struct ra_head *ra_routers;
    231 
    232 	struct dhcp_opt *nd_opts;
    233 	size_t nd_opts_len;
    234 #ifdef DHCP6
    235 	int dhcp6_rfd;
    236 	int dhcp6_wfd;
    237 	struct dhcp_opt *dhcp6_opts;
    238 	size_t dhcp6_opts_len;
    239 #endif
    240 
    241 #ifndef __linux__
    242 	int ra_global;
    243 #endif
    244 #endif /* INET6 */
    245 
    246 #ifdef PLUGIN_DEV
    247 	char *dev_load;
    248 	int dev_fd;
    249 	struct dev *dev;
    250 	void *dev_handle;
    251 #endif
    252 };
    253 
    254 #ifdef USE_SIGNALS
    255 extern const int dhcpcd_signals[];
    256 extern const size_t dhcpcd_signals_len;
    257 extern const int dhcpcd_signals_ignore[];
    258 extern const size_t dhcpcd_signals_ignore_len;
    259 #endif
    260 
    261 extern const char *dhcpcd_default_script;
    262 
    263 int dhcpcd_ifafwaiting(const struct interface *);
    264 int dhcpcd_afwaiting(const struct dhcpcd_ctx *);
    265 void dhcpcd_daemonised(struct dhcpcd_ctx *);
    266 void dhcpcd_daemonise(struct dhcpcd_ctx *);
    267 
    268 void dhcpcd_linkoverflow(struct dhcpcd_ctx *);
    269 ssize_t dhcpcd_handleargs(struct dhcpcd_ctx *, struct fd_list *, int, char **);
    270 void dhcpcd_handlecarrier(struct interface *, int, unsigned int);
    271 int dhcpcd_handleinterface(void *, int, const char *);
    272 void dhcpcd_handlehwaddr(struct interface *, uint16_t, const void *, uint8_t);
    273 void dhcpcd_dropinterface(struct interface *, const char *);
    274 void dhcpcd_dropped(struct interface *);
    275 int dhcpcd_selectprofile(struct interface *, const char *);
    276 
    277 void dhcpcd_startinterface(void *);
    278 void dhcpcd_activateinterface(struct interface *, unsigned long long);
    279 
    280 #endif
    281