1147072Sbrooks/*	$OpenBSD: dhcpd.h,v 1.33 2004/05/06 22:29:15 deraadt Exp $	*/
2147072Sbrooks
3147072Sbrooks/*
4147072Sbrooks * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
5147072Sbrooks * Copyright (c) 1995, 1996, 1997, 1998, 1999
6147072Sbrooks * The Internet Software Consortium.    All rights reserved.
7147072Sbrooks *
8147072Sbrooks * Redistribution and use in source and binary forms, with or without
9147072Sbrooks * modification, are permitted provided that the following conditions
10147072Sbrooks * are met:
11147072Sbrooks *
12147072Sbrooks * 1. Redistributions of source code must retain the above copyright
13147072Sbrooks *    notice, this list of conditions and the following disclaimer.
14147072Sbrooks * 2. Redistributions in binary form must reproduce the above copyright
15147072Sbrooks *    notice, this list of conditions and the following disclaimer in the
16147072Sbrooks *    documentation and/or other materials provided with the distribution.
17147072Sbrooks * 3. Neither the name of The Internet Software Consortium nor the names
18147072Sbrooks *    of its contributors may be used to endorse or promote products derived
19147072Sbrooks *    from this software without specific prior written permission.
20147072Sbrooks *
21147072Sbrooks * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
22147072Sbrooks * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23147072Sbrooks * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24147072Sbrooks * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25147072Sbrooks * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
26147072Sbrooks * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27147072Sbrooks * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28147072Sbrooks * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29147072Sbrooks * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30147072Sbrooks * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31147072Sbrooks * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32147072Sbrooks * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33147072Sbrooks * SUCH DAMAGE.
34147072Sbrooks *
35147072Sbrooks * This software has been written for the Internet Software Consortium
36147072Sbrooks * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
37147072Sbrooks * Enterprises.  To learn more about the Internet Software Consortium,
38147072Sbrooks * see ``http://www.vix.com/isc''.  To learn more about Vixie
39147072Sbrooks * Enterprises, see ``http://www.vix.com''.
40198352Sphilip *
41198352Sphilip * $FreeBSD$
42147072Sbrooks */
43147072Sbrooks
44226345Sdes#include <sys/param.h>
45147072Sbrooks
46147072Sbrooks#include <sys/socket.h>
47147072Sbrooks#include <sys/sockio.h>
48147072Sbrooks#include <sys/stat.h>
49147072Sbrooks#include <sys/time.h>
50147072Sbrooks#include <sys/un.h>
51147072Sbrooks#include <sys/wait.h>
52147072Sbrooks
53147072Sbrooks#include <net/if.h>
54147072Sbrooks#include <net/if_dl.h>
55147072Sbrooks#include <net/route.h>
56147072Sbrooks
57147072Sbrooks#include <netinet/in.h>
58147072Sbrooks#include <arpa/inet.h>
59147072Sbrooks
60147072Sbrooks#include <ctype.h>
61147072Sbrooks#include <errno.h>
62147072Sbrooks#include <fcntl.h>
63226345Sdes#include <libutil.h>
64147072Sbrooks#include <limits.h>
65147072Sbrooks#include <netdb.h>
66147072Sbrooks#include <paths.h>
67147072Sbrooks#include <unistd.h>
68147072Sbrooks#include <stdarg.h>
69147072Sbrooks#include <stdio.h>
70147072Sbrooks#include <stdlib.h>
71147072Sbrooks#include <string.h>
72147072Sbrooks#include <syslog.h>
73147072Sbrooks#include <time.h>
74147072Sbrooks#include <unistd.h>
75147072Sbrooks
76147072Sbrooks#include "dhcp.h"
77147072Sbrooks#include "tree.h"
78147072Sbrooks
79147072Sbrooks#define	LOCAL_PORT	68
80147072Sbrooks#define	REMOTE_PORT	67
81147072Sbrooks
82147072Sbrooksstruct option_data {
83147072Sbrooks	int		 len;
84147072Sbrooks	u_int8_t	*data;
85147072Sbrooks};
86147072Sbrooks
87147072Sbrooksstruct string_list {
88147072Sbrooks	struct string_list	*next;
89147072Sbrooks	char			*string;
90147072Sbrooks};
91147072Sbrooks
92147072Sbrooksstruct iaddr {
93147072Sbrooks	int len;
94147072Sbrooks	unsigned char iabuf[16];
95147072Sbrooks};
96147072Sbrooks
97147072Sbrooksstruct iaddrlist {
98147072Sbrooks	struct iaddrlist *next;
99147072Sbrooks	struct iaddr addr;
100147072Sbrooks};
101147072Sbrooks
102147072Sbrooksstruct packet {
103147072Sbrooks	struct dhcp_packet	*raw;
104147072Sbrooks	int			 packet_length;
105147072Sbrooks	int			 packet_type;
106147072Sbrooks	int			 options_valid;
107147072Sbrooks	int			 client_port;
108147072Sbrooks	struct iaddr		 client_addr;
109147072Sbrooks	struct interface_info	*interface;
110147072Sbrooks	struct hardware		*haddr;
111147072Sbrooks	struct option_data	 options[256];
112147072Sbrooks};
113147072Sbrooks
114147072Sbrooksstruct hardware {
115147072Sbrooks	u_int8_t htype;
116147072Sbrooks	u_int8_t hlen;
117147072Sbrooks	u_int8_t haddr[16];
118147072Sbrooks};
119147072Sbrooks
120147072Sbrooksstruct client_lease {
121147072Sbrooks	struct client_lease	*next;
122147072Sbrooks	time_t			 expiry, renewal, rebind;
123147072Sbrooks	struct iaddr		 address;
124252506Sbms	struct iaddr		 nextserver;
125147072Sbrooks	char			*server_name;
126147072Sbrooks	char			*filename;
127147072Sbrooks	struct string_list	*medium;
128147072Sbrooks	unsigned int		 is_static : 1;
129147072Sbrooks	unsigned int		 is_bootp : 1;
130147072Sbrooks	struct option_data	 options[256];
131147072Sbrooks};
132147072Sbrooks
133147072Sbrooks/* Possible states in which the client can be. */
134147072Sbrooksenum dhcp_state {
135147072Sbrooks	S_REBOOTING,
136147072Sbrooks	S_INIT,
137147072Sbrooks	S_SELECTING,
138147072Sbrooks	S_REQUESTING,
139147072Sbrooks	S_BOUND,
140147072Sbrooks	S_RENEWING,
141147072Sbrooks	S_REBINDING
142147072Sbrooks};
143147072Sbrooks
144147072Sbrooksstruct client_config {
145147072Sbrooks	struct option_data	defaults[256];
146147072Sbrooks	enum {
147147072Sbrooks		ACTION_DEFAULT,
148147072Sbrooks		ACTION_SUPERSEDE,
149147072Sbrooks		ACTION_PREPEND,
150147072Sbrooks		ACTION_APPEND
151147072Sbrooks	} default_actions[256];
152147072Sbrooks
153147072Sbrooks	struct option_data	 send_options[256];
154147072Sbrooks	u_int8_t		 required_options[256];
155147072Sbrooks	u_int8_t		 requested_options[256];
156147072Sbrooks	int			 requested_option_count;
157147072Sbrooks	time_t			 timeout;
158147072Sbrooks	time_t			 initial_interval;
159147072Sbrooks	time_t			 retry_interval;
160147072Sbrooks	time_t			 select_interval;
161147072Sbrooks	time_t			 reboot_timeout;
162147072Sbrooks	time_t			 backoff_cutoff;
163147072Sbrooks	struct string_list	*media;
164147072Sbrooks	char			*script_name;
165147072Sbrooks	enum { IGNORE, ACCEPT, PREFER }
166147072Sbrooks				 bootp_policy;
167147072Sbrooks	struct string_list	*medium;
168147072Sbrooks	struct iaddrlist	*reject_list;
169147072Sbrooks};
170147072Sbrooks
171147072Sbrooksstruct client_state {
172147072Sbrooks	struct client_lease	 *active;
173147072Sbrooks	struct client_lease	 *new;
174147072Sbrooks	struct client_lease	 *offered_leases;
175147072Sbrooks	struct client_lease	 *leases;
176147072Sbrooks	struct client_lease	 *alias;
177147072Sbrooks	enum dhcp_state		  state;
178147072Sbrooks	struct iaddr		  destination;
179147072Sbrooks	u_int32_t		  xid;
180147072Sbrooks	u_int16_t		  secs;
181147072Sbrooks	time_t			  first_sending;
182147072Sbrooks	time_t			  interval;
183147072Sbrooks	struct string_list	 *medium;
184147072Sbrooks	struct dhcp_packet	  packet;
185147072Sbrooks	int			  packet_length;
186147072Sbrooks	struct iaddr		  requested_address;
187147072Sbrooks	struct client_config	 *config;
188147072Sbrooks	char			**scriptEnv;
189147072Sbrooks	int			  scriptEnvsize;
190147072Sbrooks	struct string_list	 *env;
191147072Sbrooks	int			  envc;
192147072Sbrooks};
193147072Sbrooks
194147072Sbrooksstruct interface_info {
195147072Sbrooks	struct interface_info	*next;
196147072Sbrooks	struct hardware		 hw_address;
197147072Sbrooks	struct in_addr		 primary_address;
198147072Sbrooks	char			 name[IFNAMSIZ];
199147072Sbrooks	int			 rfdesc;
200147072Sbrooks	int			 wfdesc;
201198352Sphilip	int			 ufdesc;
202147072Sbrooks	unsigned char		*rbuf;
203147072Sbrooks	size_t			 rbuf_max;
204147072Sbrooks	size_t			 rbuf_offset;
205147072Sbrooks	size_t			 rbuf_len;
206147072Sbrooks	struct ifreq		*ifp;
207147072Sbrooks	struct client_state	*client;
208147072Sbrooks	int			 noifmedia;
209147072Sbrooks	int			 errors;
210147072Sbrooks	int			 dead;
211147072Sbrooks	u_int16_t		 index;
212239564Sjhb	int			 linkstat;
213147072Sbrooks};
214147072Sbrooks
215147072Sbrooksstruct timeout {
216147072Sbrooks	struct timeout	*next;
217147072Sbrooks	time_t		 when;
218147072Sbrooks	void		 (*func)(void *);
219147072Sbrooks	void		*what;
220147072Sbrooks};
221147072Sbrooks
222147072Sbrooksstruct protocol {
223147072Sbrooks	struct protocol	*next;
224147072Sbrooks	int fd;
225147072Sbrooks	void (*handler)(struct protocol *);
226147072Sbrooks	void *local;
227147072Sbrooks};
228147072Sbrooks
229147072Sbrooks#define DEFAULT_HASH_SIZE 97
230147072Sbrooks
231147072Sbrooksstruct hash_bucket {
232147072Sbrooks	struct hash_bucket *next;
233147072Sbrooks	unsigned char *name;
234147072Sbrooks	int len;
235147072Sbrooks	unsigned char *value;
236147072Sbrooks};
237147072Sbrooks
238147072Sbrooksstruct hash_table {
239147072Sbrooks	int hash_count;
240147072Sbrooks	struct hash_bucket *buckets[DEFAULT_HASH_SIZE];
241147072Sbrooks};
242147072Sbrooks
243147072Sbrooks/* Default path to dhcpd config file. */
244147072Sbrooks#define	_PATH_DHCLIENT_CONF	"/etc/dhclient.conf"
245147072Sbrooks#define	_PATH_DHCLIENT_DB	"/var/db/dhclient.leases"
246147072Sbrooks#define	DHCPD_LOG_FACILITY	LOG_DAEMON
247147072Sbrooks
248147072Sbrooks#define	MAX_TIME 0x7fffffff
249147072Sbrooks#define	MIN_TIME 0
250147072Sbrooks
251147072Sbrooks/* External definitions... */
252147072Sbrooks
253147072Sbrooks/* options.c */
254147072Sbrooksint cons_options(struct packet *, struct dhcp_packet *, int,
255147072Sbrooks    struct tree_cache **, int, int, int, u_int8_t *, int);
256147072Sbrookschar *pretty_print_option(unsigned int,
257147072Sbrooks    unsigned char *, int, int, int);
258147072Sbrooksvoid do_packet(struct interface_info *, struct dhcp_packet *,
259147072Sbrooks    int, unsigned int, struct iaddr, struct hardware *);
260147072Sbrooks
261147072Sbrooks/* errwarn.c */
262147072Sbrooksextern int warnings_occurred;
263147072Sbrooksvoid error(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
264147072Sbrooksint warning(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
265147072Sbrooksint note(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
266147072Sbrooksint debug(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
267147072Sbrooksint parse_warn(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
268147072Sbrooks
269147072Sbrooks/* conflex.c */
270147072Sbrooksextern int lexline, lexchar;
271147072Sbrooksextern char *token_line, *tlname;
272147072Sbrooksextern char comments[4096];
273147072Sbrooksextern int comment_index;
274147072Sbrooksextern int eol_token;
275147072Sbrooksvoid new_parse(char *);
276147072Sbrooksint next_token(char **, FILE *);
277147072Sbrooksint peek_token(char **, FILE *);
278147072Sbrooks
279147072Sbrooks/* parse.c */
280147072Sbrooksvoid skip_to_semi(FILE *);
281147072Sbrooksint parse_semi(FILE *);
282147072Sbrookschar *parse_string(FILE *);
283147072Sbrooksint parse_ip_addr(FILE *, struct iaddr *);
284147072Sbrooksvoid parse_hardware_param(FILE *, struct hardware *);
285147072Sbrooksvoid parse_lease_time(FILE *, time_t *);
286147072Sbrooksunsigned char *parse_numeric_aggregate(FILE *, unsigned char *, int *,
287147072Sbrooks    int, int, int);
288147072Sbrooksvoid convert_num(unsigned char *, char *, int, int);
289147072Sbrookstime_t parse_date(FILE *);
290147072Sbrooks
291147072Sbrooks/* tree.c */
292147072Sbrookspair cons(caddr_t, pair);
293147072Sbrooks
294147072Sbrooks/* alloc.c */
295147072Sbrooksstruct string_list	*new_string_list(size_t size);
296147072Sbrooksstruct hash_table	*new_hash_table(int);
297147072Sbrooksstruct hash_bucket	*new_hash_bucket(void);
298147072Sbrooks
299147072Sbrooks/* bpf.c */
300252620Spjdint if_register_bpf(struct interface_info *, int);
301147072Sbrooksvoid if_register_send(struct interface_info *);
302147072Sbrooksvoid if_register_receive(struct interface_info *);
303252626Spjdvoid send_packet_unpriv(int, struct dhcp_packet *, size_t, struct in_addr,
304252626Spjd    struct in_addr);
305252626Spjdstruct imsg_hdr;
306252626Spjdvoid send_packet_priv(struct interface_info *, struct imsg_hdr *, int);
307147072Sbrooksssize_t receive_packet(struct interface_info *, unsigned char *, size_t,
308147072Sbrooks    struct sockaddr_in *, struct hardware *);
309147072Sbrooks
310147072Sbrooks/* dispatch.c */
311147072Sbrooksextern void (*bootp_packet_handler)(struct interface_info *,
312147072Sbrooks    struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *);
313147072Sbrooksvoid discover_interfaces(struct interface_info *);
314147072Sbrooksvoid reinitialize_interfaces(void);
315147072Sbrooksvoid dispatch(void);
316147072Sbrooksvoid got_one(struct protocol *);
317147072Sbrooksvoid add_timeout(time_t, void (*)(void *), void *);
318147072Sbrooksvoid cancel_timeout(void (*)(void *), void *);
319147072Sbrooksvoid add_protocol(char *, int, void (*)(struct protocol *), void *);
320147072Sbrooksvoid remove_protocol(struct protocol *);
321147072Sbrooksint interface_link_status(char *);
322147072Sbrooks
323147072Sbrooks/* hash.c */
324147072Sbrooksstruct hash_table *new_hash(void);
325147072Sbrooksvoid add_hash(struct hash_table *, unsigned char *, int, unsigned char *);
326147072Sbrooksunsigned char *hash_lookup(struct hash_table *, unsigned char *, int);
327147072Sbrooks
328147072Sbrooks/* tables.c */
329147072Sbrooksextern struct option dhcp_options[256];
330147072Sbrooksextern unsigned char dhcp_option_default_priority_list[];
331147072Sbrooksextern int sizeof_dhcp_option_default_priority_list;
332147072Sbrooksextern struct hash_table universe_hash;
333147072Sbrooksextern struct universe dhcp_universe;
334147072Sbrooksvoid initialize_universes(void);
335147072Sbrooks
336147072Sbrooks/* convert.c */
337147072Sbrooksu_int32_t getULong(unsigned char *);
338147072Sbrooksint32_t getLong(unsigned char *);
339147072Sbrooksu_int16_t getUShort(unsigned char *);
340147072Sbrooksint16_t getShort(unsigned char *);
341147072Sbrooksvoid putULong(unsigned char *, u_int32_t);
342147072Sbrooksvoid putLong(unsigned char *, int32_t);
343147072Sbrooksvoid putUShort(unsigned char *, unsigned int);
344147072Sbrooksvoid putShort(unsigned char *, int);
345147072Sbrooks
346147072Sbrooks/* inet.c */
347147072Sbrooksstruct iaddr subnet_number(struct iaddr, struct iaddr);
348147072Sbrooksstruct iaddr broadcast_addr(struct iaddr, struct iaddr);
349147072Sbrooksint addr_eq(struct iaddr, struct iaddr);
350147072Sbrookschar *piaddr(struct iaddr);
351147072Sbrooks
352147072Sbrooks/* dhclient.c */
353147072Sbrooksextern char *path_dhclient_conf;
354147072Sbrooksextern char *path_dhclient_db;
355147072Sbrooksextern time_t cur_time;
356147072Sbrooksextern int log_priority;
357147072Sbrooksextern int log_perror;
358147072Sbrooks
359147072Sbrooksextern struct client_config top_level_config;
360147072Sbrooks
361226345Sdesextern struct pidfh *pidfile;
362226345Sdes
363147072Sbrooksvoid dhcpoffer(struct packet *);
364147072Sbrooksvoid dhcpack(struct packet *);
365147072Sbrooksvoid dhcpnak(struct packet *);
366147072Sbrooks
367147072Sbrooksvoid send_discover(void *);
368147072Sbrooksvoid send_request(void *);
369147072Sbrooksvoid send_decline(void *);
370147072Sbrooks
371147072Sbrooksvoid state_reboot(void *);
372147072Sbrooksvoid state_init(void *);
373147072Sbrooksvoid state_selecting(void *);
374147072Sbrooksvoid state_requesting(void *);
375147072Sbrooksvoid state_bound(void *);
376147072Sbrooksvoid state_panic(void *);
377147072Sbrooks
378147072Sbrooksvoid bind_lease(struct interface_info *);
379147072Sbrooks
380147072Sbrooksvoid make_discover(struct interface_info *, struct client_lease *);
381147072Sbrooksvoid make_request(struct interface_info *, struct client_lease *);
382147072Sbrooksvoid make_decline(struct interface_info *, struct client_lease *);
383147072Sbrooks
384147072Sbrooksvoid free_client_lease(struct client_lease *);
385147072Sbrooksvoid rewrite_client_leases(void);
386147072Sbrooksvoid write_client_lease(struct interface_info *, struct client_lease *, int);
387147072Sbrooks
388147072Sbrooksvoid	 priv_script_init(char *, char *);
389147072Sbrooksvoid	 priv_script_write_params(char *, struct client_lease *);
390147072Sbrooksint	 priv_script_go(void);
391147072Sbrooks
392147072Sbrooksvoid script_init(char *, struct string_list *);
393147072Sbrooksvoid script_write_params(char *, struct client_lease *);
394147072Sbrooksint script_go(void);
395147072Sbrooksvoid client_envadd(struct client_state *,
396147072Sbrooks    const char *, const char *, const char *, ...);
397147072Sbrooksvoid script_set_env(struct client_state *, const char *, const char *,
398147072Sbrooks    const char *);
399147072Sbrooksvoid script_flush_env(struct client_state *);
400147072Sbrooksint dhcp_option_ev_name(char *, size_t, struct option *);
401147072Sbrooks
402147072Sbrooksstruct client_lease *packet_to_lease(struct packet *);
403147072Sbrooksvoid go_daemon(void);
404147072Sbrooksvoid client_location_changed(void);
405147072Sbrooks
406147072Sbrooksvoid bootp(struct packet *);
407147072Sbrooksvoid dhcp(struct packet *);
408147072Sbrooks
409147072Sbrooks/* packet.c */
410252615Spjdvoid assemble_hw_header(struct interface_info *, unsigned char *, int *);
411147072Sbrooksvoid assemble_udp_ip_header(unsigned char *, int *, u_int32_t, u_int32_t,
412147072Sbrooks    unsigned int, unsigned char *, int);
413147072Sbrooksssize_t decode_hw_header(unsigned char *, int, struct hardware *);
414147072Sbrooksssize_t decode_udp_ip_header(unsigned char *, int, struct sockaddr_in *,
415147072Sbrooks    unsigned char *, int);
416147072Sbrooks
417147072Sbrooks/* clparse.c */
418147072Sbrooksint read_client_conf(void);
419147072Sbrooksvoid read_client_leases(void);
420147072Sbrooksvoid parse_client_statement(FILE *, struct interface_info *,
421147072Sbrooks    struct client_config *);
422147072Sbrooksint parse_X(FILE *, u_int8_t *, int);
423147072Sbrooksint parse_option_list(FILE *, u_int8_t *);
424147072Sbrooksvoid parse_interface_declaration(FILE *, struct client_config *);
425147072Sbrooksstruct interface_info *interface_or_dummy(char *);
426147072Sbrooksvoid make_client_state(struct interface_info *);
427147072Sbrooksvoid make_client_config(struct interface_info *, struct client_config *);
428147072Sbrooksvoid parse_client_lease_statement(FILE *, int);
429147072Sbrooksvoid parse_client_lease_declaration(FILE *, struct client_lease *,
430147072Sbrooks    struct interface_info **);
431147072Sbrooksstruct option *parse_option_decl(FILE *, struct option_data *);
432147072Sbrooksvoid parse_string_list(FILE *, struct string_list **, int);
433147072Sbrooksvoid parse_reject_statement(FILE *, struct client_config *);
434147072Sbrooks
435147072Sbrooks/* privsep.c */
436147072Sbrooksstruct buf	*buf_open(size_t);
437147072Sbrooksint		 buf_add(struct buf *, void *, size_t);
438147072Sbrooksint		 buf_close(int, struct buf *);
439147072Sbrooksssize_t		 buf_read(int, void *, size_t);
440252626Spjdvoid		 dispatch_imsg(struct interface_info *, int);
441