summaryrefslogtreecommitdiff
path: root/keama/keama.h
blob: 4b97139694a582a1cf459d8b4161546f63b56d9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
/*
 * Copyright (c) 2017-2019 by Internet Systems Consortium, Inc. ("ISC")
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *   Internet Systems Consortium, Inc.
 *   PO Box 360
 *   Newmarket, NH 03857 USA
 *   <info@isc.org>
 *   https://www.isc.org/
 *
 */

#ifndef EOL
#define EOL '\n'
#endif

#include "data.h"
#include "dhctoken.h"

#include <time.h>

/* Resolution of FQDNs into IPv4 addresses */
enum resolve {
	perform = 0,	/* resolve */
	fatal,		/* raise a fatal error */
	pass		/* pass the string wth a warning */
};

extern enum resolve resolve;

/* From includes/dhcp.h */

#define HTYPE_ETHER	1
#define HTYPE_IEEE802	6
#define HTYPE_FDDI	8

#define DHO_DHCP_SERVER_IDENTIFIER		54
#define DHO_VENDOR_CLASS_IDENTIFIER		60
#define DHO_USER_CLASS				77
#define DHO_VIVSO_SUBOPTIONS			125

/* From includes/dhcp6.h */
#define D6O_VENDOR_OPTS				17
#define MAX_V6RELAY_HOPS			32

/* From includes/dhcpd.h */

extern int local_family;

/* A parsing context. */

struct parse {
	int lexline;
	int lexchar;
	char *token_line;
	char *prev_line;
	char *cur_line;
	const char *tlname;
	int eol_token;

	/*
	 * In order to give nice output when we have a parsing error
	 * in our file, we keep track of where we are in the line so
	 * that we can show the user.
	 *
	 * We need to keep track of two lines, because we can look
	 * ahead, via the "peek" function, to the next line sometimes.
	 *
	 * The "line1" and "line2" variables act as buffers for this
	 * information. The "lpos" variable tells us where we are in the
	 * line.
	 *
	 * When we "put back" a character from the parsing context, we
	 * do not want to have the character appear twice in the error
	 * output. So, we set a flag, the "ugflag", which the
	 * get_char() function uses to check for this condition.
	 */
	char line1[81];
	char line2[81];
	int lpos;
	int line;
	int tlpos;
	int tline;
	enum dhcp_token token;
	int ugflag;
	char *tval;
	int tlen;
	char tokbuf[1500];

	int warnings_occurred;
	int file;
	char *inbuf;
	size_t bufix, buflen;
	size_t bufsiz;

	/*
	 * Additions for the Kea Migration Assistant.
	 */
	struct element **stack;
	size_t stack_size;
	size_t stack_top;
	size_t issue_counter;

	/* don't save below this */
	struct comments comments;

	/* TAILQ_NEXT(self) is the saved state */
	TAILQ_ENTRY(parse) next;

};

extern TAILQ_HEAD(parses, parse) parses;

#define PARAMETER	0
#define TOPLEVEL	1
#define	ROOT_GROUP	2
#define HOST_DECL	3
#define SHARED_NET_DECL	4
#define SUBNET_DECL	5
#define CLASS_DECL	6
#define	GROUP_DECL	7
#define POOL_DECL	8

/* Used as an argument to parse_class_decl() */
#define CLASS_TYPE_VENDOR	0
#define CLASS_TYPE_USER		1
#define CLASS_TYPE_CLASS	2
#define CLASS_TYPE_SUBCLASS	3

#define CLASS_DECL_DELETED	1
#define CLASS_DECL_DYNAMIC	2
#define CLASS_DECL_STATIC	4
#define CLASS_DECL_SUBCLASS	8

/* Hardware buffer size */
#define HARDWARE_ADDR_LEN 20

/* Expression context */

enum expression_context {
	context_any, /* indefinite */
	context_boolean,
	context_data,
	context_numeric,
	context_dns,
	context_data_or_numeric, /* indefinite */
	context_function
};

/* Statements */

enum statement_op {
	null_statement,
	if_statement,
	add_statement,
	eval_statement,
	break_statement,
	default_option_statement,
	supersede_option_statement,
	append_option_statement,
	prepend_option_statement,
	send_option_statement,
	statements_statement,
	on_statement,
	switch_statement,
	case_statement,
	default_statement,
	set_statement,
	unset_statement,
	let_statement,
	define_statement,
	log_statement,
	return_statement,
	execute_statement,
	vendor_opt_statement
};

/* Expression tree structure. */

enum expr_op {
	expr_none,
	expr_match,
	expr_check,
	expr_equal,
	expr_substring,
	expr_suffix,
	expr_concat,
	expr_host_lookup,
	expr_and,
	expr_or,
	expr_not,
	expr_option,
	expr_hardware,
	expr_hw_type,		/* derived from expr_hardware */
	expr_hw_address,	/* derived from expr_hardware */
	expr_packet,
	expr_const_data,
	expr_extract_int8,
	expr_extract_int16,
	expr_extract_int32,
	expr_encode_int8,
	expr_encode_int16,
	expr_encode_int32,
	expr_const_int,
	expr_exists,
	expr_encapsulate,
	expr_known,
	expr_reverse,
	expr_leased_address,
	expr_binary_to_ascii,
	expr_config_option,
	expr_host_decl_name,
	expr_pick_first_value,
 	expr_lease_time,
 	expr_dns_transaction,
	expr_static,
	expr_ns_add,
 	expr_ns_delete,
 	expr_ns_exists,
 	expr_ns_not_exists,
	expr_not_equal,
	expr_null,
	expr_variable_exists,
	expr_variable_reference,
	expr_filename,
 	expr_sname,
	expr_arg,
	expr_funcall,
	expr_function,
	expr_add,
	expr_subtract,
	expr_multiply,
	expr_divide,
	expr_remainder,
	expr_binary_and,
	expr_binary_or,
	expr_binary_xor,
	expr_client_state,
	expr_ucase,
	expr_lcase,
	expr_regex_match,
	expr_iregex_match,
	expr_gethostname,
	expr_v6relay,
	expr_concat_dclist
};

/* options */

enum option_status {
	kea_unknown = 0,	/* known only by ISC DHCP */
	isc_dhcp_unknown = 1,	/* known only by Kea */
	known = 2,		/* known by both ISC DHCP and Kea */
	special = 3,		/* requires special processing */
	dynamic = 4		/* dynamic entry */
};

struct option_def {			/* ISC DHCP option definition */
	const char *name;		/* option name */
	const char *format;		/* format string */
	const char *space;		/* space (aka universe) */
	unsigned code;			/* code point */
	enum option_status status;	/* status */
};

struct space_def {			/* ISC DHCP space definition */
	const char *old;		/* ISC DHCP space name */
	const char *name;		/* Kea space name */
	enum option_status status;	/* status */
};

struct space {
	const char *old;		/* ISC DHCP space name */
	const char *name;		/* Kea space name */
	enum option_status status;	/* status */
	struct element *vendor;		/* vendor option */
	TAILQ_ENTRY(space) next;	/* next space */
};

struct option {
	const char *old;		/* ISC DHCP option name */
	const char *name;		/* Kea option name */
	const char *format;		/* ISC DHCP format string */
	const struct space *space;	/* space (aka universe) */
	unsigned code;			/* code point */
	enum option_status status;	/* status */
	TAILQ_ENTRY(option) next;	/* next option */
};

/* Kea parse tools */
void stackPush(struct parse *cfile, struct element *elem);

/* From command line */
extern char *hook_library_path;
extern isc_boolean_t use_isc_lifetimes;
extern isc_boolean_t global_hr;

/* From common/parse.c */
void parse_error(struct parse *, const char *, ...)
	__attribute__((__format__(__printf__,2,3)))
	__attribute__((noreturn));

/* conflex.c */
struct parse *new_parse(int, char *, size_t, const char *, int);
void end_parse(struct parse *);
void save_parse_state(struct parse *);
void restore_parse_state(struct parse *);
enum dhcp_token next_token(const char **, unsigned *, struct parse *);
enum dhcp_token peek_token(const char **, unsigned *, struct parse *);
enum dhcp_token next_raw_token(const char **, unsigned *, struct parse *);
enum dhcp_token peek_raw_token(const char **, unsigned *, struct parse *);
/*
 * Use skip_token when we are skipping a token we have previously
 * used peek_token on as we know what the result will be in this case.
 */
#define skip_token(a,b,c) ((void) next_token((a),(b),(c)))

/* confparse.c */
size_t conf_file_parse(struct parse *);
void read_conf_file(struct parse *, const char *, int);
size_t conf_file_subparse(struct parse *, int);
isc_boolean_t parse_statement(struct parse *, int, isc_boolean_t);
void get_permit(struct parse *, struct element *);
void parse_pool_statement(struct parse *, int);
void parse_lbrace(struct parse *);
void parse_host_declaration(struct parse *);
void parse_class_declaration(struct parse *, int);
void parse_shared_net_declaration(struct parse *);
void parse_subnet_declaration(struct parse *);
void parse_subnet6_declaration(struct parse *);
void parse_group_declaration(struct parse *);
void close_group(struct parse *, struct element *);
struct element *parse_fixed_addr_param(struct parse *, enum dhcp_token);
void parse_address_range(struct parse *, int, size_t);
void parse_address_range6(struct parse *, int, size_t);
void parse_prefix6(struct parse *, int, size_t);
void parse_fixed_prefix6(struct parse *, size_t);
void parse_pool6_statement(struct parse *, int);
struct element *parse_allow_deny(struct parse *, int);
void parse_server_duid_conf(struct parse *);
void parse_directive(struct parse *);
void parse_option_space_dir(struct parse *);
void parse_option_code_dir(struct parse *, struct option *);
void parse_option_status_dir(struct parse *, struct option *, enum dhcp_token);
void parse_option_local_dir(struct parse *, struct option *);
void parse_option_define_dir(struct parse *, struct option *);

/* parse.c */
void skip_to_semi(struct parse *);
void skip_to_rbrace(struct parse *, int);
void parse_semi(struct parse *);
void parse_string(struct parse *, char **, unsigned *);
struct string *parse_host_name(struct parse *);
struct string *parse_ip_addr_or_hostname(struct parse *, isc_boolean_t);
struct string *parse_ip_addr(struct parse *);
struct string *parse_ip6_addr(struct parse *);
struct string *parse_ip6_addr_txt(struct parse *);
struct element *parse_hardware_param(struct parse *);
void parse_lease_time(struct parse *, time_t *);
struct string *parse_numeric_aggregate(struct parse *,
				       unsigned char *, unsigned *,
				       int, int, unsigned);
void convert_num(struct parse *, unsigned char *, const char *,
		 int, unsigned);
struct option *parse_option_name(struct parse *, isc_boolean_t,
				 isc_boolean_t *);
void parse_option_space_decl(struct parse *);
void parse_option_code_definition(struct parse *, struct option *);
void parse_vendor_code_definition(struct parse *, struct option *);
struct string *convert_format(const char *, isc_boolean_t *, isc_boolean_t *);
struct string *parse_base64(struct parse *);
struct string *parse_cshl(struct parse *);
struct string *parse_hexa(struct parse *);
isc_boolean_t parse_executable_statements(struct element *,
					  struct parse *, isc_boolean_t *,
					  enum expression_context);
isc_boolean_t parse_executable_statement(struct element *,
					 struct parse *, isc_boolean_t *,
					 enum expression_context,
					 isc_boolean_t);
isc_boolean_t parse_zone(struct element *, struct parse *);
isc_boolean_t parse_key(struct element *, struct parse *);
isc_boolean_t parse_on_statement(struct element *, struct parse *,
				 isc_boolean_t *);
isc_boolean_t parse_switch_statement(struct element *, struct parse *,
				     isc_boolean_t *);
isc_boolean_t parse_case_statement(struct element *, struct parse *,
				   isc_boolean_t *, enum expression_context);
isc_boolean_t parse_if_statement(struct element *, struct parse *,
				 isc_boolean_t *);
isc_boolean_t parse_boolean_expression(struct element *, struct parse *,
				       isc_boolean_t *);
/* currently unused */
isc_boolean_t parse_boolean(struct parse *);
isc_boolean_t parse_data_expression(struct element *, struct parse *,
				    isc_boolean_t *);
isc_boolean_t numeric_expression(struct element *, struct parse *,
				 isc_boolean_t *);
isc_boolean_t parse_non_binary(struct element *, struct parse *,
			       isc_boolean_t *, enum expression_context);
isc_boolean_t parse_expression(struct element *, struct parse *,
			       isc_boolean_t *, enum expression_context,
			       struct element *, enum expr_op);
struct string *escape_option_string(unsigned, const char *,
				   isc_boolean_t *, isc_boolean_t *);
isc_boolean_t parse_option_data(struct element *, struct parse *,
				struct option *);
isc_boolean_t parse_option_binary(struct element *, struct parse *,
				  struct option *, isc_boolean_t);
struct string * parse_option_textbin(struct parse *, struct option *);
isc_boolean_t parse_option_statement(struct element *, struct parse *,
				     struct option *, enum statement_op);
isc_boolean_t parse_config_data(struct element *, struct parse *,
				struct option *);
isc_boolean_t parse_config_statement(struct element *, struct parse *,
				     struct option *, enum statement_op);
struct string *parse_option_token(struct parse *, const char *,
				  isc_boolean_t *, isc_boolean_t *,
				  isc_boolean_t *);
struct string *parse_option_token_binary(struct parse *, const char *);
struct string *parse_domain_list(struct parse *, isc_boolean_t);
isc_boolean_t is_boolean_expression(struct element *);
isc_boolean_t is_data_expression(struct element *);
isc_boolean_t is_numeric_expression(struct element *);
int expr_precedence(enum expr_op, struct element *);

/* options.c */
void spaces_init(void);
void options_init(void);
struct space *space_lookup(const char *);
struct option *option_lookup_name(const char *, const char *);
struct option *kea_lookup_name(const char *, const char *);
struct option *option_lookup_code(const char *, unsigned);
void push_space(struct space *);
void push_option(struct option *);
void add_option_data(struct element *, struct element *);
void merge_option_data(struct element *, struct element *);
struct comments *get_config_comments(unsigned);
const char *display_status(enum option_status);

/* json.c */
struct element *json_parse(struct parse *);
struct element *json_list_parse(struct parse *);
struct element *json_map_parse(struct parse *);

/* print.c */
const char *print_expression(struct element *, isc_boolean_t *);
const char *print_boolean_expression(struct element *, isc_boolean_t *);
const char *print_data_expression(struct element *, isc_boolean_t *);
const char *print_numeric_expression(struct element *, isc_boolean_t *);

/* reduce.c */
struct element *reduce_boolean_expression(struct element *);
struct element *reduce_data_expression(struct element *);
struct element *reduce_numeric_expression(struct element *);

/* eval */
struct element *eval_expression(struct element *, isc_boolean_t *);
struct element *eval_boolean_expression(struct element *, isc_boolean_t *);
struct element *eval_data_expression(struct element *, isc_boolean_t *);
struct element *eval_numeric_expression(struct element *, isc_boolean_t *);