1/*	$OpenBSD: dhcp6leased.h,v 1.8 2024/06/06 15:15:44 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
98struct dhcp_hdr {
99	uint8_t		msg_type;	/* Message opcode/type */
100	uint8_t		xid[XID_SIZE];	/* Transaction ID */
101} __packed;
102
103struct dhcp_option_hdr {
104	uint16_t	code;
105	uint16_t	len;
106} __packed;
107
108struct dhcp_duid {
109	uint16_t	type;
110	uint8_t		uuid[UUID_SIZE];
111} __packed;
112
113struct dhcp_iapd {
114	uint32_t	iaid;
115	uint32_t	t1;
116	uint32_t	t2;
117} __packed;
118
119struct dhcp_vendor_class {
120	uint32_t	enterprise_number;
121	uint16_t	vendor_class_len;
122} __packed;
123
124struct dhcp_iaprefix {
125	uint32_t	pltime;
126	uint32_t	vltime;
127	uint8_t		prefix_len;
128	struct in6_addr	prefix;
129} __packed;
130
131struct imsgev {
132	struct imsgbuf	 ibuf;
133	void		(*handler)(int, short, void *);
134	struct event	 ev;
135	short		 events;
136};
137
138struct dhcp_route {
139	struct in_addr		 dst;
140	struct in_addr		 mask;
141	struct in_addr		 gw;
142};
143
144enum 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
178struct prefix {
179	struct in6_addr	 prefix;
180	int		 prefix_len;
181	uint32_t	 vltime;
182	uint32_t	 pltime;
183};
184
185struct 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
197struct 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
204struct 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
211struct 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
219struct dhcp6leased_conf {
220	SIMPLEQ_HEAD(iface_conf_head, iface_conf)	iface_list;
221	int						rapid_commit;
222};
223
224struct 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
232struct imsg_dhcp {
233	uint32_t		if_index;
234	ssize_t			len;
235	uint8_t			packet[1500];
236};
237
238struct 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
247struct imsg_lease_info {
248	uint32_t		 if_index;
249	struct prefix		 pds[MAX_IA];
250};
251
252/* dhcp6leased.c */
253void			 imsg_event_add(struct imsgev *);
254int			 imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
255			     pid_t, int, void *, uint16_t);
256void			 config_clear(struct dhcp6leased_conf *);
257struct dhcp6leased_conf	*config_new_empty(void);
258void			 merge_config(struct dhcp6leased_conf *, struct
259			     dhcp6leased_conf *);
260const char		*sin6_to_str(struct sockaddr_in6 *);
261
262/* engine.c */
263const char		*dhcp_message_type2str(uint8_t);
264
265/* frontend.c */
266struct iface_conf	*find_iface_conf(struct iface_conf_head *, char *);
267int			*changed_ifaces(struct dhcp6leased_conf *, struct
268			     dhcp6leased_conf *);
269/* printconf.c */
270void	print_config(struct dhcp6leased_conf *, int);
271
272/* parse.y */
273struct 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
285struct dhcp6leased_conf	*parse_config(const char *);
286struct file		*pushfile(const char *, int);
287int			 popfile(void);
288int			 kw_cmp(const void *, const void *);
289int			 lgetc(int);
290void			 lungetc(int);
291int			 findeol(void);
292
293/* parse_lease.y */
294void	parse_lease(const char*, struct imsg_ifinfo *);
295