diff options
-rw-r--r-- | sbin/dhclient/clparse.c | 206 | ||||
-rw-r--r-- | sbin/dhclient/dhclient.c | 87 | ||||
-rw-r--r-- | sbin/dhclient/dhcpd.h | 22 |
3 files changed, 107 insertions, 208 deletions
diff --git a/sbin/dhclient/clparse.c b/sbin/dhclient/clparse.c index 29eb1a735fe..78ae2f16457 100644 --- a/sbin/dhclient/clparse.c +++ b/sbin/dhclient/clparse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clparse.c,v 1.25 2005/07/16 18:38:45 krw Exp $ */ +/* $OpenBSD: clparse.c,v 1.26 2005/08/02 02:34:03 krw Exp $ */ /* Parser for dhclient config and lease files... */ @@ -43,8 +43,6 @@ #include "dhcpd.h" #include "dhctoken.h" -struct client_config top_level_config; -struct interface_info *dummy_interfaces; extern struct interface_info *ifi; char client_script_name[] = "/sbin/dhclient-script"; @@ -58,74 +56,48 @@ char client_script_name[] = "/sbin/dhclient-script"; int read_client_conf(void) { - FILE *cfile; - char *val; - int token; - struct client_config *config; + struct client_config *config = ifi->client->config; + FILE *cfile; + char *val; + int token; new_parse(path_dhclient_conf); - /* Initialize the top level client configuration. */ - memset(&top_level_config, 0, sizeof(top_level_config)); - /* Set some defaults... */ - top_level_config.timeout = 60; - top_level_config.select_interval = 0; - top_level_config.reboot_timeout = 10; - top_level_config.retry_interval = 300; - top_level_config.backoff_cutoff = 15; - top_level_config.initial_interval = 3; - top_level_config.bootp_policy = ACCEPT; - top_level_config.script_name = client_script_name; - top_level_config.requested_options - [top_level_config.requested_option_count++] = DHO_SUBNET_MASK; - top_level_config.requested_options - [top_level_config.requested_option_count++] = DHO_BROADCAST_ADDRESS; - top_level_config.requested_options - [top_level_config.requested_option_count++] = DHO_TIME_OFFSET; - top_level_config.requested_options - [top_level_config.requested_option_count++] = DHO_ROUTERS; - top_level_config.requested_options - [top_level_config.requested_option_count++] = DHO_DOMAIN_NAME; - top_level_config.requested_options - [top_level_config.requested_option_count++] = - DHO_DOMAIN_NAME_SERVERS; - top_level_config.requested_options - [top_level_config.requested_option_count++] = DHO_HOST_NAME; + config->timeout = 60; + config->select_interval = 0; + config->reboot_timeout = 10; + config->retry_interval = 300; + config->backoff_cutoff = 15; + config->initial_interval = 3; + config->bootp_policy = ACCEPT; + config->script_name = client_script_name; + config->requested_options + [config->requested_option_count++] = DHO_SUBNET_MASK; + config->requested_options + [config->requested_option_count++] = DHO_BROADCAST_ADDRESS; + config->requested_options + [config->requested_option_count++] = DHO_TIME_OFFSET; + config->requested_options + [config->requested_option_count++] = DHO_ROUTERS; + config->requested_options + [config->requested_option_count++] = DHO_DOMAIN_NAME; + config->requested_options + [config->requested_option_count++] = DHO_DOMAIN_NAME_SERVERS; + config->requested_options + [config->requested_option_count++] = DHO_HOST_NAME; if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) { do { token = peek_token(&val, cfile); if (token == EOF) break; - parse_client_statement(cfile, NULL, &top_level_config); + parse_client_statement(cfile); } while (1); token = next_token(&val, cfile); /* Clear the peek buffer */ fclose(cfile); } - /* - * Set up state and config structures for clients that don't - * have per-interface configuration declarations. - */ - config = NULL; - if (!ifi->client) { - ifi->client = malloc(sizeof(struct client_state)); - if (!ifi->client) - error("no memory for client state."); - memset(ifi->client, 0, sizeof(*(ifi->client))); - } - if (!ifi->client->config) { - if (!config) { - config = malloc(sizeof(struct client_config)); - if (!config) - error("no memory for client config."); - memcpy(config, &top_level_config, - sizeof(top_level_config)); - } - ifi->client->config = config; - } - return (!warnings_occurred); } @@ -182,11 +154,11 @@ read_client_leases(void) * ALIAS client-lease-statement */ void -parse_client_statement(FILE *cfile, struct interface_info *ip, - struct client_config *config) +parse_client_statement(FILE *cfile) { - int token, code; - char *val; + struct client_config *config = ifi->client->config; + char *val; + int token, code; switch (next_token(&val, cfile)) { case SEND: @@ -216,13 +188,7 @@ parse_client_statement(FILE *cfile, struct interface_info *ip, parse_string_list(cfile, &config->media, 1); return; case HARDWARE: - if (ip) - parse_hardware_param(cfile, &ip->hw_address); - else { - parse_warn("hardware address parameter %s", - "not allowed here."); - skip_to_semi(cfile); - } + parse_hardware_param(cfile, &ifi->hw_address); return; case REQUEST: config->requested_option_count = @@ -255,9 +221,7 @@ parse_client_statement(FILE *cfile, struct interface_info *ip, config->script_name = parse_string(cfile); return; case INTERFACE: - if (ip) - parse_warn("nested interface declaration."); - parse_interface_declaration(cfile, config); + parse_interface_declaration(cfile); return; case LEASE: parse_client_lease_statement(cfile, 1); @@ -266,7 +230,7 @@ parse_client_statement(FILE *cfile, struct interface_info *ip, parse_client_lease_statement(cfile, 2); return; case REJECT: - parse_reject_statement(cfile, config); + parse_reject_statement(cfile); return; default: parse_warn("expecting a statement."); @@ -374,11 +338,10 @@ parse_option_list(FILE *cfile, u_int8_t *list) * INTERFACE string LBRACE client-declarations RBRACE */ void -parse_interface_declaration(FILE *cfile, struct client_config *outer_config) +parse_interface_declaration(FILE *cfile) { - int token; - char *val; - struct interface_info *ip; + char *val; + int token; token = next_token(&val, cfile); if (token != STRING) { @@ -387,13 +350,10 @@ parse_interface_declaration(FILE *cfile, struct client_config *outer_config) return; } - ip = interface_or_dummy(val); - - if (!ip->client) - make_client_state(ip); - - if (!ip->client->config) - make_client_config(ip, outer_config); + if (strcmp(ifi->name, val) != 0) { + skip_to_semi(cfile); + return; + } token = next_token(&val, cfile); if (token != LBRACE) { @@ -410,58 +370,11 @@ parse_interface_declaration(FILE *cfile, struct client_config *outer_config) } if (token == RBRACE) break; - parse_client_statement(cfile, ip, ip->client->config); + parse_client_statement(cfile); } while (1); token = next_token(&val, cfile); } -struct interface_info * -interface_or_dummy(char *name) -{ - struct interface_info *ip; - - /* Find the interface (if any) that matches the name. */ - if (!strcmp(ifi->name, name)) - return (ifi); - - /* If it's not a real interface, see if it's on the dummy list. */ - for (ip = dummy_interfaces; ip; ip = ip->next) - if (!strcmp(ip->name, name)) - return (ip); - - /* - * If we didn't find an interface, make a dummy interface as a - * placeholder. - */ - ip = malloc(sizeof(*ip)); - if (!ip) - error("Insufficient memory to record interface %s", name); - memset(ip, 0, sizeof(*ip)); - strlcpy(ip->name, name, IFNAMSIZ); - ip->next = dummy_interfaces; - dummy_interfaces = ip; - return (ip); -} - -void -make_client_state(struct interface_info *ip) -{ - ip->client = malloc(sizeof(*(ip->client))); - if (!ip->client) - error("no memory for state on %s", ip->name); - memset(ip->client, 0, sizeof(*(ip->client))); -} - -void -make_client_config(struct interface_info *ip, struct client_config *config) -{ - ip->client->config = malloc(sizeof(struct client_config)); - if (!ip->client->config) - error("no memory for config for %s", ip->name); - memset(ip->client->config, 0, sizeof(*(ip->client->config))); - memcpy(ip->client->config, config, sizeof(*config)); -} - /* * client-lease-statement :== * RBRACE client-lease-declarations LBRACE @@ -475,7 +388,7 @@ void parse_client_lease_statement(FILE *cfile, int is_static) { struct client_lease *lease, *lp, *pl; - struct interface_info *ip; + struct interface_info *ip = ifi; int token; char *val; @@ -492,8 +405,6 @@ parse_client_lease_statement(FILE *cfile, int is_static) memset(lease, 0, sizeof(*lease)); lease->is_static = is_static; - ip = NULL; - do { token = peek_token(&val, cfile); if (token == EOF) { @@ -514,10 +425,6 @@ parse_client_lease_statement(FILE *cfile, int is_static) return; } - /* Make sure there's a client state structure... */ - if (!ip->client) - make_client_state(ip); - /* If this is an alias lease, it doesn't need to be sorted in. */ if (is_static == 2) { ip->client->alias = lease; @@ -602,9 +509,8 @@ void parse_client_lease_declaration(FILE *cfile, struct client_lease *lease, struct interface_info **ipp) { - int token; - char *val; - struct interface_info *ip; + char *val; + int token; switch (next_token(&val, cfile)) { case BOOTP: @@ -617,8 +523,13 @@ parse_client_lease_declaration(FILE *cfile, struct client_lease *lease, skip_to_semi(cfile); break; } - ip = interface_or_dummy(val); - *ipp = ip; + if (strcmp(ifi->name, val) != 0) { + parse_warn("wrong interface name. Expecting '%s'.", + ifi->name); + skip_to_semi(cfile); + break; + } + *ipp = ifi; break; case FIXED_ADDR: if (!parse_ip_addr(cfile, &lease->address)) @@ -858,12 +769,13 @@ parse_string_list(FILE *cfile, struct string_list **lp, int multiple) } void -parse_reject_statement(FILE *cfile, struct client_config *config) +parse_reject_statement(FILE *cfile) { - int token; - char *val; - struct iaddr addr; - struct iaddrlist *list; + struct client_config *config = ifi->client->config; + struct iaddrlist *list; + struct iaddr addr; + char *val; + int token; do { if (!parse_ip_addr(cfile, &addr)) { diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 00a4908462c..61688787cc2 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.76 2005/07/16 14:09:51 krw Exp $ */ +/* $OpenBSD: dhclient.c,v 1.77 2005/08/02 02:34:03 krw Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -277,8 +277,16 @@ main(int argc, char *argv[]) if (argc != 1) usage(); - if ((ifi = calloc(1, sizeof(struct interface_info))) == NULL) - error("calloc"); + ifi = calloc(1, sizeof(*ifi)); + if (ifi == NULL) + error("ifi calloc"); + ifi->client = calloc(1, sizeof(*(ifi->client))); + if (ifi->client == NULL) + error("ifi->client calloc"); + ifi->client->config = calloc(1, sizeof(*(ifi->client->config))); + if (ifi->client->config == NULL) + error("ifi->client->config calloc"); + if (strlcpy(ifi->name, argv[0], IFNAMSIZ) >= IFNAMSIZ) error("Interface name too long"); if (path_dhclient_db == NULL && asprintf(&path_dhclient_db, "%s.%s", @@ -1709,29 +1717,27 @@ script_init(char *reason, struct string_list *medium) void priv_script_init(char *reason, char *medium) { - struct interface_info *ip = ifi; + struct client_state *client = ifi->client; - if (ip) { - ip->client->scriptEnvsize = 100; - if (ip->client->scriptEnv == NULL) - ip->client->scriptEnv = - malloc(ip->client->scriptEnvsize * sizeof(char *)); - if (ip->client->scriptEnv == NULL) - error("script_init: no memory for environment"); + client->scriptEnvsize = 100; + if (client->scriptEnv == NULL) + client->scriptEnv = + malloc(client->scriptEnvsize * sizeof(char *)); + if (client->scriptEnv == NULL) + error("script_init: no memory for environment"); - ip->client->scriptEnv[0] = strdup(CLIENT_PATH); - if (ip->client->scriptEnv[0] == NULL) - error("script_init: no memory for environment"); + client->scriptEnv[0] = strdup(CLIENT_PATH); + if (client->scriptEnv[0] == NULL) + error("script_init: no memory for environment"); - ip->client->scriptEnv[1] = NULL; + client->scriptEnv[1] = NULL; - script_set_env(ip->client, "", "interface", ip->name); + script_set_env("", "interface", ifi->name); - if (medium) - script_set_env(ip->client, "", "medium", medium); + if (medium) + script_set_env("", "medium", medium); - script_set_env(ip->client, "", "reason", reason); - } + script_set_env("", "reason", reason); } void @@ -1742,8 +1748,7 @@ priv_script_write_params(char *prefix, struct client_lease *lease) int i, len = 0; char tbuf[128]; - script_set_env(ip->client, prefix, "ip_address", - piaddr(lease->address)); + script_set_env(prefix, "ip_address", piaddr(lease->address)); if (lease->options[DHO_SUBNET_MASK].len && (lease->options[DHO_SUBNET_MASK].len < @@ -1756,12 +1761,12 @@ priv_script_write_params(char *prefix, struct client_lease *lease) subnet = subnet_number(lease->address, netmask); if (subnet.len) { - script_set_env(ip->client, prefix, "network_number", + script_set_env(prefix, "network_number", piaddr(subnet)); if (!lease->options[DHO_BROADCAST_ADDRESS].len) { broadcast = broadcast_addr(subnet, netmask); if (broadcast.len) - script_set_env(ip->client, prefix, + script_set_env(prefix, "broadcast_address", piaddr(broadcast)); } @@ -1769,9 +1774,9 @@ priv_script_write_params(char *prefix, struct client_lease *lease) } if (lease->filename) - script_set_env(ip->client, prefix, "filename", lease->filename); + script_set_env(prefix, "filename", lease->filename); if (lease->server_name) - script_set_env(ip->client, prefix, "server_name", + script_set_env(prefix, "server_name", lease->server_name); for (i = 0; i < 256; i++) { u_int8_t *dp = NULL; @@ -1840,12 +1845,12 @@ supersede: if (dhcp_option_ev_name(name, sizeof(name), &dhcp_options[i])) - script_set_env(ip->client, prefix, name, + script_set_env(prefix, name, pretty_print_option(i, dp, len, 0, 0)); } } snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry); - script_set_env(ip->client, prefix, "expiry", tbuf); + script_set_env(prefix, "expiry", tbuf); } void @@ -1935,23 +1940,13 @@ script_go(void) int priv_script_go(void) { - char *scriptName, *argv[2], **envp, *epp[3], reason[] = "REASON=NBI"; - static char client_path[] = CLIENT_PATH; - struct interface_info *ip = ifi; + char *scriptName, *argv[2], **envp; int pid, wpid, wstatus; scripttime = time(NULL); - if (ip) { - scriptName = ip->client->config->script_name; - envp = ip->client->scriptEnv; - } else { - scriptName = top_level_config.script_name; - epp[0] = reason; - epp[1] = client_path; - epp[2] = NULL; - envp = epp; - } + scriptName = ifi->client->config->script_name; + envp = ifi->client->scriptEnv; argv[0] = scriptName; argv[1] = NULL; @@ -1973,16 +1968,15 @@ priv_script_go(void) error("execve (%s, ...): %m", scriptName); } - if (ip) - script_flush_env(ip->client); + script_flush_env(); return (wstatus & 0xff); } void -script_set_env(struct client_state *client, const char *prefix, - const char *name, const char *value) +script_set_env(const char *prefix, const char *name, const char *value) { + struct client_state *client = ifi->client; int i, j, namelen; namelen = strlen(name); @@ -2036,8 +2030,9 @@ script_set_env(struct client_state *client, const char *prefix, } void -script_flush_env(struct client_state *client) +script_flush_env(void) { + struct client_state *client = ifi->client; int i; for (i = 0; client->scriptEnv[i]; i++) { diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index c27b93db1f8..b86d6adea61 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.45 2005/07/17 19:33:55 krw Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.46 2005/08/02 02:34:03 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer <henning@openbsd.org> @@ -311,8 +311,6 @@ extern char *path_dhclient_db; extern time_t cur_time; extern int log_perror; -extern struct client_config top_level_config; - void dhcpoffer(struct packet *); void dhcpack(struct packet *); void dhcpnak(struct packet *); @@ -345,11 +343,9 @@ int priv_script_go(void); void script_init(char *, struct string_list *); void script_write_params(char *, struct client_lease *); int script_go(void); -void client_envadd(struct client_state *, - const char *, const char *, const char *, ...); -void script_set_env(struct client_state *, const char *, const char *, - const char *); -void script_flush_env(struct client_state *); +void client_envadd(const char *, const char *, const char *, ...); +void script_set_env(const char *, const char *, const char *); +void script_flush_env(void); int dhcp_option_ev_name(char *, size_t, const struct option *); struct client_lease *packet_to_lease(struct packet *); @@ -377,20 +373,16 @@ ssize_t decode_ethernet_header(struct interface_info *, unsigned char *, /* clparse.c */ int read_client_conf(void); void read_client_leases(void); -void parse_client_statement(FILE *, struct interface_info *, - struct client_config *); +void parse_client_statement(FILE *); int parse_X(FILE *, u_int8_t *, int); int parse_option_list(FILE *, u_int8_t *); -void parse_interface_declaration(FILE *, struct client_config *); -struct interface_info *interface_or_dummy(char *); -void make_client_state(struct interface_info *); -void make_client_config(struct interface_info *, struct client_config *); +void parse_interface_declaration(FILE *); void parse_client_lease_statement(FILE *, int); void parse_client_lease_declaration(FILE *, struct client_lease *, struct interface_info **); int parse_option_decl(FILE *, struct option_data *); void parse_string_list(FILE *, struct string_list **, int); -void parse_reject_statement(FILE *, struct client_config *); +void parse_reject_statement(FILE *); /* privsep.c */ struct buf *buf_open(size_t); |