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 #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
static TIME parsed_time; static TIME parsed_time;
char client_script_name [] = "/etc/dhclient-script";
struct client_config top_level_config; struct client_config top_level_config;
u_int32_t default_requested_options [] = { 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.backoff_cutoff = 15;
top_level_config.initial_interval = 3; top_level_config.initial_interval = 3;
top_level_config.bootp_policy = P_ACCEPT; 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.requested_options = default_requested_options;
top_level_config.omapi_port = -1; top_level_config.omapi_port = -1;

View File

@ -41,7 +41,7 @@
#ifndef lint #ifndef lint
static char ocopyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -104,6 +104,10 @@ int main (argc, argv, envp)
isc_result_t result; isc_result_t result;
int persist = 0; int persist = 0;
int omapi_port; int omapi_port;
int no_dhclient_conf = 0;
int no_dhclient_db = 0;
int no_dhclient_pid = 0;
char *s;
#ifdef SYSLOG_4_2 #ifdef SYSLOG_4_2
openlog ("dhclient", LOG_NDELAY); openlog ("dhclient", LOG_NDELAY);
@ -147,14 +151,17 @@ int main (argc, argv, envp)
if (++i == argc) if (++i == argc)
usage (); usage ();
path_dhclient_pid = argv [i]; path_dhclient_pid = argv [i];
no_dhclient_pid = 1;
} else if (!strcmp (argv [i], "-cf")) { } else if (!strcmp (argv [i], "-cf")) {
if (++i == argc) if (++i == argc)
usage (); usage ();
path_dhclient_conf = argv [i]; path_dhclient_conf = argv [i];
no_dhclient_conf = 1;
} else if (!strcmp (argv [i], "-lf")) { } else if (!strcmp (argv [i], "-lf")) {
if (++i == argc) if (++i == argc)
usage (); usage ();
path_dhclient_db = argv [i]; path_dhclient_db = argv [i];
no_dhclient_db = 1;
} else if (!strcmp (argv [i], "-q")) { } else if (!strcmp (argv [i], "-q")) {
quiet = 1; quiet = 1;
quiet_interface_discovery = 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 */ /* first kill of any currently running client */
if (release_mode) { if (release_mode) {
/* XXX inelegant hack to prove concept */ /* XXX inelegant hack to prove concept */
@ -2117,46 +2134,29 @@ void script_init (client, reason, medium)
const char *reason; const char *reason;
struct string_list *medium; struct string_list *medium;
{ {
int fd; struct string_list *sl, *next;
#ifndef HAVE_MKSTEMP
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) { 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) { if (client -> interface) {
fprintf (scriptFile, "interface=\"%s\"\n", client_envadd (client, "", "interface", "%s",
client -> interface -> name); client -> interface -> name);
fprintf (scriptFile, "export interface\n");
} }
if (client -> name) if (client -> name)
fprintf (scriptFile, "client=\"%s\"\n", client_envadd (client,
client -> name); "", "client", "%s", client -> name);
fprintf (scriptFile, "export client\n"); 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) void script_write_params (client, prefix, lease)
@ -2168,10 +2168,10 @@ void script_write_params (client, prefix, lease)
struct data_string data; struct data_string data;
struct option_cache *oc; struct option_cache *oc;
pair *hash; pair *hash;
char *s, *t;
fprintf (scriptFile, "%sip_address=\"%s\"\n", client_envadd (client,
prefix, piaddr (lease -> address)); prefix, "ip_address", "%s", piaddr (lease -> address));
fprintf (scriptFile, "export %sip_address\n", prefix);
/* For the benefit of Linux (and operating systems which may /* For the benefit of Linux (and operating systems which may
have similar needs), compute the network address based on 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); subnet = subnet_number (lease -> address, netmask);
if (subnet.len) { if (subnet.len) {
fprintf (scriptFile, client_envadd (client, prefix, "network_number",
"%snetwork_number=\"%s\";\n", "%s", piaddr (subnet));
prefix, piaddr (subnet));
fprintf (scriptFile,
"export %snetwork_number\n", prefix);
oc = lookup_option (&dhcp_universe, oc = lookup_option (&dhcp_universe,
lease -> options, lease -> options,
DHO_BROADCAST_ADDRESS); DHO_BROADCAST_ADDRESS);
if (!oc || if (!oc ||
!(evaluate_option_cache !(evaluate_option_cache
(&data, (struct packet *)0, (&data, (struct packet *)0,
(struct lease *)0, (struct lease *)0,
(struct option_state *)0, (struct option_state *)0,
lease -> options, lease -> options,
&global_scope, oc, MDL))) { &global_scope, oc, MDL))) {
broadcast = broadcast_addr (subnet, broadcast = broadcast_addr (subnet, netmask);
netmask); if (broadcast.len) {
if (broadcast.len) { client_envadd (client,
fprintf (scriptFile, prefix, "broadcast_address",
"%s%s=\"%s\";\n", "%s", piaddr (broadcast));
prefix,
"broadcast_address",
piaddr (broadcast));
fprintf (scriptFile,
"export %s%s\n",
prefix,
"broadcast_address");
}
} }
}
} }
} }
data_string_forget (&data, MDL); data_string_forget (&data, MDL);
} }
if (lease -> filename) { if (lease -> filename)
fprintf (scriptFile, "%sfilename=\"%s\";\n", client_envadd (client,
prefix, lease -> filename); prefix, "filename", "%s", lease -> filename);
fprintf (scriptFile, "export %sfilename\n", prefix); if (lease -> server_name)
} client_envadd (client, prefix, "server_name",
if (lease -> server_name) { "%s", lease -> server_name);
fprintf (scriptFile, "%sserver_name=\"%s\";\n",
prefix, lease -> server_name);
fprintf (scriptFile, "export %sserver_name\n", prefix);
}
execute_statements_in_scope ((struct packet *)0, execute_statements_in_scope ((struct packet *)0,
(struct lease *)0, lease -> options, (struct lease *)0, lease -> options,
@ -2251,78 +2237,155 @@ void script_write_params (client, prefix, lease)
hash = lease -> options -> universes [dhcp_universe.index]; hash = lease -> options -> universes [dhcp_universe.index];
for (i = 0; i < OPTION_HASH_SIZE; i++) { for (i = 0; i < OPTION_HASH_SIZE; i++) {
pair hp; pair hp;
for (hp = hash [i]; hp; hp = hp -> cdr) { for (hp = hash [i]; hp; hp = hp -> cdr) {
oc = (struct option_cache *)hp -> car; oc = (struct option_cache *)hp -> car;
if (evaluate_option_cache (&data, if (evaluate_option_cache (&data,
(struct packet *)0, (struct packet *)0,
(struct lease *)0, (struct lease *)0,
(struct option_state *)0, (struct option_state *)0,
lease -> options, lease -> options,
&global_scope, oc, MDL)) { &global_scope, oc, MDL)) {
if (data.len) {
if (data.len) { char name [256];
char *s = (dhcp_option_ev_name if (dhcp_option_ev_name (name, sizeof name,
(oc -> option)); oc -> option)) {
client_envadd (client, prefix, name, "%s",
fprintf (scriptFile, (pretty_print_option
"%s%s=\"%s\"\n", prefix, s, (oc -> option -> code,
(pretty_print_option data.data, data.len,
(oc -> option -> code, 0, 0)));
data.data, data.len, data_string_forget (&data, MDL);
0, 0)));
fprintf (scriptFile,
"export %s%s\n", prefix, s);
}
data_string_forget (&data, MDL);
} }
}
} }
}
} }
fprintf (scriptFile, "%sexpiry=\"%d\"\n", client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
prefix, (int)lease -> expiry); /* XXX */
fprintf (scriptFile, "export %sexpiry\n", prefix);
} }
int script_go (client) int script_go (client)
struct client_state *client; struct client_state *client;
{ {
int rval; int rval;
char *scriptName;
if (client) char *argv [2];
fprintf (scriptFile, "%s\n", char **envp;
client -> config -> script_name); char *epp [3];
else char reason [] = "REASON=NBI";
fprintf (scriptFile, "%s\n", static char client_path [] = CLIENT_PATH;
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];
int i; int i;
struct string_list *sp, *next;
int pid, wpid, wstatus;
if (strlen (option -> name) + 1 > sizeof evbuf) if (client) {
log_fatal ("option %s name is larger than static buffer.", scriptName = client -> config -> script_name;
option -> name); envp = dmalloc ((client -> envc + 2) * sizeof (char *),
for (i = 0; option -> name [i]; i++) { MDL);
if (option -> name [i] == '-') if (!envp) {
evbuf [i] = '_'; log_error ("No memory for client script environment.");
else return 0;
evbuf [i] = option -> name [i]; }
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; argv [0] = scriptName;
return evbuf; 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 () void go_daemon ()

View File

@ -87,7 +87,25 @@ hexadecimal, seperated by colons. For example:
or or
option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f; option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
.fi .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 .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 The documentation for the various options mentioned below is taken
from the latest IETF draft document on DHCP options. Options which 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, 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 u_int32_t requested_lease; /* Requested lease time, if user
doesn't configure one. */ doesn't configure one. */
struct string_list *media; /* Possible network media values. */ 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; enum policy bootp_policy;
/* Ignore, accept or prefer BOOTP /* Ignore, accept or prefer BOOTP
responses. */ responses. */
@ -708,6 +708,8 @@ struct client_state {
struct iaddr requested_address; /* Address we would like to get. */ struct iaddr requested_address; /* Address we would like to get. */
struct client_config *config; /* Client configuration. */ 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. */ /* Information about each network interface. */
@ -1636,13 +1638,16 @@ void destroy_client_lease PROTO ((struct client_lease *));
void rewrite_client_leases PROTO ((void)); void rewrite_client_leases PROTO ((void));
int write_client_lease PROTO ((struct client_state *, int write_client_lease PROTO ((struct client_state *,
struct client_lease *, int, int)); 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 *, void script_init PROTO ((struct client_state *, const char *,
struct string_list *)); struct string_list *));
void script_write_params PROTO ((struct client_state *, void script_write_params PROTO ((struct client_state *,
const char *, struct client_lease *)); const char *, struct client_lease *));
int script_go PROTO ((struct client_state *)); 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 *)); struct client_lease *packet_to_lease PROTO ((struct packet *));
void go_daemon PROTO ((void)); void go_daemon PROTO ((void));

View File

@ -1,3 +1,3 @@
/* Current version of ISC DHCP Distribution. */ /* 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); omapi_io_reference (&ph, obj, MDL);
/* remove from the list of I/O states */ /* remove from the list of I/O states */
last = &omapi_io_states;
for (p = omapi_io_states.next; p; p = p -> next) { for (p = omapi_io_states.next; p; p = p -> next) {
if (p == obj) { if (p == obj) {
omapi_io_dereference (&last -> next, MDL); omapi_io_dereference (&last -> next, MDL);

View File

@ -43,7 +43,7 @@
#ifndef lint #ifndef lint
static char ocopyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -124,6 +124,7 @@ int main (argc, argv, envp)
int no_daemon = 0; int no_daemon = 0;
int quiet = 0; int quiet = 0;
isc_result_t status; isc_result_t status;
char *s;
#ifdef SYSLOG_4_2 #ifdef SYSLOG_4_2
openlog ("dhcrelay", LOG_NDELAY); 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) { if (!quiet) {
log_info ("%s %s", message, DHCP_VERSION); log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright); log_info (copyright);

View File

@ -43,7 +43,7 @@
#ifndef lint #ifndef lint
static char ocopyright[] = 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 #endif
static char copyright[] = static char copyright[] =
@ -166,6 +166,9 @@ int main (argc, argv, envp)
struct parse *parse; struct parse *parse;
int lose; int lose;
int omapi_port; int omapi_port;
int no_dhcpd_conf = 0;
int no_dhcpd_db = 0;
int no_dhcpd_pid = 0;
/* Set up the client classification system. */ /* Set up the client classification system. */
classification_setup (); classification_setup ();
@ -221,14 +224,17 @@ int main (argc, argv, envp)
if (++i == argc) if (++i == argc)
usage (); usage ();
path_dhcpd_conf = argv [i]; path_dhcpd_conf = argv [i];
no_dhcpd_conf = 1;
} else if (!strcmp (argv [i], "-lf")) { } else if (!strcmp (argv [i], "-lf")) {
if (++i == argc) if (++i == argc)
usage (); usage ();
path_dhcpd_db = argv [i]; path_dhcpd_db = argv [i];
no_dhcpd_db = 1;
} else if (!strcmp (argv [i], "-pf")) { } else if (!strcmp (argv [i], "-pf")) {
if (++i == argc) if (++i == argc)
usage (); usage ();
path_dhcpd_pid = argv [i]; path_dhcpd_pid = argv [i];
no_dhcpd_pid = 1;
} else if (!strcmp (argv [i], "-t")) { } else if (!strcmp (argv [i], "-t")) {
/* test configurations only */ /* test configurations only */
#ifndef DEBUG #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) { if (!quiet) {
log_info ("%s %s", message, DHCP_VERSION); log_info ("%s %s", message, DHCP_VERSION);
log_info (copyright); 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 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. if the server should not attempt to do updates within a certain scope.
The \fIddns-updates\fR parameter is on by default. 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 .SH REFERENCE: OPTION STATEMENTS
.PP .PP
DHCP option statements are documented in the DHCP option statements are documented in the