mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 14:25:41 +00:00
Add class billing support.
This commit is contained in:
162
server/class.c
162
server/class.c
@@ -42,7 +42,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"$Id: class.c,v 1.6 1998/11/09 02:46:19 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
|
||||
"$Id: class.c,v 1.7 1998/11/11 07:58:35 mellon Exp $ Copyright (c) 1998 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
@@ -137,28 +137,6 @@ static char copyright[] =
|
||||
*
|
||||
*/
|
||||
|
||||
struct class unknown_class = {
|
||||
(struct class *)0,
|
||||
"unknown",
|
||||
0,
|
||||
(struct lease *)0,
|
||||
(struct hash_table *)0,
|
||||
(struct expression *)0,
|
||||
(struct expression *)0,
|
||||
(struct group *)0,
|
||||
};
|
||||
|
||||
struct class known_class = {
|
||||
(struct class *)0,
|
||||
"unknown",
|
||||
0,
|
||||
(struct lease *)0,
|
||||
(struct hash_table *)0,
|
||||
(struct expression *)0,
|
||||
(struct expression *)0,
|
||||
(struct group *)0,
|
||||
};
|
||||
|
||||
struct collection default_collection = {
|
||||
(struct collection *)0,
|
||||
"default",
|
||||
@@ -168,6 +146,8 @@ struct collection default_collection = {
|
||||
struct collection *collections = &default_collection;
|
||||
struct executable_statement *default_classification_rules;
|
||||
|
||||
int have_billing_classes;
|
||||
|
||||
/* Build the default classification rule tree. */
|
||||
|
||||
void classification_setup ()
|
||||
@@ -218,25 +198,73 @@ int check_collection (packet, collection)
|
||||
#if defined (DEBUG_CLASS_MATCHING)
|
||||
note ("checking against class %s...", class -> name);
|
||||
#endif
|
||||
if (class -> hash) {
|
||||
memset (&data, 0, sizeof data);
|
||||
memset (&data, 0, sizeof data);
|
||||
/* If a class is for billing, don't put the client in the
|
||||
class if we've already billed it to a different class. */
|
||||
if (class -> spawn) {
|
||||
status = evaluate_data_expression (&data, packet,
|
||||
&packet -> options,
|
||||
class -> spawn);
|
||||
if (status &&
|
||||
(nc = (struct class *)hash_lookup (class -> hash,
|
||||
data.data,
|
||||
data.len))) {
|
||||
if (status) {
|
||||
if ((nc = ((struct class *)
|
||||
hash_lookup (class -> hash,
|
||||
data.data,
|
||||
data.len)))) {
|
||||
#if defined (DEBUG_CLASS_MATCHING)
|
||||
note ("matches subclass %s.",
|
||||
note ("matches subclass %s.",
|
||||
print_hex_1 (data.len,
|
||||
data.data, 60));
|
||||
#endif
|
||||
data_string_forget
|
||||
(&data, "check_collection");
|
||||
classify (packet, nc);
|
||||
matched = 1;
|
||||
continue;
|
||||
}
|
||||
#if defined (DEBUG_CLASS_MATCHING)
|
||||
note ("spawning subclass %s.",
|
||||
print_hex_1 (data.len, data.data, 60));
|
||||
#endif
|
||||
classify (packet, class);
|
||||
matched = 1;
|
||||
continue;
|
||||
nc = (struct class *)
|
||||
dmalloc (sizeof (struct class),
|
||||
"class spawn");
|
||||
memset (nc, 0, sizeof *nc);
|
||||
nc -> group = class -> group;
|
||||
nc -> superclass = class;
|
||||
nc -> lease_limit = class -> lease_limit;
|
||||
nc -> dirty = 1;
|
||||
if (nc -> lease_limit) {
|
||||
nc -> billed_leases =
|
||||
(dmalloc
|
||||
(nc -> lease_limit *
|
||||
sizeof (struct lease *),
|
||||
"check_collection"));
|
||||
if (!nc -> billed_leases) {
|
||||
warn ("no memory for billing");
|
||||
data_string_forget
|
||||
(&nc -> hash_string,
|
||||
"check_collection");
|
||||
dfree (nc, "check_collection");
|
||||
continue;
|
||||
}
|
||||
memset (nc -> billed_leases, 0,
|
||||
(nc -> lease_limit *
|
||||
sizeof nc -> billed_leases));
|
||||
}
|
||||
data_string_copy (&nc -> hash_string, &data,
|
||||
"check_collection");
|
||||
data_string_forget (&data, "check_collection");
|
||||
if (!class -> hash)
|
||||
class -> hash = new_hash ();
|
||||
add_hash (class -> hash,
|
||||
nc -> hash_string.data,
|
||||
nc -> hash_string.len,
|
||||
(unsigned char *)nc);
|
||||
classify (packet, nc);
|
||||
}
|
||||
data_string_forget (&data, "check_collection");
|
||||
}
|
||||
memset (&data, 0, sizeof data);
|
||||
|
||||
status = (evaluate_boolean_expression_result
|
||||
(packet, &packet -> options, class -> expr));
|
||||
if (status) {
|
||||
@@ -244,28 +272,8 @@ int check_collection (packet, collection)
|
||||
#if defined (DEBUG_CLASS_MATCHING)
|
||||
note ("matches class.");
|
||||
#endif
|
||||
}
|
||||
if (status &&
|
||||
class -> spawn &&
|
||||
evaluate_data_expression (&data, packet,
|
||||
&packet -> options,
|
||||
class -> spawn)) {
|
||||
#if defined (DEBUG_CLASS_MATCHING)
|
||||
note ("spawning subclass %s.",
|
||||
print_hex_1 (data.len, data.data, 60));
|
||||
#endif
|
||||
nc = (struct class *)
|
||||
dmalloc (sizeof (struct class), "class spawn");
|
||||
memset (nc, 0, sizeof *nc);
|
||||
nc -> group = class -> group;
|
||||
if (!class -> hash)
|
||||
class -> hash = new_hash ();
|
||||
add_hash (class -> hash,
|
||||
data.data, data.len,
|
||||
(unsigned char *)nc);
|
||||
classify (packet, nc);
|
||||
} else if (status)
|
||||
classify (packet, class);
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
@@ -296,3 +304,47 @@ struct class *find_class (name)
|
||||
}
|
||||
return (struct class *)0;
|
||||
}
|
||||
|
||||
int unbill_class (lease, class)
|
||||
struct lease *lease;
|
||||
struct class *class;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < class -> lease_limit; i++)
|
||||
if (class -> billed_leases [i] == lease)
|
||||
break;
|
||||
if (i == class -> lease_limit) {
|
||||
warn ("lease %s unbilled with no billing arrangement.",
|
||||
piaddr (lease -> ip_addr));
|
||||
return 0;
|
||||
}
|
||||
lease -> billing_class = (struct class *)0;
|
||||
class -> billed_leases [i] = (struct lease *)0;
|
||||
class -> leases_consumed--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bill_class (lease, class)
|
||||
struct lease *lease;
|
||||
struct class *class;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (class -> leases_consumed == class -> lease_limit)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < class -> lease_limit; i++)
|
||||
if (!class -> billed_leases [i])
|
||||
break;
|
||||
|
||||
if (i == class -> lease_limit) {
|
||||
warn ("class billing consumption disagrees with leases.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
class -> billed_leases [i] = lease;
|
||||
lease -> billing_class = class;
|
||||
class -> leases_consumed++;
|
||||
return 1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user