mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 06:15:55 +00:00
Add support for interfaces_requested flag. NUL-terminate copied lease options. Add cons_option parameter. Support system status messages
This commit is contained in:
@@ -56,7 +56,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: dhclient.c,v 1.39 1997/06/03 01:40:58 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: dhclient.c,v 1.40 1997/09/16 18:09:41 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -70,6 +70,8 @@ char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
|
||||
char *path_dhclient_db = _PATH_DHCLIENT_DB;
|
||||
char *path_dhclient_pid = _PATH_DHCLIENT_PID;
|
||||
|
||||
int interfaces_requested = 0;
|
||||
|
||||
int log_perror = 1;
|
||||
|
||||
struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
|
||||
@@ -134,6 +136,7 @@ int main (argc, argv, envp)
|
||||
strcpy (tmp -> name, argv [i]);
|
||||
tmp -> next = interfaces;
|
||||
tmp -> flags = INTERFACE_REQUESTED;
|
||||
interfaces_requested = 1;
|
||||
interfaces = tmp;
|
||||
}
|
||||
}
|
||||
@@ -197,7 +200,9 @@ int main (argc, argv, envp)
|
||||
are relevant should be running, so now we once again call
|
||||
discover_interfaces(), and this time ask it to actually set
|
||||
up the interfaces. */
|
||||
discover_interfaces (DISCOVER_RUNNING);
|
||||
discover_interfaces (interfaces_requested
|
||||
? DISCOVER_REQUESTED
|
||||
: DISCOVER_RUNNING);
|
||||
|
||||
/* Make up a seed for the random number generator from current
|
||||
time plus the sum of the last four bytes of each
|
||||
@@ -223,6 +228,9 @@ int main (argc, argv, envp)
|
||||
/* Set up the bootp packet handler... */
|
||||
bootp_packet_handler = do_packet;
|
||||
|
||||
/* Start listening on the systat socket... */
|
||||
systat_startup (status_message);
|
||||
|
||||
/* Start dispatching packets and timeouts... */
|
||||
dispatch ();
|
||||
|
||||
@@ -291,8 +299,10 @@ void state_reboot (ipp)
|
||||
ip -> client -> first_sending = cur_time;
|
||||
ip -> client -> interval = ip -> client -> config -> initial_interval;
|
||||
|
||||
/* Add an immediate timeout to cause the first DHCPDISCOVER packet
|
||||
to go out. */
|
||||
/* Zap the medium list... */
|
||||
ip -> client -> medium = (struct string_list *)0;
|
||||
|
||||
/* Send out the first DHCPREQUEST packet. */
|
||||
send_request (ip);
|
||||
}
|
||||
|
||||
@@ -484,12 +494,12 @@ void dhcpack (packet)
|
||||
void bind_lease (ip)
|
||||
struct interface_info *ip;
|
||||
{
|
||||
/* Write out the new lease. */
|
||||
write_client_lease (ip, ip -> client -> new);
|
||||
|
||||
/* Remember the medium. */
|
||||
ip -> client -> new -> medium = ip -> client -> medium;
|
||||
|
||||
/* Write out the new lease. */
|
||||
write_client_lease (ip, ip -> client -> new);
|
||||
|
||||
/* Run the client script with the new parameters. */
|
||||
script_init (ip, (ip -> client -> state == S_REQUESTING
|
||||
? "BOUND"
|
||||
@@ -659,6 +669,7 @@ void dhcpoffer (packet)
|
||||
|
||||
note ("%s from %s", name, piaddr (packet -> client_addr));
|
||||
|
||||
|
||||
/* If this lease doesn't supply the minimum required parameters,
|
||||
blow it off. */
|
||||
for (i = 0; ip -> client -> config -> required_options [i]; i++) {
|
||||
@@ -777,7 +788,7 @@ struct client_lease *packet_to_lease (packet)
|
||||
if (packet -> options [i].len) {
|
||||
lease -> options [i].data =
|
||||
(unsigned char *)
|
||||
malloc (packet -> options [i].len);
|
||||
malloc (packet -> options [i].len + 1);
|
||||
if (!lease -> options [i].data) {
|
||||
warn ("dhcpoffer: no memory for option %d\n",
|
||||
i);
|
||||
@@ -789,6 +800,8 @@ struct client_lease *packet_to_lease (packet)
|
||||
packet -> options [i].len);
|
||||
lease -> options [i].len =
|
||||
packet -> options [i].len;
|
||||
lease -> options [i].data
|
||||
[lease -> options [i].len] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1114,12 +1127,28 @@ void send_request (ipp)
|
||||
if ((ip -> client -> state == S_REBOOTING ||
|
||||
ip -> client -> state == S_REQUESTING) &&
|
||||
interval > ip -> client -> config -> reboot_timeout) {
|
||||
cancel:
|
||||
ip -> client -> state = S_INIT;
|
||||
cancel_timeout (send_request, ip);
|
||||
state_init (ip);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're in the reboot state, make sure the media is set up
|
||||
correctly. */
|
||||
if (ip -> client -> state == S_REBOOTING &&
|
||||
!ip -> client -> medium &&
|
||||
ip -> client -> active -> medium ) {
|
||||
script_init (ip, "MEDIUM", ip -> client -> active -> medium);
|
||||
|
||||
/* If the medium we chose won't fly, go to INIT state. */
|
||||
if (script_go (ip))
|
||||
goto cancel;
|
||||
|
||||
/* Record the medium. */
|
||||
ip -> client -> medium = ip -> client -> active -> medium;
|
||||
}
|
||||
|
||||
/* If the lease has expired, relinquish the address and go back
|
||||
to the INIT state. */
|
||||
if (ip -> client -> state != S_REQUESTING &&
|
||||
@@ -1327,7 +1356,7 @@ void make_discover (ip, lease)
|
||||
/* Set up the option buffer... */
|
||||
ip -> client -> packet_length =
|
||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||
options, 0, 0);
|
||||
options, 0, 0, 0);
|
||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||
|
||||
@@ -1434,7 +1463,7 @@ void make_request (ip, lease)
|
||||
/* Set up the option buffer... */
|
||||
ip -> client -> packet_length =
|
||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||
options, 0, 0);
|
||||
options, 0, 0, 0);
|
||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||
|
||||
@@ -1533,7 +1562,7 @@ void make_decline (ip, lease)
|
||||
/* Set up the option buffer... */
|
||||
ip -> client -> packet_length =
|
||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||
options, 0, 0);
|
||||
options, 0, 0, 0);
|
||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||
|
||||
@@ -1599,7 +1628,7 @@ void make_release (ip, lease)
|
||||
/* Set up the option buffer... */
|
||||
ip -> client -> packet_length =
|
||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||
options, 0, 0);
|
||||
options, 0, 0, 0);
|
||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||
ip -> client -> packet_length = BOOTP_MIN_LEN;
|
||||
|
||||
@@ -1755,10 +1784,21 @@ void script_init (ip, reason, medium)
|
||||
char *reason;
|
||||
struct string_list *medium;
|
||||
{
|
||||
strcpy (scriptName, "/tmp/dcsXXXXXX");
|
||||
mktemp (scriptName);
|
||||
int fd;
|
||||
#ifndef HAVE_MKSTEMP
|
||||
|
||||
scriptFile = fopen (scriptName, "w");
|
||||
do {
|
||||
#endif
|
||||
strcpy (scriptName, "/tmp/dcsXXXXXX");
|
||||
#ifdef HAVE_MKSTEMP
|
||||
fd = mkstemp (scriptName);
|
||||
#else
|
||||
mktemp (scriptName);
|
||||
fd = creat (scriptName, 0600);
|
||||
} while (fd < 0);
|
||||
#endif
|
||||
|
||||
scriptFile = fdopen (fd, "w");
|
||||
if (!scriptFile)
|
||||
error ("can't write script file: %m");
|
||||
fprintf (scriptFile, "#!/bin/sh\n\n");
|
||||
@@ -1925,8 +1965,10 @@ void go_daemon ()
|
||||
int pid;
|
||||
|
||||
/* Don't become a daemon if the user requested otherwise. */
|
||||
if (no_daemon)
|
||||
if (no_daemon) {
|
||||
write_client_pid_file ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only do it once. */
|
||||
if (state)
|
||||
@@ -1943,5 +1985,70 @@ void go_daemon ()
|
||||
exit (0);
|
||||
/* Become session leader and get pid... */
|
||||
pid = setsid ();
|
||||
|
||||
write_client_pid_file ();
|
||||
}
|
||||
|
||||
void write_client_pid_file ()
|
||||
{
|
||||
FILE *pf;
|
||||
int pfdesc;
|
||||
|
||||
pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
||||
|
||||
if (pfdesc < 0) {
|
||||
warn ("Can't create %s: %m", path_dhclient_pid);
|
||||
return;
|
||||
}
|
||||
|
||||
pf = fdopen (pfdesc, "w");
|
||||
if (!pf)
|
||||
warn ("Can't fdopen %s: %m", path_dhclient_pid);
|
||||
else {
|
||||
fprintf (pf, "%d\n", getpid ());
|
||||
fclose (pf);
|
||||
}
|
||||
}
|
||||
|
||||
void status_message (header, data)
|
||||
struct systat_header *header;
|
||||
void *data;
|
||||
{
|
||||
switch (header -> type) {
|
||||
case NETWORK_LOCATION_CHANGED:
|
||||
client_location_changed ();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void client_location_changed ()
|
||||
{
|
||||
struct interface_info *ip;
|
||||
|
||||
for (ip = interfaces; ip; ip = ip -> next) {
|
||||
switch (ip -> client -> state) {
|
||||
case S_SELECTING:
|
||||
cancel_timeout (send_discover, ip);
|
||||
break;
|
||||
|
||||
case S_BOUND:
|
||||
cancel_timeout (state_bound, ip);
|
||||
break;
|
||||
|
||||
case S_REBOOTING:
|
||||
case S_REQUESTING:
|
||||
case S_RENEWING:
|
||||
cancel_timeout (send_request, ip);
|
||||
break;
|
||||
|
||||
case S_INIT:
|
||||
case S_REBINDING:
|
||||
break;
|
||||
}
|
||||
ip -> client -> state = S_INIT;
|
||||
state_reboot (ip);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user