2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 06:15:55 +00:00

Add billing support and pool support.

This commit is contained in:
Ted Lemon
1998-11-11 08:01:49 +00:00
parent e2bfe7b3bf
commit c4924529e6

View File

@@ -42,7 +42,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: dhcp.c,v 1.71 1998/11/09 02:46:58 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n"; "$Id: dhcp.c,v 1.72 1998/11/11 08:01:49 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -90,14 +90,15 @@ void dhcpdiscover (packet)
struct packet *packet; struct packet *packet;
{ {
struct lease *lease; struct lease *lease;
char msgbuf [1024];
note ("DHCPDISCOVER from %s via %s", sprintf (msgbuf, "DHCPDISCOVER from %s via %s",
print_hw_addr (packet -> raw -> htype, print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen, packet -> raw -> hlen,
packet -> raw -> chaddr), packet -> raw -> chaddr),
packet -> raw -> giaddr.s_addr (packet -> raw -> giaddr.s_addr
? inet_ntoa (packet -> raw -> giaddr) ? inet_ntoa (packet -> raw -> giaddr)
: packet -> interface -> name); : packet -> interface -> name));
lease = find_lease (packet, packet -> shared_network, 0); lease = find_lease (packet, packet -> shared_network, 0);
@@ -122,7 +123,7 @@ void dhcpdiscover (packet)
} }
} }
ack_lease (packet, lease, DHCPOFFER, cur_time + 120); ack_lease (packet, lease, DHCPOFFER, cur_time + 120, msgbuf);
} }
void dhcprequest (packet) void dhcprequest (packet)
@@ -135,6 +136,7 @@ void dhcprequest (packet)
struct option_cache *oc; struct option_cache *oc;
struct data_string data; struct data_string data;
int status; int status;
char msgbuf [1024];
oc = lookup_option (packet -> options.dhcp_hash, oc = lookup_option (packet -> options.dhcp_hash,
DHO_DHCP_REQUESTED_ADDRESS); DHO_DHCP_REQUESTED_ADDRESS);
@@ -159,14 +161,14 @@ void dhcprequest (packet)
else else
lease = (struct lease *)0; lease = (struct lease *)0;
note ("DHCPREQUEST for %s from %s via %s", sprintf (msgbuf, "DHCPREQUEST for %s from %s via %s",
piaddr (cip), piaddr (cip),
print_hw_addr (packet -> raw -> htype, print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen, packet -> raw -> hlen,
packet -> raw -> chaddr), packet -> raw -> chaddr),
packet -> raw -> giaddr.s_addr (packet -> raw -> giaddr.s_addr
? inet_ntoa (packet -> raw -> giaddr) ? inet_ntoa (packet -> raw -> giaddr)
: packet -> interface -> name); : packet -> interface -> name));
/* If a client on a given network REQUESTs a lease on an /* If a client on a given network REQUESTs a lease on an
address on a different network, NAK it. If the Requested address on a different network, NAK it. If the Requested
@@ -220,6 +222,7 @@ void dhcprequest (packet)
from there. Fry it. */ from there. Fry it. */
if (!packet -> shared_network) { if (!packet -> shared_network) {
if (subnet) { if (subnet) {
note ("%s: wrong network.", msgbuf);
nak_lease (packet, &cip); nak_lease (packet, &cip);
return; return;
} }
@@ -231,6 +234,7 @@ void dhcprequest (packet)
address that is not on that shared network, nak it. */ address that is not on that shared network, nak it. */
subnet = find_grouped_subnet (packet -> shared_network, cip); subnet = find_grouped_subnet (packet -> shared_network, cip);
if (!subnet) { if (!subnet) {
note ("%s: wrong network.", msgbuf);
nak_lease (packet, &cip); nak_lease (packet, &cip);
return; return;
} }
@@ -243,14 +247,18 @@ void dhcprequest (packet)
/* If we found the address the client asked for, but /* If we found the address the client asked for, but
it wasn't what got picked, the lease belongs to us, it wasn't what got picked, the lease belongs to us,
so we can tenuously justify NAKing it. */ so we can tenuously justify NAKing it. */
if (ours) if (ours) {
note ("%s: wrong lease %s.", msgbuf, piaddr (cip));
nak_lease (packet, &cip); nak_lease (packet, &cip);
} else
note ("%s: unknown lease %s", msgbuf, piaddr (cip));
return; return;
} }
/* If the address the client asked for is ours, but it wasn't /* If the address the client asked for is ours, but it wasn't
available for the client, NAK it. */ available for the client, NAK it. */
if (!lease && ours) { if (!lease && ours) {
note ("%s: lease %s unavailable.", msgbuf, piaddr (cip));
nak_lease (packet, &cip); nak_lease (packet, &cip);
return; return;
} }
@@ -270,9 +278,10 @@ void dhcprequest (packet)
packet -> raw -> chaddr, packet -> raw -> chaddr,
packet -> raw -> hlen)))) { packet -> raw -> hlen)))) {
data_string_forget (&data, "dhcprequest"); data_string_forget (&data, "dhcprequest");
ack_lease (packet, lease, DHCPACK, 0); ack_lease (packet, lease, DHCPACK, 0, msgbuf);
return; return;
} }
note ("%s: unknown lease %s.", msgbuf, piaddr (cip));
data_string_forget (&data, "dhcprequest"); data_string_forget (&data, "dhcprequest");
} }
@@ -510,11 +519,12 @@ void nak_lease (packet, cip)
warn ("send_packet: %m"); warn ("send_packet: %m");
} }
void ack_lease (packet, lease, offer, when) void ack_lease (packet, lease, offer, when, msg)
struct packet *packet; struct packet *packet;
struct lease *lease; struct lease *lease;
unsigned int offer; unsigned int offer;
TIME when; TIME when;
char *msg;
{ {
struct lease lt; struct lease lt;
struct lease_state *state; struct lease_state *state;
@@ -531,10 +541,8 @@ void ack_lease (packet, lease, offer, when)
int val; int val;
/* If we're already acking this lease, don't do it again. */ /* If we're already acking this lease, don't do it again. */
if (lease -> state) { if (lease -> state)
note ("already acking lease %s", piaddr (lease -> ip_addr));
return; return;
}
/* Allocate a lease state structure... */ /* Allocate a lease state structure... */
state = new_lease_state ("ack_lease"); state = new_lease_state ("ack_lease");
@@ -584,6 +592,7 @@ void ack_lease (packet, lease, offer, when)
/* Execute the subnet statements. */ /* Execute the subnet statements. */
execute_statements_in_scope (packet, &state -> options, execute_statements_in_scope (packet, &state -> options,
&state -> options,
lease -> subnet -> group, lease -> subnet -> group,
(struct group *)0); (struct group *)0);
@@ -592,6 +601,7 @@ void ack_lease (packet, lease, offer, when)
for (i = packet -> class_count; i > 0; i--) { for (i = packet -> class_count; i > 0; i--) {
execute_statements_in_scope execute_statements_in_scope
(packet, &state -> options, (packet, &state -> options,
&state -> options,
packet -> classes [i - 1] -> group, packet -> classes [i - 1] -> group,
(struct group *)0); (struct group *)0);
} }
@@ -601,6 +611,7 @@ void ack_lease (packet, lease, offer, when)
with its group. */ with its group. */
if (lease -> host) if (lease -> host)
execute_statements_in_scope (packet, &state -> options, execute_statements_in_scope (packet, &state -> options,
&state -> options,
lease -> host -> group, lease -> host -> group,
lease -> subnet -> group); lease -> subnet -> group);
@@ -612,6 +623,8 @@ void ack_lease (packet, lease, offer, when)
&packet -> options, oc)) { &packet -> options, oc)) {
if (d1.len && packet -> raw -> secs < d1.data [0]) { if (d1.len && packet -> raw -> secs < d1.data [0]) {
data_string_forget (&d1, "ack_lease"); data_string_forget (&d1, "ack_lease");
note ("%s: %d secs < %d",
packet -> raw -> secs, d1.data [0]);
return; return;
} }
data_string_forget (&d1, "ack_lease"); data_string_forget (&d1, "ack_lease");
@@ -655,10 +668,7 @@ void ack_lease (packet, lease, offer, when)
if (evaluate_option_cache (&d1, packet, if (evaluate_option_cache (&d1, packet,
&packet -> options, oc)) { &packet -> options, oc)) {
if (d1.len && !d1.data [0]) { if (d1.len && !d1.data [0]) {
note ("Ignoring unknown client %s", note ("%s: unknown", msg);
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
data_string_forget (&d1, "ack_lease"); data_string_forget (&d1, "ack_lease");
return; return;
} }
@@ -673,11 +683,8 @@ void ack_lease (packet, lease, offer, when)
if (evaluate_option_cache (&d1, packet, if (evaluate_option_cache (&d1, packet,
&packet -> options, oc)) { &packet -> options, oc)) {
if (d1.len && !d1.data [0]) { if (d1.len && !d1.data [0]) {
note ("Ignoring BOOTP client %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
data_string_forget (&d1, "ack_lease"); data_string_forget (&d1, "ack_lease");
note ("%s: bootp disallowed", msg);
return; return;
} }
data_string_forget (&d1, "ack_lease"); data_string_forget (&d1, "ack_lease");
@@ -689,18 +696,48 @@ void ack_lease (packet, lease, offer, when)
if (oc && if (oc &&
evaluate_option_cache (&d1, packet, &packet -> options, oc)) { evaluate_option_cache (&d1, packet, &packet -> options, oc)) {
if (d1.len && !d1.data [0]) { if (d1.len && !d1.data [0]) {
note ("Declining to boot client %s", note ("%s: booting disallowed", msg);
lease -> host -> name
? lease -> host -> name
: print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
data_string_forget (&d1, "ack_lease"); data_string_forget (&d1, "ack_lease");
return; return;
} }
data_string_forget (&d1, "ack_lease"); data_string_forget (&d1, "ack_lease");
} }
/* If we are configured to do per-class billing, do it. */
if (have_billing_classes) {
/* See if the lease is currently being billed to a
class, and if so, whether or not it can continue to
be billed to that class. */
if (lease -> billing_class) {
for (i = 0; i < packet -> class_count; i++)
if (packet -> classes [i] ==
lease -> billing_class)
break;
if (i == packet -> class_count)
unbill_class (lease, lease -> billing_class);
}
/* If we don't have an active billing, see if we need
one, and if we do, try to do so. */
if (!lease -> billing_class) {
for (i = 0; i < packet -> class_count; i++) {
if (!packet -> classes [i] -> lease_limit)
break;
}
if (i == packet -> class_count) {
for (i = 0; i < packet -> class_count; i++)
if (bill_class (lease,
packet -> classes [i]))
break;
if (i == packet -> class_count) {
note ("%s: no available billing", msg);
return;
}
}
}
}
/* Figure out the filename. */ /* Figure out the filename. */
oc = lookup_option (state -> options.server_hash, SV_FILENAME); oc = lookup_option (state -> options.server_hash, SV_FILENAME);
if (oc) if (oc)
@@ -847,6 +884,7 @@ void ack_lease (packet, lease, offer, when)
lt.host = lease -> host; lt.host = lease -> host;
lt.subnet = lease -> subnet; lt.subnet = lease -> subnet;
lt.shared_network = lease -> shared_network; lt.shared_network = lease -> shared_network;
lt.billing_class = lease -> billing_class;
/* Don't call supersede_lease on a mocked-up lease. */ /* Don't call supersede_lease on a mocked-up lease. */
if (lease -> flags & STATIC_LEASE) { if (lease -> flags & STATIC_LEASE) {
@@ -869,8 +907,10 @@ void ack_lease (packet, lease, offer, when)
it) either. */ it) either. */
if (!(supersede_lease (lease, &lt, !offer || offer == DHCPACK) if (!(supersede_lease (lease, &lt, !offer || offer == DHCPACK)
|| (offer && offer != DHCPACK))) || (offer && offer != DHCPACK))) {
note ("%s: database update failed", msg);
return; return;
}
} }
/* Remember the interface on which the packet arrived. */ /* Remember the interface on which the packet arrived. */
@@ -1129,6 +1169,8 @@ void ack_lease (packet, lease, offer, when)
lease -> state = state; lease -> state = state;
note ("%s", msg);
/* If this is a DHCPOFFER, ping the lease address before actually /* If this is a DHCPOFFER, ping the lease address before actually
sending the offer. */ sending the offer. */
if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE)) { if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE)) {
@@ -1440,12 +1482,12 @@ struct lease *find_lease (packet, share, ours)
if (hw_lease -> flags & ABANDONED_LEASE) if (hw_lease -> flags & ABANDONED_LEASE)
continue; continue;
/* If we're allowed to use this lease, do so. */ /* If we're allowed to use this lease, do so. */
if (!((lease -> pool -> prohibit_list && if (!((hw_lease -> pool -> prohibit_list &&
permitted (packet, permitted (packet,
lease -> pool -> prohibit_list)) || hw_lease -> pool -> prohibit_list)) ||
(lease -> pool -> permit_list && (hw_lease -> pool -> permit_list &&
!permitted (packet, !permitted (packet,
lease -> pool -> permit_list)))) hw_lease -> pool -> permit_list))))
break; break;
} }
} }