summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/dhclient/clparse.c206
-rw-r--r--sbin/dhclient/dhclient.c87
-rw-r--r--sbin/dhclient/dhcpd.h22
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);