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