]>
Commit | Line | Data |
---|---|---|
d7837182 TL |
1 | /* conflex.c |
2 | ||
3 | Lexical scanner for dhcpd config file... */ | |
4 | ||
5 | /* | |
49a7fb58 | 6 | * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC") |
98311e4b | 7 | * Copyright (c) 1995-2003 by Internet Software Consortium |
d7837182 | 8 | * |
7512d88b TM |
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/. | |
d7837182 | 12 | * |
98311e4b DH |
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. | |
d7837182 | 20 | * |
98311e4b | 21 | * Internet Systems Consortium, Inc. |
429a56d7 TM |
22 | * PO Box 360 |
23 | * Newmarket, NH 03857 USA | |
98311e4b | 24 | * <info@isc.org> |
2c85ac9b | 25 | * https://www.isc.org/ |
49733f31 | 26 | * |
d7837182 TL |
27 | */ |
28 | ||
d7837182 | 29 | #include "dhcpd.h" |
d7837182 TL |
30 | #include <ctype.h> |
31 | ||
a34feb7d | 32 | static int get_char (struct parse *); |
e9263b5c | 33 | static void unget_char(struct parse *, int); |
a34feb7d | 34 | static void skip_to_eol (struct parse *); |
bda33169 | 35 | static enum dhcp_token read_whitespace(int c, struct parse *cfile); |
a34feb7d TM |
36 | static enum dhcp_token read_string (struct parse *); |
37 | static enum dhcp_token read_number (int, struct parse *); | |
38 | static enum dhcp_token read_num_or_name (int, struct parse *); | |
39 | static enum dhcp_token intern (char *, enum dhcp_token); | |
d7837182 | 40 | |
24f9d67e | 41 | isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp) |
6f4b5b31 TL |
42 | struct parse **cfile; |
43 | int file; | |
44 | char *inbuf; | |
b1b7b521 TL |
45 | unsigned buflen; |
46 | const char *name; | |
24f9d67e | 47 | int eolp; |
6f4b5b31 | 48 | { |
c40e954c | 49 | isc_result_t status = ISC_R_SUCCESS; |
6f4b5b31 | 50 | struct parse *tmp; |
512994ed | 51 | |
bda33169 SK |
52 | tmp = dmalloc(sizeof(struct parse), MDL); |
53 | if (tmp == NULL) { | |
c40e954c | 54 | return (ISC_R_NOMEMORY); |
bda33169 | 55 | } |
512994ed | 56 | |
bda33169 | 57 | /* |
f6b8f48d | 58 | * We don't need to initialize things to zero here, since |
bda33169 SK |
59 | * dmalloc() returns memory that is set to zero. |
60 | */ | |
66eaae18 SK |
61 | tmp->tlname = name; |
62 | tmp->lpos = tmp -> line = 1; | |
bda33169 SK |
63 | tmp->cur_line = tmp->line1; |
64 | tmp->prev_line = tmp->line2; | |
65 | tmp->token_line = tmp->cur_line; | |
66 | tmp->cur_line[0] = tmp->prev_line[0] = 0; | |
66eaae18 SK |
67 | tmp->file = file; |
68 | tmp->eol_token = eolp; | |
69 | ||
bda33169 | 70 | if (inbuf != NULL) { |
66eaae18 SK |
71 | tmp->inbuf = inbuf; |
72 | tmp->buflen = buflen; | |
73 | tmp->bufsiz = 0; | |
6f4b5b31 | 74 | } else { |
66eaae18 SK |
75 | struct stat sb; |
76 | ||
c40e954c EH |
77 | if (fstat(file, &sb) < 0) { |
78 | status = ISC_R_IOERROR; | |
79 | goto cleanup; | |
80 | } | |
81 | ||
82 | if (sb.st_size == 0) | |
83 | goto cleanup; | |
66eaae18 | 84 | |
c40e954c | 85 | tmp->bufsiz = tmp->buflen = (size_t) sb.st_size; |
66eaae18 SK |
86 | tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED, |
87 | file, 0); | |
88 | ||
89 | if (tmp->inbuf == MAP_FAILED) { | |
c40e954c EH |
90 | status = ISC_R_IOERROR; |
91 | goto cleanup; | |
6f4b5b31 | 92 | } |
6f4b5b31 TL |
93 | } |
94 | ||
95 | *cfile = tmp; | |
c40e954c EH |
96 | return (ISC_R_SUCCESS); |
97 | ||
98 | cleanup: | |
99 | dfree(tmp, MDL); | |
100 | return (status); | |
6f4b5b31 TL |
101 | } |
102 | ||
103 | isc_result_t end_parse (cfile) | |
104 | struct parse **cfile; | |
58304e8e | 105 | { |
88cd8aca | 106 | /* "Memory" config files have no file. */ |
66eaae18 SK |
107 | if ((*cfile)->file != -1) { |
108 | munmap((*cfile)->inbuf, (*cfile)->bufsiz); | |
88cd8aca | 109 | close((*cfile)->file); |
66eaae18 | 110 | } |
bda33169 SK |
111 | |
112 | if ((*cfile)->saved_state != NULL) { | |
113 | dfree((*cfile)->saved_state, MDL); | |
114 | } | |
f6b8f48d | 115 | |
88cd8aca DH |
116 | dfree(*cfile, MDL); |
117 | *cfile = NULL; | |
6f4b5b31 | 118 | return ISC_R_SUCCESS; |
58304e8e TL |
119 | } |
120 | ||
bda33169 SK |
121 | /* |
122 | * Save the current state of the parser. | |
123 | * | |
124 | * Only one state may be saved. Any previous saved state is | |
125 | * lost. | |
126 | */ | |
127 | isc_result_t | |
128 | save_parse_state(struct parse *cfile) { | |
129 | /* | |
130 | * Free any previous saved state. | |
131 | */ | |
132 | if (cfile->saved_state != NULL) { | |
133 | dfree(cfile->saved_state, MDL); | |
134 | } | |
135 | ||
136 | /* | |
137 | * Save our current state. | |
138 | */ | |
139 | cfile->saved_state = dmalloc(sizeof(struct parse), MDL); | |
140 | if (cfile->saved_state == NULL) { | |
141 | return ISC_R_NOMEMORY; | |
142 | } | |
143 | memcpy(cfile->saved_state, cfile, sizeof(*cfile)); | |
144 | return ISC_R_SUCCESS; | |
145 | } | |
146 | ||
147 | /* | |
148 | * Return the parser to the previous saved state. | |
149 | * | |
743d6937 TM |
150 | * You must call save_parse_state() every time before calling |
151 | * restore_parse_state(). | |
152 | * | |
153 | * Note: When the read function callback is in use in ldap mode, | |
154 | * a call to get_char() may reallocate the buffer and will append | |
155 | * config data to the buffer until a state restore. | |
156 | * Do not restore to the (freed) pointer and size, but use new one. | |
bda33169 SK |
157 | */ |
158 | isc_result_t | |
159 | restore_parse_state(struct parse *cfile) { | |
160 | struct parse *saved_state; | |
743d6937 TM |
161 | #if defined(LDAP_CONFIGURATION) |
162 | char *inbuf = cfile->inbuf; | |
163 | size_t size = cfile->bufsiz; | |
164 | #endif | |
bda33169 SK |
165 | |
166 | if (cfile->saved_state == NULL) { | |
98bf1607 | 167 | return DHCP_R_NOTYET; |
bda33169 SK |
168 | } |
169 | ||
170 | saved_state = cfile->saved_state; | |
171 | memcpy(cfile, saved_state, sizeof(*cfile)); | |
743d6937 TM |
172 | dfree(saved_state, MDL); |
173 | cfile->saved_state = NULL; | |
174 | ||
175 | #if defined(LDAP_CONFIGURATION) | |
176 | cfile->inbuf = inbuf; | |
177 | cfile->bufsiz = size; | |
178 | #endif | |
bda33169 SK |
179 | return ISC_R_SUCCESS; |
180 | } | |
181 | ||
d7837182 | 182 | static int get_char (cfile) |
6f4b5b31 | 183 | struct parse *cfile; |
d7837182 | 184 | { |
6f4b5b31 TL |
185 | /* My kingdom for WITH... */ |
186 | int c; | |
187 | ||
33692791 DH |
188 | if (cfile->bufix == cfile->buflen) { |
189 | #if !defined(LDAP_CONFIGURATION) | |
66eaae18 | 190 | c = EOF; |
33692791 DH |
191 | #else /* defined(LDAP_CONFIGURATION) */ |
192 | if (cfile->read_function != NULL) | |
193 | c = cfile->read_function(cfile); | |
194 | else | |
195 | c = EOF; | |
196 | #endif | |
197 | } else { | |
66eaae18 SK |
198 | c = cfile->inbuf [cfile->bufix]; |
199 | cfile->bufix++; | |
6f4b5b31 TL |
200 | } |
201 | ||
66eaae18 | 202 | if (!cfile->ugflag) { |
d7837182 | 203 | if (c == EOL) { |
f6b8f48d | 204 | if (cfile->cur_line == cfile->line1) { |
66eaae18 SK |
205 | cfile->cur_line = cfile->line2; |
206 | cfile->prev_line = cfile->line1; | |
512994ed | 207 | } else { |
66eaae18 SK |
208 | cfile->cur_line = cfile->line1; |
209 | cfile->prev_line = cfile->line2; | |
512994ed | 210 | } |
66eaae18 SK |
211 | cfile->line++; |
212 | cfile->lpos = 1; | |
213 | cfile->cur_line [0] = 0; | |
512994ed | 214 | } else if (c != EOF) { |
66eaae18 SK |
215 | if (cfile->lpos <= 80) { |
216 | cfile->cur_line [cfile->lpos - 1] = c; | |
217 | cfile->cur_line [cfile->lpos] = 0; | |
512994ed | 218 | } |
66eaae18 | 219 | cfile->lpos++; |
d7837182 TL |
220 | } |
221 | } else | |
66eaae18 | 222 | cfile->ugflag = 0; |
f6b8f48d | 223 | return c; |
d7837182 TL |
224 | } |
225 | ||
d19e816e SK |
226 | /* |
227 | * Return a character to our input buffer. | |
228 | */ | |
e9263b5c | 229 | static void |
d19e816e SK |
230 | unget_char(struct parse *cfile, int c) { |
231 | if (c != EOF) { | |
232 | cfile->bufix--; | |
233 | cfile->ugflag = 1; /* do not put characters into | |
234 | our error buffer on the next | |
235 | call to get_char() */ | |
236 | } | |
237 | } | |
238 | ||
bda33169 SK |
239 | /* |
240 | * GENERAL NOTE ABOUT TOKENS | |
241 | * | |
f6b8f48d | 242 | * We normally only want non-whitespace tokens. There are some |
bda33169 SK |
243 | * circumstances where we *do* want to see whitespace (for example |
244 | * when parsing IPv6 addresses). | |
245 | * | |
f6b8f48d | 246 | * Generally we use the next_token() function to read tokens. This |
28868515 | 247 | * in turn calls get_next_token, which does *not* return tokens for |
bda33169 SK |
248 | * whitespace. Rather, it skips these. |
249 | * | |
250 | * When we need to see whitespace, we us next_raw_token(), which also | |
251 | * returns the WHITESPACE token. | |
252 | * | |
253 | * The peek_token() and peek_raw_token() functions work as expected. | |
254 | * | |
255 | * Warning: if you invoke peek_token(), then if there is a whitespace | |
256 | * token, it will be lost, and subsequent use of next_raw_token() or | |
257 | * peek_raw_token() will NOT see it. | |
258 | */ | |
259 | ||
260 | static enum dhcp_token | |
261 | get_raw_token(struct parse *cfile) { | |
d7837182 | 262 | int c; |
104c88cd | 263 | enum dhcp_token ttok; |
089fb364 | 264 | static char tb [2]; |
b645f9d5 | 265 | int l, p; |
d7837182 TL |
266 | |
267 | do { | |
6f4b5b31 TL |
268 | l = cfile -> line; |
269 | p = cfile -> lpos; | |
58304e8e | 270 | |
d7837182 | 271 | c = get_char (cfile); |
f6b8f48d | 272 | if (!((c == '\n') && cfile->eol_token) && |
bda33169 SK |
273 | isascii(c) && isspace(c)) { |
274 | ttok = read_whitespace(c, cfile); | |
275 | break; | |
276 | } | |
d7837182 TL |
277 | if (c == '#') { |
278 | skip_to_eol (cfile); | |
279 | continue; | |
280 | } | |
d7837182 | 281 | if (c == '"') { |
6f4b5b31 TL |
282 | cfile -> lexline = l; |
283 | cfile -> lexchar = p; | |
d7837182 TL |
284 | ttok = read_string (cfile); |
285 | break; | |
286 | } | |
a8b53b42 | 287 | if ((isascii (c) && isdigit (c)) || c == '-') { |
6f4b5b31 TL |
288 | cfile -> lexline = l; |
289 | cfile -> lexchar = p; | |
d7837182 TL |
290 | ttok = read_number (c, cfile); |
291 | break; | |
292 | } else if (isascii (c) && isalpha (c)) { | |
6f4b5b31 TL |
293 | cfile -> lexline = l; |
294 | cfile -> lexchar = p; | |
50b025a3 | 295 | ttok = read_num_or_name (c, cfile); |
d7837182 | 296 | break; |
0b69dcc8 TL |
297 | } else if (c == EOF) { |
298 | ttok = END_OF_FILE; | |
b3519f23 | 299 | cfile -> tlen = 0; |
0b69dcc8 | 300 | break; |
d7837182 | 301 | } else { |
6f4b5b31 TL |
302 | cfile -> lexline = l; |
303 | cfile -> lexchar = p; | |
089fb364 TL |
304 | tb [0] = c; |
305 | tb [1] = 0; | |
6f4b5b31 | 306 | cfile -> tval = tb; |
b3519f23 | 307 | cfile -> tlen = 1; |
d7837182 TL |
308 | ttok = c; |
309 | break; | |
310 | } | |
311 | } while (1); | |
312 | return ttok; | |
313 | } | |
314 | ||
bda33169 SK |
315 | /* |
316 | * The get_next_token() function consumes the next token and | |
317 | * returns it to the caller. | |
318 | * | |
f6b8f48d | 319 | * Since the code is almost the same for "normal" and "raw" |
bda33169 SK |
320 | * input, we pass a flag to alter the way it works. |
321 | */ | |
322 | ||
f6b8f48d TM |
323 | static enum dhcp_token |
324 | get_next_token(const char **rval, unsigned *rlen, | |
bda33169 | 325 | struct parse *cfile, isc_boolean_t raw) { |
d7837182 TL |
326 | int rv; |
327 | ||
6f4b5b31 TL |
328 | if (cfile -> token) { |
329 | if (cfile -> lexline != cfile -> tline) | |
330 | cfile -> token_line = cfile -> cur_line; | |
331 | cfile -> lexchar = cfile -> tlpos; | |
332 | cfile -> lexline = cfile -> tline; | |
333 | rv = cfile -> token; | |
334 | cfile -> token = 0; | |
d7837182 | 335 | } else { |
bda33169 | 336 | rv = get_raw_token(cfile); |
6f4b5b31 | 337 | cfile -> token_line = cfile -> cur_line; |
d7837182 | 338 | } |
bda33169 SK |
339 | |
340 | if (!raw) { | |
341 | while (rv == WHITESPACE) { | |
342 | rv = get_raw_token(cfile); | |
343 | cfile->token_line = cfile->cur_line; | |
344 | } | |
345 | } | |
f6b8f48d | 346 | |
d7837182 | 347 | if (rval) |
6f4b5b31 | 348 | *rval = cfile -> tval; |
b3519f23 TL |
349 | if (rlen) |
350 | *rlen = cfile -> tlen; | |
089fb364 | 351 | #ifdef DEBUG_TOKENS |
6f4b5b31 | 352 | fprintf (stderr, "%s:%d ", cfile -> tval, rv); |
089fb364 | 353 | #endif |
d7837182 TL |
354 | return rv; |
355 | } | |
356 | ||
bda33169 SK |
357 | |
358 | /* | |
359 | * Get the next token from cfile and return it. | |
360 | * | |
f6b8f48d | 361 | * If rval is non-NULL, set the pointer it contains to |
bda33169 SK |
362 | * the contents of the token. |
363 | * | |
f6b8f48d | 364 | * If rlen is non-NULL, set the integer it contains to |
bda33169 SK |
365 | * the length of the token. |
366 | */ | |
367 | ||
368 | enum dhcp_token | |
369 | next_token(const char **rval, unsigned *rlen, struct parse *cfile) { | |
370 | return get_next_token(rval, rlen, cfile, ISC_FALSE); | |
371 | } | |
372 | ||
373 | ||
374 | /* | |
375 | * The same as the next_token() function above, but will return space | |
376 | * as the WHITESPACE token. | |
377 | */ | |
378 | ||
379 | enum dhcp_token | |
380 | next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) { | |
381 | return get_next_token(rval, rlen, cfile, ISC_TRUE); | |
382 | } | |
383 | ||
384 | ||
385 | /* | |
386 | * The do_peek_token() function checks the next token without | |
387 | * consuming it, and returns it to the caller. | |
388 | * | |
f6b8f48d TM |
389 | * Since the code is almost the same for "normal" and "raw" |
390 | * input, we pass a flag to alter the way it works. (See the | |
bda33169 SK |
391 | * warning in the GENERAL NOTES ABOUT TOKENS above though.) |
392 | */ | |
393 | ||
394 | enum dhcp_token | |
395 | do_peek_token(const char **rval, unsigned int *rlen, | |
396 | struct parse *cfile, isc_boolean_t raw) { | |
58304e8e TL |
397 | int x; |
398 | ||
bda33169 | 399 | if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) { |
6f4b5b31 TL |
400 | cfile -> tlpos = cfile -> lexchar; |
401 | cfile -> tline = cfile -> lexline; | |
bda33169 SK |
402 | |
403 | do { | |
404 | cfile->token = get_raw_token(cfile); | |
405 | } while (!raw && (cfile->token == WHITESPACE)); | |
406 | ||
6f4b5b31 TL |
407 | if (cfile -> lexline != cfile -> tline) |
408 | cfile -> token_line = cfile -> prev_line; | |
409 | ||
410 | x = cfile -> lexchar; | |
411 | cfile -> lexchar = cfile -> tlpos; | |
412 | cfile -> tlpos = x; | |
413 | ||
414 | x = cfile -> lexline; | |
415 | cfile -> lexline = cfile -> tline; | |
416 | cfile -> tline = x; | |
58304e8e | 417 | } |
d7837182 | 418 | if (rval) |
6f4b5b31 | 419 | *rval = cfile -> tval; |
b3519f23 TL |
420 | if (rlen) |
421 | *rlen = cfile -> tlen; | |
089fb364 | 422 | #ifdef DEBUG_TOKENS |
6f4b5b31 | 423 | fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token); |
089fb364 | 424 | #endif |
6f4b5b31 | 425 | return cfile -> token; |
d7837182 TL |
426 | } |
427 | ||
bda33169 SK |
428 | |
429 | /* | |
f6b8f48d | 430 | * Get the next token from cfile and return it, leaving it for a |
bda33169 SK |
431 | * subsequent call to next_token(). |
432 | * | |
433 | * Note that it WILL consume whitespace tokens. | |
434 | * | |
f6b8f48d | 435 | * If rval is non-NULL, set the pointer it contains to |
bda33169 SK |
436 | * the contents of the token. |
437 | * | |
f6b8f48d | 438 | * If rlen is non-NULL, set the integer it contains to |
bda33169 SK |
439 | * the length of the token. |
440 | */ | |
441 | ||
442 | enum dhcp_token | |
443 | peek_token(const char **rval, unsigned *rlen, struct parse *cfile) { | |
444 | return do_peek_token(rval, rlen, cfile, ISC_FALSE); | |
445 | } | |
446 | ||
447 | ||
448 | /* | |
449 | * The same as the peek_token() function above, but will return space | |
450 | * as the WHITESPACE token. | |
451 | */ | |
452 | ||
453 | enum dhcp_token | |
454 | peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile) { | |
455 | return do_peek_token(rval, rlen, cfile, ISC_TRUE); | |
456 | } | |
457 | ||
d7837182 | 458 | static void skip_to_eol (cfile) |
6f4b5b31 | 459 | struct parse *cfile; |
d7837182 TL |
460 | { |
461 | int c; | |
462 | do { | |
463 | c = get_char (cfile); | |
464 | if (c == EOF) | |
465 | return; | |
466 | if (c == EOL) { | |
d7837182 TL |
467 | return; |
468 | } | |
469 | } while (1); | |
470 | } | |
471 | ||
bda33169 SK |
472 | static enum dhcp_token |
473 | read_whitespace(int c, struct parse *cfile) { | |
474 | int ofs; | |
475 | ||
476 | /* | |
477 | * Read as much whitespace as we have available. | |
478 | */ | |
479 | ofs = 0; | |
480 | do { | |
36e2c224 | 481 | if (ofs >= (sizeof(cfile->tokbuf) - 1)) { |
360cc6d9 SR |
482 | /* |
483 | * As the file includes a huge amount of whitespace, | |
484 | * it's probably broken. | |
485 | * Print out a warning and bail out. | |
486 | */ | |
487 | parse_warn(cfile, | |
488 | "whitespace too long, buffer overflow."); | |
489 | log_fatal("Exiting"); | |
490 | } | |
bda33169 SK |
491 | cfile->tokbuf[ofs++] = c; |
492 | c = get_char(cfile); | |
743d6937 TM |
493 | if (c == EOF) |
494 | return END_OF_FILE; | |
f6b8f48d | 495 | } while (!((c == '\n') && cfile->eol_token) && |
bda33169 SK |
496 | isascii(c) && isspace(c)); |
497 | ||
498 | /* | |
499 | * Put the last (non-whitespace) character back. | |
500 | */ | |
d19e816e | 501 | unget_char(cfile, c); |
bda33169 SK |
502 | |
503 | /* | |
504 | * Return our token. | |
505 | */ | |
506 | cfile->tokbuf[ofs] = '\0'; | |
507 | cfile->tlen = ofs; | |
508 | cfile->tval = cfile->tokbuf; | |
509 | return WHITESPACE; | |
510 | } | |
511 | ||
104c88cd | 512 | static enum dhcp_token read_string (cfile) |
6f4b5b31 | 513 | struct parse *cfile; |
d7837182 TL |
514 | { |
515 | int i; | |
516 | int bs = 0; | |
517 | int c; | |
98311e4b DH |
518 | int value = 0; |
519 | int hex = 0; | |
d7837182 | 520 | |
6f4b5b31 | 521 | for (i = 0; i < sizeof cfile -> tokbuf; i++) { |
2b6e0559 | 522 | again: |
d7837182 TL |
523 | c = get_char (cfile); |
524 | if (c == EOF) { | |
6f4b5b31 | 525 | parse_warn (cfile, "eof in string constant"); |
d7837182 TL |
526 | break; |
527 | } | |
2b6e0559 TL |
528 | if (bs == 1) { |
529 | switch (c) { | |
530 | case 't': | |
531 | cfile -> tokbuf [i] = '\t'; | |
532 | break; | |
533 | case 'r': | |
534 | cfile -> tokbuf [i] = '\r'; | |
535 | break; | |
536 | case 'n': | |
537 | cfile -> tokbuf [i] = '\n'; | |
538 | break; | |
539 | case 'b': | |
540 | cfile -> tokbuf [i] = '\b'; | |
541 | break; | |
542 | case '0': | |
543 | case '1': | |
544 | case '2': | |
545 | case '3': | |
546 | hex = 0; | |
547 | value = c - '0'; | |
548 | ++bs; | |
549 | goto again; | |
550 | case 'x': | |
551 | hex = 1; | |
552 | value = 0; | |
553 | ++bs; | |
554 | goto again; | |
555 | default: | |
556 | cfile -> tokbuf [i] = c; | |
2b6e0559 TL |
557 | break; |
558 | } | |
d7837182 | 559 | bs = 0; |
2b6e0559 TL |
560 | } else if (bs > 1) { |
561 | if (hex) { | |
562 | if (c >= '0' && c <= '9') { | |
563 | value = value * 16 + (c - '0'); | |
564 | } else if (c >= 'a' && c <= 'f') { | |
565 | value = value * 16 + (c - 'a' + 10); | |
566 | } else if (c >= 'A' && c <= 'F') { | |
567 | value = value * 16 + (c - 'A' + 10); | |
568 | } else { | |
569 | parse_warn (cfile, | |
570 | "invalid hex digit: %x", | |
571 | c); | |
572 | bs = 0; | |
573 | continue; | |
574 | } | |
575 | if (++bs == 4) { | |
576 | cfile -> tokbuf [i] = value; | |
577 | bs = 0; | |
578 | } else | |
579 | goto again; | |
580 | } else { | |
71765b58 | 581 | if (c >= '0' && c <= '7') { |
2b6e0559 TL |
582 | value = value * 8 + (c - '0'); |
583 | } else { | |
584 | if (value != 0) { | |
585 | parse_warn (cfile, | |
586 | "invalid octal digit %x", | |
587 | c); | |
588 | continue; | |
589 | } else | |
590 | cfile -> tokbuf [i] = 0; | |
591 | bs = 0; | |
592 | } | |
593 | if (++bs == 4) { | |
594 | cfile -> tokbuf [i] = value; | |
595 | bs = 0; | |
596 | } else | |
597 | goto again; | |
598 | } | |
599 | } else if (c == '\\') { | |
d7837182 | 600 | bs = 1; |
2b6e0559 TL |
601 | goto again; |
602 | } else if (c == '"') | |
d7837182 TL |
603 | break; |
604 | else | |
6f4b5b31 | 605 | cfile -> tokbuf [i] = c; |
d7837182 TL |
606 | } |
607 | /* Normally, I'd feel guilty about this, but we're talking about | |
608 | strings that'll fit in a DHCP packet here... */ | |
6f4b5b31 TL |
609 | if (i == sizeof cfile -> tokbuf) { |
610 | parse_warn (cfile, | |
611 | "string constant larger than internal buffer"); | |
d7837182 TL |
612 | --i; |
613 | } | |
6f4b5b31 | 614 | cfile -> tokbuf [i] = 0; |
b3519f23 | 615 | cfile -> tlen = i; |
6f4b5b31 | 616 | cfile -> tval = cfile -> tokbuf; |
d7837182 TL |
617 | return STRING; |
618 | } | |
619 | ||
104c88cd | 620 | static enum dhcp_token read_number (c, cfile) |
d7837182 | 621 | int c; |
6f4b5b31 | 622 | struct parse *cfile; |
d7837182 | 623 | { |
d7837182 | 624 | int i = 0; |
512994ed TL |
625 | int token = NUMBER; |
626 | ||
6f4b5b31 TL |
627 | cfile -> tokbuf [i++] = c; |
628 | for (; i < sizeof cfile -> tokbuf; i++) { | |
d7837182 | 629 | c = get_char (cfile); |
98311e4b | 630 | |
98311e4b DH |
631 | /* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote. |
632 | * Except in the case of '0x' syntax hex, which gets called | |
633 | * a NAME at '0x', and returned to NUMBER_OR_NAME once it's | |
634 | * verified to be at least 0xf or less. | |
635 | */ | |
636 | switch(isascii(c) ? token : BREAK) { | |
637 | case NUMBER: | |
638 | if(isdigit(c)) | |
639 | break; | |
640 | /* FALLTHROUGH */ | |
641 | case NUMBER_OR_NAME: | |
642 | if(isxdigit(c)) { | |
643 | token = NUMBER_OR_NAME; | |
644 | break; | |
645 | } | |
646 | /* FALLTHROUGH */ | |
647 | case NAME: | |
648 | if((i == 2) && isxdigit(c) && | |
649 | (cfile->tokbuf[0] == '0') && | |
650 | ((cfile->tokbuf[1] == 'x') || | |
651 | (cfile->tokbuf[1] == 'X'))) { | |
652 | token = NUMBER_OR_NAME; | |
653 | break; | |
654 | } else if(((c == '-') || (c == '_') || isalnum(c))) { | |
655 | token = NAME; | |
656 | break; | |
657 | } | |
658 | /* FALLTHROUGH */ | |
659 | case BREAK: | |
660 | /* At this point c is either EOF or part of the next | |
661 | * token. If not EOF, rewind the file one byte so | |
662 | * the next token is read from there. | |
663 | */ | |
d19e816e | 664 | unget_char(cfile, c); |
98311e4b DH |
665 | goto end_read; |
666 | ||
667 | default: | |
668 | log_fatal("read_number():%s:%d: impossible case", MDL); | |
669 | } | |
98311e4b | 670 | |
6f4b5b31 | 671 | cfile -> tokbuf [i] = c; |
d7837182 | 672 | } |
98311e4b | 673 | |
6f4b5b31 TL |
674 | if (i == sizeof cfile -> tokbuf) { |
675 | parse_warn (cfile, | |
676 | "numeric token larger than internal buffer"); | |
d7837182 TL |
677 | --i; |
678 | } | |
98311e4b DH |
679 | |
680 | end_read: | |
6f4b5b31 | 681 | cfile -> tokbuf [i] = 0; |
b3519f23 | 682 | cfile -> tlen = i; |
6f4b5b31 | 683 | cfile -> tval = cfile -> tokbuf; |
98311e4b | 684 | |
7dc9b5fb DH |
685 | /* |
686 | * If this entire token from start to finish was "-", such as | |
687 | * the middle parameter in "42 - 7", return just the MINUS token. | |
688 | */ | |
689 | if ((i == 1) && (cfile->tokbuf[i] == '-')) | |
690 | return MINUS; | |
691 | else | |
692 | return token; | |
d7837182 TL |
693 | } |
694 | ||
104c88cd | 695 | static enum dhcp_token read_num_or_name (c, cfile) |
d7837182 | 696 | int c; |
6f4b5b31 | 697 | struct parse *cfile; |
d7837182 TL |
698 | { |
699 | int i = 0; | |
104c88cd | 700 | enum dhcp_token rv = NUMBER_OR_NAME; |
6f4b5b31 TL |
701 | cfile -> tokbuf [i++] = c; |
702 | for (; i < sizeof cfile -> tokbuf; i++) { | |
d7837182 TL |
703 | c = get_char (cfile); |
704 | if (!isascii (c) || | |
705 | (c != '-' && c != '_' && !isalnum (c))) { | |
d19e816e | 706 | unget_char(cfile, c); |
d7837182 TL |
707 | break; |
708 | } | |
709 | if (!isxdigit (c)) | |
50b025a3 | 710 | rv = NAME; |
6f4b5b31 | 711 | cfile -> tokbuf [i] = c; |
d7837182 | 712 | } |
6f4b5b31 TL |
713 | if (i == sizeof cfile -> tokbuf) { |
714 | parse_warn (cfile, "token larger than internal buffer"); | |
d7837182 TL |
715 | --i; |
716 | } | |
6f4b5b31 | 717 | cfile -> tokbuf [i] = 0; |
b3519f23 | 718 | cfile -> tlen = i; |
6f4b5b31 | 719 | cfile -> tval = cfile -> tokbuf; |
28868515 | 720 | return intern(cfile->tval, rv); |
d7837182 TL |
721 | } |
722 | ||
28868515 SK |
723 | static enum dhcp_token |
724 | intern(char *atom, enum dhcp_token dfv) { | |
725 | if (!isascii(atom[0])) | |
54d9cf28 TL |
726 | return dfv; |
727 | ||
28868515 | 728 | switch (tolower((unsigned char)atom[0])) { |
33d7b01a TL |
729 | case '-': |
730 | if (atom [1] == 0) | |
731 | return MINUS; | |
732 | break; | |
733 | ||
4660b519 | 734 | case 'a': |
9e3eb22a DH |
735 | if (!strcasecmp(atom + 1, "bandoned")) |
736 | return TOKEN_ABANDONED; | |
737 | if (!strcasecmp(atom + 1, "ctive")) | |
738 | return TOKEN_ACTIVE; | |
739 | if (!strncasecmp(atom + 1, "dd", 2)) { | |
740 | if (atom[3] == '\0') | |
741 | return TOKEN_ADD; | |
742 | else if (!strcasecmp(atom + 3, "ress")) | |
743 | return ADDRESS; | |
744 | break; | |
745 | } | |
746 | if (!strcasecmp(atom + 1, "fter")) | |
747 | return AFTER; | |
5484ac9e MA |
748 | if (isascii(atom[1]) && |
749 | (tolower((unsigned char)atom[1]) == 'l')) { | |
9e3eb22a DH |
750 | if (!strcasecmp(atom + 2, "gorithm")) |
751 | return ALGORITHM; | |
752 | if (!strcasecmp(atom + 2, "ias")) | |
753 | return ALIAS; | |
5484ac9e MA |
754 | if (isascii(atom[2]) && |
755 | (tolower((unsigned char)atom[2]) == 'l')) { | |
9e3eb22a DH |
756 | if (atom[3] == '\0') |
757 | return ALL; | |
758 | else if (!strcasecmp(atom + 3, "ow")) | |
759 | return ALLOW; | |
551d1bc4 TL |
760 | break; |
761 | } | |
9e3eb22a DH |
762 | if (!strcasecmp(atom + 2, "so")) |
763 | return TOKEN_ALSO; | |
551d1bc4 TL |
764 | break; |
765 | } | |
5484ac9e MA |
766 | if (isascii(atom[1]) && |
767 | (tolower((unsigned char)atom[1]) == 'n')) { | |
9e3eb22a DH |
768 | if (!strcasecmp(atom + 2, "d")) |
769 | return AND; | |
770 | if (!strcasecmp(atom + 2, "ycast-mac")) | |
771 | return ANYCAST_MAC; | |
772 | break; | |
773 | } | |
774 | if (!strcasecmp(atom + 1, "ppend")) | |
89500b31 | 775 | return APPEND; |
9e3eb22a | 776 | if (!strcasecmp(atom + 1, "rray")) |
f8b21a3d | 777 | return ARRAY; |
5484ac9e MA |
778 | if (isascii(atom[1]) && |
779 | (tolower((unsigned char)atom[1]) == 't')) { | |
9e3eb22a DH |
780 | if (atom[2] == '\0') |
781 | return AT; | |
782 | if (!strcasecmp(atom + 2, "sfp")) | |
783 | return ATSFP; | |
784 | break; | |
785 | } | |
347d4962 TM |
786 | if (!strcasecmp(atom + 1, "uthoring-byte-order")) |
787 | return AUTHORING_BYTE_ORDER; | |
9e3eb22a | 788 | if (!strncasecmp(atom + 1, "ut", 2)) { |
23d39ae2 SR |
789 | if (isascii(atom[3]) && |
790 | (tolower((unsigned char)atom[3]) == 'h')) { | |
9e3eb22a DH |
791 | if (!strncasecmp(atom + 4, "enticat", 7)) { |
792 | if (!strcasecmp(atom + 11, "ed")) | |
793 | return AUTHENTICATED; | |
794 | if (!strcasecmp(atom + 11, "ion")) | |
795 | return AUTHENTICATION; | |
796 | break; | |
797 | } | |
798 | if (!strcasecmp(atom + 4, "oritative")) | |
799 | return AUTHORITATIVE; | |
800 | break; | |
801 | } | |
802 | if (!strcasecmp(atom + 3, "o-partner-down")) | |
803 | return AUTO_PARTNER_DOWN; | |
804 | break; | |
805 | } | |
4660b519 | 806 | break; |
58304e8e | 807 | case 'b': |
007e3ee4 TL |
808 | if (!strcasecmp (atom + 1, "ackup")) |
809 | return TOKEN_BACKUP; | |
810 | if (!strcasecmp (atom + 1, "ootp")) | |
811 | return TOKEN_BOOTP; | |
812 | if (!strcasecmp (atom + 1, "inding")) | |
813 | return BINDING; | |
6df38ab2 TL |
814 | if (!strcasecmp (atom + 1, "inary-to-ascii")) |
815 | return BINARY_TO_ASCII; | |
3951e13c TL |
816 | if (!strcasecmp (atom + 1, "ackoff-cutoff")) |
817 | return BACKOFF_CUTOFF; | |
4660b519 TL |
818 | if (!strcasecmp (atom + 1, "ooting")) |
819 | return BOOTING; | |
58304e8e TL |
820 | if (!strcasecmp (atom + 1, "oot-unknown-clients")) |
821 | return BOOT_UNKNOWN_CLIENTS; | |
52cdb300 TL |
822 | if (!strcasecmp (atom + 1, "reak")) |
823 | return BREAK; | |
bcc73737 TL |
824 | if (!strcasecmp (atom + 1, "illing")) |
825 | return BILLING; | |
f8b21a3d TL |
826 | if (!strcasecmp (atom + 1, "oolean")) |
827 | return BOOLEAN; | |
ff56f1d9 TL |
828 | if (!strcasecmp (atom + 1, "alance")) |
829 | return BALANCE; | |
cf199463 TL |
830 | if (!strcasecmp (atom + 1, "ound")) |
831 | return BOUND; | |
347d4962 TM |
832 | if (!strcasecmp(atom+1, "ig-endian")) { |
833 | return TOKEN_BIG_ENDIAN; | |
834 | } | |
52cdb300 | 835 | break; |
089fb364 | 836 | case 'c': |
792156a9 | 837 | if (!strcasecmp(atom + 1, "ase")) |
14a2c383 | 838 | return CASE; |
792156a9 | 839 | if (!strcasecmp(atom + 1, "heck")) |
80fcef91 | 840 | return CHECK; |
792156a9 | 841 | if (!strcasecmp(atom + 1, "iaddr")) |
97ca1699 | 842 | return CIADDR; |
792156a9 DH |
843 | if (isascii(atom[1]) && |
844 | tolower((unsigned char)atom[1]) == 'l') { | |
845 | if (!strcasecmp(atom + 2, "ass")) | |
846 | return CLASS; | |
847 | if (!strncasecmp(atom + 2, "ient", 4)) { | |
848 | if (!strcasecmp(atom + 6, "s")) | |
849 | return CLIENTS; | |
8ef5db71 | 850 | if (atom[6] == '-') { |
792156a9 DH |
851 | if (!strcasecmp(atom + 7, "hostname")) |
852 | return CLIENT_HOSTNAME; | |
853 | if (!strcasecmp(atom + 7, "identifier")) | |
854 | return CLIENT_IDENTIFIER; | |
855 | if (!strcasecmp(atom + 7, "state")) | |
856 | return CLIENT_STATE; | |
857 | if (!strcasecmp(atom + 7, "updates")) | |
858 | return CLIENT_UPDATES; | |
859 | break; | |
860 | } | |
861 | break; | |
862 | } | |
863 | if (!strcasecmp(atom + 2, "ose")) | |
864 | return TOKEN_CLOSE; | |
865 | if (!strcasecmp(atom + 2, "tt")) | |
866 | return CLTT; | |
867 | break; | |
868 | } | |
869 | if (isascii(atom[1]) && | |
870 | tolower((unsigned char)atom[1]) == 'o') { | |
871 | if (!strcasecmp(atom + 2, "de")) | |
872 | return CODE; | |
873 | if (isascii(atom[2]) && | |
874 | tolower((unsigned char)atom[2]) == 'm') { | |
875 | if (!strcasecmp(atom + 3, "mit")) | |
876 | return COMMIT; | |
877 | if (!strcasecmp(atom + 3, | |
878 | "munications-interrupted")) | |
879 | return COMMUNICATIONS_INTERRUPTED; | |
880 | if (!strcasecmp(atom + 3, "pressed")) | |
881 | return COMPRESSED; | |
882 | break; | |
883 | } | |
884 | if (isascii(atom[2]) && | |
885 | tolower((unsigned char)atom[2]) == 'n') { | |
886 | if (!strcasecmp(atom + 3, "cat")) | |
887 | return CONCAT; | |
888 | if (!strcasecmp(atom + 3, "fig-option")) | |
889 | return CONFIG_OPTION; | |
890 | if (!strcasecmp(atom + 3, "flict-done")) | |
891 | return CONFLICT_DONE; | |
892 | if (!strcasecmp(atom + 3, "nect")) | |
893 | return CONNECT; | |
894 | break; | |
895 | } | |
896 | break; | |
74f45f96 | 897 | } |
792156a9 DH |
898 | if (!strcasecmp(atom + 1, "reate")) |
899 | return TOKEN_CREATE; | |
089fb364 | 900 | break; |
685963dc | 901 | case 'd': |
5e864416 DH |
902 | if (!strcasecmp(atom + 1, "b-time-format")) |
903 | return DB_TIME_FORMAT; | |
89500b31 TL |
904 | if (!strcasecmp (atom + 1, "omain")) |
905 | return DOMAIN; | |
dba5803b DH |
906 | if (!strncasecmp (atom + 1, "omain-", 6)) { |
907 | if (!strcasecmp(atom + 7, "name")) | |
908 | return DOMAIN_NAME; | |
909 | if (!strcasecmp(atom + 7, "list")) | |
910 | return DOMAIN_LIST; | |
911 | } | |
38c4774a SR |
912 | if (!strcasecmp (atom + 1, "o-forward-updates")) |
913 | return DO_FORWARD_UPDATE; | |
914 | /* do-forward-update is included for historical reasons */ | |
98311e4b DH |
915 | if (!strcasecmp (atom + 1, "o-forward-update")) |
916 | return DO_FORWARD_UPDATE; | |
e7a9c293 DN |
917 | if (!strcasecmp (atom + 1, "ebug")) |
918 | return TOKEN_DEBUG; | |
4660b519 TL |
919 | if (!strcasecmp (atom + 1, "eny")) |
920 | return DENY; | |
07dc11f8 | 921 | if (!strcasecmp (atom + 1, "eleted")) |
007e3ee4 | 922 | return TOKEN_DELETED; |
2b6e0559 TL |
923 | if (!strcasecmp (atom + 1, "elete")) |
924 | return TOKEN_DELETE; | |
4660b519 TL |
925 | if (!strncasecmp (atom + 1, "efault", 6)) { |
926 | if (!atom [7]) | |
927 | return DEFAULT; | |
98bd7ca0 DH |
928 | if (!strcasecmp(atom + 7, "-duid")) |
929 | return DEFAULT_DUID; | |
4660b519 TL |
930 | if (!strcasecmp (atom + 7, "-lease-time")) |
931 | return DEFAULT_LEASE_TIME; | |
932 | break; | |
933 | } | |
f197003d TL |
934 | if (!strncasecmp (atom + 1, "ynamic", 6)) { |
935 | if (!atom [7]) | |
936 | return DYNAMIC; | |
937 | if (!strncasecmp (atom + 7, "-bootp", 6)) { | |
938 | if (!atom [13]) | |
939 | return DYNAMIC_BOOTP; | |
940 | if (!strcasecmp (atom + 13, "-lease-cutoff")) | |
941 | return DYNAMIC_BOOTP_LEASE_CUTOFF; | |
942 | if (!strcasecmp (atom + 13, "-lease-length")) | |
943 | return DYNAMIC_BOOTP_LEASE_LENGTH; | |
944 | break; | |
945 | } | |
58304e8e | 946 | } |
337b3e52 TL |
947 | if (!strcasecmp (atom + 1, "uplicates")) |
948 | return DUPLICATES; | |
1038f739 TL |
949 | if (!strcasecmp (atom + 1, "eclines")) |
950 | return DECLINES; | |
33d7b01a TL |
951 | if (!strncasecmp (atom + 1, "efine", 5)) { |
952 | if (!strcasecmp (atom + 6, "d")) | |
953 | return DEFINED; | |
954 | if (!atom [6]) | |
955 | return DEFINE; | |
956 | } | |
7f152466 TM |
957 | if (!strcasecmp (atom + 1, "isconnect")) |
958 | return DISCONNECT; | |
685963dc | 959 | break; |
089fb364 | 960 | case 'e': |
f6b8f48d | 961 | if (isascii (atom [1]) && |
28868515 | 962 | tolower((unsigned char)atom[1]) == 'x') { |
0c6a64b2 TL |
963 | if (!strcasecmp (atom + 2, "tract-int")) |
964 | return EXTRACT_INT; | |
965 | if (!strcasecmp (atom + 2, "ists")) | |
966 | return EXISTS; | |
a6d79ad7 TL |
967 | if (!strcasecmp (atom + 2, "piry")) |
968 | return EXPIRY; | |
969 | if (!strcasecmp (atom + 2, "pire")) | |
970 | return EXPIRE; | |
007e3ee4 TL |
971 | if (!strcasecmp (atom + 2, "pired")) |
972 | return TOKEN_EXPIRED; | |
0c6a64b2 | 973 | } |
337b3e52 | 974 | if (!strcasecmp (atom + 1, "ncode-int")) |
a6d79ad7 | 975 | return ENCODE_INT; |
5e864416 DH |
976 | if (!strcasecmp(atom + 1, "poch")) |
977 | return EPOCH; | |
089fb364 TL |
978 | if (!strcasecmp (atom + 1, "thernet")) |
979 | return ETHERNET; | |
980 | if (!strcasecmp (atom + 1, "nds")) | |
981 | return ENDS; | |
52cdb300 TL |
982 | if (!strncasecmp (atom + 1, "ls", 2)) { |
983 | if (!strcasecmp (atom + 3, "e")) | |
984 | return ELSE; | |
985 | if (!strcasecmp (atom + 3, "if")) | |
986 | return ELSIF; | |
987 | break; | |
988 | } | |
e7a9c293 DN |
989 | if (!strcasecmp (atom + 1, "rror")) |
990 | return ERROR; | |
34731eed TL |
991 | if (!strcasecmp (atom + 1, "val")) |
992 | return EVAL; | |
eebf58bc TL |
993 | if (!strcasecmp (atom + 1, "ncapsulate")) |
994 | return ENCAPSULATE; | |
b543fea9 DH |
995 | if (!strcasecmp(atom + 1, "xecute")) |
996 | return EXECUTE; | |
98bd7ca0 DH |
997 | if (!strcasecmp(atom+1, "n")) { |
998 | return EN; | |
999 | } | |
d7837182 TL |
1000 | break; |
1001 | case 'f': | |
e7a9c293 DN |
1002 | if (!strcasecmp (atom + 1, "atal")) |
1003 | return FATAL; | |
d7837182 TL |
1004 | if (!strcasecmp (atom + 1, "ilename")) |
1005 | return FILENAME; | |
1006 | if (!strcasecmp (atom + 1, "ixed-address")) | |
1007 | return FIXED_ADDR; | |
98bd7ca0 DH |
1008 | if (!strcasecmp (atom + 1, "ixed-address6")) |
1009 | return FIXED_ADDR6; | |
80c9fdb0 FD |
1010 | if (!strcasecmp (atom + 1, "ixed-prefix6")) |
1011 | return FIXED_PREFIX6; | |
a167f312 | 1012 | if (!strcasecmp (atom + 1, "ddi")) |
219a65eb | 1013 | return TOKEN_FDDI; |
14a2c383 TL |
1014 | if (!strcasecmp (atom + 1, "ormerr")) |
1015 | return NS_FORMERR; | |
33d7b01a TL |
1016 | if (!strcasecmp (atom + 1, "unction")) |
1017 | return FUNCTION; | |
ff56f1d9 TL |
1018 | if (!strcasecmp (atom + 1, "ailover")) |
1019 | return FAILOVER; | |
007e3ee4 TL |
1020 | if (!strcasecmp (atom + 1, "ree")) |
1021 | return TOKEN_FREE; | |
d7837182 | 1022 | break; |
97ca1699 | 1023 | case 'g': |
33ea4622 DH |
1024 | if (!strncasecmp(atom + 1, "et", 2)) { |
1025 | if (!strcasecmp(atom + 3, "-lease-hostnames")) | |
1026 | return GET_LEASE_HOSTNAMES; | |
023fbaa0 TM |
1027 | if (!strcasecmp(atom + 3, "hostbyname")) |
1028 | return GETHOSTBYNAME; | |
33ea4622 DH |
1029 | if (!strcasecmp(atom + 3, "hostname")) |
1030 | return GETHOSTNAME; | |
1031 | break; | |
1032 | } | |
97ca1699 TL |
1033 | if (!strcasecmp (atom + 1, "iaddr")) |
1034 | return GIADDR; | |
58304e8e TL |
1035 | if (!strcasecmp (atom + 1, "roup")) |
1036 | return GROUP; | |
97ca1699 | 1037 | break; |
089fb364 | 1038 | case 'h': |
f7fdb216 DH |
1039 | if (!strcasecmp(atom + 1, "ash")) |
1040 | return HASH; | |
2b6e0559 TL |
1041 | if (!strcasecmp (atom + 1, "ba")) |
1042 | return HBA; | |
089fb364 TL |
1043 | if (!strcasecmp (atom + 1, "ost")) |
1044 | return HOST; | |
79a65726 TL |
1045 | if (!strcasecmp (atom + 1, "ost-decl-name")) |
1046 | return HOST_DECL_NAME; | |
98bd7ca0 DH |
1047 | if (!strcasecmp(atom + 1, "ost-identifier")) |
1048 | return HOST_IDENTIFIER; | |
089fb364 TL |
1049 | if (!strcasecmp (atom + 1, "ardware")) |
1050 | return HARDWARE; | |
7e0f16d0 TL |
1051 | if (!strcasecmp (atom + 1, "ostname")) |
1052 | return HOSTNAME; | |
9345f3cc DN |
1053 | if (!strcasecmp (atom + 1, "elp")) |
1054 | return TOKEN_HELP; | |
cc1bd34e TM |
1055 | if (!strcasecmp (atom + 1, "ex")) { |
1056 | return TOKEN_HEX; | |
1057 | } | |
089fb364 | 1058 | break; |
f71f026a | 1059 | case 'i': |
f6b8f48d | 1060 | if (!strcasecmp(atom+1, "a-na")) |
98bd7ca0 | 1061 | return IA_NA; |
f6b8f48d | 1062 | if (!strcasecmp(atom+1, "a-ta")) |
1d9774ab | 1063 | return IA_TA; |
f6b8f48d | 1064 | if (!strcasecmp(atom+1, "a-pd")) |
1d9774ab | 1065 | return IA_PD; |
f6b8f48d | 1066 | if (!strcasecmp(atom+1, "aaddr")) |
98bd7ca0 | 1067 | return IAADDR; |
f6b8f48d | 1068 | if (!strcasecmp(atom+1, "aprefix")) |
1d9774ab | 1069 | return IAPREFIX; |
20916cae TL |
1070 | if (!strcasecmp (atom + 1, "nclude")) |
1071 | return INCLUDE; | |
f8b21a3d TL |
1072 | if (!strcasecmp (atom + 1, "nteger")) |
1073 | return INTEGER; | |
b047bd38 SR |
1074 | if (!strcasecmp (atom + 1, "nfiniband")) |
1075 | return TOKEN_INFINIBAND; | |
be1ee858 TL |
1076 | if (!strcasecmp (atom + 1, "nfinite")) |
1077 | return INFINITE; | |
e7a9c293 DN |
1078 | if (!strcasecmp (atom + 1, "nfo")) |
1079 | return INFO; | |
f8b21a3d TL |
1080 | if (!strcasecmp (atom + 1, "p-address")) |
1081 | return IP_ADDRESS; | |
98bd7ca0 DH |
1082 | if (!strcasecmp (atom + 1, "p6-address")) |
1083 | return IP6_ADDRESS; | |
3951e13c TL |
1084 | if (!strcasecmp (atom + 1, "nitial-interval")) |
1085 | return INITIAL_INTERVAL; | |
5d082abd TM |
1086 | if (!strcasecmp (atom + 1, "nitial-delay")) |
1087 | return INITIAL_DELAY; | |
f71f026a TL |
1088 | if (!strcasecmp (atom + 1, "nterface")) |
1089 | return INTERFACE; | |
a167f312 TL |
1090 | if (!strcasecmp (atom + 1, "dentifier")) |
1091 | return IDENTIFIER; | |
52cdb300 TL |
1092 | if (!strcasecmp (atom + 1, "f")) |
1093 | return IF; | |
2b6e0559 TL |
1094 | if (!strcasecmp (atom + 1, "s")) |
1095 | return IS; | |
bd8734b5 TL |
1096 | if (!strcasecmp (atom + 1, "gnore")) |
1097 | return IGNORE; | |
f71f026a | 1098 | break; |
f197003d | 1099 | case 'k': |
98311e4b DH |
1100 | if (!strncasecmp (atom + 1, "nown", 4)) { |
1101 | if (!strcasecmp (atom + 5, "-clients")) | |
1102 | return KNOWN_CLIENTS; | |
1103 | if (!atom[5]) | |
1104 | return KNOWN; | |
1105 | break; | |
1106 | } | |
e6a480f0 TL |
1107 | if (!strcasecmp (atom + 1, "ey")) |
1108 | return KEY; | |
e6ffc27f TM |
1109 | if (!strcasecmp (atom + 1, "ey-algorithm")) |
1110 | return KEY_ALGORITHM; | |
f197003d | 1111 | break; |
089fb364 | 1112 | case 'l': |
2727c1cf DH |
1113 | if (!strcasecmp (atom + 1, "case")) |
1114 | return LCASE; | |
089fb364 TL |
1115 | if (!strcasecmp (atom + 1, "ease")) |
1116 | return LEASE; | |
98bd7ca0 DH |
1117 | if (!strcasecmp(atom + 1, "ease6")) |
1118 | return LEASE6; | |
6df38ab2 TL |
1119 | if (!strcasecmp (atom + 1, "eased-address")) |
1120 | return LEASED_ADDRESS; | |
71a34477 | 1121 | if (!strcasecmp (atom + 1, "ease-time")) |
069e9f4c | 1122 | return LEASE_TIME; |
6d103865 SK |
1123 | if (!strcasecmp(atom + 1, "easequery")) |
1124 | return LEASEQUERY; | |
f7fdb216 DH |
1125 | if (!strcasecmp(atom + 1, "ength")) |
1126 | return LENGTH; | |
bcc73737 TL |
1127 | if (!strcasecmp (atom + 1, "imit")) |
1128 | return LIMIT; | |
34731eed TL |
1129 | if (!strcasecmp (atom + 1, "et")) |
1130 | return LET; | |
ff56f1d9 TL |
1131 | if (!strcasecmp (atom + 1, "oad")) |
1132 | return LOAD; | |
5e864416 DH |
1133 | if (!strcasecmp(atom + 1, "ocal")) |
1134 | return LOCAL; | |
e7a9c293 DN |
1135 | if (!strcasecmp (atom + 1, "og")) |
1136 | return LOG; | |
98bd7ca0 DH |
1137 | if (!strcasecmp(atom+1, "lt")) { |
1138 | return LLT; | |
1139 | } | |
1140 | if (!strcasecmp(atom+1, "l")) { | |
1141 | return LL; | |
1142 | } | |
347d4962 TM |
1143 | if (!strcasecmp(atom+1, "ittle-endian")) { |
1144 | return TOKEN_LITTLE_ENDIAN; | |
1145 | } | |
cc1bd34e TM |
1146 | if (!strcasecmp (atom + 1, "ease-id-format")) { |
1147 | return LEASE_ID_FORMAT; | |
1148 | } | |
d7837182 | 1149 | break; |
685963dc | 1150 | case 'm': |
ff56f1d9 TL |
1151 | if (!strncasecmp (atom + 1, "ax", 2)) { |
1152 | if (!atom [3]) | |
1153 | return TOKEN_MAX; | |
2426234f DH |
1154 | if (!strcasecmp (atom + 3, "-balance")) |
1155 | return MAX_BALANCE; | |
4cba29f0 | 1156 | if (!strncasecmp (atom + 3, "-lease-", 7)) { |
2426234f DH |
1157 | if (!strcasecmp(atom + 10, "misbalance")) |
1158 | return MAX_LEASE_MISBALANCE; | |
1159 | if (!strcasecmp(atom + 10, "ownership")) | |
1160 | return MAX_LEASE_OWNERSHIP; | |
1161 | if (!strcasecmp(atom + 10, "time")) | |
1162 | return MAX_LEASE_TIME; | |
1163 | } | |
98bd7ca0 DH |
1164 | if (!strcasecmp(atom + 3, "-life")) |
1165 | return MAX_LIFE; | |
ff56f1d9 | 1166 | if (!strcasecmp (atom + 3, "-transmit-idle")) |
a167f312 | 1167 | return MAX_TRANSMIT_IDLE; |
ff56f1d9 | 1168 | if (!strcasecmp (atom + 3, "-response-delay")) |
a167f312 | 1169 | return MAX_RESPONSE_DELAY; |
ff56f1d9 | 1170 | if (!strcasecmp (atom + 3, "-unacked-updates")) |
2b6e0559 | 1171 | return MAX_UNACKED_UPDATES; |
a167f312 | 1172 | } |
8028ab1d | 1173 | if (!strncasecmp (atom + 1, "in-", 3)) { |
2426234f DH |
1174 | if (!strcasecmp (atom + 4, "balance")) |
1175 | return MIN_BALANCE; | |
8028ab1d TL |
1176 | if (!strcasecmp (atom + 4, "lease-time")) |
1177 | return MIN_LEASE_TIME; | |
1178 | if (!strcasecmp (atom + 4, "secs")) | |
1179 | return MIN_SECS; | |
1180 | break; | |
1181 | } | |
4660b519 TL |
1182 | if (!strncasecmp (atom + 1, "edi", 3)) { |
1183 | if (!strcasecmp (atom + 4, "a")) | |
1184 | return MEDIA; | |
1185 | if (!strcasecmp (atom + 4, "um")) | |
1186 | return MEDIUM; | |
1187 | break; | |
1188 | } | |
52cdb300 TL |
1189 | if (!strcasecmp (atom + 1, "atch")) |
1190 | return MATCH; | |
f197003d TL |
1191 | if (!strcasecmp (atom + 1, "embers")) |
1192 | return MEMBERS; | |
a167f312 TL |
1193 | if (!strcasecmp (atom + 1, "y")) |
1194 | return MY; | |
2b6e0559 TL |
1195 | if (!strcasecmp (atom + 1, "clt")) |
1196 | return MCLT; | |
685963dc TL |
1197 | break; |
1198 | case 'n': | |
a167f312 TL |
1199 | if (!strcasecmp (atom + 1, "ormal")) |
1200 | return NORMAL; | |
89500b31 TL |
1201 | if (!strcasecmp (atom + 1, "ameserver")) |
1202 | return NAMESERVER; | |
685963dc TL |
1203 | if (!strcasecmp (atom + 1, "etmask")) |
1204 | return NETMASK; | |
be1ee858 TL |
1205 | if (!strcasecmp (atom + 1, "ever")) |
1206 | return NEVER; | |
58304e8e TL |
1207 | if (!strcasecmp (atom + 1, "ext-server")) |
1208 | return NEXT_SERVER; | |
a167f312 TL |
1209 | if (!strcasecmp (atom + 1, "ot")) |
1210 | return TOKEN_NOT; | |
2b6e0559 | 1211 | if (!strcasecmp (atom + 1, "o")) |
8da06bb1 | 1212 | return TOKEN_NO; |
14a2c383 TL |
1213 | if (!strcasecmp (atom + 1, "oerror")) |
1214 | return NS_NOERROR; | |
1215 | if (!strcasecmp (atom + 1, "otauth")) | |
1216 | return NS_NOTAUTH; | |
1217 | if (!strcasecmp (atom + 1, "otimp")) | |
1218 | return NS_NOTIMP; | |
1219 | if (!strcasecmp (atom + 1, "otzone")) | |
1220 | return NS_NOTZONE; | |
1221 | if (!strcasecmp (atom + 1, "xdomain")) | |
1222 | return NS_NXDOMAIN; | |
1223 | if (!strcasecmp (atom + 1, "xrrset")) | |
1224 | return NS_NXRRSET; | |
1225 | if (!strcasecmp (atom + 1, "ull")) | |
1226 | return TOKEN_NULL; | |
007e3ee4 TL |
1227 | if (!strcasecmp (atom + 1, "ext")) |
1228 | return TOKEN_NEXT; | |
5ec697e6 TL |
1229 | if (!strcasecmp (atom + 1, "ew")) |
1230 | return TOKEN_NEW; | |
685963dc | 1231 | break; |
d7837182 | 1232 | case 'o': |
9ea249af TL |
1233 | if (!strcasecmp (atom + 1, "mapi")) |
1234 | return OMAPI; | |
80fcef91 TL |
1235 | if (!strcasecmp (atom + 1, "r")) |
1236 | return OR; | |
79a65726 TL |
1237 | if (!strcasecmp (atom + 1, "n")) |
1238 | return ON; | |
9345f3cc DN |
1239 | if (!strcasecmp (atom + 1, "pen")) |
1240 | return TOKEN_OPEN; | |
d7837182 TL |
1241 | if (!strcasecmp (atom + 1, "ption")) |
1242 | return OPTION; | |
512994ed TL |
1243 | if (!strcasecmp (atom + 1, "ne-lease-per-client")) |
1244 | return ONE_LEASE_PER_CLIENT; | |
f197003d TL |
1245 | if (!strcasecmp (atom + 1, "f")) |
1246 | return OF; | |
2b6e0559 TL |
1247 | if (!strcasecmp (atom + 1, "wner")) |
1248 | return OWNER; | |
cc1bd34e TM |
1249 | if (!strcasecmp (atom + 1, "ctal")) { |
1250 | return TOKEN_OCTAL; | |
1251 | } | |
512994ed TL |
1252 | break; |
1253 | case 'p': | |
45c332f0 SR |
1254 | if (!strcasecmp (atom + 1, "arse-vendor-option")) |
1255 | return PARSE_VENDOR_OPT; | |
89500b31 TL |
1256 | if (!strcasecmp (atom + 1, "repend")) |
1257 | return PREPEND; | |
98bd7ca0 DH |
1258 | if (!strcasecmp(atom + 1, "referred-life")) |
1259 | return PREFERRED_LIFE; | |
512994ed TL |
1260 | if (!strcasecmp (atom + 1, "acket")) |
1261 | return PACKET; | |
f197003d TL |
1262 | if (!strcasecmp (atom + 1, "ool")) |
1263 | return POOL; | |
01fa619f SR |
1264 | if (!strcasecmp (atom + 1, "ool6")) |
1265 | return POOL6; | |
80c9fdb0 FD |
1266 | if (!strcasecmp (atom + 1, "refix6")) |
1267 | return PREFIX6; | |
f197003d TL |
1268 | if (!strcasecmp (atom + 1, "seudo")) |
1269 | return PSEUDO; | |
a167f312 TL |
1270 | if (!strcasecmp (atom + 1, "eer")) |
1271 | return PEER; | |
1272 | if (!strcasecmp (atom + 1, "rimary")) | |
1273 | return PRIMARY; | |
d424157d SR |
1274 | if (!strcasecmp (atom + 1, "rimary6")) |
1275 | return PRIMARY6; | |
a167f312 TL |
1276 | if (!strncasecmp (atom + 1, "artner", 6)) { |
1277 | if (!atom [7]) | |
1278 | return PARTNER; | |
1279 | if (!strcasecmp (atom + 7, "-down")) | |
1280 | return PARTNER_DOWN; | |
1281 | } | |
1282 | if (!strcasecmp (atom + 1, "ort")) | |
1283 | return PORT; | |
1284 | if (!strcasecmp (atom + 1, "otential-conflict")) | |
1285 | return POTENTIAL_CONFLICT; | |
34731eed TL |
1286 | if (!strcasecmp (atom + 1, "ick-first-value") || |
1287 | !strcasecmp (atom + 1, "ick")) | |
1288 | return PICK; | |
05815916 TL |
1289 | if (!strcasecmp (atom + 1, "aused")) |
1290 | return PAUSED; | |
d7837182 | 1291 | break; |
089fb364 | 1292 | case 'r': |
fdfebedf | 1293 | if (!strcasecmp(atom + 1, "ange")) |
089fb364 | 1294 | return RANGE; |
fdfebedf | 1295 | if (!strcasecmp(atom + 1, "ange6")) |
98bd7ca0 | 1296 | return RANGE6; |
5484ac9e MA |
1297 | if (isascii(atom[1]) && |
1298 | (tolower((unsigned char)atom[1]) == 'e')) { | |
fdfebedf DH |
1299 | if (!strcasecmp(atom + 2, "bind")) |
1300 | return REBIND; | |
1301 | if (!strcasecmp(atom + 2, "boot")) | |
1302 | return REBOOT; | |
1303 | if (!strcasecmp(atom + 2, "contact-interval")) | |
1304 | return RECONTACT_INTERVAL; | |
1305 | if (!strncasecmp(atom + 2, "cover", 5)) { | |
1306 | if (atom[7] == '\0') | |
1307 | return RECOVER; | |
1308 | if (!strcasecmp(atom + 7, "-done")) | |
1309 | return RECOVER_DONE; | |
1310 | if (!strcasecmp(atom + 7, "-wait")) | |
1311 | return RECOVER_WAIT; | |
1312 | break; | |
1313 | } | |
1314 | if (!strcasecmp(atom + 2, "fresh")) | |
1315 | return REFRESH; | |
1316 | if (!strcasecmp(atom + 2, "fused")) | |
1317 | return NS_REFUSED; | |
1318 | if (!strcasecmp(atom + 2, "ject")) | |
1319 | return REJECT; | |
1320 | if (!strcasecmp(atom + 2, "lease")) | |
1321 | return RELEASE; | |
1322 | if (!strcasecmp(atom + 2, "leased")) | |
1323 | return TOKEN_RELEASED; | |
1324 | if (!strcasecmp(atom + 2, "move")) | |
1325 | return REMOVE; | |
1326 | if (!strcasecmp(atom + 2, "new")) | |
1327 | return RENEW; | |
1328 | if (!strcasecmp(atom + 2, "quest")) | |
1329 | return REQUEST; | |
1330 | if (!strcasecmp(atom + 2, "quire")) | |
1331 | return REQUIRE; | |
5484ac9e MA |
1332 | if (isascii(atom[2]) && |
1333 | (tolower((unsigned char)atom[2]) == 's')) { | |
fdfebedf DH |
1334 | if (!strcasecmp(atom + 3, "erved")) |
1335 | return TOKEN_RESERVED; | |
1336 | if (!strcasecmp(atom + 3, "et")) | |
1337 | return TOKEN_RESET; | |
1338 | if (!strcasecmp(atom + 3, | |
1339 | "olution-interrupted")) | |
1340 | return RESOLUTION_INTERRUPTED; | |
1341 | break; | |
1342 | } | |
1343 | if (!strcasecmp(atom + 2, "try")) | |
1344 | return RETRY; | |
1345 | if (!strcasecmp(atom + 2, "turn")) | |
1346 | return RETURN; | |
1347 | if (!strcasecmp(atom + 2, "verse")) | |
1348 | return REVERSE; | |
1349 | if (!strcasecmp(atom + 2, "wind")) | |
1350 | return REWIND; | |
1351 | break; | |
98bd7ca0 | 1352 | } |
089fb364 TL |
1353 | break; |
1354 | case 's': | |
fdfebedf DH |
1355 | if (!strcasecmp(atom + 1, "cript")) |
1356 | return SCRIPT; | |
f6b8f48d | 1357 | if (isascii(atom[1]) && |
28868515 | 1358 | tolower((unsigned char)atom[1]) == 'e') { |
fdfebedf DH |
1359 | if (!strcasecmp(atom + 2, "arch")) |
1360 | return SEARCH; | |
f6b8f48d | 1361 | if (isascii(atom[2]) && |
28868515 | 1362 | tolower((unsigned char)atom[2]) == 'c') { |
4cba29f0 | 1363 | if (!strncasecmp(atom + 3, "ond", 3)) { |
f7fdb216 | 1364 | if (!strcasecmp(atom + 6, "ary")) |
d424157d SR |
1365 | return SECONDARY; |
1366 | if (!strcasecmp(atom + 6, "ary6")) | |
1367 | return SECONDARY6; | |
f7fdb216 DH |
1368 | if (!strcasecmp(atom + 6, "s")) |
1369 | return SECONDS; | |
1370 | break; | |
1371 | } | |
1372 | if (!strcasecmp(atom + 3, "ret")) | |
1373 | return SECRET; | |
1374 | break; | |
1375 | } | |
1376 | if (!strncasecmp(atom + 2, "lect", 4)) { | |
1377 | if (atom[6] == '\0') | |
1378 | return SELECT; | |
1379 | if (!strcasecmp(atom + 6, "-timeout")) | |
1380 | return SELECT_TIMEOUT; | |
1381 | break; | |
1382 | } | |
1383 | if (!strcasecmp(atom + 2, "nd")) | |
1384 | return SEND; | |
1385 | if (!strncasecmp(atom + 2, "rv", 2)) { | |
1386 | if (!strncasecmp(atom + 4, "er", 2)) { | |
1387 | if (atom[6] == '\0') | |
8da06bb1 | 1388 | return TOKEN_SERVER; |
f7fdb216 | 1389 | if (atom[6] == '-') { |
98bd7ca0 | 1390 | if (!strcasecmp(atom + 7, |
f6b8f48d | 1391 | "duid")) |
98bd7ca0 | 1392 | return SERVER_DUID; |
f7fdb216 DH |
1393 | if (!strcasecmp(atom + 7, |
1394 | "name")) | |
1395 | return SERVER_NAME; | |
1396 | if (!strcasecmp(atom + 7, | |
1397 | "identifier")) | |
1398 | return SERVER_IDENTIFIER; | |
1399 | break; | |
1400 | } | |
1401 | break; | |
1402 | } | |
1403 | if (!strcasecmp(atom + 4, "fail")) | |
1404 | return NS_SERVFAIL; | |
1405 | break; | |
1406 | } | |
1407 | if (!strcasecmp(atom + 2, "t")) | |
1408 | return TOKEN_SET; | |
52cdb300 TL |
1409 | break; |
1410 | } | |
f6b8f48d | 1411 | if (isascii(atom[1]) && |
28868515 | 1412 | tolower((unsigned char)atom[1]) == 'h') { |
f7fdb216 DH |
1413 | if (!strcasecmp(atom + 2, "ared-network")) |
1414 | return SHARED_NETWORK; | |
1415 | if (!strcasecmp(atom + 2, "utdown")) | |
1416 | return SHUTDOWN; | |
1417 | break; | |
1418 | } | |
f6b8f48d | 1419 | if (isascii(atom[1]) && |
28868515 | 1420 | tolower((unsigned char)atom[1]) == 'i') { |
f7fdb216 DH |
1421 | if (!strcasecmp(atom + 2, "addr")) |
1422 | return SIADDR; | |
1423 | if (!strcasecmp(atom + 2, "gned")) | |
1424 | return SIGNED; | |
1425 | if (!strcasecmp(atom + 2, "ze")) | |
1426 | return SIZE; | |
1427 | break; | |
1428 | } | |
f6b8f48d | 1429 | if (isascii(atom[1]) && |
28868515 | 1430 | tolower((unsigned char)atom[1]) == 'p') { |
f6b8f48d | 1431 | if (isascii(atom[2]) && |
28868515 | 1432 | tolower((unsigned char)atom[2]) == 'a') { |
f7fdb216 DH |
1433 | if (!strcasecmp(atom + 3, "ce")) |
1434 | return SPACE; | |
1435 | if (!strcasecmp(atom + 3, "wn")) | |
1436 | return SPAWN; | |
1437 | break; | |
1438 | } | |
1439 | if (!strcasecmp(atom + 2, "lit")) | |
1440 | return SPLIT; | |
1441 | break; | |
1442 | } | |
f6b8f48d | 1443 | if (isascii(atom[1]) && |
28868515 | 1444 | tolower((unsigned char)atom[1]) == 't') { |
f6b8f48d | 1445 | if (isascii(atom[2]) && |
28868515 | 1446 | tolower((unsigned char)atom[2]) == 'a') { |
57868747 | 1447 | if(!strncasecmp(atom + 3, "rt", 2)) { |
f7fdb216 DH |
1448 | if (!strcasecmp(atom + 5, "s")) |
1449 | return STARTS; | |
1450 | if (!strcasecmp(atom + 5, "up")) | |
1451 | return STARTUP; | |
1452 | break; | |
1453 | } | |
57868747 | 1454 | if (isascii(atom[3]) && |
28868515 | 1455 | tolower((unsigned char)atom[3]) == 't') { |
f7fdb216 DH |
1456 | if (!strcasecmp(atom + 4, "e")) |
1457 | return STATE; | |
1458 | if (!strcasecmp(atom + 4, "ic")) | |
1459 | return STATIC; | |
1460 | break; | |
1461 | } | |
1462 | } | |
1463 | if (!strcasecmp(atom + 2, "ring")) | |
1464 | return STRING_TOKEN; | |
1465 | break; | |
1466 | } | |
1467 | if (!strncasecmp(atom + 1, "ub", 2)) { | |
1468 | if (!strcasecmp(atom + 3, "class")) | |
1469 | return SUBCLASS; | |
1470 | if (!strcasecmp(atom + 3, "net")) | |
1471 | return SUBNET; | |
98bd7ca0 DH |
1472 | if (!strcasecmp(atom + 3, "net6")) |
1473 | return SUBNET6; | |
f7fdb216 DH |
1474 | if (!strcasecmp(atom + 3, "string")) |
1475 | return SUBSTRING; | |
1476 | break; | |
1477 | } | |
f6b8f48d | 1478 | if (isascii(atom[1]) && |
28868515 | 1479 | tolower((unsigned char)atom[1]) == 'u') { |
f7fdb216 DH |
1480 | if (!strcasecmp(atom + 2, "ffix")) |
1481 | return SUFFIX; | |
1482 | if (!strcasecmp(atom + 2, "persede")) | |
1483 | return SUPERSEDE; | |
1484 | } | |
1485 | if (!strcasecmp(atom + 1, "witch")) | |
1486 | return SWITCH; | |
089fb364 TL |
1487 | break; |
1488 | case 't': | |
54d9cf28 | 1489 | if (!strcasecmp (atom + 1, "imestamp")) |
089fb364 | 1490 | return TIMESTAMP; |
f71f026a TL |
1491 | if (!strcasecmp (atom + 1, "imeout")) |
1492 | return TIMEOUT; | |
58304e8e TL |
1493 | if (!strcasecmp (atom + 1, "oken-ring")) |
1494 | return TOKEN_RING; | |
f8b21a3d TL |
1495 | if (!strcasecmp (atom + 1, "ext")) |
1496 | return TEXT; | |
2b6e0559 TL |
1497 | if (!strcasecmp (atom + 1, "stp")) |
1498 | return TSTP; | |
1499 | if (!strcasecmp (atom + 1, "sfp")) | |
1500 | return TSFP; | |
1687c64b TL |
1501 | if (!strcasecmp (atom + 1, "ransmission")) |
1502 | return TRANSMISSION; | |
80c9fdb0 FD |
1503 | if (!strcasecmp(atom + 1, "emporary")) |
1504 | return TEMPORARY; | |
089fb364 TL |
1505 | break; |
1506 | case 'u': | |
2727c1cf DH |
1507 | if (!strcasecmp (atom + 1, "case")) |
1508 | return UCASE; | |
34731eed TL |
1509 | if (!strcasecmp (atom + 1, "nset")) |
1510 | return UNSET; | |
f8b21a3d TL |
1511 | if (!strcasecmp (atom + 1, "nsigned")) |
1512 | return UNSIGNED; | |
089fb364 TL |
1513 | if (!strcasecmp (atom + 1, "id")) |
1514 | return UID; | |
a167f312 TL |
1515 | if (!strncasecmp (atom + 1, "se", 2)) { |
1516 | if (!strcasecmp (atom + 3, "r-class")) | |
1517 | return USER_CLASS; | |
1518 | if (!strcasecmp (atom + 3, "-host-decl-names")) | |
1519 | return USE_HOST_DECL_NAMES; | |
1520 | if (!strcasecmp (atom + 3, | |
1521 | "-lease-addr-for-default-route")) | |
1522 | return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE; | |
1523 | break; | |
1524 | } | |
f197003d TL |
1525 | if (!strncasecmp (atom + 1, "nknown", 6)) { |
1526 | if (!strcasecmp (atom + 7, "-clients")) | |
1527 | return UNKNOWN_CLIENTS; | |
822e866a TL |
1528 | if (!strcasecmp (atom + 7, "-state")) |
1529 | return UNKNOWN_STATE; | |
f197003d TL |
1530 | if (!atom [7]) |
1531 | return UNKNOWN; | |
1532 | break; | |
1533 | } | |
1534 | if (!strcasecmp (atom + 1, "nauthenticated")) | |
3453299d | 1535 | return UNAUTHENTICATED; |
2b6e0559 TL |
1536 | if (!strcasecmp (atom + 1, "pdate")) |
1537 | return UPDATE; | |
b0e3a220 TL |
1538 | break; |
1539 | case 'v': | |
619304cd SR |
1540 | if (!strcasecmp (atom + 1, "6relay")) |
1541 | return V6RELAY; | |
1542 | if (!strcasecmp (atom + 1, "6relopt")) | |
1543 | return V6RELOPT; | |
b0e3a220 TL |
1544 | if (!strcasecmp (atom + 1, "endor-class")) |
1545 | return VENDOR_CLASS; | |
eebf58bc TL |
1546 | if (!strcasecmp (atom + 1, "endor")) |
1547 | return VENDOR; | |
089fb364 | 1548 | break; |
52cdb300 TL |
1549 | case 'w': |
1550 | if (!strcasecmp (atom + 1, "ith")) | |
1551 | return WITH; | |
f7fdb216 DH |
1552 | if (!strcasecmp(atom + 1, "idth")) |
1553 | return WIDTH; | |
52cdb300 | 1554 | break; |
97ca1699 TL |
1555 | case 'y': |
1556 | if (!strcasecmp (atom + 1, "iaddr")) | |
1557 | return YIADDR; | |
14a2c383 TL |
1558 | if (!strcasecmp (atom + 1, "xdomain")) |
1559 | return NS_YXDOMAIN; | |
1560 | if (!strcasecmp (atom + 1, "xrrset")) | |
1561 | return NS_YXRRSET; | |
97ca1699 | 1562 | break; |
cfc62a06 | 1563 | case 'z': |
4cafb815 EH |
1564 | if (!strcasecmp (atom + 1, "erolen")) |
1565 | return ZEROLEN; | |
cfc62a06 TL |
1566 | if (!strcasecmp (atom + 1, "one")) |
1567 | return ZONE; | |
1568 | break; | |
d7837182 TL |
1569 | } |
1570 | return dfv; | |
1571 | } |