ISC DHCP  4.3.2
A reference DHCPv4 and DHCPv6 implementation
class.c
Go to the documentation of this file.
1 /* class.c
2 
3  Handling for client classes. */
4 
5 /*
6  * Copyright (c) 2009,2012-2014 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 1998-2003 by Internet Software Consortium
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Internet Systems Consortium, Inc.
23  * 950 Charter Street
24  * Redwood City, CA 94063
25  * <info@isc.org>
26  * https://www.isc.org/
27  *
28  */
29 
30 #include "dhcpd.h"
31 
33  (struct collection *)0,
34  "default",
35  (struct class *)0,
36 };
37 
40 
42 
43 /* Build the default classification rule tree. */
44 
46 {
47  /* eval ... */
48  default_classification_rules = (struct executable_statement *)0;
49  if (!executable_statement_allocate (&default_classification_rules,
50  MDL))
51  log_fatal ("Can't allocate check of default collection");
52  default_classification_rules -> op = eval_statement;
53 
54  /* check-collection "default" */
55  if (!expression_allocate (&default_classification_rules -> data.eval,
56  MDL))
57  log_fatal ("Can't allocate default check expression");
58  default_classification_rules -> data.eval -> op = expr_check;
59  default_classification_rules -> data.eval -> data.check =
61 }
62 
64  struct packet *packet;
65 {
66  execute_statements (NULL, packet, NULL, NULL, packet->options, NULL,
67  &global_scope, default_classification_rules, NULL);
68 }
69 
71  struct packet *packet;
72  struct lease *lease;
73  struct collection *collection;
74 {
75  struct class *class, *nc;
76  struct data_string data;
77  int matched = 0;
78  int status;
79  int ignorep;
80  int classfound;
81 
82  for (class = collection -> classes; class; class = class -> nic) {
83 #if defined (DEBUG_CLASS_MATCHING)
84  log_info ("checking against class %s...", class -> name);
85 #endif
86  memset (&data, 0, sizeof data);
87 
88  /* If there is a "match if" expression, check it. If
89  we get a match, and there's no subclass expression,
90  it's a match. If we get a match and there is a subclass
91  expression, then we check the submatch. If it's not a
92  match, that's final - we don't check the submatch. */
93 
94  if (class -> expr) {
96  (&ignorep, packet, lease,
97  (struct client_state *)0,
98  packet -> options, (struct option_state *)0,
99  lease ? &lease -> scope : &global_scope,
100  class -> expr));
101  if (status) {
102  if (!class -> submatch) {
103  matched = 1;
104 #if defined (DEBUG_CLASS_MATCHING)
105  log_info ("matches class.");
106 #endif
107  classify (packet, class);
108  continue;
109  }
110  } else
111  continue;
112  }
113 
114  /* Check to see if the client matches an existing subclass.
115  If it doesn't, and this is a spawning class, spawn a new
116  subclass and put the client in it. */
117  if (class -> submatch) {
118  status = (evaluate_data_expression
119  (&data, packet, lease,
120  (struct client_state *)0,
121  packet -> options, (struct option_state *)0,
122  lease ? &lease -> scope : &global_scope,
123  class -> submatch, MDL));
124  if (status && data.len) {
125  nc = (struct class *)0;
126  classfound = class_hash_lookup (&nc, class -> hash,
127  (const char *)data.data, data.len, MDL);
128 
129 #ifdef LDAP_CONFIGURATION
130  if (!classfound && find_subclass_in_ldap (class, &nc, &data))
131  classfound = 1;
132 #endif
133 
134  if (classfound) {
135 #if defined (DEBUG_CLASS_MATCHING)
136  log_info ("matches subclass %s.",
137  print_hex_1 (data.len,
138  data.data, 60));
139 #endif
140  data_string_forget (&data, MDL);
141  classify (packet, nc);
142  matched = 1;
143  class_dereference (&nc, MDL);
144  continue;
145  }
146  if (!class -> spawning) {
147  data_string_forget (&data, MDL);
148  continue;
149  }
150  /* XXX Write out the spawned class? */
151 #if defined (DEBUG_CLASS_MATCHING)
152  log_info ("spawning subclass %s.",
153  print_hex_1 (data.len, data.data, 60));
154 #endif
155  status = class_allocate (&nc, MDL);
156  group_reference (&nc -> group,
157  class -> group, MDL);
158  class_reference (&nc -> superclass,
159  class, MDL);
160  nc -> lease_limit = class -> lease_limit;
161  nc -> dirty = 1;
162  if (nc -> lease_limit) {
163  nc -> billed_leases =
164  (dmalloc
165  (nc -> lease_limit *
166  sizeof (struct lease *),
167  MDL));
168  if (!nc -> billed_leases) {
169  log_error ("no memory for%s",
170  " billing");
172  (&nc -> hash_string,
173  MDL);
174  class_dereference (&nc, MDL);
175  data_string_forget (&data,
176  MDL);
177  continue;
178  }
179  memset (nc -> billed_leases, 0,
180  (nc -> lease_limit *
181  sizeof (struct lease *)));
182  }
183  data_string_copy (&nc -> hash_string, &data,
184  MDL);
185  data_string_forget (&data, MDL);
186  if (!class -> hash)
187  class_new_hash(&class->hash,
189  class_hash_add (class -> hash,
190  (const char *)
191  nc -> hash_string.data,
192  nc -> hash_string.len,
193  nc, MDL);
194  classify (packet, nc);
195  class_dereference (&nc, MDL);
196  }
197  }
198  }
199  return matched;
200 }
201 
202 void classify (packet, class)
203  struct packet *packet;
204  struct class *class;
205 {
206  if (packet -> class_count < PACKET_MAX_CLASSES)
207  class_reference (&packet -> classes [packet -> class_count++],
208  class, MDL);
209  else
210  log_error ("too many classes match %s",
211  print_hw_addr (packet -> raw -> htype,
212  packet -> raw -> hlen,
213  packet -> raw -> chaddr));
214 }
215 
216 
217 isc_result_t unlink_class(struct class **class) {
218  struct collection *lp;
219  struct class *cp, *pp;
220 
221  for (lp = collections; lp; lp = lp -> next) {
222  for (pp = 0, cp = lp -> classes; cp; pp = cp, cp = cp -> nic)
223  if (cp == *class) {
224  if (pp == 0) {
225  lp->classes = cp->nic;
226  } else {
227  pp->nic = cp->nic;
228  }
229  cp->nic = 0;
230  class_dereference(class, MDL);
231 
232  return ISC_R_SUCCESS;
233  }
234  }
235  return ISC_R_NOTFOUND;
236 }
237 
238 
239 isc_result_t find_class (struct class **class, const char *name,
240  const char *file, int line)
241 {
242  struct collection *lp;
243  struct class *cp;
244 
245  for (lp = collections; lp; lp = lp -> next) {
246  for (cp = lp -> classes; cp; cp = cp -> nic)
247  if (cp -> name && !strcmp (name, cp -> name)) {
248  return class_reference (class, cp, file, line);
249  }
250  }
251  return ISC_R_NOTFOUND;
252 }
253 
254 int unbill_class (lease, class)
255  struct lease *lease;
256  struct class *class;
257 {
258  int i;
259 
260  for (i = 0; i < class -> lease_limit; i++)
261  if (class -> billed_leases [i] == lease)
262  break;
263  if (i == class -> lease_limit) {
264  log_error ("lease %s unbilled with no billing arrangement.",
265  piaddr (lease -> ip_addr));
266  return 0;
267  }
268  class_dereference (&lease -> billing_class, MDL);
269  lease_dereference (&class -> billed_leases [i], MDL);
270  class -> leases_consumed--;
271  return 1;
272 }
273 
274 int bill_class (lease, class)
275  struct lease *lease;
276  struct class *class;
277 {
278  int i;
279 
280  if (lease -> billing_class) {
281  log_error ("lease billed with existing billing arrangement.");
282  unbill_class (lease, lease -> billing_class);
283  }
284 
285  if (class -> leases_consumed == class -> lease_limit)
286  return 0;
287 
288  for (i = 0; i < class -> lease_limit; i++)
289  if (!class -> billed_leases [i])
290  break;
291 
292  if (i == class -> lease_limit) {
293  log_error ("class billing consumption disagrees with leases.");
294  return 0;
295  }
296 
297  lease_reference (&class -> billed_leases [i], lease, MDL);
298  class_reference (&lease -> billing_class, class, MDL);
299  class -> leases_consumed++;
300  return 1;
301 }
int executable_statement_allocate(struct executable_statement **ptr, const char *file, int line)
Definition: alloc.c:959
struct class * nic
Definition: dhcpd.h:1014
const char int line
Definition: dhcpd.h:3615
struct binding_scope * global_scope
Definition: tree.c:39
Definition: dhcpd.h:521
unsigned len
Definition: tree.h:80
const char * piaddr(const struct iaddr addr)
Definition: inet.c:581
void * dmalloc(unsigned, const char *, int)
Definition: alloc.c:56
struct class * superclass
Definition: dhcpd.h:1015
int expression_allocate(struct expression **cptr, const char *file, int line)
Definition: alloc.c:427
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
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition: inet.c:65
#define MDL
Definition: omapip.h:568
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2477
class_hash_t * hash
Definition: dhcpd.h:1028
enum executable_statement::statement_op op
int group_reference(struct group **ptr, struct group *bp, const char *file, int line)
Definition: alloc.c:178
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1340
struct data_string hash_string
Definition: dhcpd.h:1029
#define SCLASS_HASH_SIZE
Definition: dhcpd.h:210
int log_error(const char *,...) __attribute__((__format__(__printf__
int check_collection(struct packet *packet, struct lease *lease, struct collection *collection)
Definition: class.c:70
struct executable_statement * default_classification_rules
Definition: class.c:39
void classify(struct packet *packet, struct class *class)
Definition: class.c:202
char * name
Definition: dhcpd.h:1016
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int evaluate_boolean_expression_result(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr)
Definition: tree.c:2769
void classify_client(struct packet *packet)
Definition: class.c:63
struct expression * expr
Definition: dhcpd.h:1032
Definition: dhcpd.h:376
struct expression * submatch
Definition: dhcpd.h:1036
int lease_limit
Definition: dhcpd.h:1019
int int log_info(const char *,...) __attribute__((__format__(__printf__
int evaluate_data_expression(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct expression *expr, const char *file, int line)
Definition: tree.c:1115
struct class * classes
Definition: dhcpd.h:1002
union executable_statement::@7 data
struct lease ** billed_leases
Definition: dhcpd.h:1021
isc_result_t find_class(struct class **class, const char *name, const char *file, int line)
Definition: class.c:239
Definition: dhcpd.h:884
int have_billing_classes
Definition: class.c:41
struct collection * collections
Definition: class.c:38
void classification_setup()
Definition: class.c:45
const char * file
Definition: dhcpd.h:3615
Definition: dhcpd.h:1012
int unbill_class(struct lease *lease, struct class *class)
Definition: class.c:254
const unsigned char * data
Definition: tree.h:79
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
Definition: alloc.c:1324
struct collection default_collection
Definition: class.c:32
isc_result_t unlink_class(struct class **class)
Definition: class.c:217
int dirty
Definition: dhcpd.h:1025
#define PACKET_MAX_CLASSES
Definition: dhcpd.h:417
int spawning
Definition: dhcpd.h:1037
int bill_class(struct lease *lease, struct class *class)
Definition: class.c:274