2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 22:05:23 +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 #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -99,6 +99,7 @@ int main (argc, argv, envp)
int i; int i;
struct servent *ent; struct servent *ent;
struct interface_info *ip; struct interface_info *ip;
int seed;
#ifdef SYSLOG_4_2 #ifdef SYSLOG_4_2
openlog ("dhclient", LOG_NDELAY); openlog ("dhclient", LOG_NDELAY);
@@ -107,7 +108,7 @@ int main (argc, argv, envp)
openlog ("dhclient", LOG_NDELAY, LOG_DAEMON); openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
#endif #endif
#if !(defined (DEBUG) || defined (SYSLOG_4_2)) #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
setlogmask (LOG_UPTO (LOG_INFO)); setlogmask (LOG_UPTO (LOG_INFO));
#endif #endif
@@ -143,7 +144,9 @@ int main (argc, argv, envp)
local_port = htons (68); local_port = htons (68);
else else
local_port = ent -> s_port; local_port = ent -> s_port;
#ifndef __CYGWIN32__
endservent (); endservent ();
#endif
} }
remote_port = htons (ntohs (local_port) - 1); /* XXX */ remote_port = htons (ntohs (local_port) - 1); /* XXX */
@@ -196,9 +199,23 @@ int main (argc, argv, envp)
up the interfaces. */ up the interfaces. */
discover_interfaces (DISCOVER_RUNNING); 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. */ /* Start a configuration state machine for each interface. */
for (ip = interfaces; ip; ip = ip -> next) { for (ip = interfaces; ip; ip = ip -> next) {
srandom (cur_time + *(int *)(&ip -> hw_address.haddr [0]));
ip -> client -> state = S_INIT; ip -> client -> state = S_INIT;
state_reboot (ip); state_reboot (ip);
} }
@@ -258,7 +275,8 @@ void state_reboot (ipp)
/* If we don't remember an active lease, go straight to INIT. */ /* If we don't remember an active lease, go straight to INIT. */
if (!ip -> client -> active || if (!ip -> client -> active ||
ip -> client -> active -> rebind < cur_time) { ip -> client -> active -> rebind < cur_time ||
ip -> client -> active -> is_bootp) {
state_init (ip); state_init (ip);
return; return;
} }
@@ -359,6 +377,23 @@ void state_selecting (ipp)
return; 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. */ /* Go to the REQUESTING state. */
ip -> client -> destination = iaddr_broadcast; ip -> client -> destination = iaddr_broadcast;
ip -> client -> state = S_REQUESTING; ip -> client -> state = S_REQUESTING;
@@ -447,6 +482,12 @@ void dhcpack (packet)
ip -> client -> new -> renewal += cur_time; ip -> client -> new -> renewal += cur_time;
ip -> client -> new -> rebind += 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 out the new lease. */
write_client_lease (ip, ip -> client -> new); write_client_lease (ip, ip -> client -> new);
@@ -478,7 +519,8 @@ void dhcpack (packet)
add_timeout (ip -> client -> active -> renewal, add_timeout (ip -> client -> active -> renewal,
state_bound, ip); 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 -> active -> renewal - cur_time);
ip -> client -> state = S_BOUND; ip -> client -> state = S_BOUND;
reinitialize_interfaces (); reinitialize_interfaces ();
@@ -536,10 +578,9 @@ void db_startup ()
void bootp (packet) void bootp (packet)
struct packet *packet; struct packet *packet;
{ {
note ("BOOTREPLY from %s", if (packet -> raw -> op == BOOTREPLY)
print_hw_addr (packet -> raw -> htype, dhcpoffer (packet);
packet -> raw -> hlen,
packet -> raw -> chaddr));
} }
void dhcp (packet) void dhcp (packet)
@@ -570,6 +611,8 @@ void dhcpoffer (packet)
struct client_lease *lease, *lp; struct client_lease *lease, *lp;
int i; int i;
int arp_timeout_needed, stop_selecting; int arp_timeout_needed, stop_selecting;
char *name = (packet -> options [DHO_DHCP_MESSAGE_TYPE].len
? "DHCPOFFER" : "BOOTREPLY");
#ifdef DEBUG_PACKET #ifdef DEBUG_PACKET
dump_packet (packet); dump_packet (packet);
@@ -579,11 +622,11 @@ void dhcpoffer (packet)
has an unrecognizable transaction id, then just drop it. */ has an unrecognizable transaction id, then just drop it. */
if (ip -> client -> state != S_SELECTING || if (ip -> client -> state != S_SELECTING ||
packet -> interface -> client -> xid != packet -> raw -> xid) { packet -> interface -> client -> xid != packet -> raw -> xid) {
debug ("DHCPOFFER in wrong transaction."); debug ("%s in wrong transaction.", name);
return; return;
} }
note ("DHCPOFFER from %s", note ("%s from %s", name,
print_hw_addr (packet -> raw -> htype, print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen, packet -> raw -> hlen,
packet -> raw -> chaddr)); packet -> raw -> chaddr));
@@ -593,7 +636,7 @@ void dhcpoffer (packet)
for (i = 0; ip -> client -> config -> required_options [i]; i++) { for (i = 0; ip -> client -> config -> required_options [i]; i++) {
if (!packet -> options [ip -> client -> config -> if (!packet -> options [ip -> client -> config ->
required_options [i]].len) { required_options [i]].len) {
note ("DHCPOFFER isn't satisfactory."); note ("%s isn't satisfactory.", name);
return; return;
} }
} }
@@ -604,7 +647,7 @@ void dhcpoffer (packet)
if (lease -> address.len == sizeof packet -> raw -> yiaddr && if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
!memcmp (lease -> address.iabuf, !memcmp (lease -> address.iabuf,
&packet -> raw -> yiaddr, lease -> address.len)) { &packet -> raw -> yiaddr, lease -> address.len)) {
debug ("DHCPOFFER already seen."); debug ("%s already seen.", name);
return; return;
} }
} }
@@ -615,6 +658,11 @@ void dhcpoffer (packet)
return; 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. */ /* Record the medium under which this lease was offered. */
lease -> medium = ip -> client -> medium; 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 /* 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 one after the right interval has expired. If we don't get an offer by
(T1) interval but not yet past the rebind (T2) interval, unicast the time we reach the panic interval, call the panic function. */
the message; otherwise broadcast it. If the lease expires, go back to
the INIT state. */
void send_discover (ipp) void send_discover (ipp)
void *ipp; void *ipp;
@@ -893,17 +939,17 @@ void send_discover (ipp)
(ip -> client -> first_sending + (ip -> client -> first_sending +
ip -> client -> config -> timeout) - cur_time + 1; 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. */ /* Record the number of seconds since we started sending. */
if (interval < 255) if (interval < 255)
ip -> client -> packet.secs = interval; ip -> client -> packet.secs = interval;
else else
ip -> client -> packet.secs = 255; 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. */ /* Send out a packet. */
result = send_packet (ip, (struct packet *)0, result = send_packet (ip, (struct packet *)0,
&ip -> client -> packet, &ip -> client -> packet,
@@ -933,10 +979,8 @@ void state_panic (ipp)
/* We may not have an active lease, but we may have some /* We may not have an active lease, but we may have some
predefined leases that we can try. */ predefined leases that we can try. */
if (!ip -> client -> active && ip -> client -> leases) { if (!ip -> client -> active && ip -> client -> leases)
loop = ip -> client -> leases;
goto activate_next; goto activate_next;
}
/* Run through the list of leases and see if one can be used. */ /* Run through the list of leases and see if one can be used. */
while (ip -> client -> active) { while (ip -> client -> active) {
@@ -1001,6 +1045,8 @@ void state_panic (ipp)
now. */ now. */
if (ip -> client -> active == loop) if (ip -> client -> active == loop)
break; break;
else if (!loop)
loop = ip -> client -> active;
} }
/* No leases were available, or what was available didn't work, so /* 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"); fprintf (leaseFile, "lease {\n");
if (lease -> is_bootp)
fprintf (leaseFile, " bootp;\n");
fprintf (leaseFile, " interface \"%s\";\n", ip -> name); fprintf (leaseFile, " interface \"%s\";\n", ip -> name);
fprintf (leaseFile, " fixed-address %s;\n", fprintf (leaseFile, " fixed-address %s;\n",
piaddr (lease -> address)); piaddr (lease -> address));
@@ -1706,6 +1754,8 @@ void script_write_params (ip, prefix, lease)
struct client_lease *lease; struct client_lease *lease;
{ {
int i; int i;
u_int8_t dbuf [1500];
int len;
fprintf (scriptFile, "%sip_address=\"%s\"\n", fprintf (scriptFile, "%sip_address=\"%s\"\n",
prefix, piaddr (lease -> address)); prefix, piaddr (lease -> address));
@@ -1721,13 +1771,82 @@ void script_write_params (ip, prefix, lease)
fprintf (scriptFile, "export %sserver_name\n", prefix); fprintf (scriptFile, "export %sserver_name\n", prefix);
} }
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
u_int8_t *dp;
if (ip -> client -> config -> defaults [i].len) {
if (lease -> options [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]); char *s = dhcp_option_ev_name (&dhcp_options [i]);
fprintf (scriptFile,
"%s%s=\"%s\"\n", prefix, s, fprintf (scriptFile, "%s%s=\"%s\"\n", prefix, s,
pretty_print_option pretty_print_option (i, dp, len, 0));
(i, lease -> options [i].data,
lease -> options [i].len, 0));
fprintf (scriptFile, "export %s%s\n", prefix, s); fprintf (scriptFile, "export %s%s\n", prefix, s);
} }
} }