mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-01 14:55:30 +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
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -70,6 +70,8 @@ char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
|
|||||||
char *path_dhclient_db = _PATH_DHCLIENT_DB;
|
char *path_dhclient_db = _PATH_DHCLIENT_DB;
|
||||||
char *path_dhclient_pid = _PATH_DHCLIENT_PID;
|
char *path_dhclient_pid = _PATH_DHCLIENT_PID;
|
||||||
|
|
||||||
|
int interfaces_requested = 0;
|
||||||
|
|
||||||
int log_perror = 1;
|
int log_perror = 1;
|
||||||
|
|
||||||
struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
|
struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
|
||||||
@@ -134,6 +136,7 @@ int main (argc, argv, envp)
|
|||||||
strcpy (tmp -> name, argv [i]);
|
strcpy (tmp -> name, argv [i]);
|
||||||
tmp -> next = interfaces;
|
tmp -> next = interfaces;
|
||||||
tmp -> flags = INTERFACE_REQUESTED;
|
tmp -> flags = INTERFACE_REQUESTED;
|
||||||
|
interfaces_requested = 1;
|
||||||
interfaces = tmp;
|
interfaces = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +200,9 @@ int main (argc, argv, envp)
|
|||||||
are relevant should be running, so now we once again call
|
are relevant should be running, so now we once again call
|
||||||
discover_interfaces(), and this time ask it to actually set
|
discover_interfaces(), and this time ask it to actually set
|
||||||
up the interfaces. */
|
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
|
/* Make up a seed for the random number generator from current
|
||||||
time plus the sum of the last four bytes of each
|
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... */
|
/* Set up the bootp packet handler... */
|
||||||
bootp_packet_handler = do_packet;
|
bootp_packet_handler = do_packet;
|
||||||
|
|
||||||
|
/* Start listening on the systat socket... */
|
||||||
|
systat_startup (status_message);
|
||||||
|
|
||||||
/* Start dispatching packets and timeouts... */
|
/* Start dispatching packets and timeouts... */
|
||||||
dispatch ();
|
dispatch ();
|
||||||
|
|
||||||
@@ -291,8 +299,10 @@ void state_reboot (ipp)
|
|||||||
ip -> client -> first_sending = cur_time;
|
ip -> client -> first_sending = cur_time;
|
||||||
ip -> client -> interval = ip -> client -> config -> initial_interval;
|
ip -> client -> interval = ip -> client -> config -> initial_interval;
|
||||||
|
|
||||||
/* Add an immediate timeout to cause the first DHCPDISCOVER packet
|
/* Zap the medium list... */
|
||||||
to go out. */
|
ip -> client -> medium = (struct string_list *)0;
|
||||||
|
|
||||||
|
/* Send out the first DHCPREQUEST packet. */
|
||||||
send_request (ip);
|
send_request (ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,12 +494,12 @@ void dhcpack (packet)
|
|||||||
void bind_lease (ip)
|
void bind_lease (ip)
|
||||||
struct interface_info *ip;
|
struct interface_info *ip;
|
||||||
{
|
{
|
||||||
/* Write out the new lease. */
|
|
||||||
write_client_lease (ip, ip -> client -> new);
|
|
||||||
|
|
||||||
/* Remember the medium. */
|
/* Remember the medium. */
|
||||||
ip -> client -> new -> medium = ip -> client -> 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. */
|
/* Run the client script with the new parameters. */
|
||||||
script_init (ip, (ip -> client -> state == S_REQUESTING
|
script_init (ip, (ip -> client -> state == S_REQUESTING
|
||||||
? "BOUND"
|
? "BOUND"
|
||||||
@@ -659,6 +669,7 @@ void dhcpoffer (packet)
|
|||||||
|
|
||||||
note ("%s from %s", name, piaddr (packet -> client_addr));
|
note ("%s from %s", name, piaddr (packet -> client_addr));
|
||||||
|
|
||||||
|
|
||||||
/* If this lease doesn't supply the minimum required parameters,
|
/* If this lease doesn't supply the minimum required parameters,
|
||||||
blow it off. */
|
blow it off. */
|
||||||
for (i = 0; ip -> client -> config -> required_options [i]; i++) {
|
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) {
|
if (packet -> options [i].len) {
|
||||||
lease -> options [i].data =
|
lease -> options [i].data =
|
||||||
(unsigned char *)
|
(unsigned char *)
|
||||||
malloc (packet -> options [i].len);
|
malloc (packet -> options [i].len + 1);
|
||||||
if (!lease -> options [i].data) {
|
if (!lease -> options [i].data) {
|
||||||
warn ("dhcpoffer: no memory for option %d\n",
|
warn ("dhcpoffer: no memory for option %d\n",
|
||||||
i);
|
i);
|
||||||
@@ -789,6 +800,8 @@ struct client_lease *packet_to_lease (packet)
|
|||||||
packet -> options [i].len);
|
packet -> options [i].len);
|
||||||
lease -> options [i].len =
|
lease -> options [i].len =
|
||||||
packet -> 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 ||
|
if ((ip -> client -> state == S_REBOOTING ||
|
||||||
ip -> client -> state == S_REQUESTING) &&
|
ip -> client -> state == S_REQUESTING) &&
|
||||||
interval > ip -> client -> config -> reboot_timeout) {
|
interval > ip -> client -> config -> reboot_timeout) {
|
||||||
|
cancel:
|
||||||
ip -> client -> state = S_INIT;
|
ip -> client -> state = S_INIT;
|
||||||
cancel_timeout (send_request, ip);
|
cancel_timeout (send_request, ip);
|
||||||
state_init (ip);
|
state_init (ip);
|
||||||
return;
|
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
|
/* If the lease has expired, relinquish the address and go back
|
||||||
to the INIT state. */
|
to the INIT state. */
|
||||||
if (ip -> client -> state != S_REQUESTING &&
|
if (ip -> client -> state != S_REQUESTING &&
|
||||||
@@ -1327,7 +1356,7 @@ void make_discover (ip, lease)
|
|||||||
/* Set up the option buffer... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||||
options, 0, 0);
|
options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
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... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||||
options, 0, 0);
|
options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
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... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||||
options, 0, 0);
|
options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
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... */
|
/* Set up the option buffer... */
|
||||||
ip -> client -> packet_length =
|
ip -> client -> packet_length =
|
||||||
cons_options ((struct packet *)0, &ip -> client -> packet,
|
cons_options ((struct packet *)0, &ip -> client -> packet,
|
||||||
options, 0, 0);
|
options, 0, 0, 0);
|
||||||
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
if (ip -> client -> packet_length < BOOTP_MIN_LEN)
|
||||||
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;
|
char *reason;
|
||||||
struct string_list *medium;
|
struct string_list *medium;
|
||||||
{
|
{
|
||||||
strcpy (scriptName, "/tmp/dcsXXXXXX");
|
int fd;
|
||||||
mktemp (scriptName);
|
#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)
|
if (!scriptFile)
|
||||||
error ("can't write script file: %m");
|
error ("can't write script file: %m");
|
||||||
fprintf (scriptFile, "#!/bin/sh\n\n");
|
fprintf (scriptFile, "#!/bin/sh\n\n");
|
||||||
@@ -1925,8 +1965,10 @@ void go_daemon ()
|
|||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
/* Don't become a daemon if the user requested otherwise. */
|
/* Don't become a daemon if the user requested otherwise. */
|
||||||
if (no_daemon)
|
if (no_daemon) {
|
||||||
|
write_client_pid_file ();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only do it once. */
|
/* Only do it once. */
|
||||||
if (state)
|
if (state)
|
||||||
@@ -1943,5 +1985,70 @@ void go_daemon ()
|
|||||||
exit (0);
|
exit (0);
|
||||||
/* Become session leader and get pid... */
|
/* Become session leader and get pid... */
|
||||||
pid = setsid ();
|
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