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:
126
server/dhcp.c
126
server/dhcp.c
@@ -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, <, !offer || offer == DHCPACK)
|
if (!(supersede_lease (lease, <, !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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user