xref: /openbsd/sbin/dhcp6leased/dhcp6leased.h (revision 7571100d)
1 /*	$OpenBSD: dhcp6leased.h,v 1.9 2024/07/10 12:44:46 florian Exp $	*/
2 
3 /*
4  * Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
5  * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
6  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #ifndef nitems
22 #define	nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
23 #endif
24 
25 #define	_PATH_LOCKFILE		"/dev/dhcp6leased.lock"
26 #define	_PATH_CONF_FILE		"/etc/dhcp6leased.conf"
27 #define	_PATH_CTRL_SOCKET	"/dev/dhcp6leased.sock"
28 #define	DHCP6LEASED_USER	"_dhcp6leased"
29 #define	DHCP6LEASED_RTA_LABEL	"dhcp6leased"
30 #define	CLIENT_PORT		546
31 #define	SERVER_PORT		547
32 #define	_PATH_LEASE		"/var/db/dhcp6leased/"
33 #define	_PATH_UUID		_PATH_LEASE"uuid"
34 #define	UUID_SIZE		16
35 #define UUID_STR_SIZE		sizeof("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n")
36 #define	DUID_UUID_TYPE		4
37 #define	XID_SIZE		3
38 #define	SERVERID_SIZE		130 /* 2 octet type, max 128 octets data */
39 #define	MAX_IA			32
40 #define	LEASE_SIZE		4096
41 #define	LEASE_IA_PD_PREFIX	"ia_pd "
42 /* MAXDNAME from arpa/namesr.h */
43 #define	DHCP6LEASED_MAX_DNSSL	1025
44 #define	MAX_RDNS_COUNT		8 /* max nameserver in a RTM_PROPOSAL */
45 
46 /* A 1500 bytes packet can hold less than 300 classless static routes */
47 #define	MAX_DHCP_ROUTES		256
48 
49 #define	OPENBSD_ENTERPRISENO	30155
50 
51 /* DHCP message types. */
52 #define	DHCPSOLICIT		1
53 #define	DHCPADVERTISE		2
54 #define	DHCPREQUEST		3
55 #define	DHCPCONFIRM		4
56 #define	DHCPRENEW		5
57 #define	DHCPREBIND		6
58 #define	DHCPREPLY		7
59 #define	DHCPRELEASE		8
60 #define	DHCPDECLINE		9
61 #define	DHCPRECONFIGURE		10
62 #define	DHCPINFORMATIONREQUEST	11
63 #define	DHCPRELAYFORW		12
64 #define	DHCPRELAYREPL		13
65 
66 /* DHCP options */
67 #define	DHO_CLIENTID		1
68 #define	DHO_SERVERID		2
69 #define	DHO_ORO			6
70 #define	DHO_ELAPSED_TIME	8
71 #define	DHO_STATUS_CODE		13
72 #define	DHO_RAPID_COMMIT	14
73 #define	DHO_VENDOR_CLASS	16
74 #define	DHO_IA_PD		25
75 #define	DHO_IA_PREFIX		26
76 #define	DHO_SOL_MAX_RT		82
77 #define	DHO_INF_MAX_RT		83
78 
79 /* Status Code Option status codes */
80 #define	DHCP_STATUS_SUCCESS		0
81 #define	DHCP_STATUS_UNSPECFAIL		1
82 #define	DHCP_STATUS_NOADDRSAVAIL	2
83 #define	DHCP_STATUS_NOBINDING		3
84 #define	DHCP_STATUS_NOTONLINK		4
85 #define	DHCP_STATUS_USEMULTICAST	5
86 #define	DHCP_STATUS_NOPREFIXAVAIL	6
87 
88 /* Ignore parts of DHCP lease */
89 #define	IGN_ROUTES	1
90 #define	IGN_DNS		2
91 
92 #define	MAX_SERVERS	16	/* max servers that can be ignored per if */
93 
94 #define	IMSG_DATA_SIZE(imsg)	((imsg).hdr.len - IMSG_HEADER_SIZE)
95 #define	DHCP_SNAME_LEN		64
96 #define	DHCP_FILE_LEN		128
97 
98 struct dhcp_hdr {
99 	uint8_t		msg_type;	/* Message opcode/type */
100 	uint8_t		xid[XID_SIZE];	/* Transaction ID */
101 } __packed;
102 
103 struct dhcp_option_hdr {
104 	uint16_t	code;
105 	uint16_t	len;
106 } __packed;
107 
108 struct dhcp_duid {
109 	uint16_t	type;
110 	uint8_t		uuid[UUID_SIZE];
111 } __packed;
112 
113 struct dhcp_iapd {
114 	uint32_t	iaid;
115 	uint32_t	t1;
116 	uint32_t	t2;
117 } __packed;
118 
119 struct dhcp_vendor_class {
120 	uint32_t	enterprise_number;
121 	uint16_t	vendor_class_len;
122 } __packed;
123 
124 struct dhcp_iaprefix {
125 	uint32_t	pltime;
126 	uint32_t	vltime;
127 	uint8_t		prefix_len;
128 	struct in6_addr	prefix;
129 } __packed;
130 
131 struct imsgev {
132 	struct imsgbuf	 ibuf;
133 	void		(*handler)(int, short, void *);
134 	struct event	 ev;
135 	short		 events;
136 };
137 
138 struct dhcp_route {
139 	struct in_addr		 dst;
140 	struct in_addr		 mask;
141 	struct in_addr		 gw;
142 };
143 
144 enum imsg_type {
145 	IMSG_NONE,
146 	IMSG_CTL_LOG_VERBOSE,
147 	IMSG_CTL_SHOW_INTERFACE_INFO,
148 	IMSG_CTL_SEND_REQUEST,
149 	IMSG_CTL_RELOAD,
150 	IMSG_CTL_END,
151 	IMSG_RECONF_CONF,
152 	IMSG_RECONF_IFACE,
153 	IMSG_RECONF_IFACE_IA,
154 	IMSG_RECONF_IFACE_PD,
155 	IMSG_RECONF_IFACE_IA_END,
156 	IMSG_RECONF_IFACE_END,
157 	IMSG_RECONF_END,
158 	IMSG_SEND_SOLICIT,
159 	IMSG_SEND_REQUEST,
160 	IMSG_SEND_RENEW,
161 	IMSG_SEND_REBIND,
162 	IMSG_SOCKET_IPC,
163 	IMSG_OPEN_UDPSOCK,
164 	IMSG_UDPSOCK,
165 	IMSG_ROUTESOCK,
166 	IMSG_UUID,
167 	IMSG_CONTROLFD,
168 	IMSG_STARTUP,
169 	IMSG_UPDATE_IF,
170 	IMSG_REMOVE_IF,
171 	IMSG_DHCP,
172 	IMSG_CONFIGURE_ADDRESS,
173 	IMSG_DECONFIGURE_ADDRESS,
174 	IMSG_REQUEST_REBOOT,
175 	IMSG_WRITE_LEASE,
176 };
177 
178 struct prefix {
179 	struct in6_addr	 prefix;
180 	int		 prefix_len;
181 	uint32_t	 vltime;
182 	uint32_t	 pltime;
183 };
184 
185 struct ctl_engine_info {
186 	uint32_t		if_index;
187 	int			running;
188 	int			link_state;
189 	char			state[sizeof("IF_INIT_REBOOT")];
190 	struct timespec		request_time;
191 	uint32_t		lease_time;
192 	uint32_t		t1;
193 	uint32_t		t2;
194 	struct prefix		pds[MAX_IA];
195 };
196 
197 struct iface_pd_conf {
198 	SIMPLEQ_ENTRY(iface_pd_conf)	 entry;
199 	char				 name[IF_NAMESIZE];
200 	struct in6_addr			 prefix_mask;
201 	int				 prefix_len;
202 };
203 
204 struct iface_ia_conf {
205 	SIMPLEQ_ENTRY(iface_ia_conf)			 entry;
206 	SIMPLEQ_HEAD(iface_pd_conf_head, iface_pd_conf)	 iface_pd_list;
207 	int						 id;
208 	int						 prefix_len;
209 };
210 
211 struct iface_conf {
212 	SIMPLEQ_ENTRY(iface_conf)		 entry;
213 	SIMPLEQ_HEAD(iface_ia_conf_head,
214 	    iface_ia_conf)			 iface_ia_list;
215 	uint32_t				 ia_count;
216 	char					 name[IF_NAMESIZE];
217 };
218 
219 struct dhcp6leased_conf {
220 	SIMPLEQ_HEAD(iface_conf_head, iface_conf)	iface_list;
221 	int						rapid_commit;
222 };
223 
224 struct imsg_ifinfo {
225 	uint32_t		if_index;
226 	int			rdomain;
227 	int			running;
228 	int			link_state;
229 	struct prefix		pds[MAX_IA];
230 };
231 
232 struct imsg_dhcp {
233 	uint32_t		if_index;
234 	ssize_t			len;
235 	uint8_t			packet[1500];
236 };
237 
238 struct imsg_req_dhcp {
239 	uint32_t		 if_index;
240 	int			 elapsed_time;
241 	uint8_t			 xid[XID_SIZE];
242 	int			 serverid_len;
243 	uint8_t			 serverid[SERVERID_SIZE];
244 	struct prefix		 pds[MAX_IA];
245 };
246 
247 struct imsg_lease_info {
248 	uint32_t		 if_index;
249 	struct prefix		 pds[MAX_IA];
250 };
251 
252 /* dhcp6leased.c */
253 void			 imsg_event_add(struct imsgev *);
254 int			 imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
255 			     pid_t, int, void *, uint16_t);
256 void			 config_clear(struct dhcp6leased_conf *);
257 struct dhcp6leased_conf	*config_new_empty(void);
258 void			 merge_config(struct dhcp6leased_conf *, struct
259 			     dhcp6leased_conf *);
260 const char		*sin6_to_str(struct sockaddr_in6 *);
261 
262 /* engine.c */
263 const char		*dhcp_message_type2str(int);
264 
265 /* frontend.c */
266 struct iface_conf	*find_iface_conf(struct iface_conf_head *, char *);
267 int			*changed_ifaces(struct dhcp6leased_conf *, struct
268 			     dhcp6leased_conf *);
269 /* printconf.c */
270 void	print_config(struct dhcp6leased_conf *, int);
271 
272 /* parse.y */
273 struct file {
274 	TAILQ_ENTRY(file)	 entry;
275 	FILE			*stream;
276 	char			*name;
277 	size_t			 ungetpos;
278 	size_t			 ungetsize;
279 	u_char			*ungetbuf;
280 	int			 eof_reached;
281 	int			 lineno;
282 	int			 errors;
283 };
284 
285 struct dhcp6leased_conf	*parse_config(const char *);
286 struct file		*pushfile(const char *, int);
287 int			 popfile(void);
288 int			 kw_cmp(const void *, const void *);
289 int			 lgetc(int);
290 void			 lungetc(int);
291 int			 findeol(void);
292 
293 /* parse_lease.y */
294 void	parse_lease(const char*, struct imsg_ifinfo *);
295