From: Ted Lemon Date: Wed, 11 Nov 1998 07:58:35 +0000 (+0000) Subject: Add class billing support. X-Git-Tag: carrel-2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ee7b56249a090cf31b4be2ac12b94da265a052c4;p=thirdparty%2Fdhcp.git Add class billing support. --- diff --git a/server/class.c b/server/class.c index 3a90376cb..7f403f6c1 100644 --- a/server/class.c +++ b/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; +}