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:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user