mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-29 13:28:14 +00:00
Cygwin32 compatibility. Handle prepend, append and supersede option modifiers. Minimal BOOTP support. Handle seed generation differently.
This commit is contained in:
parent
d7c8ea3224
commit
66f973e41e
@ -56,7 +56,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: dhclient.c,v 1.35 1997/03/29 01:24:30 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: dhclient.c,v 1.36 1997/05/09 07:54:14 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@ -99,6 +99,7 @@ int main (argc, argv, envp)
|
||||
int i;
|
||||
struct servent *ent;
|
||||
struct interface_info *ip;
|
||||
int seed;
|
||||
|
||||
#ifdef SYSLOG_4_2
|
||||
openlog ("dhclient", LOG_NDELAY);
|
||||
@ -107,7 +108,7 @@ int main (argc, argv, envp)
|
||||
openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
|
||||
#endif
|
||||
|
||||
#if !(defined (DEBUG) || defined (SYSLOG_4_2))
|
||||
#if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
|
||||
setlogmask (LOG_UPTO (LOG_INFO));
|
||||
#endif
|
||||
|
||||
@ -143,7 +144,9 @@ int main (argc, argv, envp)
|
||||
local_port = htons (68);
|
||||
else
|
||||
local_port = ent -> s_port;
|
||||
#ifndef __CYGWIN32__
|
||||
endservent ();
|
||||
#endif
|
||||
}
|
||||
remote_port = htons (ntohs (local_port) - 1); /* XXX */
|
||||
|
||||
@ -196,9 +199,23 @@ int main (argc, argv, envp)
|
||||
up the interfaces. */
|
||||
discover_interfaces (DISCOVER_RUNNING);
|
||||
|
||||
/* Make up a seed for the random number generator from current
|
||||
time plus the sum of the last four bytes of each
|
||||
interface's hardware address interpreted as an integer.
|
||||
Not much entropy, but we're booting, so we're not likely to
|
||||
find anything better. */
|
||||
seed = 0; /* Unfortunately, what's on the stack isn't random. :') */
|
||||
for (ip = interfaces; ip; ip = ip -> next) {
|
||||
int junk;
|
||||
memcpy (&junk,
|
||||
&ip -> hw_address.haddr [ip -> hw_address.hlen -
|
||||
sizeof seed], sizeof seed);
|
||||
seed += junk;
|
||||
}
|
||||
srandom (seed + cur_time);
|
||||
|
||||
/* Start a configuration state machine for each interface. */
|
||||
for (ip = interfaces; ip; ip = ip -> next) {
|
||||
srandom (cur_time + *(int *)(&ip -> hw_address.haddr [0]));
|
||||
ip -> client -> state = S_INIT;
|
||||
state_reboot (ip);
|
||||
}
|
||||
@ -258,7 +275,8 @@ void state_reboot (ipp)
|
||||
|
||||
/* If we don't remember an active lease, go straight to INIT. */
|
||||
if (!ip -> client -> active ||
|
||||
ip -> client -> active -> rebind < cur_time) {
|
||||
ip -> client -> active -> rebind < cur_time ||
|
||||
ip -> client -> active -> is_bootp) {
|
||||
state_init (ip);
|
||||
return;
|
||||
}
|
||||
@ -359,6 +377,23 @@ void state_selecting (ipp)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If it was a BOOTREPLY, we can just take the address right now. */
|
||||
if (!picked -> options [DHO_DHCP_MESSAGE_TYPE].len) {
|
||||
ip -> client -> new = picked;
|
||||
|
||||
/* Make up some lease expiry times
|
||||
XXX these should be configurable. */
|
||||
ip -> client -> new -> expiry = cur_time + 12000;
|
||||
ip -> client -> new -> renewal += cur_time + 8000;
|
||||
ip -> client -> new -> rebind += cur_time + 10000;
|
||||
|
||||
ip -> client -> state = S_REQUESTING;
|
||||
|
||||
/* Bind to the address we received. */
|
||||
bind_lease (ip);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Go to the REQUESTING state. */
|
||||
ip -> client -> destination = iaddr_broadcast;
|
||||
ip -> client -> state = S_REQUESTING;
|
||||
@ -447,6 +482,12 @@ void dhcpack (packet)
|
||||
ip -> client -> new -> renewal += cur_time;
|
||||
ip -> client -> new -> rebind += cur_time;
|
||||
|
||||
bind_lease (ip);
|
||||
}
|
||||
|
||||
void bind_lease (ip)
|
||||
struct interface_info *ip;
|
||||
{
|
||||
/* Write out the new lease. */
|
||||
write_client_lease (ip, ip -> client -> new);
|
||||
|
||||
@ -478,7 +519,8 @@ void dhcpack (packet)
|
||||
add_timeout (ip -> client -> active -> renewal,
|
||||
state_bound, ip);
|
||||
|
||||
note ("bound: renewal in %d seconds.",
|
||||
note ("bound to %s -- renewal in %d seconds.",
|
||||
piaddr (ip -> client -> active -> address),
|
||||
ip -> client -> active -> renewal - cur_time);
|
||||
ip -> client -> state = S_BOUND;
|
||||
reinitialize_interfaces ();
|
||||
@ -536,10 +578,9 @@ void db_startup ()
|
||||
void bootp (packet)
|
||||
struct packet *packet;
|
||||
{
|
||||
note ("BOOTREPLY from %s",
|
||||
print_hw_addr (packet -> raw -> htype,
|
||||
packet -> raw -> hlen,
|
||||
packet -> raw -> chaddr));
|
||||
if (packet -> raw -> op == BOOTREPLY)
|
||||
dhcpoffer (packet);
|
||||
|
||||
}
|
||||
|
||||
void dhcp (packet)
|
||||
@ -570,6 +611,8 @@ void dhcpoffer (packet)
|
||||
struct client_lease *lease, *lp;
|
||||
int i;
|
||||
int arp_timeout_needed, stop_selecting;
|
||||
char *name = (packet -> options [DHO_DHCP_MESSAGE_TYPE].len
|
||||
? "DHCPOFFER" : "BOOTREPLY");
|
||||
|
||||
#ifdef DEBUG_PACKET
|
||||
dump_packet (packet);
|
||||
@ -579,11 +622,11 @@ void dhcpoffer (packet)
|
||||
has an unrecognizable transaction id, then just drop it. */
|
||||
if (ip -> client -> state != S_SELECTING ||
|
||||
packet -> interface -> client -> xid != packet -> raw -> xid) {
|
||||
debug ("DHCPOFFER in wrong transaction.");
|
||||
debug ("%s in wrong transaction.", name);
|
||||
return;
|
||||
}
|
||||
|
||||
note ("DHCPOFFER from %s",
|
||||
note ("%s from %s", name,
|
||||
print_hw_addr (packet -> raw -> htype,
|
||||
packet -> raw -> hlen,
|
||||
packet -> raw -> chaddr));
|
||||
@ -593,7 +636,7 @@ void dhcpoffer (packet)
|
||||
for (i = 0; ip -> client -> config -> required_options [i]; i++) {
|
||||
if (!packet -> options [ip -> client -> config ->
|
||||
required_options [i]].len) {
|
||||
note ("DHCPOFFER isn't satisfactory.");
|
||||
note ("%s isn't satisfactory.", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -604,7 +647,7 @@ void dhcpoffer (packet)
|
||||
if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
|
||||
!memcmp (lease -> address.iabuf,
|
||||
&packet -> raw -> yiaddr, lease -> address.len)) {
|
||||
debug ("DHCPOFFER already seen.");
|
||||
debug ("%s already seen.", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -615,6 +658,11 @@ void dhcpoffer (packet)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this lease was acquired through a BOOTREPLY, record that
|
||||
fact. */
|
||||
if (!packet -> options [DHO_DHCP_MESSAGE_TYPE].len)
|
||||
lease -> is_bootp = 1;
|
||||
|
||||
/* Record the medium under which this lease was offered. */
|
||||
lease -> medium = ip -> client -> medium;
|
||||
|
||||
@ -806,10 +854,8 @@ void dhcpnak (packet)
|
||||
}
|
||||
|
||||
/* Send out a DHCPDISCOVER packet, and set a timeout to send out another
|
||||
one after the right interval has expired. If we are past the renewal
|
||||
(T1) interval but not yet past the rebind (T2) interval, unicast
|
||||
the message; otherwise broadcast it. If the lease expires, go back to
|
||||
the INIT state. */
|
||||
one after the right interval has expired. If we don't get an offer by
|
||||
the time we reach the panic interval, call the panic function. */
|
||||
|
||||
void send_discover (ipp)
|
||||
void *ipp;
|
||||
@ -893,17 +939,17 @@ void send_discover (ipp)
|
||||
(ip -> client -> first_sending +
|
||||
ip -> client -> config -> timeout) - cur_time + 1;
|
||||
|
||||
note ("DHCPDISCOVER on %s to %s port %d interval %ld",
|
||||
ip -> name,
|
||||
inet_ntoa (sockaddr_broadcast.sin_addr),
|
||||
ntohs (sockaddr_broadcast.sin_port), ip -> client -> interval);
|
||||
|
||||
/* Record the number of seconds since we started sending. */
|
||||
if (interval < 255)
|
||||
ip -> client -> packet.secs = interval;
|
||||
else
|
||||
ip -> client -> packet.secs = 255;
|
||||
|
||||
note ("DHCPDISCOVER on %s to %s port %d interval %ld",
|
||||
ip -> name,
|
||||
inet_ntoa (sockaddr_broadcast.sin_addr),
|
||||
ntohs (sockaddr_broadcast.sin_port), ip -> client -> interval);
|
||||
|
||||
/* Send out a packet. */
|
||||
result = send_packet (ip, (struct packet *)0,
|
||||
&ip -> client -> packet,
|
||||
@ -933,10 +979,8 @@ void state_panic (ipp)
|
||||
|
||||
/* We may not have an active lease, but we may have some
|
||||
predefined leases that we can try. */
|
||||
if (!ip -> client -> active && ip -> client -> leases) {
|
||||
loop = ip -> client -> leases;
|
||||
if (!ip -> client -> active && ip -> client -> leases)
|
||||
goto activate_next;
|
||||
}
|
||||
|
||||
/* Run through the list of leases and see if one can be used. */
|
||||
while (ip -> client -> active) {
|
||||
@ -1001,6 +1045,8 @@ void state_panic (ipp)
|
||||
now. */
|
||||
if (ip -> client -> active == loop)
|
||||
break;
|
||||
else if (!loop)
|
||||
loop = ip -> client -> active;
|
||||
}
|
||||
|
||||
/* No leases were available, or what was available didn't work, so
|
||||
@ -1626,6 +1672,8 @@ void write_client_lease (ip, lease)
|
||||
}
|
||||
|
||||
fprintf (leaseFile, "lease {\n");
|
||||
if (lease -> is_bootp)
|
||||
fprintf (leaseFile, " bootp;\n");
|
||||
fprintf (leaseFile, " interface \"%s\";\n", ip -> name);
|
||||
fprintf (leaseFile, " fixed-address %s;\n",
|
||||
piaddr (lease -> address));
|
||||
@ -1706,6 +1754,8 @@ void script_write_params (ip, prefix, lease)
|
||||
struct client_lease *lease;
|
||||
{
|
||||
int i;
|
||||
u_int8_t dbuf [1500];
|
||||
int len;
|
||||
|
||||
fprintf (scriptFile, "%sip_address=\"%s\"\n",
|
||||
prefix, piaddr (lease -> address));
|
||||
@ -1721,13 +1771,82 @@ void script_write_params (ip, prefix, lease)
|
||||
fprintf (scriptFile, "export %sserver_name\n", prefix);
|
||||
}
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (lease -> options [i].len) {
|
||||
u_int8_t *dp;
|
||||
|
||||
if (ip -> client -> config -> defaults [i].len) {
|
||||
if (lease -> options [i].len) {
|
||||
switch (ip -> client ->
|
||||
config -> default_actions [i]) {
|
||||
case ACTION_DEFAULT:
|
||||
dp = lease -> options [i].data;
|
||||
len = lease -> options [i].len;
|
||||
break;
|
||||
case ACTION_SUPERSEDE:
|
||||
supersede:
|
||||
dp = ip -> client ->
|
||||
config -> defaults [i].data;
|
||||
len = ip -> client ->
|
||||
config -> defaults [i].len;
|
||||
break;
|
||||
case ACTION_PREPEND:
|
||||
len = (ip -> client ->
|
||||
config -> defaults [i].len +
|
||||
lease -> options [i].len);
|
||||
if (len > sizeof dbuf) {
|
||||
warn ("no space to %s %s",
|
||||
"prepend option",
|
||||
dhcp_options [i].name);
|
||||
goto supersede;
|
||||
}
|
||||
dp = dbuf;
|
||||
memcpy (dp,
|
||||
ip -> client ->
|
||||
config -> defaults [i].data,
|
||||
ip -> client ->
|
||||
config -> defaults [i].len);
|
||||
memcpy (dp + ip -> client ->
|
||||
config -> defaults [i].len,
|
||||
lease -> options [i].data,
|
||||
lease -> options [i].len);
|
||||
break;
|
||||
case ACTION_APPEND:
|
||||
len = (ip -> client ->
|
||||
config -> defaults [i].len +
|
||||
lease -> options [i].len);
|
||||
if (len > sizeof dbuf) {
|
||||
warn ("no space to %s %s",
|
||||
"prepend option",
|
||||
dhcp_options [i].name);
|
||||
goto supersede;
|
||||
}
|
||||
dp = dbuf;
|
||||
memcpy (dp,
|
||||
ip -> client ->
|
||||
config -> defaults [i].data,
|
||||
ip -> client ->
|
||||
config -> defaults [i].len);
|
||||
memcpy (dp + ip -> client ->
|
||||
config -> defaults [i].len,
|
||||
lease -> options [i].data,
|
||||
lease -> options [i].len);
|
||||
}
|
||||
} else {
|
||||
dp = ip -> client ->
|
||||
config -> defaults [i].data;
|
||||
len = ip -> client ->
|
||||
config -> defaults [i].len;
|
||||
}
|
||||
} else if (lease -> options [i].len) {
|
||||
len = lease -> options [i].len;
|
||||
dp = lease -> options [i].data;
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
if (len) {
|
||||
char *s = dhcp_option_ev_name (&dhcp_options [i]);
|
||||
fprintf (scriptFile,
|
||||
"%s%s=\"%s\"\n", prefix, s,
|
||||
pretty_print_option
|
||||
(i, lease -> options [i].data,
|
||||
lease -> options [i].len, 0));
|
||||
|
||||
fprintf (scriptFile, "%s%s=\"%s\"\n", prefix, s,
|
||||
pretty_print_option (i, dp, len, 0));
|
||||
fprintf (scriptFile, "export %s%s\n", prefix, s);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user