2
0
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:
Ted Lemon 1997-05-09 07:54:14 +00:00
parent d7c8ea3224
commit 66f973e41e

View File

@ -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);
}
}