ISC DHCP  4.3.2
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) - 1)) {
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  /* do-forward-update is included for historical reasons */
896  if (!strcasecmp (atom + 1, "o-forward-update"))
897  return DO_FORWARD_UPDATE;
898  if (!strcasecmp (atom + 1, "ebug"))
899  return TOKEN_DEBUG;
900  if (!strcasecmp (atom + 1, "eny"))
901  return DENY;
902  if (!strcasecmp (atom + 1, "eleted"))
903  return TOKEN_DELETED;
904  if (!strcasecmp (atom + 1, "elete"))
905  return TOKEN_DELETE;
906  if (!strncasecmp (atom + 1, "efault", 6)) {
907  if (!atom [7])
908  return DEFAULT;
909  if (!strcasecmp(atom + 7, "-duid"))
910  return DEFAULT_DUID;
911  if (!strcasecmp (atom + 7, "-lease-time"))
912  return DEFAULT_LEASE_TIME;
913  break;
914  }
915  if (!strncasecmp (atom + 1, "ynamic", 6)) {
916  if (!atom [7])
917  return DYNAMIC;
918  if (!strncasecmp (atom + 7, "-bootp", 6)) {
919  if (!atom [13])
920  return DYNAMIC_BOOTP;
921  if (!strcasecmp (atom + 13, "-lease-cutoff"))
923  if (!strcasecmp (atom + 13, "-lease-length"))
925  break;
926  }
927  }
928  if (!strcasecmp (atom + 1, "uplicates"))
929  return DUPLICATES;
930  if (!strcasecmp (atom + 1, "eclines"))
931  return DECLINES;
932  if (!strncasecmp (atom + 1, "efine", 5)) {
933  if (!strcasecmp (atom + 6, "d"))
934  return DEFINED;
935  if (!atom [6])
936  return DEFINE;
937  }
938  break;
939  case 'e':
940  if (isascii (atom [1]) &&
941  tolower((unsigned char)atom[1]) == 'x') {
942  if (!strcasecmp (atom + 2, "tract-int"))
943  return EXTRACT_INT;
944  if (!strcasecmp (atom + 2, "ists"))
945  return EXISTS;
946  if (!strcasecmp (atom + 2, "piry"))
947  return EXPIRY;
948  if (!strcasecmp (atom + 2, "pire"))
949  return EXPIRE;
950  if (!strcasecmp (atom + 2, "pired"))
951  return TOKEN_EXPIRED;
952  }
953  if (!strcasecmp (atom + 1, "ncode-int"))
954  return ENCODE_INT;
955  if (!strcasecmp(atom + 1, "poch"))
956  return EPOCH;
957  if (!strcasecmp (atom + 1, "thernet"))
958  return ETHERNET;
959  if (!strcasecmp (atom + 1, "nds"))
960  return ENDS;
961  if (!strncasecmp (atom + 1, "ls", 2)) {
962  if (!strcasecmp (atom + 3, "e"))
963  return ELSE;
964  if (!strcasecmp (atom + 3, "if"))
965  return ELSIF;
966  break;
967  }
968  if (!strcasecmp (atom + 1, "rror"))
969  return ERROR;
970  if (!strcasecmp (atom + 1, "val"))
971  return EVAL;
972  if (!strcasecmp (atom + 1, "ncapsulate"))
973  return ENCAPSULATE;
974  if (!strcasecmp(atom + 1, "xecute"))
975  return EXECUTE;
976  if (!strcasecmp(atom+1, "n")) {
977  return EN;
978  }
979  break;
980  case 'f':
981  if (!strcasecmp (atom + 1, "atal"))
982  return FATAL;
983  if (!strcasecmp (atom + 1, "ilename"))
984  return FILENAME;
985  if (!strcasecmp (atom + 1, "ixed-address"))
986  return FIXED_ADDR;
987  if (!strcasecmp (atom + 1, "ixed-address6"))
988  return FIXED_ADDR6;
989  if (!strcasecmp (atom + 1, "ixed-prefix6"))
990  return FIXED_PREFIX6;
991  if (!strcasecmp (atom + 1, "ddi"))
992  return TOKEN_FDDI;
993  if (!strcasecmp (atom + 1, "ormerr"))
994  return NS_FORMERR;
995  if (!strcasecmp (atom + 1, "unction"))
996  return FUNCTION;
997  if (!strcasecmp (atom + 1, "ailover"))
998  return FAILOVER;
999  if (!strcasecmp (atom + 1, "ree"))
1000  return TOKEN_FREE;
1001  break;
1002  case 'g':
1003  if (!strncasecmp(atom + 1, "et", 2)) {
1004  if (!strcasecmp(atom + 3, "-lease-hostnames"))
1005  return GET_LEASE_HOSTNAMES;
1006  if (!strcasecmp(atom + 3, "hostbyname"))
1007  return GETHOSTBYNAME;
1008  if (!strcasecmp(atom + 3, "hostname"))
1009  return GETHOSTNAME;
1010  break;
1011  }
1012  if (!strcasecmp (atom + 1, "iaddr"))
1013  return GIADDR;
1014  if (!strcasecmp (atom + 1, "roup"))
1015  return GROUP;
1016  break;
1017  case 'h':
1018  if (!strcasecmp(atom + 1, "ash"))
1019  return HASH;
1020  if (!strcasecmp (atom + 1, "ba"))
1021  return HBA;
1022  if (!strcasecmp (atom + 1, "ost"))
1023  return HOST;
1024  if (!strcasecmp (atom + 1, "ost-decl-name"))
1025  return HOST_DECL_NAME;
1026  if (!strcasecmp(atom + 1, "ost-identifier"))
1027  return HOST_IDENTIFIER;
1028  if (!strcasecmp (atom + 1, "ardware"))
1029  return HARDWARE;
1030  if (!strcasecmp (atom + 1, "ostname"))
1031  return HOSTNAME;
1032  if (!strcasecmp (atom + 1, "elp"))
1033  return TOKEN_HELP;
1034  break;
1035  case 'i':
1036  if (!strcasecmp(atom+1, "a-na"))
1037  return IA_NA;
1038  if (!strcasecmp(atom+1, "a-ta"))
1039  return IA_TA;
1040  if (!strcasecmp(atom+1, "a-pd"))
1041  return IA_PD;
1042  if (!strcasecmp(atom+1, "aaddr"))
1043  return IAADDR;
1044  if (!strcasecmp(atom+1, "aprefix"))
1045  return IAPREFIX;
1046  if (!strcasecmp (atom + 1, "nclude"))
1047  return INCLUDE;
1048  if (!strcasecmp (atom + 1, "nteger"))
1049  return INTEGER;
1050  if (!strcasecmp (atom + 1, "nfiniband"))
1051  return TOKEN_INFINIBAND;
1052  if (!strcasecmp (atom + 1, "nfinite"))
1053  return INFINITE;
1054  if (!strcasecmp (atom + 1, "nfo"))
1055  return INFO;
1056  if (!strcasecmp (atom + 1, "p-address"))
1057  return IP_ADDRESS;
1058  if (!strcasecmp (atom + 1, "p6-address"))
1059  return IP6_ADDRESS;
1060  if (!strcasecmp (atom + 1, "nitial-interval"))
1061  return INITIAL_INTERVAL;
1062  if (!strcasecmp (atom + 1, "nitial-delay"))
1063  return INITIAL_DELAY;
1064  if (!strcasecmp (atom + 1, "nterface"))
1065  return INTERFACE;
1066  if (!strcasecmp (atom + 1, "dentifier"))
1067  return IDENTIFIER;
1068  if (!strcasecmp (atom + 1, "f"))
1069  return IF;
1070  if (!strcasecmp (atom + 1, "s"))
1071  return IS;
1072  if (!strcasecmp (atom + 1, "gnore"))
1073  return IGNORE;
1074  break;
1075  case 'k':
1076  if (!strncasecmp (atom + 1, "nown", 4)) {
1077  if (!strcasecmp (atom + 5, "-clients"))
1078  return KNOWN_CLIENTS;
1079  if (!atom[5])
1080  return KNOWN;
1081  break;
1082  }
1083  if (!strcasecmp (atom + 1, "ey"))
1084  return KEY;
1085  break;
1086  case 'l':
1087  if (!strcasecmp (atom + 1, "case"))
1088  return LCASE;
1089  if (!strcasecmp (atom + 1, "ease"))
1090  return LEASE;
1091  if (!strcasecmp(atom + 1, "ease6"))
1092  return LEASE6;
1093  if (!strcasecmp (atom + 1, "eased-address"))
1094  return LEASED_ADDRESS;
1095  if (!strcasecmp (atom + 1, "ease-time"))
1096  return LEASE_TIME;
1097  if (!strcasecmp(atom + 1, "easequery"))
1098  return LEASEQUERY;
1099  if (!strcasecmp(atom + 1, "ength"))
1100  return LENGTH;
1101  if (!strcasecmp (atom + 1, "imit"))
1102  return LIMIT;
1103  if (!strcasecmp (atom + 1, "et"))
1104  return LET;
1105  if (!strcasecmp (atom + 1, "oad"))
1106  return LOAD;
1107  if (!strcasecmp(atom + 1, "ocal"))
1108  return LOCAL;
1109  if (!strcasecmp (atom + 1, "og"))
1110  return LOG;
1111  if (!strcasecmp(atom+1, "lt")) {
1112  return LLT;
1113  }
1114  if (!strcasecmp(atom+1, "l")) {
1115  return LL;
1116  }
1117  break;
1118  case 'm':
1119  if (!strncasecmp (atom + 1, "ax", 2)) {
1120  if (!atom [3])
1121  return TOKEN_MAX;
1122  if (!strcasecmp (atom + 3, "-balance"))
1123  return MAX_BALANCE;
1124  if (!strncasecmp (atom + 3, "-lease-", 7)) {
1125  if (!strcasecmp(atom + 10, "misbalance"))
1126  return MAX_LEASE_MISBALANCE;
1127  if (!strcasecmp(atom + 10, "ownership"))
1128  return MAX_LEASE_OWNERSHIP;
1129  if (!strcasecmp(atom + 10, "time"))
1130  return MAX_LEASE_TIME;
1131  }
1132  if (!strcasecmp(atom + 3, "-life"))
1133  return MAX_LIFE;
1134  if (!strcasecmp (atom + 3, "-transmit-idle"))
1135  return MAX_TRANSMIT_IDLE;
1136  if (!strcasecmp (atom + 3, "-response-delay"))
1137  return MAX_RESPONSE_DELAY;
1138  if (!strcasecmp (atom + 3, "-unacked-updates"))
1139  return MAX_UNACKED_UPDATES;
1140  }
1141  if (!strncasecmp (atom + 1, "in-", 3)) {
1142  if (!strcasecmp (atom + 4, "balance"))
1143  return MIN_BALANCE;
1144  if (!strcasecmp (atom + 4, "lease-time"))
1145  return MIN_LEASE_TIME;
1146  if (!strcasecmp (atom + 4, "secs"))
1147  return MIN_SECS;
1148  break;
1149  }
1150  if (!strncasecmp (atom + 1, "edi", 3)) {
1151  if (!strcasecmp (atom + 4, "a"))
1152  return MEDIA;
1153  if (!strcasecmp (atom + 4, "um"))
1154  return MEDIUM;
1155  break;
1156  }
1157  if (!strcasecmp (atom + 1, "atch"))
1158  return MATCH;
1159  if (!strcasecmp (atom + 1, "embers"))
1160  return MEMBERS;
1161  if (!strcasecmp (atom + 1, "y"))
1162  return MY;
1163  if (!strcasecmp (atom + 1, "clt"))
1164  return MCLT;
1165  break;
1166  case 'n':
1167  if (!strcasecmp (atom + 1, "ormal"))
1168  return NORMAL;
1169  if (!strcasecmp (atom + 1, "ameserver"))
1170  return NAMESERVER;
1171  if (!strcasecmp (atom + 1, "etmask"))
1172  return NETMASK;
1173  if (!strcasecmp (atom + 1, "ever"))
1174  return NEVER;
1175  if (!strcasecmp (atom + 1, "ext-server"))
1176  return NEXT_SERVER;
1177  if (!strcasecmp (atom + 1, "ot"))
1178  return TOKEN_NOT;
1179  if (!strcasecmp (atom + 1, "o"))
1180  return TOKEN_NO;
1181  if (!strcasecmp (atom + 1, "oerror"))
1182  return NS_NOERROR;
1183  if (!strcasecmp (atom + 1, "otauth"))
1184  return NS_NOTAUTH;
1185  if (!strcasecmp (atom + 1, "otimp"))
1186  return NS_NOTIMP;
1187  if (!strcasecmp (atom + 1, "otzone"))
1188  return NS_NOTZONE;
1189  if (!strcasecmp (atom + 1, "xdomain"))
1190  return NS_NXDOMAIN;
1191  if (!strcasecmp (atom + 1, "xrrset"))
1192  return NS_NXRRSET;
1193  if (!strcasecmp (atom + 1, "ull"))
1194  return TOKEN_NULL;
1195  if (!strcasecmp (atom + 1, "ext"))
1196  return TOKEN_NEXT;
1197  if (!strcasecmp (atom + 1, "ew"))
1198  return TOKEN_NEW;
1199  break;
1200  case 'o':
1201  if (!strcasecmp (atom + 1, "mapi"))
1202  return OMAPI;
1203  if (!strcasecmp (atom + 1, "r"))
1204  return OR;
1205  if (!strcasecmp (atom + 1, "n"))
1206  return ON;
1207  if (!strcasecmp (atom + 1, "pen"))
1208  return TOKEN_OPEN;
1209  if (!strcasecmp (atom + 1, "ption"))
1210  return OPTION;
1211  if (!strcasecmp (atom + 1, "ne-lease-per-client"))
1212  return ONE_LEASE_PER_CLIENT;
1213  if (!strcasecmp (atom + 1, "f"))
1214  return OF;
1215  if (!strcasecmp (atom + 1, "wner"))
1216  return OWNER;
1217  break;
1218  case 'p':
1219  if (!strcasecmp (atom + 1, "repend"))
1220  return PREPEND;
1221  if (!strcasecmp(atom + 1, "referred-life"))
1222  return PREFERRED_LIFE;
1223  if (!strcasecmp (atom + 1, "acket"))
1224  return PACKET;
1225  if (!strcasecmp (atom + 1, "ool"))
1226  return POOL;
1227  if (!strcasecmp (atom + 1, "ool6"))
1228  return POOL6;
1229  if (!strcasecmp (atom + 1, "refix6"))
1230  return PREFIX6;
1231  if (!strcasecmp (atom + 1, "seudo"))
1232  return PSEUDO;
1233  if (!strcasecmp (atom + 1, "eer"))
1234  return PEER;
1235  if (!strcasecmp (atom + 1, "rimary"))
1236  return PRIMARY;
1237  if (!strcasecmp (atom + 1, "rimary6"))
1238  return PRIMARY6;
1239  if (!strncasecmp (atom + 1, "artner", 6)) {
1240  if (!atom [7])
1241  return PARTNER;
1242  if (!strcasecmp (atom + 7, "-down"))
1243  return PARTNER_DOWN;
1244  }
1245  if (!strcasecmp (atom + 1, "ort"))
1246  return PORT;
1247  if (!strcasecmp (atom + 1, "otential-conflict"))
1248  return POTENTIAL_CONFLICT;
1249  if (!strcasecmp (atom + 1, "ick-first-value") ||
1250  !strcasecmp (atom + 1, "ick"))
1251  return PICK;
1252  if (!strcasecmp (atom + 1, "aused"))
1253  return PAUSED;
1254  break;
1255  case 'r':
1256  if (!strcasecmp(atom + 1, "ange"))
1257  return RANGE;
1258  if (!strcasecmp(atom + 1, "ange6"))
1259  return RANGE6;
1260  if (isascii(atom[1]) &&
1261  (tolower((unsigned char)atom[1]) == 'e')) {
1262  if (!strcasecmp(atom + 2, "bind"))
1263  return REBIND;
1264  if (!strcasecmp(atom + 2, "boot"))
1265  return REBOOT;
1266  if (!strcasecmp(atom + 2, "contact-interval"))
1267  return RECONTACT_INTERVAL;
1268  if (!strncasecmp(atom + 2, "cover", 5)) {
1269  if (atom[7] == '\0')
1270  return RECOVER;
1271  if (!strcasecmp(atom + 7, "-done"))
1272  return RECOVER_DONE;
1273  if (!strcasecmp(atom + 7, "-wait"))
1274  return RECOVER_WAIT;
1275  break;
1276  }
1277  if (!strcasecmp(atom + 2, "fresh"))
1278  return REFRESH;
1279  if (!strcasecmp(atom + 2, "fused"))
1280  return NS_REFUSED;
1281  if (!strcasecmp(atom + 2, "ject"))
1282  return REJECT;
1283  if (!strcasecmp(atom + 2, "lease"))
1284  return RELEASE;
1285  if (!strcasecmp(atom + 2, "leased"))
1286  return TOKEN_RELEASED;
1287  if (!strcasecmp(atom + 2, "move"))
1288  return REMOVE;
1289  if (!strcasecmp(atom + 2, "new"))
1290  return RENEW;
1291  if (!strcasecmp(atom + 2, "quest"))
1292  return REQUEST;
1293  if (!strcasecmp(atom + 2, "quire"))
1294  return REQUIRE;
1295  if (isascii(atom[2]) &&
1296  (tolower((unsigned char)atom[2]) == 's')) {
1297  if (!strcasecmp(atom + 3, "erved"))
1298  return TOKEN_RESERVED;
1299  if (!strcasecmp(atom + 3, "et"))
1300  return TOKEN_RESET;
1301  if (!strcasecmp(atom + 3,
1302  "olution-interrupted"))
1303  return RESOLUTION_INTERRUPTED;
1304  break;
1305  }
1306  if (!strcasecmp(atom + 2, "try"))
1307  return RETRY;
1308  if (!strcasecmp(atom + 2, "turn"))
1309  return RETURN;
1310  if (!strcasecmp(atom + 2, "verse"))
1311  return REVERSE;
1312  if (!strcasecmp(atom + 2, "wind"))
1313  return REWIND;
1314  break;
1315  }
1316  break;
1317  case 's':
1318  if (!strcasecmp(atom + 1, "cript"))
1319  return SCRIPT;
1320  if (isascii(atom[1]) &&
1321  tolower((unsigned char)atom[1]) == 'e') {
1322  if (!strcasecmp(atom + 2, "arch"))
1323  return SEARCH;
1324  if (isascii(atom[2]) &&
1325  tolower((unsigned char)atom[2]) == 'c') {
1326  if (!strncasecmp(atom + 3, "ond", 3)) {
1327  if (!strcasecmp(atom + 6, "ary"))
1328  return SECONDARY;
1329  if (!strcasecmp(atom + 6, "ary6"))
1330  return SECONDARY6;
1331  if (!strcasecmp(atom + 6, "s"))
1332  return SECONDS;
1333  break;
1334  }
1335  if (!strcasecmp(atom + 3, "ret"))
1336  return SECRET;
1337  break;
1338  }
1339  if (!strncasecmp(atom + 2, "lect", 4)) {
1340  if (atom[6] == '\0')
1341  return SELECT;
1342  if (!strcasecmp(atom + 6, "-timeout"))
1343  return SELECT_TIMEOUT;
1344  break;
1345  }
1346  if (!strcasecmp(atom + 2, "nd"))
1347  return SEND;
1348  if (!strncasecmp(atom + 2, "rv", 2)) {
1349  if (!strncasecmp(atom + 4, "er", 2)) {
1350  if (atom[6] == '\0')
1351  return TOKEN_SERVER;
1352  if (atom[6] == '-') {
1353  if (!strcasecmp(atom + 7,
1354  "duid"))
1355  return SERVER_DUID;
1356  if (!strcasecmp(atom + 7,
1357  "name"))
1358  return SERVER_NAME;
1359  if (!strcasecmp(atom + 7,
1360  "identifier"))
1361  return SERVER_IDENTIFIER;
1362  break;
1363  }
1364  break;
1365  }
1366  if (!strcasecmp(atom + 4, "fail"))
1367  return NS_SERVFAIL;
1368  break;
1369  }
1370  if (!strcasecmp(atom + 2, "t"))
1371  return TOKEN_SET;
1372  break;
1373  }
1374  if (isascii(atom[1]) &&
1375  tolower((unsigned char)atom[1]) == 'h') {
1376  if (!strcasecmp(atom + 2, "ared-network"))
1377  return SHARED_NETWORK;
1378  if (!strcasecmp(atom + 2, "utdown"))
1379  return SHUTDOWN;
1380  break;
1381  }
1382  if (isascii(atom[1]) &&
1383  tolower((unsigned char)atom[1]) == 'i') {
1384  if (!strcasecmp(atom + 2, "addr"))
1385  return SIADDR;
1386  if (!strcasecmp(atom + 2, "gned"))
1387  return SIGNED;
1388  if (!strcasecmp(atom + 2, "ze"))
1389  return SIZE;
1390  break;
1391  }
1392  if (isascii(atom[1]) &&
1393  tolower((unsigned char)atom[1]) == 'p') {
1394  if (isascii(atom[2]) &&
1395  tolower((unsigned char)atom[2]) == 'a') {
1396  if (!strcasecmp(atom + 3, "ce"))
1397  return SPACE;
1398  if (!strcasecmp(atom + 3, "wn"))
1399  return SPAWN;
1400  break;
1401  }
1402  if (!strcasecmp(atom + 2, "lit"))
1403  return SPLIT;
1404  break;
1405  }
1406  if (isascii(atom[1]) &&
1407  tolower((unsigned char)atom[1]) == 't') {
1408  if (isascii(atom[2]) &&
1409  tolower((unsigned char)atom[2]) == 'a') {
1410  if(!strncasecmp(atom + 3, "rt", 2)) {
1411  if (!strcasecmp(atom + 5, "s"))
1412  return STARTS;
1413  if (!strcasecmp(atom + 5, "up"))
1414  return STARTUP;
1415  break;
1416  }
1417  if (isascii(atom[3]) &&
1418  tolower((unsigned char)atom[3]) == 't') {
1419  if (!strcasecmp(atom + 4, "e"))
1420  return STATE;
1421  if (!strcasecmp(atom + 4, "ic"))
1422  return STATIC;
1423  break;
1424  }
1425  }
1426  if (!strcasecmp(atom + 2, "ring"))
1427  return STRING_TOKEN;
1428  break;
1429  }
1430  if (!strncasecmp(atom + 1, "ub", 2)) {
1431  if (!strcasecmp(atom + 3, "class"))
1432  return SUBCLASS;
1433  if (!strcasecmp(atom + 3, "net"))
1434  return SUBNET;
1435  if (!strcasecmp(atom + 3, "net6"))
1436  return SUBNET6;
1437  if (!strcasecmp(atom + 3, "string"))
1438  return SUBSTRING;
1439  break;
1440  }
1441  if (isascii(atom[1]) &&
1442  tolower((unsigned char)atom[1]) == 'u') {
1443  if (!strcasecmp(atom + 2, "ffix"))
1444  return SUFFIX;
1445  if (!strcasecmp(atom + 2, "persede"))
1446  return SUPERSEDE;
1447  }
1448  if (!strcasecmp(atom + 1, "witch"))
1449  return SWITCH;
1450  break;
1451  case 't':
1452  if (!strcasecmp (atom + 1, "imestamp"))
1453  return TIMESTAMP;
1454  if (!strcasecmp (atom + 1, "imeout"))
1455  return TIMEOUT;
1456  if (!strcasecmp (atom + 1, "oken-ring"))
1457  return TOKEN_RING;
1458  if (!strcasecmp (atom + 1, "ext"))
1459  return TEXT;
1460  if (!strcasecmp (atom + 1, "stp"))
1461  return TSTP;
1462  if (!strcasecmp (atom + 1, "sfp"))
1463  return TSFP;
1464  if (!strcasecmp (atom + 1, "ransmission"))
1465  return TRANSMISSION;
1466  if (!strcasecmp(atom + 1, "emporary"))
1467  return TEMPORARY;
1468  break;
1469  case 'u':
1470  if (!strcasecmp (atom + 1, "case"))
1471  return UCASE;
1472  if (!strcasecmp (atom + 1, "nset"))
1473  return UNSET;
1474  if (!strcasecmp (atom + 1, "nsigned"))
1475  return UNSIGNED;
1476  if (!strcasecmp (atom + 1, "id"))
1477  return UID;
1478  if (!strncasecmp (atom + 1, "se", 2)) {
1479  if (!strcasecmp (atom + 3, "r-class"))
1480  return USER_CLASS;
1481  if (!strcasecmp (atom + 3, "-host-decl-names"))
1482  return USE_HOST_DECL_NAMES;
1483  if (!strcasecmp (atom + 3,
1484  "-lease-addr-for-default-route"))
1486  break;
1487  }
1488  if (!strncasecmp (atom + 1, "nknown", 6)) {
1489  if (!strcasecmp (atom + 7, "-clients"))
1490  return UNKNOWN_CLIENTS;
1491  if (!strcasecmp (atom + 7, "-state"))
1492  return UNKNOWN_STATE;
1493  if (!atom [7])
1494  return UNKNOWN;
1495  break;
1496  }
1497  if (!strcasecmp (atom + 1, "nauthenticated"))
1498  return UNAUTHENTICATED;
1499  if (!strcasecmp (atom + 1, "pdate"))
1500  return UPDATE;
1501  break;
1502  case 'v':
1503  if (!strcasecmp (atom + 1, "6relay"))
1504  return V6RELAY;
1505  if (!strcasecmp (atom + 1, "6relopt"))
1506  return V6RELOPT;
1507  if (!strcasecmp (atom + 1, "endor-class"))
1508  return VENDOR_CLASS;
1509  if (!strcasecmp (atom + 1, "endor"))
1510  return VENDOR;
1511  break;
1512  case 'w':
1513  if (!strcasecmp (atom + 1, "ith"))
1514  return WITH;
1515  if (!strcasecmp(atom + 1, "idth"))
1516  return WIDTH;
1517  break;
1518  case 'y':
1519  if (!strcasecmp (atom + 1, "iaddr"))
1520  return YIADDR;
1521  if (!strcasecmp (atom + 1, "xdomain"))
1522  return NS_YXDOMAIN;
1523  if (!strcasecmp (atom + 1, "xrrset"))
1524  return NS_YXRRSET;
1525  break;
1526  case 'z':
1527  if (!strcasecmp (atom + 1, "erolen"))
1528  return ZEROLEN;
1529  if (!strcasecmp (atom + 1, "one"))
1530  return ZONE;
1531  break;
1532  }
1533  return dfv;
1534 }
1535 
Definition: dhctoken.h:100
Definition: dhctoken.h:96
Definition: dhctoken.h:266
const char int line
Definition: dhcpd.h:3615
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:291
Definition: dhctoken.h:71
size_t buflen
Definition: dhcpd.h:300
#define MDL
Definition: omapip.h:568
#define DHCP_R_NOTYET
Definition: result.h:49
int tlpos
Definition: dhcpd.h:289
Definition: dhctoken.h:152
Definition: dhctoken.h:137
Definition: dhctoken.h:349
int lpos
Definition: dhcpd.h:287
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:265
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:303
enum dhcp_token peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:440
Definition: dhcpd.h:259
int eol_token
Definition: dhcpd.h:266
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:290
Definition: dhctoken.h:221
Definition: dhctoken.h:228
void dfree(void *, const char *, int)
Definition: alloc.c:131
int tlen
Definition: dhcpd.h:294
Definition: dhctoken.h:223
Definition: dhctoken.h:348
Definition: dhctoken.h:188
Definition: dhctoken.h:203
char line1[81]
Definition: dhcpd.h:285
void cleanup(void)
char * token_line
Definition: dhcpd.h:262
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:263
Definition: dhctoken.h:347
Definition: dhctoken.h:167
size_t bufsiz
Definition: dhcpd.h:301
const char int
Definition: omapip.h:443
size_t bufix
Definition: dhcpd.h:300
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:286
Definition: dhctoken.h:226
Definition: dhctoken.h:206
int ugflag
Definition: dhcpd.h:292
char * cur_line
Definition: dhcpd.h:264
Definition: dhctoken.h:74
Definition: dhctoken.h:145
const char * file
Definition: dhcpd.h:3615
char * name
Definition: dhcpd.h:970
Definition: dhctoken.h:254
char * inbuf
Definition: dhcpd.h:299
char tokbuf[1500]
Definition: dhcpd.h:295
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:5591
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:293
int file
Definition: dhcpd.h:298
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