ISC DHCP  4.4.3-P1
A reference DHCPv4 and DHCPv6 implementation
conflex.c
Go to the documentation of this file.
1 /* conflex.c
2 
3  Lexical scanner for dhcpd config file... */
4 
5 /*
6  * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1995-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 #include <ctype.h>
31 
32 static int get_char (struct parse *);
33 static void unget_char(struct parse *, int);
34 static void skip_to_eol (struct parse *);
35 static enum dhcp_token read_whitespace(int c, struct parse *cfile);
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);
40 
41 isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
42  struct parse **cfile;
43  int file;
44  char *inbuf;
45  unsigned buflen;
46  const char *name;
47  int eolp;
48 {
49  isc_result_t status = ISC_R_SUCCESS;
50  struct parse *tmp;
51 
52  tmp = dmalloc(sizeof(struct parse), MDL);
53  if (tmp == NULL) {
54  return (ISC_R_NOMEMORY);
55  }
56 
57  /*
58  * We don't need to initialize things to zero here, since
59  * dmalloc() returns memory that is set to zero.
60  */
61  tmp->tlname = name;
62  tmp->lpos = tmp -> line = 1;
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;
67  tmp->file = file;
68  tmp->eol_token = eolp;
69 
70  if (inbuf != NULL) {
71  tmp->inbuf = inbuf;
72  tmp->buflen = buflen;
73  tmp->bufsiz = 0;
74  } else {
75  struct stat sb;
76 
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;
84 
85  tmp->bufsiz = tmp->buflen = (size_t) sb.st_size;
86  tmp->inbuf = mmap(NULL, tmp->bufsiz, PROT_READ, MAP_SHARED,
87  file, 0);
88 
89  if (tmp->inbuf == MAP_FAILED) {
90  status = ISC_R_IOERROR;
91  goto cleanup;
92  }
93  }
94 
95  *cfile = tmp;
96  return (ISC_R_SUCCESS);
97 
98 cleanup:
99  dfree(tmp, MDL);
100  return (status);
101 }
102 
103 isc_result_t end_parse (cfile)
104  struct parse **cfile;
105 {
106  /* "Memory" config files have no file. */
107  if ((*cfile)->file != -1) {
108  munmap((*cfile)->inbuf, (*cfile)->bufsiz);
109  close((*cfile)->file);
110  }
111 
112  if ((*cfile)->saved_state != NULL) {
113  dfree((*cfile)->saved_state, MDL);
114  }
115 
116  dfree(*cfile, MDL);
117  *cfile = NULL;
118  return ISC_R_SUCCESS;
119 }
120 
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  *
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.
157  */
158 isc_result_t
159 restore_parse_state(struct parse *cfile) {
160  struct parse *saved_state;
161 #if defined(LDAP_CONFIGURATION)
162  char *inbuf = cfile->inbuf;
163  size_t size = cfile->bufsiz;
164 #endif
165 
166  if (cfile->saved_state == NULL) {
167  return DHCP_R_NOTYET;
168  }
169 
170  saved_state = cfile->saved_state;
171  memcpy(cfile, saved_state, sizeof(*cfile));
173  cfile->saved_state = NULL;
174 
175 #if defined(LDAP_CONFIGURATION)
176  cfile->inbuf = inbuf;
177  cfile->bufsiz = size;
178 #endif
179  return ISC_R_SUCCESS;
180 }
181 
182 static int get_char (cfile)
183  struct parse *cfile;
184 {
185  /* My kingdom for WITH... */
186  int c;
187 
188  if (cfile->bufix == cfile->buflen) {
189 #if !defined(LDAP_CONFIGURATION)
190  c = EOF;
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 {
198  c = cfile->inbuf [cfile->bufix];
199  cfile->bufix++;
200  }
201 
202  if (!cfile->ugflag) {
203  if (c == EOL) {
204  if (cfile->cur_line == cfile->line1) {
205  cfile->cur_line = cfile->line2;
206  cfile->prev_line = cfile->line1;
207  } else {
208  cfile->cur_line = cfile->line1;
209  cfile->prev_line = cfile->line2;
210  }
211  cfile->line++;
212  cfile->lpos = 1;
213  cfile->cur_line [0] = 0;
214  } else if (c != EOF) {
215  if (cfile->lpos <= 80) {
216  cfile->cur_line [cfile->lpos - 1] = c;
217  cfile->cur_line [cfile->lpos] = 0;
218  }
219  cfile->lpos++;
220  }
221  } else
222  cfile->ugflag = 0;
223  return c;
224 }
225 
226 /*
227  * Return a character to our input buffer.
228  */
229 static void
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 
239 /*
240  * GENERAL NOTE ABOUT TOKENS
241  *
242  * We normally only want non-whitespace tokens. There are some
243  * circumstances where we *do* want to see whitespace (for example
244  * when parsing IPv6 addresses).
245  *
246  * Generally we use the next_token() function to read tokens. This
247  * in turn calls get_next_token, which does *not* return tokens for
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) {
262  int c;
263  enum dhcp_token ttok;
264  static char tb [2];
265  int l, p;
266 
267  do {
268  l = cfile -> line;
269  p = cfile -> lpos;
270 
271  c = get_char (cfile);
272  if (!((c == '\n') && cfile->eol_token) &&
273  isascii(c) && isspace(c)) {
274  ttok = read_whitespace(c, cfile);
275  break;
276  }
277  if (c == '#') {
278  skip_to_eol (cfile);
279  continue;
280  }
281  if (c == '"') {
282  cfile -> lexline = l;
283  cfile -> lexchar = p;
284  ttok = read_string (cfile);
285  break;
286  }
287  if ((isascii (c) && isdigit (c)) || c == '-') {
288  cfile -> lexline = l;
289  cfile -> lexchar = p;
290  ttok = read_number (c, cfile);
291  break;
292  } else if (isascii (c) && isalpha (c)) {
293  cfile -> lexline = l;
294  cfile -> lexchar = p;
295  ttok = read_num_or_name (c, cfile);
296  break;
297  } else if (c == EOF) {
298  ttok = END_OF_FILE;
299  cfile -> tlen = 0;
300  break;
301  } else {
302  cfile -> lexline = l;
303  cfile -> lexchar = p;
304  tb [0] = c;
305  tb [1] = 0;
306  cfile -> tval = tb;
307  cfile -> tlen = 1;
308  ttok = c;
309  break;
310  }
311  } while (1);
312  return ttok;
313 }
314 
315 /*
316  * The get_next_token() function consumes the next token and
317  * returns it to the caller.
318  *
319  * Since the code is almost the same for "normal" and "raw"
320  * input, we pass a flag to alter the way it works.
321  */
322 
323 static enum dhcp_token
324 get_next_token(const char **rval, unsigned *rlen,
325  struct parse *cfile, isc_boolean_t raw) {
326  int rv;
327 
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;
335  } else {
336  rv = get_raw_token(cfile);
337  cfile -> token_line = cfile -> cur_line;
338  }
339 
340  if (!raw) {
341  while (rv == WHITESPACE) {
342  rv = get_raw_token(cfile);
343  cfile->token_line = cfile->cur_line;
344  }
345  }
346 
347  if (rval)
348  *rval = cfile -> tval;
349  if (rlen)
350  *rlen = cfile -> tlen;
351 #ifdef DEBUG_TOKENS
352  fprintf (stderr, "%s:%d ", cfile -> tval, rv);
353 #endif
354  return rv;
355 }
356 
357 
358 /*
359  * Get the next token from cfile and return it.
360  *
361  * If rval is non-NULL, set the pointer it contains to
362  * the contents of the token.
363  *
364  * If rlen is non-NULL, set the integer it contains to
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  *
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
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) {
397  int x;
398 
399  if (!cfile->token || (!raw && (cfile->token == WHITESPACE))) {
400  cfile -> tlpos = cfile -> lexchar;
401  cfile -> tline = cfile -> lexline;
402 
403  do {
404  cfile->token = get_raw_token(cfile);
405  } while (!raw && (cfile->token == WHITESPACE));
406 
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;
417  }
418  if (rval)
419  *rval = cfile -> tval;
420  if (rlen)
421  *rlen = cfile -> tlen;
422 #ifdef DEBUG_TOKENS
423  fprintf (stderr, "(%s:%d) ", cfile -> tval, cfile -> token);
424 #endif
425  return cfile -> token;
426 }
427 
428 
429 /*
430  * Get the next token from cfile and return it, leaving it for a
431  * subsequent call to next_token().
432  *
433  * Note that it WILL consume whitespace tokens.
434  *
435  * If rval is non-NULL, set the pointer it contains to
436  * the contents of the token.
437  *
438  * If rlen is non-NULL, set the integer it contains to
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 
458 static void skip_to_eol (cfile)
459  struct parse *cfile;
460 {
461  int c;
462  do {
463  c = get_char (cfile);
464  if (c == EOF)
465  return;
466  if (c == EOL) {
467  return;
468  }
469  } while (1);
470 }
471 
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 {
481  if (ofs >= (sizeof(cfile->tokbuf) - 1)) {
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  }
491  cfile->tokbuf[ofs++] = c;
492  c = get_char(cfile);
493  if (c == EOF)
494  return END_OF_FILE;
495  } while (!((c == '\n') && cfile->eol_token) &&
496  isascii(c) && isspace(c));
497 
498  /*
499  * Put the last (non-whitespace) character back.
500  */
501  unget_char(cfile, c);
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 
512 static enum dhcp_token read_string (cfile)
513  struct parse *cfile;
514 {
515  int i;
516  int bs = 0;
517  int c;
518  int value = 0;
519  int hex = 0;
520 
521  for (i = 0; i < sizeof cfile -> tokbuf; i++) {
522  again:
523  c = get_char (cfile);
524  if (c == EOF) {
525  parse_warn (cfile, "eof in string constant");
526  break;
527  }
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;
557  break;
558  }
559  bs = 0;
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 {
581  if (c >= '0' && c <= '7') {
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 == '\\') {
600  bs = 1;
601  goto again;
602  } else if (c == '"')
603  break;
604  else
605  cfile -> tokbuf [i] = c;
606  }
607  /* Normally, I'd feel guilty about this, but we're talking about
608  strings that'll fit in a DHCP packet here... */
609  if (i == sizeof cfile -> tokbuf) {
610  parse_warn (cfile,
611  "string constant larger than internal buffer");
612  --i;
613  }
614  cfile -> tokbuf [i] = 0;
615  cfile -> tlen = i;
616  cfile -> tval = cfile -> tokbuf;
617  return STRING;
618 }
619 
620 static enum dhcp_token read_number (c, cfile)
621  int c;
622  struct parse *cfile;
623 {
624  int i = 0;
625  int token = NUMBER;
626 
627  cfile -> tokbuf [i++] = c;
628  for (; i < sizeof cfile -> tokbuf; i++) {
629  c = get_char (cfile);
630 
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)) {
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'))) {
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  */
664  unget_char(cfile, c);
665  goto end_read;
666 
667  default:
668  log_fatal("read_number():%s:%d: impossible case", MDL);
669  }
670 
671  cfile -> tokbuf [i] = c;
672  }
673 
674  if (i == sizeof cfile -> tokbuf) {
675  parse_warn (cfile,
676  "numeric token larger than internal buffer");
677  --i;
678  }
679 
680  end_read:
681  cfile -> tokbuf [i] = 0;
682  cfile -> tlen = i;
683  cfile -> tval = cfile -> tokbuf;
684 
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;
693 }
694 
695 static enum dhcp_token read_num_or_name (c, cfile)
696  int c;
697  struct parse *cfile;
698 {
699  int i = 0;
700  enum dhcp_token rv = NUMBER_OR_NAME;
701  cfile -> tokbuf [i++] = c;
702  for (; i < sizeof cfile -> tokbuf; i++) {
703  c = get_char (cfile);
704  if (!isascii (c) ||
705  (c != '-' && c != '_' && !isalnum (c))) {
706  unget_char(cfile, c);
707  break;
708  }
709  if (!isxdigit (c))
710  rv = NAME;
711  cfile -> tokbuf [i] = c;
712  }
713  if (i == sizeof cfile -> tokbuf) {
714  parse_warn (cfile, "token larger than internal buffer");
715  --i;
716  }
717  cfile -> tokbuf [i] = 0;
718  cfile -> tlen = i;
719  cfile -> tval = cfile -> tokbuf;
720  return intern(cfile->tval, rv);
721 }
722 
723 static enum dhcp_token
724 intern(char *atom, enum dhcp_token dfv) {
725  if (!isascii(atom[0]))
726  return dfv;
727 
728  switch (tolower((unsigned char)atom[0])) {
729  case '-':
730  if (atom [1] == 0)
731  return MINUS;
732  break;
733 
734  case 'a':
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;
748  if (isascii(atom[1]) &&
749  (tolower((unsigned char)atom[1]) == 'l')) {
750  if (!strcasecmp(atom + 2, "gorithm"))
751  return ALGORITHM;
752  if (!strcasecmp(atom + 2, "ias"))
753  return ALIAS;
754  if (isascii(atom[2]) &&
755  (tolower((unsigned char)atom[2]) == 'l')) {
756  if (atom[3] == '\0')
757  return ALL;
758  else if (!strcasecmp(atom + 3, "ow"))
759  return ALLOW;
760  break;
761  }
762  if (!strcasecmp(atom + 2, "so"))
763  return TOKEN_ALSO;
764  break;
765  }
766  if (isascii(atom[1]) &&
767  (tolower((unsigned char)atom[1]) == 'n')) {
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"))
775  return APPEND;
776  if (!strcasecmp(atom + 1, "rray"))
777  return ARRAY;
778  if (isascii(atom[1]) &&
779  (tolower((unsigned char)atom[1]) == 't')) {
780  if (atom[2] == '\0')
781  return AT;
782  if (!strcasecmp(atom + 2, "sfp"))
783  return ATSFP;
784  break;
785  }
786  if (!strcasecmp(atom + 1, "uthoring-byte-order"))
787  return AUTHORING_BYTE_ORDER;
788  if (!strncasecmp(atom + 1, "ut", 2)) {
789  if (isascii(atom[3]) &&
790  (tolower((unsigned char)atom[3]) == 'h')) {
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  }
806  break;
807  case 'b':
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;
814  if (!strcasecmp (atom + 1, "inary-to-ascii"))
815  return BINARY_TO_ASCII;
816  if (!strcasecmp (atom + 1, "ackoff-cutoff"))
817  return BACKOFF_CUTOFF;
818  if (!strcasecmp (atom + 1, "ooting"))
819  return BOOTING;
820  if (!strcasecmp (atom + 1, "oot-unknown-clients"))
821  return BOOT_UNKNOWN_CLIENTS;
822  if (!strcasecmp (atom + 1, "reak"))
823  return BREAK;
824  if (!strcasecmp (atom + 1, "illing"))
825  return BILLING;
826  if (!strcasecmp (atom + 1, "oolean"))
827  return BOOLEAN;
828  if (!strcasecmp (atom + 1, "alance"))
829  return BALANCE;
830  if (!strcasecmp (atom + 1, "ound"))
831  return BOUND;
832  if (!strcasecmp(atom+1, "ig-endian")) {
833  return TOKEN_BIG_ENDIAN;
834  }
835  if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
836  return BOOTP_BROADCAST_ALWAYS;
837  break;
838  case 'c':
839  if (!strcasecmp(atom + 1, "ase"))
840  return CASE;
841  if (!strcasecmp(atom + 1, "heck"))
842  return CHECK;
843  if (!strcasecmp(atom + 1, "iaddr"))
844  return CIADDR;
845  if (isascii(atom[1]) &&
846  tolower((unsigned char)atom[1]) == 'l') {
847  if (!strcasecmp(atom + 2, "ass"))
848  return CLASS;
849  if (!strncasecmp(atom + 2, "ient", 4)) {
850  if (!strcasecmp(atom + 6, "s"))
851  return CLIENTS;
852  if (atom[6] == '-') {
853  if (!strcasecmp(atom + 7, "hostname"))
854  return CLIENT_HOSTNAME;
855  if (!strcasecmp(atom + 7, "identifier"))
856  return CLIENT_IDENTIFIER;
857  if (!strcasecmp(atom + 7, "state"))
858  return CLIENT_STATE;
859  if (!strcasecmp(atom + 7, "updates"))
860  return CLIENT_UPDATES;
861  break;
862  }
863  break;
864  }
865  if (!strcasecmp(atom + 2, "ose"))
866  return TOKEN_CLOSE;
867  if (!strcasecmp(atom + 2, "tt"))
868  return CLTT;
869  break;
870  }
871  if (isascii(atom[1]) &&
872  tolower((unsigned char)atom[1]) == 'o') {
873  if (!strcasecmp(atom + 2, "de"))
874  return CODE;
875  if (isascii(atom[2]) &&
876  tolower((unsigned char)atom[2]) == 'm') {
877  if (!strcasecmp(atom + 3, "mit"))
878  return COMMIT;
879  if (!strcasecmp(atom + 3,
880  "munications-interrupted"))
882  if (!strcasecmp(atom + 3, "pressed"))
883  return COMPRESSED;
884  break;
885  }
886  if (isascii(atom[2]) &&
887  tolower((unsigned char)atom[2]) == 'n') {
888  if (!strcasecmp(atom + 3, "cat"))
889  return CONCAT;
890  if (!strcasecmp(atom + 3, "fig-option"))
891  return CONFIG_OPTION;
892  if (!strcasecmp(atom + 3, "flict-done"))
893  return CONFLICT_DONE;
894  if (!strcasecmp(atom + 3, "nect"))
895  return CONNECT;
896  break;
897  }
898  break;
899  }
900  if (!strcasecmp(atom + 1, "reate"))
901  return TOKEN_CREATE;
902  break;
903  case 'd':
904  if (!strcasecmp(atom + 1, "b-time-format"))
905  return DB_TIME_FORMAT;
906  if (!strcasecmp (atom + 1, "omain"))
907  return DOMAIN;
908  if (!strncasecmp (atom + 1, "omain-", 6)) {
909  if (!strcasecmp(atom + 7, "name"))
910  return DOMAIN_NAME;
911  if (!strcasecmp(atom + 7, "list"))
912  return DOMAIN_LIST;
913  }
914  if (!strcasecmp (atom + 1, "o-forward-updates"))
915  return DO_FORWARD_UPDATE;
916  /* do-forward-update is included for historical reasons */
917  if (!strcasecmp (atom + 1, "o-forward-update"))
918  return DO_FORWARD_UPDATE;
919  if (!strcasecmp (atom + 1, "ebug"))
920  return TOKEN_DEBUG;
921  if (!strcasecmp (atom + 1, "eny"))
922  return DENY;
923  if (!strcasecmp (atom + 1, "eleted"))
924  return TOKEN_DELETED;
925  if (!strcasecmp (atom + 1, "elete"))
926  return TOKEN_DELETE;
927  if (!strncasecmp (atom + 1, "efault", 6)) {
928  if (!atom [7])
929  return DEFAULT;
930  if (!strcasecmp(atom + 7, "-duid"))
931  return DEFAULT_DUID;
932  if (!strcasecmp (atom + 7, "-lease-time"))
933  return DEFAULT_LEASE_TIME;
934  break;
935  }
936  if (!strncasecmp (atom + 1, "ynamic", 6)) {
937  if (!atom [7])
938  return DYNAMIC;
939  if (!strncasecmp (atom + 7, "-bootp", 6)) {
940  if (!atom [13])
941  return DYNAMIC_BOOTP;
942  if (!strcasecmp (atom + 13, "-lease-cutoff"))
944  if (!strcasecmp (atom + 13, "-lease-length"))
946  break;
947  }
948  }
949  if (!strcasecmp (atom + 1, "uplicates"))
950  return DUPLICATES;
951  if (!strcasecmp (atom + 1, "eclines"))
952  return DECLINES;
953  if (!strncasecmp (atom + 1, "efine", 5)) {
954  if (!strcasecmp (atom + 6, "d"))
955  return DEFINED;
956  if (!atom [6])
957  return DEFINE;
958  }
959  if (!strcasecmp (atom + 1, "isconnect"))
960  return DISCONNECT;
961  break;
962  case 'e':
963  if (isascii (atom [1]) &&
964  tolower((unsigned char)atom[1]) == 'x') {
965  if (!strcasecmp (atom + 2, "tract-int"))
966  return EXTRACT_INT;
967  if (!strcasecmp (atom + 2, "ists"))
968  return EXISTS;
969  if (!strcasecmp (atom + 2, "piry"))
970  return EXPIRY;
971  if (!strcasecmp (atom + 2, "pire"))
972  return EXPIRE;
973  if (!strcasecmp (atom + 2, "pired"))
974  return TOKEN_EXPIRED;
975  }
976  if (!strcasecmp (atom + 1, "ncode-int"))
977  return ENCODE_INT;
978  if (!strcasecmp(atom + 1, "poch"))
979  return EPOCH;
980  if (!strcasecmp (atom + 1, "thernet"))
981  return ETHERNET;
982  if (!strcasecmp (atom + 1, "nds"))
983  return ENDS;
984  if (!strncasecmp (atom + 1, "ls", 2)) {
985  if (!strcasecmp (atom + 3, "e"))
986  return ELSE;
987  if (!strcasecmp (atom + 3, "if"))
988  return ELSIF;
989  break;
990  }
991  if (!strcasecmp (atom + 1, "rror"))
992  return ERROR;
993  if (!strcasecmp (atom + 1, "val"))
994  return EVAL;
995  if (!strcasecmp (atom + 1, "ncapsulate"))
996  return ENCAPSULATE;
997  if (!strcasecmp(atom + 1, "xecute"))
998  return EXECUTE;
999  if (!strcasecmp(atom+1, "n")) {
1000  return EN;
1001  }
1002  break;
1003  case 'f':
1004  if (!strcasecmp (atom + 1, "atal"))
1005  return FATAL;
1006  if (!strcasecmp (atom + 1, "ilename"))
1007  return FILENAME;
1008  if (!strcasecmp (atom + 1, "ixed-address"))
1009  return FIXED_ADDR;
1010  if (!strcasecmp (atom + 1, "ixed-address6"))
1011  return FIXED_ADDR6;
1012  if (!strcasecmp (atom + 1, "ixed-prefix6"))
1013  return FIXED_PREFIX6;
1014  if (!strcasecmp (atom + 1, "ddi"))
1015  return TOKEN_FDDI;
1016  if (!strcasecmp (atom + 1, "ormerr"))
1017  return NS_FORMERR;
1018  if (!strcasecmp (atom + 1, "unction"))
1019  return FUNCTION;
1020  if (!strcasecmp (atom + 1, "ailover"))
1021  return FAILOVER;
1022  if (!strcasecmp (atom + 1, "ree"))
1023  return TOKEN_FREE;
1024  break;
1025  case 'g':
1026  if (!strncasecmp(atom + 1, "et", 2)) {
1027  if (!strcasecmp(atom + 3, "-lease-hostnames"))
1028  return GET_LEASE_HOSTNAMES;
1029  if (!strcasecmp(atom + 3, "hostbyname"))
1030  return GETHOSTBYNAME;
1031  if (!strcasecmp(atom + 3, "hostname"))
1032  return GETHOSTNAME;
1033  break;
1034  }
1035  if (!strcasecmp (atom + 1, "iaddr"))
1036  return GIADDR;
1037  if (!strcasecmp (atom + 1, "roup"))
1038  return GROUP;
1039  break;
1040  case 'h':
1041  if (!strcasecmp(atom + 1, "ash"))
1042  return HASH;
1043  if (!strcasecmp (atom + 1, "ba"))
1044  return HBA;
1045  if (!strcasecmp (atom + 1, "ost"))
1046  return HOST;
1047  if (!strcasecmp (atom + 1, "ost-decl-name"))
1048  return HOST_DECL_NAME;
1049  if (!strcasecmp(atom + 1, "ost-identifier"))
1050  return HOST_IDENTIFIER;
1051  if (!strcasecmp (atom + 1, "ardware"))
1052  return HARDWARE;
1053  if (!strcasecmp (atom + 1, "ostname"))
1054  return HOSTNAME;
1055  if (!strcasecmp (atom + 1, "elp"))
1056  return TOKEN_HELP;
1057  if (!strcasecmp (atom + 1, "ex")) {
1058  return TOKEN_HEX;
1059  }
1060  break;
1061  case 'i':
1062  if (!strcasecmp(atom+1, "a-na"))
1063  return IA_NA;
1064  if (!strcasecmp(atom+1, "a-ta"))
1065  return IA_TA;
1066  if (!strcasecmp(atom+1, "a-pd"))
1067  return IA_PD;
1068  if (!strcasecmp(atom+1, "aaddr"))
1069  return IAADDR;
1070  if (!strcasecmp(atom+1, "aprefix"))
1071  return IAPREFIX;
1072  if (!strcasecmp (atom + 1, "nclude"))
1073  return INCLUDE;
1074  if (!strcasecmp (atom + 1, "nteger"))
1075  return INTEGER;
1076  if (!strcasecmp (atom + 1, "nfiniband"))
1077  return TOKEN_INFINIBAND;
1078  if (!strcasecmp (atom + 1, "nfinite"))
1079  return INFINITE;
1080  if (!strcasecmp (atom + 1, "nfo"))
1081  return INFO;
1082  if (!strcasecmp (atom + 1, "p-address"))
1083  return IP_ADDRESS;
1084  if (!strcasecmp (atom + 1, "p6-address"))
1085  return IP6_ADDRESS;
1086  if (!strcasecmp (atom + 1, "nitial-interval"))
1087  return INITIAL_INTERVAL;
1088  if (!strcasecmp (atom + 1, "nitial-delay"))
1089  return INITIAL_DELAY;
1090  if (!strcasecmp (atom + 1, "nterface"))
1091  return INTERFACE;
1092  if (!strcasecmp (atom + 1, "dentifier"))
1093  return IDENTIFIER;
1094  if (!strcasecmp (atom + 1, "f"))
1095  return IF;
1096  if (!strcasecmp (atom + 1, "s"))
1097  return IS;
1098  if (!strcasecmp (atom + 1, "gnore"))
1099  return IGNORE;
1100  break;
1101  case 'k':
1102  if (!strncasecmp (atom + 1, "nown", 4)) {
1103  if (!strcasecmp (atom + 5, "-clients"))
1104  return KNOWN_CLIENTS;
1105  if (!atom[5])
1106  return KNOWN;
1107  break;
1108  }
1109  if (!strcasecmp (atom + 1, "ey"))
1110  return KEY;
1111  if (!strcasecmp (atom + 1, "ey-algorithm"))
1112  return KEY_ALGORITHM;
1113  break;
1114  case 'l':
1115  if (!strcasecmp (atom + 1, "case"))
1116  return LCASE;
1117  if (!strcasecmp (atom + 1, "ease"))
1118  return LEASE;
1119  if (!strcasecmp(atom + 1, "ease6"))
1120  return LEASE6;
1121  if (!strcasecmp (atom + 1, "eased-address"))
1122  return LEASED_ADDRESS;
1123  if (!strcasecmp (atom + 1, "ease-time"))
1124  return LEASE_TIME;
1125  if (!strcasecmp(atom + 1, "easequery"))
1126  return LEASEQUERY;
1127  if (!strcasecmp(atom + 1, "ength"))
1128  return LENGTH;
1129  if (!strcasecmp (atom + 1, "imit"))
1130  return LIMIT;
1131  if (!strcasecmp (atom + 1, "et"))
1132  return LET;
1133  if (!strcasecmp (atom + 1, "oad"))
1134  return LOAD;
1135  if (!strcasecmp(atom + 1, "ocal"))
1136  return LOCAL;
1137  if (!strcasecmp (atom + 1, "og"))
1138  return LOG;
1139  if (!strcasecmp(atom+1, "lt")) {
1140  return LLT;
1141  }
1142  if (!strcasecmp(atom+1, "l")) {
1143  return LL;
1144  }
1145  if (!strcasecmp(atom+1, "ittle-endian")) {
1146  return TOKEN_LITTLE_ENDIAN;
1147  }
1148  if (!strcasecmp (atom + 1, "ease-id-format")) {
1149  return LEASE_ID_FORMAT;
1150  }
1151  break;
1152  case 'm':
1153  if (!strncasecmp (atom + 1, "ax", 2)) {
1154  if (!atom [3])
1155  return TOKEN_MAX;
1156  if (!strcasecmp (atom + 3, "-balance"))
1157  return MAX_BALANCE;
1158  if (!strncasecmp (atom + 3, "-lease-", 7)) {
1159  if (!strcasecmp(atom + 10, "misbalance"))
1160  return MAX_LEASE_MISBALANCE;
1161  if (!strcasecmp(atom + 10, "ownership"))
1162  return MAX_LEASE_OWNERSHIP;
1163  if (!strcasecmp(atom + 10, "time"))
1164  return MAX_LEASE_TIME;
1165  }
1166  if (!strcasecmp(atom + 3, "-life"))
1167  return MAX_LIFE;
1168  if (!strcasecmp (atom + 3, "-transmit-idle"))
1169  return MAX_TRANSMIT_IDLE;
1170  if (!strcasecmp (atom + 3, "-response-delay"))
1171  return MAX_RESPONSE_DELAY;
1172  if (!strcasecmp (atom + 3, "-unacked-updates"))
1173  return MAX_UNACKED_UPDATES;
1174  }
1175  if (!strncasecmp (atom + 1, "in-", 3)) {
1176  if (!strcasecmp (atom + 4, "balance"))
1177  return MIN_BALANCE;
1178  if (!strcasecmp (atom + 4, "lease-time"))
1179  return MIN_LEASE_TIME;
1180  if (!strcasecmp (atom + 4, "secs"))
1181  return MIN_SECS;
1182  break;
1183  }
1184  if (!strncasecmp (atom + 1, "edi", 3)) {
1185  if (!strcasecmp (atom + 4, "a"))
1186  return MEDIA;
1187  if (!strcasecmp (atom + 4, "um"))
1188  return MEDIUM;
1189  break;
1190  }
1191  if (!strcasecmp (atom + 1, "atch"))
1192  return MATCH;
1193  if (!strcasecmp (atom + 1, "embers"))
1194  return MEMBERS;
1195  if (!strcasecmp (atom + 1, "y"))
1196  return MY;
1197  if (!strcasecmp (atom + 1, "clt"))
1198  return MCLT;
1199  break;
1200  case 'n':
1201  if (!strcasecmp (atom + 1, "ormal"))
1202  return NORMAL;
1203  if (!strcasecmp (atom + 1, "ameserver"))
1204  return NAMESERVER;
1205  if (!strcasecmp (atom + 1, "etmask"))
1206  return NETMASK;
1207  if (!strcasecmp (atom + 1, "ever"))
1208  return NEVER;
1209  if (!strcasecmp (atom + 1, "ext-server"))
1210  return NEXT_SERVER;
1211  if (!strcasecmp (atom + 1, "ot"))
1212  return TOKEN_NOT;
1213  if (!strcasecmp (atom + 1, "o"))
1214  return TOKEN_NO;
1215  if (!strcasecmp (atom + 1, "oerror"))
1216  return NS_NOERROR;
1217  if (!strcasecmp (atom + 1, "otauth"))
1218  return NS_NOTAUTH;
1219  if (!strcasecmp (atom + 1, "otimp"))
1220  return NS_NOTIMP;
1221  if (!strcasecmp (atom + 1, "otzone"))
1222  return NS_NOTZONE;
1223  if (!strcasecmp (atom + 1, "xdomain"))
1224  return NS_NXDOMAIN;
1225  if (!strcasecmp (atom + 1, "xrrset"))
1226  return NS_NXRRSET;
1227  if (!strcasecmp (atom + 1, "ull"))
1228  return TOKEN_NULL;
1229  if (!strcasecmp (atom + 1, "ext"))
1230  return TOKEN_NEXT;
1231  if (!strcasecmp (atom + 1, "ew"))
1232  return TOKEN_NEW;
1233  break;
1234  case 'o':
1235  if (!strcasecmp (atom + 1, "mapi"))
1236  return OMAPI;
1237  if (!strcasecmp (atom + 1, "r"))
1238  return OR;
1239  if (!strcasecmp (atom + 1, "n"))
1240  return ON;
1241  if (!strcasecmp (atom + 1, "pen"))
1242  return TOKEN_OPEN;
1243  if (!strcasecmp (atom + 1, "ption"))
1244  return OPTION;
1245  if (!strcasecmp (atom + 1, "ne-lease-per-client"))
1246  return ONE_LEASE_PER_CLIENT;
1247  if (!strcasecmp (atom + 1, "f"))
1248  return OF;
1249  if (!strcasecmp (atom + 1, "wner"))
1250  return OWNER;
1251  if (!strcasecmp (atom + 1, "ctal")) {
1252  return TOKEN_OCTAL;
1253  }
1254  break;
1255  case 'p':
1256  if (!strcasecmp (atom + 1, "arse-vendor-option"))
1257  return PARSE_VENDOR_OPT;
1258  if (!strcasecmp (atom + 1, "repend"))
1259  return PREPEND;
1260  if (!strcasecmp(atom + 1, "referred-life"))
1261  return PREFERRED_LIFE;
1262  if (!strcasecmp (atom + 1, "acket"))
1263  return PACKET;
1264  if (!strcasecmp (atom + 1, "ool"))
1265  return POOL;
1266  if (!strcasecmp (atom + 1, "ool6"))
1267  return POOL6;
1268  if (!strcasecmp (atom + 1, "refix6"))
1269  return PREFIX6;
1270  if (!strcasecmp (atom + 1, "seudo"))
1271  return PSEUDO;
1272  if (!strcasecmp (atom + 1, "eer"))
1273  return PEER;
1274  if (!strcasecmp (atom + 1, "rimary"))
1275  return PRIMARY;
1276  if (!strcasecmp (atom + 1, "rimary6"))
1277  return PRIMARY6;
1278  if (!strncasecmp (atom + 1, "artner", 6)) {
1279  if (!atom [7])
1280  return PARTNER;
1281  if (!strcasecmp (atom + 7, "-down"))
1282  return PARTNER_DOWN;
1283  }
1284  if (!strcasecmp (atom + 1, "ort"))
1285  return PORT;
1286  if (!strcasecmp (atom + 1, "otential-conflict"))
1287  return POTENTIAL_CONFLICT;
1288  if (!strcasecmp (atom + 1, "ick-first-value") ||
1289  !strcasecmp (atom + 1, "ick"))
1290  return PICK;
1291  if (!strcasecmp (atom + 1, "aused"))
1292  return PAUSED;
1293  break;
1294  case 'r':
1295  if (!strcasecmp(atom + 1, "ange"))
1296  return RANGE;
1297  if (!strcasecmp(atom + 1, "ange6"))
1298  return RANGE6;
1299  if (isascii(atom[1]) &&
1300  (tolower((unsigned char)atom[1]) == 'e')) {
1301  if (!strcasecmp(atom + 2, "bind"))
1302  return REBIND;
1303  if (!strcasecmp(atom + 2, "boot"))
1304  return REBOOT;
1305  if (!strcasecmp(atom + 2, "contact-interval"))
1306  return RECONTACT_INTERVAL;
1307  if (!strncasecmp(atom + 2, "cover", 5)) {
1308  if (atom[7] == '\0')
1309  return RECOVER;
1310  if (!strcasecmp(atom + 7, "-done"))
1311  return RECOVER_DONE;
1312  if (!strcasecmp(atom + 7, "-wait"))
1313  return RECOVER_WAIT;
1314  break;
1315  }
1316  if (!strcasecmp(atom + 2, "fresh"))
1317  return REFRESH;
1318  if (!strcasecmp(atom + 2, "fused"))
1319  return NS_REFUSED;
1320  if (!strcasecmp(atom + 2, "ject"))
1321  return REJECT;
1322  if (!strcasecmp(atom + 2, "lease"))
1323  return RELEASE;
1324  if (!strcasecmp(atom + 2, "leased"))
1325  return TOKEN_RELEASED;
1326  if (!strcasecmp(atom + 2, "move"))
1327  return REMOVE;
1328  if (!strcasecmp(atom + 2, "new"))
1329  return RENEW;
1330  if (!strcasecmp(atom + 2, "quest"))
1331  return REQUEST;
1332  if (!strcasecmp(atom + 2, "quire"))
1333  return REQUIRE;
1334  if (isascii(atom[2]) &&
1335  (tolower((unsigned char)atom[2]) == 's')) {
1336  if (!strcasecmp(atom + 3, "erved"))
1337  return TOKEN_RESERVED;
1338  if (!strcasecmp(atom + 3, "et"))
1339  return TOKEN_RESET;
1340  if (!strcasecmp(atom + 3,
1341  "olution-interrupted"))
1342  return RESOLUTION_INTERRUPTED;
1343  break;
1344  }
1345  if (!strcasecmp(atom + 2, "try"))
1346  return RETRY;
1347  if (!strcasecmp(atom + 2, "turn"))
1348  return RETURN;
1349  if (!strcasecmp(atom + 2, "verse"))
1350  return REVERSE;
1351  if (!strcasecmp(atom + 2, "wind"))
1352  return REWIND;
1353  break;
1354  }
1355  break;
1356  case 's':
1357  if (!strcasecmp(atom + 1, "cript"))
1358  return SCRIPT;
1359  if (isascii(atom[1]) &&
1360  tolower((unsigned char)atom[1]) == 'e') {
1361  if (!strcasecmp(atom + 2, "arch"))
1362  return SEARCH;
1363  if (isascii(atom[2]) &&
1364  tolower((unsigned char)atom[2]) == 'c') {
1365  if (!strncasecmp(atom + 3, "ond", 3)) {
1366  if (!strcasecmp(atom + 6, "ary"))
1367  return SECONDARY;
1368  if (!strcasecmp(atom + 6, "ary6"))
1369  return SECONDARY6;
1370  if (!strcasecmp(atom + 6, "s"))
1371  return SECONDS;
1372  break;
1373  }
1374  if (!strcasecmp(atom + 3, "ret"))
1375  return SECRET;
1376  break;
1377  }
1378  if (!strncasecmp(atom + 2, "lect", 4)) {
1379  if (atom[6] == '\0')
1380  return SELECT;
1381  if (!strcasecmp(atom + 6, "-timeout"))
1382  return SELECT_TIMEOUT;
1383  break;
1384  }
1385  if (!strcasecmp(atom + 2, "nd"))
1386  return SEND;
1387  if (!strncasecmp(atom + 2, "rv", 2)) {
1388  if (!strncasecmp(atom + 4, "er", 2)) {
1389  if (atom[6] == '\0')
1390  return TOKEN_SERVER;
1391  if (atom[6] == '-') {
1392  if (!strcasecmp(atom + 7,
1393  "duid"))
1394  return SERVER_DUID;
1395  if (!strcasecmp(atom + 7,
1396  "name"))
1397  return SERVER_NAME;
1398  if (!strcasecmp(atom + 7,
1399  "identifier"))
1400  return SERVER_IDENTIFIER;
1401  break;
1402  }
1403  break;
1404  }
1405  if (!strcasecmp(atom + 4, "fail"))
1406  return NS_SERVFAIL;
1407  break;
1408  }
1409  if (!strcasecmp(atom + 2, "t"))
1410  return TOKEN_SET;
1411  break;
1412  }
1413  if (isascii(atom[1]) &&
1414  tolower((unsigned char)atom[1]) == 'h') {
1415  if (!strcasecmp(atom + 2, "ared-network"))
1416  return SHARED_NETWORK;
1417  if (!strcasecmp(atom + 2, "utdown"))
1418  return SHUTDOWN;
1419  break;
1420  }
1421  if (isascii(atom[1]) &&
1422  tolower((unsigned char)atom[1]) == 'i') {
1423  if (!strcasecmp(atom + 2, "addr"))
1424  return SIADDR;
1425  if (!strcasecmp(atom + 2, "gned"))
1426  return SIGNED;
1427  if (!strcasecmp(atom + 2, "ze"))
1428  return SIZE;
1429  break;
1430  }
1431  if (isascii(atom[1]) &&
1432  tolower((unsigned char)atom[1]) == 'p') {
1433  if (isascii(atom[2]) &&
1434  tolower((unsigned char)atom[2]) == 'a') {
1435  if (!strcasecmp(atom + 3, "ce"))
1436  return SPACE;
1437  if (!strcasecmp(atom + 3, "wn"))
1438  return SPAWN;
1439  break;
1440  }
1441  if (!strcasecmp(atom + 2, "lit"))
1442  return SPLIT;
1443  break;
1444  }
1445  if (isascii(atom[1]) &&
1446  tolower((unsigned char)atom[1]) == 't') {
1447  if (isascii(atom[2]) &&
1448  tolower((unsigned char)atom[2]) == 'a') {
1449  if(!strncasecmp(atom + 3, "rt", 2)) {
1450  if (!strcasecmp(atom + 5, "s"))
1451  return STARTS;
1452  if (!strcasecmp(atom + 5, "up"))
1453  return STARTUP;
1454  break;
1455  }
1456  if (isascii(atom[3]) &&
1457  tolower((unsigned char)atom[3]) == 't') {
1458  if (!strcasecmp(atom + 4, "e"))
1459  return STATE;
1460  if (!strcasecmp(atom + 4, "ic"))
1461  return STATIC;
1462  break;
1463  }
1464  }
1465  if (!strcasecmp(atom + 2, "ring"))
1466  return STRING_TOKEN;
1467  break;
1468  }
1469  if (!strncasecmp(atom + 1, "ub", 2)) {
1470  if (!strcasecmp(atom + 3, "class"))
1471  return SUBCLASS;
1472  if (!strcasecmp(atom + 3, "net"))
1473  return SUBNET;
1474  if (!strcasecmp(atom + 3, "net6"))
1475  return SUBNET6;
1476  if (!strcasecmp(atom + 3, "string"))
1477  return SUBSTRING;
1478  break;
1479  }
1480  if (isascii(atom[1]) &&
1481  tolower((unsigned char)atom[1]) == 'u') {
1482  if (!strcasecmp(atom + 2, "ffix"))
1483  return SUFFIX;
1484  if (!strcasecmp(atom + 2, "persede"))
1485  return SUPERSEDE;
1486  }
1487  if (!strcasecmp(atom + 1, "witch"))
1488  return SWITCH;
1489  break;
1490  case 't':
1491  if (!strcasecmp (atom + 1, "imestamp"))
1492  return TIMESTAMP;
1493  if (!strcasecmp (atom + 1, "imeout"))
1494  return TIMEOUT;
1495  if (!strcasecmp (atom + 1, "oken-ring"))
1496  return TOKEN_RING;
1497  if (!strcasecmp (atom + 1, "ext"))
1498  return TEXT;
1499  if (!strcasecmp (atom + 1, "stp"))
1500  return TSTP;
1501  if (!strcasecmp (atom + 1, "sfp"))
1502  return TSFP;
1503  if (!strcasecmp (atom + 1, "ransmission"))
1504  return TRANSMISSION;
1505  if (!strcasecmp(atom + 1, "emporary"))
1506  return TEMPORARY;
1507  break;
1508  case 'u':
1509  if (!strcasecmp (atom + 1, "case"))
1510  return UCASE;
1511  if (!strcasecmp (atom + 1, "nset"))
1512  return UNSET;
1513  if (!strcasecmp (atom + 1, "nsigned"))
1514  return UNSIGNED;
1515  if (!strcasecmp (atom + 1, "id"))
1516  return UID;
1517  if (!strncasecmp (atom + 1, "se", 2)) {
1518  if (!strcasecmp (atom + 3, "r-class"))
1519  return USER_CLASS;
1520  if (!strcasecmp (atom + 3, "-host-decl-names"))
1521  return USE_HOST_DECL_NAMES;
1522  if (!strcasecmp (atom + 3,
1523  "-lease-addr-for-default-route"))
1525  break;
1526  }
1527  if (!strncasecmp (atom + 1, "nknown", 6)) {
1528  if (!strcasecmp (atom + 7, "-clients"))
1529  return UNKNOWN_CLIENTS;
1530  if (!strcasecmp (atom + 7, "-state"))
1531  return UNKNOWN_STATE;
1532  if (!atom [7])
1533  return UNKNOWN;
1534  break;
1535  }
1536  if (!strcasecmp (atom + 1, "nauthenticated"))
1537  return UNAUTHENTICATED;
1538  if (!strcasecmp (atom + 1, "pdate"))
1539  return UPDATE;
1540  break;
1541  case 'v':
1542  if (!strcasecmp (atom + 1, "6relay"))
1543  return V6RELAY;
1544  if (!strcasecmp (atom + 1, "6relopt"))
1545  return V6RELOPT;
1546  if (!strcasecmp (atom + 1, "endor-class"))
1547  return VENDOR_CLASS;
1548  if (!strcasecmp (atom + 1, "endor"))
1549  return VENDOR;
1550  break;
1551  case 'w':
1552  if (!strcasecmp (atom + 1, "ith"))
1553  return WITH;
1554  if (!strcasecmp(atom + 1, "idth"))
1555  return WIDTH;
1556  break;
1557  case 'y':
1558  if (!strcasecmp (atom + 1, "iaddr"))
1559  return YIADDR;
1560  if (!strcasecmp (atom + 1, "xdomain"))
1561  return NS_YXDOMAIN;
1562  if (!strcasecmp (atom + 1, "xrrset"))
1563  return NS_YXRRSET;
1564  break;
1565  case 'z':
1566  if (!strcasecmp (atom + 1, "erolen"))
1567  return ZEROLEN;
1568  if (!strcasecmp (atom + 1, "one"))
1569  return ZONE;
1570  break;
1571  }
1572  return dfv;
1573 }
int line
Definition: dhcpd.h:317
const char int line
Definition: dhcpd.h:3802
Definition: dhctoken.h:146
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
Definition: conflex.c:41
Definition: data.h:205
#define ISC_FALSE
Definition: data.h:152
Definition: dhctoken.h:252
Definition: dhctoken.h:267
Definition: dhctoken.h:151
Definition: dhctoken.h:284
Definition: dhctoken.h:51
enum dhcp_token token
Definition: dhcpd.h:320
isc_boolean_t
Definition: data.h:150
size_t buflen
Definition: dhcpd.h:329
Definition: dhctoken.h:143
#define MDL
Definition: omapip.h:567
Definition: dhctoken.h:153
#define DHCP_R_NOTYET
Definition: result.h:50
int tlpos
Definition: dhcpd.h:318
Definition: dhctoken.h:235
char * cur_line
Definition: dhcpd.h:293
dhcp_token
Definition: dhctoken.h:34
int lpos
Definition: dhcpd.h:316
enum dhcp_token next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:380
Definition: dhctoken.h:207
Definition: dhctoken.h:137
Definition: dhctoken.h:75
Definition: dhctoken.h:229
char * tval
Definition: dhcpd.h:322
isc_result_t restore_parse_state(struct parse *cfile)
Definition: conflex.c:159
Definition: dhctoken.h:224
int lexchar
Definition: dhcrelay.c:52
struct parse * saved_state
Definition: dhcpd.h:332
Definition: dhctoken.h:259
Definition: dhcpd.h:288
int eol_token
Definition: dhcpd.h:295
void log_fatal(const char *,...) __attribute__((__format__(__printf__
Definition: dhctoken.h:251
Definition: dhctoken.h:159
#define ISC_TRUE
Definition: data.h:153
Definition: dhctoken.h:74
Definition: dhctoken.h:349
enum dhcp_token peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:454
Definition: dhctoken.h:222
Definition: dhctoken.h:173
Definition: dhctoken.h:59
Definition: dhctoken.h:76
int tline
Definition: dhcpd.h:319
Definition: dhctoken.h:280
void dfree(void *, const char *, int)
Definition: alloc.c:145
int tlen
Definition: dhcpd.h:323
isc_result_t save_parse_state(struct parse *cfile)
Definition: conflex.c:128
Definition: dhctoken.h:256
Definition: dhctoken.h:73
Definition: dhctoken.h:204
Definition: dhctoken.h:225
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
Definition: dhctoken.h:321
#define ISC_R_SUCCESS
void cleanup(void)
Definition: dhctoken.h:255
char line2[81]
Definition: dhcpd.h:315
Definition: dhctoken.h:138
char tokbuf[1500]
Definition: dhcpd.h:324
Definition: dhctoken.h:221
Definition: dhctoken.h:348
#define EOL
Definition: dhcpd.h:88
Definition: dhctoken.h:101
Definition: dhctoken.h:69
size_t bufsiz
Definition: dhcpd.h:330
const char * tlname
Definition: dhcpd.h:294
isc_result_t end_parse(struct parse **cfile)
Definition: conflex.c:103
Definition: dhctoken.h:350
Definition: dhctoken.h:168
size_t bufix
Definition: dhcpd.h:329
int parse_warn(struct parse *cfile, const char *fmt,...)
Definition: parse.c:5643
char * inbuf
Definition: dhcpd.h:328
Definition: dhctoken.h:227
Definition: dhctoken.h:322
Definition: dhctoken.h:97
Definition: dhctoken.h:72
enum dhcp_token next_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:369
int ugflag
Definition: dhcpd.h:321
const char * file
Definition: dhcpd.h:3802
char * name
Definition: dhcpd.h:1060
char * token_line
Definition: dhcpd.h:291
Definition: dhctoken.h:166
char line1[81]
Definition: dhcpd.h:314
int lexline
Definition: dhcrelay.c:51
Definition: dhctoken.h:189
enum dhcp_token do_peek_token(const char **rval, unsigned int *rlen, struct parse *cfile, isc_boolean_t raw)
Definition: conflex.c:395
Definition: dhctoken.h:196
char * token_line
Definition: dhcrelay.c:53
char * prev_line
Definition: dhcpd.h:292
Definition: dhctoken.h:115
int file
Definition: dhcpd.h:327
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:443
Definition: dhctoken.h:162