2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 14:25:41 +00:00

Intermediate changes to support actual DHCP protocol engine

This commit is contained in:
Ted Lemon
1996-02-21 12:11:09 +00:00
parent d9c6d82c49
commit 97ca16995f
29 changed files with 972 additions and 120 deletions

View File

@@ -49,5 +49,205 @@ static char copyright[] =
void dhcp (packet)
struct packet *packet;
{
struct lease *uid_lease, *ip_lease, *hw_lease, *lease;
struct iaddr cip;
struct lease lt;
TIME lease_time;
dump_packet (packet);
/* Try to find a lease that's been assigned to the specified
unique client identifier. */
if (packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len)
uid_lease =
find_lease_by_uid (packet -> options
[DHO_DHCP_CLIENT_IDENTIFIER].data,
packet -> options
[DHO_DHCP_CLIENT_IDENTIFIER].len);
else
uid_lease = (struct lease *)0;
/* Try to find a lease that's been attached to the client's
hardware address... */
hw_lease = find_lease_by_hw_addr (packet -> raw -> chaddr,
packet -> raw -> hlen);
/* Try to find a lease that's been allocated to the client's
IP address. */
if (packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len &&
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len
<= sizeof cip.iabuf) {
cip.len = packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len;
memcpy (cip.iabuf,
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].data,
packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len);
memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
ip_lease = find_lease_by_ip_addr (cip);
} else
ip_lease = (struct lease *)0;
printf ("First blush:\n");
if (ip_lease) {
printf ("ip_lease: ");
print_lease (ip_lease);
}
if (hw_lease) {
printf ("hw_lease: ");
print_lease (hw_lease);
}
if (uid_lease) {
printf ("uid_lease: ");
print_lease (uid_lease);
}
/* Toss extra pointers to the same lease... */
if (ip_lease == hw_lease)
ip_lease = (struct lease *)0;
if (hw_lease == uid_lease)
hw_lease = (struct lease *)0;
if (ip_lease == uid_lease)
ip_lease = (struct lease *)0;
printf ("Second blush:\n");
if (ip_lease) {
printf ("ip_lease: ");
print_lease (ip_lease);
}
if (hw_lease) {
printf ("hw_lease: ");
print_lease (hw_lease);
}
if (uid_lease) {
printf ("uid_lease: ");
print_lease (uid_lease);
}
/* If we got an ip address lease, make sure it isn't assigned to
some *other* client! If it was assigned to this client, we'd
have zeroed it out above, so the only way we can take it at this
point is if some other client had it but it's timed out, or if no
other client has ever had it. */
if (ip_lease &&
ip_lease -> ends >= cur_time)
ip_lease = (struct lease *)0;
/* Now eliminate leases that are on the wrong subnet... */
if (ip_lease && packet -> subnet != ip_lease -> contain) {
release_lease (ip_lease);
ip_lease = (struct lease *)0;
}
if (uid_lease && packet -> subnet != uid_lease -> contain) {
release_lease (uid_lease);
uid_lease = (struct lease *)0;
}
if (hw_lease && packet -> subnet != hw_lease -> contain) {
release_lease (hw_lease);
hw_lease = (struct lease *)0;
}
printf ("Third blush:\n");
if (ip_lease) {
printf ("ip_lease: ");
print_lease (ip_lease);
}
if (hw_lease) {
printf ("hw_lease: ");
print_lease (hw_lease);
}
if (uid_lease) {
printf ("uid_lease: ");
print_lease (uid_lease);
}
/* At this point, if ip_lease is nonzero, we can assign it to
this client. */
lease = ip_lease;
/* If we got a lease that matched the client identifier, we may want
to use it, but if we already have a lease we like, we must free
the lease that matched the client identifier. */
if (uid_lease) {
if (lease) {
release_lease (uid_lease);
} else
lease = uid_lease;
}
/* The lease that matched the hardware address is treated likewise. */
if (hw_lease) {
if (lease) {
release_lease (hw_lease);
} else
lease = hw_lease;
}
/* If we didn't find a lease, try to allocate one... */
if (!lease) {
lease = packet -> subnet -> last_lease;
/* If there are no leases in that subnet that have
expired, we have nothing to offer this client. */
if (lease -> ends >= cur_time) {
note ("no free leases on subnet %s",
piaddr (packet -> subnet -> net));
return;
}
lease -> host = (struct host_decl *)0;
}
/* At this point, we have a lease that we can offer the client.
Now we construct a lease structure that contains what we want,
and call supersede_lease to do the right thing with it. */
memset (&lt, 0, sizeof lt);
/* Use the ip address of the lease that we finally found in
the database. */
lt.ip_addr = lease -> ip_addr;
/* Start now. */
lt.starts = cur_time;
/* Figure out how long a lease to assign. */
if (packet -> options [DHO_DHCP_LEASE_TIME].len == 4) {
lease_time = getULong (packet ->
options [DHO_DHCP_LEASE_TIME].data);
/* Don't let the client ask for a longer lease than
is supported for this subnet. */
if (lease_time > packet -> subnet -> max_lease_time)
lease_time = packet -> subnet -> max_lease_time;
} else
lease_time = packet -> subnet -> default_lease_time;
lt.ends = cur_time + lease_time;
lt.timestamp = cur_time;
/* Record the uid, if given... */
if (packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len) {
lt.uid_len =
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len;
lt.uid = packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data;
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].data =
(unsigned char *)0;
packet -> options [DHO_DHCP_CLIENT_IDENTIFIER].len = 0;
}
/* Record the hardware address, if given... */
lt.hardware_addr.hlen = packet -> raw -> hlen;
lt.hardware_addr.htype = packet -> raw -> htype;
memcpy (lt.hardware_addr.haddr, packet -> raw -> chaddr,
packet -> raw -> hlen);
lt.host = lease -> host; /* XXX */
lt.contain = lease -> contain;
/* Record the transaction id... */
lt.xid = packet -> raw -> xid;
/* Install the new information about this lease in the database. */
supersede_lease (lease, &lt);
/* Send a response to the client... */
dump_subnets ();
}