Merge 20000719 changes

This commit is contained in:
mellon 2000-07-20 05:59:17 +00:00
parent 8e7171f5ab
commit 4b564fe2bf
9 changed files with 268 additions and 140 deletions

View File

@ -43,13 +43,15 @@
#ifndef lint
static char copyright[] =
"$Id: clparse.c,v 1.6 2000/06/24 06:50:01 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
"$Id: clparse.c,v 1.7 2000/07/20 05:59:17 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static TIME parsed_time;
char client_script_name [] = "/etc/dhclient-script";
struct client_config top_level_config;
u_int32_t default_requested_options [] = {
@ -94,7 +96,7 @@ isc_result_t read_client_conf ()
top_level_config.backoff_cutoff = 15;
top_level_config.initial_interval = 3;
top_level_config.bootp_policy = P_ACCEPT;
top_level_config.script_name = "/etc/dhclient-script";
top_level_config.script_name = client_script_name;
top_level_config.requested_options = default_requested_options;
top_level_config.omapi_port = -1;

View File

@ -41,7 +41,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhclient.c,v 1.27 2000/06/24 06:50:01 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 Internet Software Consortium. All rights reserved.\n";
"$Id: dhclient.c,v 1.28 2000/07/20 05:59:17 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -104,6 +104,10 @@ int main (argc, argv, envp)
isc_result_t result;
int persist = 0;
int omapi_port;
int no_dhclient_conf = 0;
int no_dhclient_db = 0;
int no_dhclient_pid = 0;
char *s;
#ifdef SYSLOG_4_2
openlog ("dhclient", LOG_NDELAY);
@ -147,14 +151,17 @@ int main (argc, argv, envp)
if (++i == argc)
usage ();
path_dhclient_pid = argv [i];
no_dhclient_pid = 1;
} else if (!strcmp (argv [i], "-cf")) {
if (++i == argc)
usage ();
path_dhclient_conf = argv [i];
no_dhclient_conf = 1;
} else if (!strcmp (argv [i], "-lf")) {
if (++i == argc)
usage ();
path_dhclient_db = argv [i];
no_dhclient_db = 1;
} else if (!strcmp (argv [i], "-q")) {
quiet = 1;
quiet_interface_discovery = 1;
@ -195,6 +202,16 @@ int main (argc, argv, envp)
}
}
if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) {
path_dhclient_conf = s;
}
if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) {
path_dhclient_db = s;
}
if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) {
path_dhclient_pid = s;
}
/* first kill of any currently running client */
if (release_mode) {
/* XXX inelegant hack to prove concept */
@ -2117,46 +2134,29 @@ void script_init (client, reason, medium)
const char *reason;
struct string_list *medium;
{
int fd;
#ifndef HAVE_MKSTEMP
struct string_list *sl, *next;
do {
#endif
strcpy (scriptName, "/tmp/dcsXXXXXX");
#ifdef HAVE_MKSTEMP
fd = mkstemp (scriptName);
#else
if (!mktemp (scriptName))
log_fatal ("can't create temporary script %s: %m",
scriptName);
fd = open (scriptName, O_EXCL | O_CREAT | O_WRONLY, 0600);
} while (fd < 0 && errno == EEXIST);
#endif
if (fd < 0)
log_fatal ("can't create temporary script %s: %m", scriptName);
scriptFile = fdopen (fd, "w");
if (!scriptFile)
log_fatal ("can't write script file: %m");
fprintf (scriptFile, "#!/bin/sh\n\n");
if (client) {
for (sl = client -> env; sl; sl = next) {
next = sl -> next;
dfree (sl, MDL);
}
client -> env = (struct string_list *)0;
client -> envc = 0;
if (client -> interface) {
fprintf (scriptFile, "interface=\"%s\"\n",
client -> interface -> name);
fprintf (scriptFile, "export interface\n");
client_envadd (client, "", "interface", "%s",
client -> interface -> name);
}
if (client -> name)
fprintf (scriptFile, "client=\"%s\"\n",
client -> name);
fprintf (scriptFile, "export client\n");
client_envadd (client,
"", "client", "%s", client -> name);
if (medium)
client_envadd (client,
"", "medium", "%s", medium -> string);
client_envadd (client, "", "reason", "%s", reason);
}
if (medium) {
fprintf (scriptFile, "medium=\"%s\"\n", medium -> string);
fprintf (scriptFile, "export medium\n");
}
fprintf (scriptFile, "reason=\"%s\"\n", reason);
fprintf (scriptFile, "export reason\n");
}
void script_write_params (client, prefix, lease)
@ -2168,10 +2168,10 @@ void script_write_params (client, prefix, lease)
struct data_string data;
struct option_cache *oc;
pair *hash;
char *s, *t;
fprintf (scriptFile, "%sip_address=\"%s\"\n",
prefix, piaddr (lease -> address));
fprintf (scriptFile, "export %sip_address\n", prefix);
client_envadd (client,
prefix, "ip_address", "%s", piaddr (lease -> address));
/* For the benefit of Linux (and operating systems which may
have similar needs), compute the network address based on
@ -2197,51 +2197,37 @@ void script_write_params (client, prefix, lease)
subnet = subnet_number (lease -> address, netmask);
if (subnet.len) {
fprintf (scriptFile,
"%snetwork_number=\"%s\";\n",
prefix, piaddr (subnet));
fprintf (scriptFile,
"export %snetwork_number\n", prefix);
client_envadd (client, prefix, "network_number",
"%s", piaddr (subnet));
oc = lookup_option (&dhcp_universe,
lease -> options,
DHO_BROADCAST_ADDRESS);
if (!oc ||
!(evaluate_option_cache
(&data, (struct packet *)0,
(struct lease *)0,
(struct option_state *)0,
lease -> options,
&global_scope, oc, MDL))) {
broadcast = broadcast_addr (subnet,
netmask);
if (broadcast.len) {
fprintf (scriptFile,
"%s%s=\"%s\";\n",
prefix,
"broadcast_address",
piaddr (broadcast));
fprintf (scriptFile,
"export %s%s\n",
prefix,
"broadcast_address");
}
oc = lookup_option (&dhcp_universe,
lease -> options,
DHO_BROADCAST_ADDRESS);
if (!oc ||
!(evaluate_option_cache
(&data, (struct packet *)0,
(struct lease *)0,
(struct option_state *)0,
lease -> options,
&global_scope, oc, MDL))) {
broadcast = broadcast_addr (subnet, netmask);
if (broadcast.len) {
client_envadd (client,
prefix, "broadcast_address",
"%s", piaddr (broadcast));
}
}
}
}
data_string_forget (&data, MDL);
}
if (lease -> filename) {
fprintf (scriptFile, "%sfilename=\"%s\";\n",
prefix, lease -> filename);
fprintf (scriptFile, "export %sfilename\n", prefix);
}
if (lease -> server_name) {
fprintf (scriptFile, "%sserver_name=\"%s\";\n",
prefix, lease -> server_name);
fprintf (scriptFile, "export %sserver_name\n", prefix);
}
if (lease -> filename)
client_envadd (client,
prefix, "filename", "%s", lease -> filename);
if (lease -> server_name)
client_envadd (client, prefix, "server_name",
"%s", lease -> server_name);
execute_statements_in_scope ((struct packet *)0,
(struct lease *)0, lease -> options,
@ -2251,78 +2237,155 @@ void script_write_params (client, prefix, lease)
hash = lease -> options -> universes [dhcp_universe.index];
for (i = 0; i < OPTION_HASH_SIZE; i++) {
pair hp;
pair hp;
for (hp = hash [i]; hp; hp = hp -> cdr) {
oc = (struct option_cache *)hp -> car;
for (hp = hash [i]; hp; hp = hp -> cdr) {
oc = (struct option_cache *)hp -> car;
if (evaluate_option_cache (&data,
(struct packet *)0,
(struct lease *)0,
(struct option_state *)0,
lease -> options,
&global_scope, oc, MDL)) {
if (data.len) {
char *s = (dhcp_option_ev_name
(oc -> option));
fprintf (scriptFile,
"%s%s=\"%s\"\n", prefix, s,
(pretty_print_option
(oc -> option -> code,
data.data, data.len,
0, 0)));
fprintf (scriptFile,
"export %s%s\n", prefix, s);
}
data_string_forget (&data, MDL);
if (evaluate_option_cache (&data,
(struct packet *)0,
(struct lease *)0,
(struct option_state *)0,
lease -> options,
&global_scope, oc, MDL)) {
if (data.len) {
char name [256];
if (dhcp_option_ev_name (name, sizeof name,
oc -> option)) {
client_envadd (client, prefix, name, "%s",
(pretty_print_option
(oc -> option -> code,
data.data, data.len,
0, 0)));
data_string_forget (&data, MDL);
}
}
}
}
}
fprintf (scriptFile, "%sexpiry=\"%d\"\n",
prefix, (int)lease -> expiry); /* XXX */
fprintf (scriptFile, "export %sexpiry\n", prefix);
client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
}
int script_go (client)
struct client_state *client;
{
int rval;
if (client)
fprintf (scriptFile, "%s\n",
client -> config -> script_name);
else
fprintf (scriptFile, "%s\n",
top_level_config.script_name);
fprintf (scriptFile, "exit $?\n");
fclose (scriptFile);
chmod (scriptName, 0700);
rval = system (scriptName);
if (!save_scripts)
unlink (scriptName);
return rval;
}
char *dhcp_option_ev_name (option)
struct option *option;
{
static char evbuf [256];
char *scriptName;
char *argv [2];
char **envp;
char *epp [3];
char reason [] = "REASON=NBI";
static char client_path [] = CLIENT_PATH;
int i;
struct string_list *sp, *next;
int pid, wpid, wstatus;
if (strlen (option -> name) + 1 > sizeof evbuf)
log_fatal ("option %s name is larger than static buffer.",
option -> name);
for (i = 0; option -> name [i]; i++) {
if (option -> name [i] == '-')
evbuf [i] = '_';
else
evbuf [i] = option -> name [i];
if (client) {
scriptName = client -> config -> script_name;
envp = dmalloc ((client -> envc + 2) * sizeof (char *),
MDL);
if (!envp) {
log_error ("No memory for client script environment.");
return 0;
}
i = 0;
for (sp = client -> env; sp; sp = sp -> next) {
envp [i++] = sp -> string;
}
envp [i++] = client_path;
envp [i] = (char *)0;
} else {
scriptName = top_level_config.script_name;
epp [0] = reason;
epp [1] = client_path;
epp [2] = (char *)0;
envp = epp;
}
evbuf [i] = 0;
return evbuf;
argv [0] = scriptName;
argv [1] = (char *)0;
pid = fork ();
if (pid < 0) {
log_error ("fork: %m");
wstatus = 0;
} else if (pid) {
do {
wpid = wait (&wstatus);
} while (wpid != pid && wpid > 0);
if (wpid < 0) {
log_error ("wait: %m");
wstatus = 0;
}
} else {
execve (scriptName, argv, envp);
log_error ("execve (%s, ...): %m", scriptName);
exit (0);
}
if (client) {
for (sp = client -> env; sp; sp = next) {
next = sp -> next;
dfree (sp, MDL);
}
client -> env = (struct string_list *)0;
client -> envc = 0;
dfree (envp, MDL);
}
return wstatus & 0xff;
}
void client_envadd (struct client_state *client,
const char *prefix, const char *name, const char *fmt, ...)
{
char spbuf [1024];
char *s;
unsigned len, i;
struct string_list *val;
va_list list;
va_start (list, fmt);
len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
va_end (list);
val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
len + sizeof *val, MDL);
if (!val)
return;
s = val -> string;
strcpy (s, prefix);
strcat (s, name);
s += strlen (s);
*s++ = '=';
if (len >= sizeof spbuf) {
va_start (list, fmt);
vsnprintf (s, len + 1, fmt, list);
va_end (list);
} else
strcpy (s, spbuf);
val -> next = client -> env;
client -> env = val;
client -> envc++;
}
int dhcp_option_ev_name (buf, buflen, option)
char *buf;
unsigned buflen;
struct option *option;
{
int i;
for (i = 0; option -> name [i]; i++) {
if (i + 1 == buflen)
return 0;
if (option -> name [i] == '-')
buf [i] = '_';
else
buf [i] = option -> name [i];
}
buf [i] = 0;
return 1;
}
void go_daemon ()

View File

@ -87,7 +87,25 @@ hexadecimal, seperated by colons. For example:
or
option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
.fi
.SH SETTING OPTION VALUES USING EXPRESSIONS
Sometimes it's helpful to be able to set the value of a DHCP option
based on some value that the client has sent. To do this, you can
use expression evaluation. The
.B dhcp-eval(5)
manual page describes how to write expressions. To assign the result
of an evaluation to an option, define the option as follows:
.nf
.sp 1
\fBoption \fImy-option \fB= \fIexpression \fB;\fR
.fi
.PP
For example:
.nf
.sp 1
option hostname = binary-to-ascii (16, 8, "-",
substring (hardware, 1, 6));
.fi
.SH STANDARD DHCP OPTIONS
The documentation for the various options mentioned below is taken
from the latest IETF draft document on DHCP options. Options which
are not listed by name may be defined by the name option-\fInnn\fR,

View File

@ -665,7 +665,7 @@ struct client_config {
u_int32_t requested_lease; /* Requested lease time, if user
doesn't configure one. */
struct string_list *media; /* Possible network media values. */
const char *script_name; /* Name of config script. */
char *script_name; /* Name of config script. */
enum policy bootp_policy;
/* Ignore, accept or prefer BOOTP
responses. */
@ -708,6 +708,8 @@ struct client_state {
struct iaddr requested_address; /* Address we would like to get. */
struct client_config *config; /* Client configuration. */
struct string_list *env; /* Client script environment. */
int envc; /* Number of entries in environment. */
};
/* Information about each network interface. */
@ -1636,13 +1638,16 @@ void destroy_client_lease PROTO ((struct client_lease *));
void rewrite_client_leases PROTO ((void));
int write_client_lease PROTO ((struct client_state *,
struct client_lease *, int, int));
char *dhcp_option_ev_name PROTO ((struct option *));
int dhcp_option_ev_name (char *, size_t, struct option *);
void script_init PROTO ((struct client_state *, const char *,
struct string_list *));
void script_write_params PROTO ((struct client_state *,
const char *, struct client_lease *));
int script_go PROTO ((struct client_state *));
void client_envadd (struct client_state *,
const char *, const char *, const char *, ...)
__attribute__((__format__(__printf__,4,5)));
struct client_lease *packet_to_lease PROTO ((struct packet *));
void go_daemon PROTO ((void));

View File

@ -1,3 +1,3 @@
/* Current version of ISC DHCP Distribution. */
#define DHCP_VERSION "V3.0b2pl0-20000708"
#define DHCP_VERSION "V3.0b2pl0-20000719"

View File

@ -122,6 +122,7 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h)
omapi_io_reference (&ph, obj, MDL);
/* remove from the list of I/O states */
last = &omapi_io_states;
for (p = omapi_io_states.next; p; p = p -> next) {
if (p == obj) {
omapi_io_dereference (&last -> next, MDL);

View File

@ -43,7 +43,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhcrelay.c,v 1.4 2000/06/10 18:17:21 mellon Exp $ Copyright (c) 1997-2000 Internet Software Consortium. All rights reserved.\n";
"$Id: dhcrelay.c,v 1.5 2000/07/20 05:59:20 mellon Exp $ Copyright (c) 1997-2000 Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -124,6 +124,7 @@ int main (argc, argv, envp)
int no_daemon = 0;
int quiet = 0;
isc_result_t status;
char *s;
#ifdef SYSLOG_4_2
openlog ("dhcrelay", LOG_NDELAY);
@ -214,6 +215,10 @@ int main (argc, argv, envp)
}
}
if ((s = getenv ("PATH_DHCRELAY_PID"))) {
path_dhcrelay_pid = s;
}
if (!quiet) {
log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright);

View File

@ -43,7 +43,7 @@
#ifndef lint
static char ocopyright[] =
"$Id: dhcpd.c,v 1.20 2000/07/08 20:52:20 mellon Exp $ Copyright 1995-2000 Internet Software Consortium.";
"$Id: dhcpd.c,v 1.21 2000/07/20 05:59:20 mellon Exp $ Copyright 1995-2000 Internet Software Consortium.";
#endif
static char copyright[] =
@ -166,6 +166,9 @@ int main (argc, argv, envp)
struct parse *parse;
int lose;
int omapi_port;
int no_dhcpd_conf = 0;
int no_dhcpd_db = 0;
int no_dhcpd_pid = 0;
/* Set up the client classification system. */
classification_setup ();
@ -221,14 +224,17 @@ int main (argc, argv, envp)
if (++i == argc)
usage ();
path_dhcpd_conf = argv [i];
no_dhcpd_conf = 1;
} else if (!strcmp (argv [i], "-lf")) {
if (++i == argc)
usage ();
path_dhcpd_db = argv [i];
no_dhcpd_db = 1;
} else if (!strcmp (argv [i], "-pf")) {
if (++i == argc)
usage ();
path_dhcpd_pid = argv [i];
no_dhcpd_pid = 1;
} else if (!strcmp (argv [i], "-t")) {
/* test configurations only */
#ifndef DEBUG
@ -268,6 +274,16 @@ int main (argc, argv, envp)
}
}
if (!no_dhcpd_conf && (s = getenv ("PATH_DHCPD_CONF"))) {
path_dhcpd_conf = s;
}
if (!no_dhcpd_db && (s = getenv ("PATH_DHCPD_DB"))) {
path_dhcpd_db = s;
}
if (!no_dhcpd_pid && (s = getenv ("PATH_DHCPD_PID"))) {
path_dhcpd_pid = s;
}
if (!quiet) {
log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright);

View File

@ -1404,6 +1404,24 @@ The \fIddns-updates\fR parameter controls whether or not the server will
attempt to do a ddns update when a lease is confirmed. Set this to \fIoff\fR
if the server should not attempt to do updates within a certain scope.
The \fIddns-updates\fR parameter is on by default.
.SH SETTING PARAMETER VALUES USING EXPRESSIONS
Sometimes it's helpful to be able to set the value of a DHCP server
parameter based on some value that the client has sent. To do this,
you can use expression evaluation. The
.B dhcp-eval(5)
manual page describes how to write expressions. To assign the result
of an evaluation to an option, define the option as follows:
.nf
.sp 1
\fImy-parameter \fB= \fIexpression \fB;\fR
.fi
.PP
For example:
.nf
.sp 1
ddns-hostname = binary-to-ascii (16, 8, "-",
substring (hardware, 1, 6));
.fi
.SH REFERENCE: OPTION STATEMENTS
.PP
DHCP option statements are documented in the