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