2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-09-02 23:35:23 +00:00

Move some state into the lease structure so that we can test a lease before acking it, and so that we can do DNS lookups asynchronously

This commit is contained in:
Ted Lemon
1997-03-05 06:37:05 +00:00
parent 5eead2781b
commit 11b37280ba

View File

@@ -42,7 +42,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: dhcp.c,v 1.41 1997/03/05 06:18:55 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; "$Id: dhcp.c,v 1.42 1997/03/05 06:37:05 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"
@@ -409,15 +409,16 @@ void nak_lease (packet, cip)
from = packet -> interface -> primary_address; from = packet -> interface -> primary_address;
/* Make sure that the packet is at least as big as a BOOTP packet. */
if (outgoing.packet_length < BOOTP_MIN_LEN)
outgoing.packet_length = BOOTP_MIN_LEN;
/* If this was gatewayed, send it back to the gateway. /* If this was gatewayed, send it back to the gateway.
Otherwise, broadcast it on the local network. */ Otherwise, broadcast it on the local network. */
if (raw.giaddr.s_addr) { if (raw.giaddr.s_addr) {
to.sin_addr = raw.giaddr; to.sin_addr = raw.giaddr;
to.sin_port = local_port; to.sin_port = local_port;
if (outgoing.packet_length < BOOTP_MIN_LEN)
outgoing.packet_length = BOOTP_MIN_LEN;
#ifdef USE_FALLBACK #ifdef USE_FALLBACK
result = send_fallback (&fallback_interface, result = send_fallback (&fallback_interface,
packet, &raw, outgoing.packet_length, packet, &raw, outgoing.packet_length,
@@ -449,31 +450,7 @@ void ack_lease (packet, lease, offer, when)
TIME lease_time; TIME lease_time;
TIME offered_lease_time; TIME offered_lease_time;
int bufs = 0;
struct packet outgoing;
struct dhcp_packet raw;
struct tree_cache *options [256];
struct sockaddr_in to;
struct in_addr from;
struct hardware hto;
int result;
unsigned char lease_time_buf [4];
unsigned char lease_t1_buf [4];
unsigned char lease_t2_buf [4];
struct tree_cache lease_time_tree;
struct tree_cache lease_t1_tree;
struct tree_cache lease_t2_tree;
struct tree_cache dhcpoffer_tree;
struct tree_cache server_id_tree;
struct tree_cache vendor_class_tree;
struct tree_cache user_class_tree;
struct tree_cache hostname_tree;
struct tree_cache netmask_tree;
struct class *vendor_class, *user_class; struct class *vendor_class, *user_class;
char *filename;
char *server_name;
int i; int i;
if (packet -> options [DHO_DHCP_CLASS_IDENTIFIER].len) { if (packet -> options [DHO_DHCP_CLASS_IDENTIFIER].len) {
@@ -501,21 +478,21 @@ void ack_lease (packet, lease, offer, when)
/* Choose a filename; first from the host_decl, if any, then from /* Choose a filename; first from the host_decl, if any, then from
the user class, then from the vendor class. */ the user class, then from the vendor class. */
if (lease -> host && lease -> host -> group -> filename) if (lease -> host && lease -> host -> group -> filename)
filename = lease -> host -> group -> filename; lease -> filename = lease -> host -> group -> filename;
else if (user_class && user_class -> group -> filename) else if (user_class && user_class -> group -> filename)
filename = user_class -> group -> filename; lease -> filename = user_class -> group -> filename;
else if (vendor_class && vendor_class -> group -> filename) else if (vendor_class && vendor_class -> group -> filename)
filename = vendor_class -> group -> filename; lease -> filename = vendor_class -> group -> filename;
else filename = (char *)0; else lease -> filename = (char *)0;
/* Choose a server name as above. */ /* Choose a server name as above. */
if (lease -> host && lease -> host -> group -> server_name) if (lease -> host && lease -> host -> group -> server_name)
server_name = lease -> host -> group -> server_name; lease -> server_name = lease -> host -> group -> server_name;
else if (user_class && user_class -> group -> server_name) else if (user_class && user_class -> group -> server_name)
server_name = user_class -> group -> server_name; lease -> server_name = user_class -> group -> server_name;
else if (vendor_class && vendor_class -> group -> server_name) else if (vendor_class && vendor_class -> group -> server_name)
server_name = vendor_class -> group -> server_name; lease -> server_name = vendor_class -> group -> server_name;
else server_name = (char *)0; else lease -> server_name = (char *)0;
/* At this point, we have a lease that we can offer the client. /* At this point, we have a lease that we can offer the client.
Now we construct a lease structure that contains what we want, Now we construct a lease structure that contains what we want,
@@ -589,13 +566,22 @@ void ack_lease (packet, lease, offer, when)
lt.timestamp = cur_time; lt.timestamp = cur_time;
/* Record the uid, if given... */ /* Record the uid, if given... */
if (packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len) { i = DHO_DHCP_CLIENT_IDENTIFIER;
lt.uid_len = if (packet -> options [i].len) {
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len; if (packet -> options [i].len <= sizeof lt.uid_buf) {
lt.uid = packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data; memcpy (lt.uid_buf, packet -> options [i].data,
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data = packet -> options [i].len);
(unsigned char *)0; lt.uid = lt.uid_buf;
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len = 0; lt.uid_max = sizeof lt.uid_buf;
lt.uid_len = packet -> options [i].len;
} else {
lt.uid_max = lt.uid_len = packet -> options [i].len;
lt.uid = (unsigned char *)malloc (lt.uid_max);
if (!lt.uid)
error ("can't allocate memory for large uid.");
memcpy (lt.uid,
packet -> options [i].data, lt.uid_len);
}
} }
/* Record the hardware address, if given... */ /* Record the hardware address, if given... */
@@ -622,42 +608,44 @@ void ack_lease (packet, lease, offer, when)
|| (offer && offer != DHCPACK))) || (offer && offer != DHCPACK)))
return; return;
/* Send a response to the client... */ /* Remember the interface on which the packet arrived. */
lease -> ip = packet -> interface;
memset (&outgoing, 0, sizeof outgoing); /* Set a flag if this client is a lame Microsoft client that NUL
memset (&raw, 0, sizeof raw); terminates string options and expects us to do likewise. */
outgoing.raw = &raw; if (packet -> options [DHO_HOST_NAME].data &&
packet -> options [DHO_HOST_NAME].data
/* Copy in the filename if given; otherwise, flag the filename [packet -> options [DHO_HOST_NAME].len - 1] == '\0')
buffer as available for options. */ lease -> flags |= MS_NULL_TERMINATION;
if (filename)
strncpy (raw.file, filename, sizeof raw.file);
else else
bufs |= 1; lease -> flags &= ~MS_NULL_TERMINATION;
/* Copy in the server name if given; otherwise, flag the /* Remember the giaddr, xid, secs, flags and hops. */
server_name buffer as available for options. */ lease -> giaddr = packet -> raw -> giaddr;
if (server_name) lease -> ciaddr = packet -> raw -> giaddr;
strncpy (raw.sname, server_name, sizeof raw.sname); lease -> xid = packet -> raw -> xid;
else lease -> secs = packet -> raw -> secs;
bufs |= 2; /* XXX */ lease -> bootp_flags = packet -> raw -> flags;
lease -> hops = packet -> raw -> hops;
lease -> offer = offer;
memcpy (raw.chaddr, packet -> raw -> chaddr, packet -> raw -> hlen); /* Figure out what options to send to the client: */
raw.hlen = packet -> raw -> hlen;
raw.htype = packet -> raw -> htype;
/* Start out with the subnet options... */ /* Start out with the subnet options... */
memcpy (options, lease -> subnet -> group -> options, sizeof options); memcpy (lease -> options,
lease -> subnet -> group -> options,
sizeof lease -> options);
/* Vendor and user classes are only supported for DHCP clients. */ /* Vendor and user classes are only supported for DHCP clients. */
if (offer) { if (lease -> offer) {
/* If we have a vendor class, install those options, /* If we have a vendor class, install those options,
superseding any subnet options. */ superseding any subnet options. */
if (vendor_class) { if (vendor_class) {
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
if (vendor_class -> group -> options [i]) if (vendor_class -> group -> options [i])
options [i] = (vendor_class -> group -> lease -> options [i] =
options [i]); (vendor_class -> group ->
options [i]);
} }
/* If we have a user class, install those options, /* If we have a user class, install those options,
@@ -665,8 +653,9 @@ void ack_lease (packet, lease, offer, when)
if (user_class) { if (user_class) {
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
if (user_class -> group -> options [i]) if (user_class -> group -> options [i])
options [i] = (user_class -> group -> lease -> options [i] =
options [i]); (user_class -> group ->
options [i]);
} }
} }
@@ -676,45 +665,45 @@ void ack_lease (packet, lease, offer, when)
if (lease -> host) { if (lease -> host) {
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
if (lease -> host -> group -> options [i]) if (lease -> host -> group -> options [i])
options [i] = (lease -> host -> lease -> options [i] = (lease -> host ->
group -> options [i]); group -> options [i]);
} }
/* If we didn't get a hostname from an option somewhere, see if /* If we didn't get a hostname from an option somewhere, see if
we can get one from the lease. */ we can get one from the lease. */
if (!options [DHO_HOST_NAME] && lease -> hostname) { i = DHO_HOST_NAME;
options [DHO_HOST_NAME] = &hostname_tree; if (!lease -> options [i] && lease -> hostname) {
options [DHO_HOST_NAME] -> value = lease -> options [i] = new_tree_cache ("hostname");
lease -> options [i] -> flags = TC_TEMPORARY;
lease -> options [i] -> value =
(unsigned char *)lease -> hostname; (unsigned char *)lease -> hostname;
options [DHO_HOST_NAME] -> buf_size = lease -> options [i] -> len = strlen (lease -> hostname);
options [DHO_HOST_NAME] -> len = lease -> options [i] -> buf_size = lease -> options [i] -> len;
strlen (lease -> hostname); lease -> options [i] -> timeout = 0xFFFFFFFF;
options [DHO_HOST_NAME] -> timeout = 0xFFFFFFFF; lease -> options [i] -> tree = (struct tree *)0;
options [DHO_HOST_NAME] -> tree = (struct tree *)0;
} }
/* Now, if appropriate, put in DHCP-specific options that /* Now, if appropriate, put in DHCP-specific options that
override those. */ override those. */
if (offer) { if (lease -> offer) {
options [DHO_DHCP_MESSAGE_TYPE] = &dhcpoffer_tree; i = DHO_DHCP_MESSAGE_TYPE;
options [DHO_DHCP_MESSAGE_TYPE] -> value = &offer; lease -> options [i] = new_tree_cache ("message-type");
options [DHO_DHCP_MESSAGE_TYPE] -> len = sizeof offer; lease -> options [i] -> flags = TC_TEMPORARY;
options [DHO_DHCP_MESSAGE_TYPE] -> buf_size = sizeof offer; lease -> options [i] -> value = &lease -> offer;
options [DHO_DHCP_MESSAGE_TYPE] -> timeout = 0xFFFFFFFF; lease -> options [i] -> len = sizeof lease -> offer;
options [DHO_DHCP_MESSAGE_TYPE] -> tree = (struct tree *)0; lease -> options [i] -> buf_size = sizeof lease -> offer;
lease -> options [i] -> timeout = 0xFFFFFFFF;
lease -> options [i] -> tree = (struct tree *)0;
options [DHO_DHCP_SERVER_IDENTIFIER] = &server_id_tree; i = DHO_DHCP_SERVER_IDENTIFIER;
options [DHO_DHCP_SERVER_IDENTIFIER] -> value = lease -> options [i] = new_tree_cache ("server-id");
(unsigned char *) lease -> options [i] -> value =
&packet -> interface -> primary_address; (unsigned char *)&lease -> ip -> primary_address;
options [DHO_DHCP_SERVER_IDENTIFIER] -> len = lease -> options [i] -> len =
sizeof packet -> interface -> primary_address; sizeof lease -> ip -> primary_address;
options [DHO_DHCP_SERVER_IDENTIFIER] -> buf_size = lease -> options [i] -> buf_size = lease -> options [i] -> len;
sizeof packet -> interface -> primary_address; lease -> options [i] -> timeout = 0xFFFFFFFF;
options [DHO_DHCP_SERVER_IDENTIFIER] -> timeout = lease -> options [i] -> tree = (struct tree *)0;
0xFFFFFFFF;
options [DHO_DHCP_SERVER_IDENTIFIER] -> tree =
(struct tree *)0;
/* Sanity check the lease time. */ /* Sanity check the lease time. */
if ((lease->offered_expiry - cur_time) < 15) if ((lease->offered_expiry - cur_time) < 15)
@@ -728,97 +717,157 @@ void ack_lease (packet, lease, offer, when)
offered_lease_time = offered_lease_time =
lease -> offered_expiry - cur_time; lease -> offered_expiry - cur_time;
putULong (lease_time_buf, offered_lease_time); putULong ((unsigned char *)&lease -> expiry,
options [DHO_DHCP_LEASE_TIME] = &lease_time_tree; offered_lease_time);
options [DHO_DHCP_LEASE_TIME] -> value = lease_time_buf; i = DHO_DHCP_LEASE_TIME;
options [DHO_DHCP_LEASE_TIME] -> len = sizeof lease_time_buf; lease -> options [i] = new_tree_cache ("lease-expiry");
options [DHO_DHCP_LEASE_TIME] -> lease -> options [i] -> flags = TC_TEMPORARY;
buf_size = sizeof lease_time_buf; lease -> options [i] -> value =
options [DHO_DHCP_LEASE_TIME] -> timeout = 0xFFFFFFFF; (unsigned char *)&lease -> expiry;
options [DHO_DHCP_LEASE_TIME] -> tree = (struct tree *)0; lease -> options [i] -> len = sizeof lease -> expiry;
lease -> options [i] -> buf_size = sizeof lease -> expiry;
lease -> options [i] -> timeout = 0xFFFFFFFF;
lease -> options [i] -> tree = (struct tree *)0;
/* Renewal time is lease time * 0.5. */ /* Renewal time is lease time * 0.5. */
offered_lease_time /= 2; offered_lease_time /= 2;
putULong (lease_t1_buf, offered_lease_time); putULong ((unsigned char *)&lease -> renewal,
options [DHO_DHCP_RENEWAL_TIME] = &lease_t1_tree; offered_lease_time);
options [DHO_DHCP_RENEWAL_TIME] -> value = lease_t1_buf; i = DHO_DHCP_RENEWAL_TIME;
options [DHO_DHCP_RENEWAL_TIME] -> len = sizeof lease_t1_buf; lease -> options [i] = new_tree_cache ("renewal-time");
options [DHO_DHCP_RENEWAL_TIME] -> lease -> options [i] -> flags = TC_TEMPORARY;
buf_size = sizeof lease_t1_buf; lease -> options [i] -> value =
options [DHO_DHCP_RENEWAL_TIME] -> timeout = 0xFFFFFFFF; (unsigned char *)&lease -> renewal;
options [DHO_DHCP_RENEWAL_TIME] -> tree = (struct tree *)0; lease -> options [i] -> len = sizeof lease -> renewal;
lease -> options [i] -> buf_size = sizeof lease -> renewal;
lease -> options [i] -> timeout = 0xFFFFFFFF;
lease -> options [i] -> tree = (struct tree *)0;
/* Rebinding time is lease time * 0.875. */ /* Rebinding time is lease time * 0.875. */
offered_lease_time += (offered_lease_time / 2 offered_lease_time += (offered_lease_time / 2
+ offered_lease_time / 4); + offered_lease_time / 4);
putULong (lease_t2_buf, offered_lease_time); putULong ((unsigned char *)&lease -> rebind,
options [DHO_DHCP_REBINDING_TIME] = &lease_t2_tree; offered_lease_time);
options [DHO_DHCP_REBINDING_TIME] -> value = lease_t2_buf; i = DHO_DHCP_REBINDING_TIME;
options [DHO_DHCP_REBINDING_TIME] -> len = sizeof lease_t2_buf; lease -> options [i] = new_tree_cache ("rebind-time");
options [DHO_DHCP_REBINDING_TIME] -> lease -> options [i] -> flags = TC_TEMPORARY;
buf_size = sizeof lease_t2_buf; lease -> options [i] -> value =
options [DHO_DHCP_REBINDING_TIME] -> timeout = 0xFFFFFFFF; (unsigned char *)&lease -> rebind;
options [DHO_DHCP_REBINDING_TIME] -> tree = (struct tree *)0; lease -> options [i] -> len = sizeof lease -> rebind;
lease -> options [i] -> buf_size = sizeof lease -> rebind;
lease -> options [i] -> timeout = 0xFFFFFFFF;
lease -> options [i] -> tree = (struct tree *)0;
/* If we used the vendor class the client specified, we /* If we used the vendor class the client specified, we
have to return it. */ have to return it. */
if (vendor_class) { if (vendor_class) {
options [DHO_DHCP_CLASS_IDENTIFIER] = i = DHO_DHCP_CLASS_IDENTIFIER;
&vendor_class_tree; lease -> options [i] =
options [DHO_DHCP_CLASS_IDENTIFIER] -> new_tree_cache ("class-identifier");
value = (unsigned char *)vendor_class -> name; lease -> options [i] -> flags = TC_TEMPORARY;
options [DHO_DHCP_CLASS_IDENTIFIER] -> lease -> options [i] -> value =
len = strlen (vendor_class -> name); (unsigned char *)vendor_class -> name;
options [DHO_DHCP_CLASS_IDENTIFIER] -> lease -> options [i] -> len =
buf_size = strlen (vendor_class -> name); strlen (vendor_class -> name);
options [DHO_DHCP_CLASS_IDENTIFIER] -> lease -> options [i] -> buf_size =
timeout = 0xFFFFFFFF; lease -> options [i] -> len;
options [DHO_DHCP_CLASS_IDENTIFIER] -> lease -> options [i] -> timeout = 0xFFFFFFFF;
tree = (struct tree *)0; lease -> options [i] -> tree = (struct tree *)0;
} }
/* If we used the user class the client specified, we /* If we used the user class the client specified, we
have to return it. */ have to return it. */
if (user_class) { if (user_class) {
options [DHO_DHCP_USER_CLASS_ID] = &user_class_tree; i = DHO_DHCP_USER_CLASS_ID;
options [DHO_DHCP_USER_CLASS_ID] -> lease -> options [i] = new_tree_cache ("user-class");
value = (unsigned char *)user_class -> name; lease -> options [i] -> flags = TC_TEMPORARY;
options [DHO_DHCP_USER_CLASS_ID] -> lease -> options [i] -> value =
len = strlen (user_class -> name); (unsigned char *)user_class -> name;
options [DHO_DHCP_USER_CLASS_ID] -> lease -> options [i] -> len =
buf_size = strlen (user_class -> name); strlen (user_class -> name);
options [DHO_DHCP_USER_CLASS_ID] -> lease -> options [i] -> buf_size =
timeout = 0xFFFFFFFF; lease -> options [i] -> len;
options [DHO_DHCP_USER_CLASS_ID] -> lease -> options [i] -> timeout = 0xFFFFFFFF;
tree = (struct tree *)0; lease -> options [i] -> tree = (struct tree *)0;
} }
} }
/* Use the subnet mask from the subnet declaration if no other /* Use the subnet mask from the subnet declaration if no other
mask has been provided. */ mask has been provided. */
if (!options [DHO_SUBNET_MASK]) { i = DHO_SUBNET_MASK;
options [DHO_SUBNET_MASK] = &netmask_tree; if (!lease -> options [i]) {
netmask_tree.value = lease -> subnet -> netmask.iabuf; lease -> options [i] = new_tree_cache ("subnet-mask");
netmask_tree.len = lease -> subnet -> netmask.len; lease -> options [i] -> flags = TC_TEMPORARY;
netmask_tree.buf_size = lease -> subnet -> netmask.len; lease -> options [i] -> value =
netmask_tree.timeout = 0xFFFFFFFF; lease -> subnet -> netmask.iabuf;
netmask_tree.tree = (struct tree *)0; lease -> options [i] -> len = lease -> subnet -> netmask.len;
lease -> options [i] -> buf_size =
lease -> subnet -> netmask.len;
lease -> options [i] -> timeout = 0xFFFFFFFF;
lease -> options [i] -> tree = (struct tree *)0;
} }
#ifdef DEBUG_PACKET
dump_packet (packet);
dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
#endif
dhcp_reply (lease);
}
void dhcp_reply (lease)
struct lease *lease;
{
int bufs = 0;
int packet_length;
struct dhcp_packet raw;
struct sockaddr_in to;
struct in_addr from;
struct hardware hto;
int result;
int i;
/* Send a response to the client... */
memset (&raw, 0, sizeof raw);
/* Copy in the filename if given; otherwise, flag the filename
buffer as available for options. */
if (lease -> filename)
strncpy (raw.file, lease -> filename, sizeof raw.file);
else
bufs |= 1;
/* Copy in the server name if given; otherwise, flag the
server_name buffer as available for options. */
if (lease -> server_name)
strncpy (raw.sname, lease -> server_name, sizeof raw.sname);
else
bufs |= 2; /* XXX */
memcpy (raw.chaddr, lease -> hardware_addr.haddr,
lease -> hardware_addr.hlen);
raw.hlen = lease -> hardware_addr.hlen;
raw.htype = lease -> hardware_addr.htype;
/* See if this is a Microsoft client that NUL-terminates its /* See if this is a Microsoft client that NUL-terminates its
strings and expects us to do likewise... */ strings and expects us to do likewise... */
if (packet -> options [DHO_HOST_NAME].data && if (lease -> flags & MS_NULL_TERMINATION)
packet -> options [DHO_HOST_NAME].data packet_length = cons_options ((struct packet *)0,
[packet -> options [DHO_HOST_NAME].len - 1] == '\0') &raw, lease -> options, bufs, 1);
outgoing.packet_length =
cons_options (packet, outgoing.raw, options, bufs, 1);
else else
outgoing.packet_length = packet_length = cons_options ((struct packet *)0,
cons_options (packet, outgoing.raw, options, bufs, 0); &raw, lease -> options, bufs, 0);
if (!offer && outgoing.packet_length < BOOTP_MIN_LEN)
outgoing.packet_length = BOOTP_MIN_LEN;
raw.ciaddr = packet -> raw -> ciaddr; /* Having done the cons_options(), we can release the tree_cache
entries. */
for (i = 0; i < 256; i++) {
if (lease -> options [i] &&
lease -> options [i] -> flags & TC_TEMPORARY)
free_tree_cache (lease -> options [i], "dhcp_reply");
}
memcpy (&raw.ciaddr, &lease -> ciaddr, sizeof raw.ciaddr);
memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4); memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
/* Figure out the address of the next server. */ /* Figure out the address of the next server. */
@@ -832,33 +881,33 @@ void ack_lease (packet, lease, offer, when)
memcpy (&raw.siaddr, memcpy (&raw.siaddr,
lease -> subnet -> interface_address.iabuf, 4); lease -> subnet -> interface_address.iabuf, 4);
else else
raw.siaddr = packet -> interface -> primary_address; raw.siaddr = lease -> ip -> primary_address;
raw.giaddr = packet -> raw -> giaddr; raw.giaddr = lease -> giaddr;
raw.xid = packet -> raw -> xid; raw.xid = lease -> xid;
raw.secs = packet -> raw -> secs; raw.secs = lease -> secs;
raw.flags = packet -> raw -> flags; raw.flags = lease -> bootp_flags;
raw.hops = packet -> raw -> hops; raw.hops = lease -> hops;
raw.op = BOOTREPLY; raw.op = BOOTREPLY;
/* Say what we're doing... */ /* Say what we're doing... */
note ("%s on %s to %s via %s", note ("%s on %s to %s via %s",
(offer (lease -> offer
? (offer == DHCPACK ? "DHCPACK" : "DHCPOFFER") ? (lease -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
: "BOOTREPLY"), : "BOOTREPLY"),
piaddr (lease -> ip_addr), piaddr (lease -> ip_addr),
print_hw_addr (packet -> raw -> htype, print_hw_addr (lease -> hardware_addr.htype,
packet -> raw -> hlen, lease -> hardware_addr.hlen,
packet -> raw -> chaddr), lease -> hardware_addr.haddr),
packet -> raw -> giaddr.s_addr lease -> giaddr.s_addr
? inet_ntoa (packet -> raw -> giaddr) ? inet_ntoa (lease -> giaddr)
: packet -> interface -> name); : lease -> ip -> name);
/* Set up the hardware address... */ /* Set up the hardware address... */
hto.htype = packet -> raw -> htype; hto.htype = lease -> hardware_addr.htype;
hto.hlen = packet -> raw -> hlen; hto.hlen = lease -> hardware_addr.hlen;
memcpy (hto.haddr, packet -> raw -> chaddr, hto.hlen); memcpy (hto.haddr, lease -> hardware_addr.haddr, hto.hlen);
to.sin_family = AF_INET; to.sin_family = AF_INET;
#ifdef HAVE_SA_LEN #ifdef HAVE_SA_LEN
@@ -866,26 +915,26 @@ void ack_lease (packet, lease, offer, when)
#endif #endif
memset (to.sin_zero, 0, sizeof to.sin_zero); memset (to.sin_zero, 0, sizeof to.sin_zero);
from = packet -> interface -> primary_address; from = lease -> ip -> primary_address;
#ifdef DEBUG_PACKET #ifdef DEBUG_PACKET
dump_packet (packet); dump_raw ((unsigned char *)&raw, packet_length);
dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
dump_packet (&outgoing);
dump_raw ((unsigned char *)&raw, outgoing.packet_length);
#endif #endif
/* Make sure outgoing packets are at least as big
as a BOOTP packet. */
if (packet_length < BOOTP_MIN_LEN)
packet_length = BOOTP_MIN_LEN;
/* If this was gatewayed, send it back to the gateway... */ /* If this was gatewayed, send it back to the gateway... */
if (raw.giaddr.s_addr) { if (raw.giaddr.s_addr) {
to.sin_addr = raw.giaddr; to.sin_addr = raw.giaddr;
to.sin_port = local_port; to.sin_port = local_port;
if (outgoing.packet_length < BOOTP_MIN_LEN)
outgoing.packet_length = BOOTP_MIN_LEN;
#ifdef USE_FALLBACK #ifdef USE_FALLBACK
result = send_fallback (&fallback_interface, result = send_fallback (&fallback_interface,
packet, &raw, outgoing.packet_length, (struct packet *)0,
&raw, packet_length,
raw.siaddr, &to, &hto); raw.siaddr, &to, &hto);
if (result < 0) if (result < 0)
warn ("send_fallback: %m"); warn ("send_fallback: %m");
@@ -895,14 +944,15 @@ void ack_lease (packet, lease, offer, when)
/* If it comes from a client who already knows its address and /* If it comes from a client who already knows its address and
is not requesting a broadcast response, sent it directly to is not requesting a broadcast response, sent it directly to
that client. */ that client. */
} else if (raw.ciaddr.s_addr && offer == DHCPACK && } else if (raw.ciaddr.s_addr && lease -> offer == DHCPACK &&
!(raw.flags & htons (BOOTP_BROADCAST))) { !(raw.flags & htons (BOOTP_BROADCAST))) {
to.sin_addr = packet -> raw -> ciaddr; to.sin_addr = lease -> ciaddr;
to.sin_port = remote_port; /* XXX */ to.sin_port = remote_port; /* XXX */
#ifdef USE_FALLBACK #ifdef USE_FALLBACK
result = send_fallback (&fallback_interface, result = send_fallback (&fallback_interface,
packet, &raw, outgoing.packet_length, (struct packet *)0,
&raw, packet_length,
raw.siaddr, &to, &hto); raw.siaddr, &to, &hto);
if (result < 0) if (result < 0)
warn ("send_fallback: %m"); warn ("send_fallback: %m");
@@ -916,8 +966,8 @@ void ack_lease (packet, lease, offer, when)
} }
result = send_packet (packet -> interface, result = send_packet (lease -> ip,
packet, &raw, outgoing.packet_length, (struct packet *)0, &raw, packet_length,
raw.siaddr, &to, &hto); raw.siaddr, &to, &hto);
if (result < 0) if (result < 0)
warn ("sendpkt: %m"); warn ("sendpkt: %m");