ISC DHCP 4.4.3-P1
A reference DHCPv4 and DHCPv6 implementation
 
Loading...
Searching...
No Matches
class.c
Go to the documentation of this file.
1/* class.c
2
3 Handling for client classes. */
4
5/*
6 * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1998-2003 by Internet Software Consortium
8 *
9 * This Source Code Form is subject to the terms of the Mozilla Public
10 * License, v. 2.0. If a copy of the MPL was not distributed with this
11 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 * Internet Systems Consortium, Inc.
22 * PO Box 360
23 * Newmarket, NH 03857 USA
24 * <info@isc.org>
25 * https://www.isc.org/
26 *
27 */
28
29#include "dhcpd.h"
30
32
34
35/* Build the default classification rule tree. */
36
38{
39 /* eval ... */
42 MDL))
43 log_fatal ("Can't allocate check of default collection");
45
46 /* check-collection "default" */
48 MDL))
49 log_fatal ("Can't allocate default check expression");
51 default_classification_rules -> data.eval -> data.check =
53}
54
56 struct packet *packet;
57{
58 execute_statements (NULL, packet, NULL, NULL, packet->options, NULL,
60}
61
63 struct packet *packet;
64 struct lease *lease;
65 struct collection *collection;
66{
67 struct class *class, *nc;
68 struct data_string data;
69 int matched = 0;
70 int status;
71 int ignorep;
72 int classfound;
73
74 for (class = collection -> classes; class; class = class -> nic) {
75#if defined (DEBUG_CLASS_MATCHING)
76 log_info ("checking against class %s...", class -> name);
77#endif
78 memset (&data, 0, sizeof data);
79
80 /* If there is a "match if" expression, check it. If
81 we get a match, and there's no subclass expression,
82 it's a match. If we get a match and there is a subclass
83 expression, then we check the submatch. If it's not a
84 match, that's final - we don't check the submatch. */
85
86 if (class -> expr) {
88 (&ignorep, packet, lease,
89 (struct client_state *)0,
90 packet -> options, (struct option_state *)0,
91 lease ? &lease -> scope : &global_scope,
92 class -> expr));
93 if (status) {
94 if (!class -> submatch) {
95 matched = 1;
96#if defined (DEBUG_CLASS_MATCHING)
97 log_info ("matches class.");
98#endif
99 classify (packet, class);
100 continue;
101 }
102 } else
103 continue;
104 }
105
106 /* Check to see if the client matches an existing subclass.
107 If it doesn't, and this is a spawning class, spawn a new
108 subclass and put the client in it. */
109 if (class -> submatch) {
111 (&data, packet, lease,
112 (struct client_state *)0,
113 packet -> options, (struct option_state *)0,
114 lease ? &lease -> scope : &global_scope,
115 class -> submatch, MDL));
116 if (status && data.len) {
117 nc = (struct class *)0;
118 classfound = class_hash_lookup (&nc, class -> hash,
119 (const char *)data.data, data.len, MDL);
120
121#ifdef LDAP_CONFIGURATION
122 if (!classfound && find_subclass_in_ldap (class, &nc, &data))
123 classfound = 1;
124#endif
125
126 if (classfound) {
127#if defined (DEBUG_CLASS_MATCHING)
128 log_info ("matches subclass %s.",
129 print_hex_1 (data.len,
130 data.data, 60));
131#endif
132 data_string_forget (&data, MDL);
133 classify (packet, nc);
134 matched = 1;
135 class_dereference (&nc, MDL);
136 continue;
137 }
138 if (!class -> spawning) {
139 data_string_forget (&data, MDL);
140 continue;
141 }
142 /* XXX Write out the spawned class? */
143#if defined (DEBUG_CLASS_MATCHING)
144 log_info ("spawning subclass %s.",
145 print_hex_1 (data.len, data.data, 60));
146#endif
147 status = class_allocate (&nc, MDL);
148 group_reference (&nc -> group,
149 class -> group, MDL);
150 class_reference (&nc -> superclass,
151 class, MDL);
152 nc -> lease_limit = class -> lease_limit;
153 nc -> dirty = 1;
154 if (nc -> lease_limit) {
155 nc -> billed_leases =
156 (dmalloc
157 (nc -> lease_limit *
158 sizeof (struct lease *),
159 MDL));
160 if (!nc -> billed_leases) {
161 log_error ("no memory for%s",
162 " billing");
164 (&nc -> hash_string,
165 MDL);
166 class_dereference (&nc, MDL);
167 data_string_forget (&data,
168 MDL);
169 continue;
170 }
171 memset (nc -> billed_leases, 0,
172 (nc -> lease_limit *
173 sizeof (struct lease *)));
174 }
175 data_string_copy (&nc -> hash_string, &data,
176 MDL);
177 if (!class -> hash)
178 class_new_hash(&class->hash,
180 class_hash_add (class -> hash,
181 (const char *)
182 nc -> hash_string.data,
183 nc -> hash_string.len,
184 nc, MDL);
185 classify (packet, nc);
186 class_dereference (&nc, MDL);
187 }
188
189 data_string_forget (&data, MDL);
190 }
191 }
192 return matched;
193}
194
195void classify (packet, class)
196 struct packet *packet;
197 struct class *class;
198{
199 if (packet -> class_count < PACKET_MAX_CLASSES)
200 class_reference (&packet -> classes [packet -> class_count++],
201 class, MDL);
202 else
203 log_error ("too many classes match %s",
204 print_hw_addr (packet -> raw -> htype,
205 packet -> raw -> hlen,
206 packet -> raw -> chaddr));
207}
208
209
210isc_result_t unlink_class(struct class **class) {
211 struct collection *lp;
212 struct class *cp, *pp;
213
214 for (lp = collections; lp; lp = lp -> next) {
215 for (pp = 0, cp = lp -> classes; cp; pp = cp, cp = cp -> nic)
216 if (cp == *class) {
217 if (pp == 0) {
218 lp->classes = cp->nic;
219 } else {
220 pp->nic = cp->nic;
221 }
222 cp->nic = 0;
223 class_dereference(class, MDL);
224
225 return ISC_R_SUCCESS;
226 }
227 }
228 return ISC_R_NOTFOUND;
229}
230
231
232isc_result_t find_class (struct class **class, const char *name,
233 const char *file, int line)
234{
235 struct collection *lp;
236 struct class *cp;
237
238 for (lp = collections; lp; lp = lp -> next) {
239 for (cp = lp -> classes; cp; cp = cp -> nic)
240 if (cp -> name && !strcmp (name, cp -> name)) {
241 return class_reference (class, cp, file, line);
242 }
243 }
244 return ISC_R_NOTFOUND;
245}
246
247/* Removes the billing class from a lease
248 *
249 * Note that because classes can be created and removed dynamically, it is
250 * possible that the class to which a lease was billed has since been deleted.
251 * To cover the case where the lease is the last reference to a deleted class
252 * we remove the lease reference from the class first, then the class from the
253 * lease. To protect ourselves from the reverse situation, where the class is
254 * the last reference to the lease (unlikely), we create a guard reference to
255 * the lease, then remove it at the end.
256 */
258 struct lease *lease;
259{
260 int i;
261 struct class* class = lease->billing_class;
262 struct lease* refholder = NULL;
263
264 /* if there's no billing to remove, nothing to do */
265 if (class == NULL) {
266 return;
267 }
268
269 /* Find the lease in the list of the class's billed leases */
270 for (i = 0; i < class->lease_limit; i++) {
271 if (class->billed_leases[i] == lease)
272 break;
273 }
274
275 /* Create guard reference, so class cannot be last reference to lease */
276 lease_reference(&refholder, lease, MDL);
277
278 /* If the class doesn't have the lease, then something is broken
279 * programmatically. We'll log it but skip the lease dereference. */
280 if (i == class->lease_limit) {
281 log_error ("lease %s unbilled with no billing arrangement.",
283 } else {
284 /* Remove the lease from the class */
285 lease_dereference(&class->billed_leases[i], MDL);
286 class->leases_consumed--;
287 }
288
289 /* Remove the class from the lease */
290 class_dereference(&lease->billing_class, MDL);
291
292 /* Ditch our guard reference */
293 lease_dereference(&refholder, MDL);
294}
295
296int bill_class (lease, class)
297 struct lease *lease;
298 struct class *class;
299{
300 int i;
301
302 if (lease -> billing_class) {
303 log_error ("lease billed with existing billing arrangement.");
305 }
306
307 if (class -> leases_consumed == class -> lease_limit)
308 return 0;
309
310 for (i = 0; i < class -> lease_limit; i++)
311 if (!class -> billed_leases [i])
312 break;
313
314 if (i == class -> lease_limit) {
315 log_error ("class billing consumption disagrees with leases.");
316 return 0;
317 }
318
319 lease_reference (&class -> billed_leases [i], lease, MDL);
320 class_reference (&lease -> billing_class, class, MDL);
321 class -> leases_consumed++;
322 return 1;
323}
void classification_setup()
Definition class.c:37
isc_result_t find_class(struct class **class, const char *name, const char *file, int line)
Definition class.c:232
int bill_class(struct lease *lease, struct class *class)
Definition class.c:296
int check_collection(struct packet *packet, struct lease *lease, struct collection *collection)
Definition class.c:62
void classify(struct packet *packet, struct class *class)
Definition class.c:195
isc_result_t unlink_class(struct class **class)
Definition class.c:210
void unbill_class(struct lease *lease)
Definition class.c:257
void classify_client(struct packet *packet)
Definition class.c:55
int expression_allocate(struct expression **cptr, const char *file, int line)
Definition alloc.c:426
int executable_statement_allocate(struct executable_statement **ptr, const char *file, int line)
Definition alloc.c:958
struct collection default_collection
Definition parse.c:33
struct collection * collections
Definition parse.c:34
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
Definition print.c:171
#define SCLASS_HASH_SIZE
Definition dhcpd.h:203
void data_string_copy(struct data_string *, const struct data_string *, const char *, int)
Definition alloc.c:1323
int have_billing_classes
Definition class.c:33
struct executable_statement * default_classification_rules
Definition class.c:31
#define PACKET_MAX_CLASSES
Definition dhcpd.h:452
void data_string_forget(struct data_string *, const char *, int)
Definition alloc.c:1339
int evaluate_boolean_expression_result(int *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *)
Definition tree.c:2780
int group_reference(struct group **, struct group *, const char *, int)
Definition alloc.c:177
const char int line
Definition dhcpd.h:3802
int evaluate_data_expression(struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct expression *, const char *, int)
Definition tree.c:1126
void classify(struct packet *, struct class *)
Definition dhclient.c:1556
const char * file
Definition dhcpd.h:3802
#define print_hex_1(len, data, limit)
Definition dhcpd.h:2638
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
Definition execute.c:35
const char * piaddr(const struct iaddr addr)
Definition inet.c:579
#define ISC_R_SUCCESS
@ eval_statement
Definition keama.h:167
#define MDL
Definition omapip.h:567
void * dmalloc(size_t, const char *, int)
Definition alloc.c:57
int log_error(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
struct class * nic
Definition dhcpd.h:1104
struct expression * submatch
Definition dhcpd.h:1126
struct lease ** billed_leases
Definition dhcpd.h:1111
struct expression * expr
Definition dhcpd.h:1122
struct class * superclass
Definition dhcpd.h:1105
class_hash_t * hash
Definition dhcpd.h:1118
int spawning
Definition dhcpd.h:1127
struct data_string hash_string
Definition dhcpd.h:1119
char * name
Definition dhcpd.h:1106
int lease_limit
Definition dhcpd.h:1109
int dirty
Definition dhcpd.h:1115
struct class * classes
Definition dhcpd.h:1092
const unsigned char * data
Definition tree.h:78
unsigned len
Definition tree.h:79
enum executable_statement::statement_op op
union executable_statement::@336221350347175166011011356261373334214214051201 data
Definition dhcpd.h:962
Definition dhcpd.h:560
struct iaddr ip_addr
Definition dhcpd.h:569
struct class * billing_class
Definition dhcpd.h:579
struct option_state * options
Definition dhcpd.h:449
struct binding_scope * global_scope
Definition tree.c:38
@ expr_check
Definition tree.h:134