ISC DHCP  4.3.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-2015 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() 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));
172  dfree(saved_state, MDL);
173  cfile->saved_state = NULL;
174 
175 #if defined(LDAP_CONFIGURATION)
176  cfile->inbuf = inbuf;
177  cfile->bufsiz = size;
178 #endif
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)) {
643  token = NUMBER_OR_NAME;
644  break;
645  }
646  /* FALLTHROUGH */
647  case NAME:
648  if((i == 2) && isxdigit(c) &&
649  (cfile->tokbuf[0] == '0') &&
650  ((cfile->tokbuf[1] == 'x') ||
651  (cfile->tokbuf[1] == 'X'))) {
652  token = NUMBER_OR_NAME;
653  break;
654  } else if(((c == '-') || (c == '_') || isalnum(c))) {
655  token = NAME;
656  break;
657  }
658  /* FALLTHROUGH */
659  case BREAK:
660  /* At this point c is either EOF or part of the next
661  * token. If not EOF, rewind the file one byte so
662  * the next token is read from there.
663  */
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 (!strncasecmp(atom + 1, "ut", 2)) {
787  if (isascii(atom[3]) &&
788  (tolower((unsigned char)atom[3]) == 'h')) {
789  if (!strncasecmp(atom + 4, "enticat", 7)) {
790  if (!strcasecmp(atom + 11, "ed"))
791  return AUTHENTICATED;
792  if (!strcasecmp(atom + 11, "ion"))
793  return AUTHENTICATION;
794  break;
795  }
796  if (!strcasecmp(atom + 4, "oritative"))
797  return AUTHORITATIVE;
798  break;
799  }
800  if (!strcasecmp(atom + 3, "o-partner-down"))
801  return AUTO_PARTNER_DOWN;
802  break;
803  }
804  break;
805  case 'b':
806  if (!strcasecmp (atom + 1, "ackup"))
807  return TOKEN_BACKUP;
808  if (!strcasecmp (atom + 1, "ootp"))
809  return TOKEN_BOOTP;
810  if (!strcasecmp (atom + 1, "inding"))
811  return BINDING;
812  if (!strcasecmp (atom + 1, "inary-to-ascii"))
813  return BINARY_TO_ASCII;
814  if (!strcasecmp (atom + 1, "ackoff-cutoff"))
815  return BACKOFF_CUTOFF;
816  if (!strcasecmp (atom + 1, "ooting"))
817  return BOOTING;
818  if (!strcasecmp (atom + 1, "oot-unknown-clients"))
819  return BOOT_UNKNOWN_CLIENTS;
820  if (!strcasecmp (atom + 1, "reak"))
821  return BREAK;
822  if (!strcasecmp (atom + 1, "illing"))
823  return BILLING;
824  if (!strcasecmp (atom + 1, "oolean"))
825  return BOOLEAN;
826  if (!strcasecmp (atom + 1, "alance"))
827  return BALANCE;
828  if (!strcasecmp (atom + 1, "ound"))
829  return BOUND;
830  if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
831  return BOOTP_BROADCAST_ALWAYS;
832  break;
833  case 'c':
834  if (!strcasecmp(atom + 1, "ase"))
835  return CASE;
836  if (!strcasecmp(atom + 1, "heck"))
837  return CHECK;
838  if (!strcasecmp(atom + 1, "iaddr"))
839  return CIADDR;
840  if (isascii(atom[1]) &&
841  tolower((unsigned char)atom[1]) == 'l') {
842  if (!strcasecmp(atom + 2, "ass"))
843  return CLASS;
844  if (!strncasecmp(atom + 2, "ient", 4)) {
845  if (!strcasecmp(atom + 6, "s"))
846  return CLIENTS;
847  if (atom[6] == '-') {
848  if (!strcasecmp(atom + 7, "hostname"))
849  return CLIENT_HOSTNAME;
850  if (!strcasecmp(atom + 7, "identifier"))
851  return CLIENT_IDENTIFIER;
852  if (!strcasecmp(atom + 7, "state"))
853  return CLIENT_STATE;
854  if (!strcasecmp(atom + 7, "updates"))
855  return CLIENT_UPDATES;
856  break;
857  }
858  break;
859  }
860  if (!strcasecmp(atom + 2, "ose"))
861  return TOKEN_CLOSE;
862  if (!strcasecmp(atom + 2, "tt"))
863  return CLTT;
864  break;
865  }
866  if (isascii(atom[1]) &&
867  tolower((unsigned char)atom[1]) == 'o') {
868  if (!strcasecmp(atom + 2, "de"))
869  return CODE;
870  if (isascii(atom[2]) &&
871  tolower((unsigned char)atom[2]) == 'm') {
872  if (!strcasecmp(atom + 3, "mit"))
873  return COMMIT;
874  if (!strcasecmp(atom + 3,
875  "munications-interrupted"))
877  if (!strcasecmp(atom + 3, "pressed"))
878  return COMPRESSED;
879  break;
880  }
881  if (isascii(atom[2]) &&
882  tolower((unsigned char)atom[2]) == 'n') {
883  if (!strcasecmp(atom + 3, "cat"))
884  return CONCAT;
885  if (!strcasecmp(atom + 3, "fig-option"))
886  return CONFIG_OPTION;
887  if (!strcasecmp(atom + 3, "flict-done"))
888  return CONFLICT_DONE;
889  if (!strcasecmp(atom + 3, "nect"))
890  return CONNECT;
891  break;
892  }
893  break;
894  }
895  if (!strcasecmp(atom + 1, "reate"))
896  return TOKEN_CREATE;
897  break;
898  case 'd':
899  if (!strcasecmp(atom + 1, "b-time-format"))
900  return DB_TIME_FORMAT;
901  if (!strcasecmp (atom + 1, "omain"))
902  return DOMAIN;
903  if (!strncasecmp (atom + 1, "omain-", 6)) {
904  if (!strcasecmp(atom + 7, "name"))
905  return DOMAIN_NAME;
906  if (!strcasecmp(atom + 7, "list"))
907  return DOMAIN_LIST;
908  }
909  if (!strcasecmp (atom + 1, "o-forward-updates"))
910  return DO_FORWARD_UPDATE;
911  /* do-forward-update is included for historical reasons */
912  if (!strcasecmp (atom + 1, "o-forward-update"))
913  return DO_FORWARD_UPDATE;
914  if (!strcasecmp (atom + 1, "ebug"))
915  return TOKEN_DEBUG;
916  if (!strcasecmp (atom + 1, "eny"))
917  return DENY;
918  if (!strcasecmp (atom + 1, "eleted"))
919  return TOKEN_DELETED;
920  if (!strcasecmp (atom + 1, "elete"))
921  return TOKEN_DELETE;
922  if (!strncasecmp (atom + 1, "efault", 6)) {
923  if (!atom [7])
924  return DEFAULT;
925  if (!strcasecmp(atom + 7, "-duid"))
926  return DEFAULT_DUID;
927  if (!strcasecmp (atom + 7, "-lease-time"))
928  return DEFAULT_LEASE_TIME;
929  break;
930  }
931  if (!strncasecmp (atom + 1, "ynamic", 6)) {
932  if (!atom [7])
933  return DYNAMIC;
934  if (!strncasecmp (atom + 7, "-bootp", 6)) {
935  if (!atom [13])
936  return DYNAMIC_BOOTP;
937  if (!strcasecmp (atom + 13, "-lease-cutoff"))
939  if (!strcasecmp (atom + 13, "-lease-length"))
941  break;
942  }
943  }
944  if (!strcasecmp (atom + 1, "uplicates"))
945  return DUPLICATES;
946  if (!strcasecmp (atom + 1, "eclines"))
947  return DECLINES;
948  if (!strncasecmp (atom + 1, "efine", 5)) {
949  if (!strcasecmp (atom + 6, "d"))
950  return DEFINED;
951  if (!atom [6])
952  return DEFINE;
953  }
954  break;
955  case 'e':
956  if (isascii (atom [1]) &&
957  tolower((unsigned char)atom[1]) == 'x') {
958  if (!strcasecmp (atom + 2, "tract-int"))
959  return EXTRACT_INT;
960  if (!strcasecmp (atom + 2, "ists"))
961  return EXISTS;
962  if (!strcasecmp (atom + 2, "piry"))
963  return EXPIRY;
964  if (!strcasecmp (atom + 2, "pire"))
965  return EXPIRE;
966  if (!strcasecmp (atom + 2, "pired"))
967  return TOKEN_EXPIRED;
968  }
969  if (!strcasecmp (atom + 1, "ncode-int"))
970  return ENCODE_INT;
971  if (!strcasecmp(atom + 1, "poch"))
972  return EPOCH;
973  if (!strcasecmp (atom + 1, "thernet"))
974  return ETHERNET;
975  if (!strcasecmp (atom + 1, "nds"))
976  return ENDS;
977  if (!strncasecmp (atom + 1, "ls", 2)) {
978  if (!strcasecmp (atom + 3, "e"))
979  return ELSE;
980  if (!strcasecmp (atom + 3, "if"))
981  return ELSIF;
982  break;
983  }
984  if (!strcasecmp (atom + 1, "rror"))
985  return ERROR;
986  if (!strcasecmp (atom + 1, "val"))
987  return EVAL;
988  if (!strcasecmp (atom + 1, "ncapsulate"))
989  return ENCAPSULATE;
990  if (!strcasecmp(atom + 1, "xecute"))
991  return EXECUTE;
992  if (!strcasecmp(atom+1, "n")) {
993  return EN;
994  }
995  break;
996  case 'f':
997  if (!strcasecmp (atom + 1, "atal"))
998  return FATAL;
999  if (!strcasecmp (atom + 1, "ilename"))
1000  return FILENAME;
1001  if (!strcasecmp (atom + 1, "ixed-address"))
1002  return FIXED_ADDR;
1003  if (!strcasecmp (atom + 1, "ixed-address6"))
1004  return FIXED_ADDR6;
1005  if (!strcasecmp (atom + 1, "ixed-prefix6"))
1006  return FIXED_PREFIX6;
1007  if (!strcasecmp (atom + 1, "ddi"))
1008  return TOKEN_FDDI;
1009  if (!strcasecmp (atom + 1, "ormerr"))
1010  return NS_FORMERR;
1011  if (!strcasecmp (atom + 1, "unction"))
1012  return FUNCTION;
1013  if (!strcasecmp (atom + 1, "ailover"))
1014  return FAILOVER;
1015  if (!strcasecmp (atom + 1, "ree"))
1016  return TOKEN_FREE;
1017  break;
1018  case 'g':
1019  if (!strncasecmp(atom + 1, "et", 2)) {
1020  if (!strcasecmp(atom + 3, "-lease-hostnames"))
1021  return GET_LEASE_HOSTNAMES;
1022  if (!strcasecmp(atom + 3, "hostbyname"))
1023  return GETHOSTBYNAME;
1024  if (!strcasecmp(atom + 3, "hostname"))
1025  return GETHOSTNAME;
1026  break;
1027  }
1028  if (!strcasecmp (atom + 1, "iaddr"))
1029  return GIADDR;
1030  if (!strcasecmp (atom + 1, "roup"))
1031  return GROUP;
1032  break;
1033  case 'h':
1034  if (!strcasecmp(atom + 1, "ash"))
1035  return HASH;
1036  if (!strcasecmp (atom + 1, "ba"))
1037  return HBA;
1038  if (!strcasecmp (atom + 1, "ost"))
1039  return HOST;
1040  if (!strcasecmp (atom + 1, "ost-decl-name"))
1041  return HOST_DECL_NAME;
1042  if (!strcasecmp(atom + 1, "ost-identifier"))
1043  return HOST_IDENTIFIER;
1044  if (!strcasecmp (atom + 1, "ardware"))
1045  return HARDWARE;
1046  if (!strcasecmp (atom + 1, "ostname"))
1047  return HOSTNAME;
1048  if (!strcasecmp (atom + 1, "elp"))
1049  return TOKEN_HELP;
1050  break;
1051  case 'i':
1052  if (!strcasecmp(atom+1, "a-na"))
1053  return IA_NA;
1054  if (!strcasecmp(atom+1, "a-ta"))
1055  return IA_TA;
1056  if (!strcasecmp(atom+1, "a-pd"))
1057  return IA_PD;
1058  if (!strcasecmp(atom+1, "aaddr"))
1059  return IAADDR;
1060  if (!strcasecmp(atom+1, "aprefix"))
1061  return IAPREFIX;
1062  if (!strcasecmp (atom + 1, "nclude"))
1063  return INCLUDE;
1064  if (!strcasecmp (atom + 1, "nteger"))
1065  return INTEGER;
1066  if (!strcasecmp (atom + 1, "nfiniband"))
1067  return TOKEN_INFINIBAND;
1068  if (!strcasecmp (atom + 1, "nfinite"))
1069  return INFINITE;
1070  if (!strcasecmp (atom + 1, "nfo"))
1071  return INFO;
1072  if (!strcasecmp (atom + 1, "p-address"))
1073  return IP_ADDRESS;
1074  if (!strcasecmp (atom + 1, "p6-address"))
1075  return IP6_ADDRESS;
1076  if (!strcasecmp (atom + 1, "nitial-interval"))
1077  return INITIAL_INTERVAL;
1078  if (!strcasecmp (atom + 1, "nitial-delay"))
1079  return INITIAL_DELAY;
1080  if (!strcasecmp (atom + 1, "nterface"))
1081  return INTERFACE;
1082  if (!strcasecmp (atom + 1, "dentifier"))
1083  return IDENTIFIER;
1084  if (!strcasecmp (atom + 1, "f"))
1085  return IF;
1086  if (!strcasecmp (atom + 1, "s"))
1087  return IS;
1088  if (!strcasecmp (atom + 1, "gnore"))
1089  return IGNORE;
1090  break;
1091  case 'k':
1092  if (!strncasecmp (atom + 1, "nown", 4)) {
1093  if (!strcasecmp (atom + 5, "-clients"))
1094  return KNOWN_CLIENTS;
1095  if (!atom[5])
1096  return KNOWN;
1097  break;
1098  }
1099  if (!strcasecmp (atom + 1, "ey"))
1100  return KEY;
1101  break;
1102  case 'l':
1103  if (!strcasecmp (atom + 1, "case"))
1104  return LCASE;
1105  if (!strcasecmp (atom + 1, "ease"))
1106  return LEASE;
1107  if (!strcasecmp(atom + 1, "ease6"))
1108  return LEASE6;
1109  if (!strcasecmp (atom + 1, "eased-address"))
1110  return LEASED_ADDRESS;
1111  if (!strcasecmp (atom + 1, "ease-time"))
1112  return LEASE_TIME;
1113  if (!strcasecmp(atom + 1, "easequery"))
1114  return LEASEQUERY;
1115  if (!strcasecmp(atom + 1, "ength"))
1116  return LENGTH;
1117  if (!strcasecmp (atom + 1, "imit"))
1118  return LIMIT;
1119  if (!strcasecmp (atom + 1, "et"))
1120  return LET;
1121  if (!strcasecmp (atom + 1, "oad"))
1122  return LOAD;
1123  if (!strcasecmp(atom + 1, "ocal"))
1124  return LOCAL;
1125  if (!strcasecmp (atom + 1, "og"))
1126  return LOG;
1127  if (!strcasecmp(atom+1, "lt")) {
1128  return LLT;
1129  }
1130  if (!strcasecmp(atom+1, "l")) {
1131  return LL;
1132  }
1133  break;
1134  case 'm':
1135  if (!strncasecmp (atom + 1, "ax", 2)) {
1136  if (!atom [3])
1137  return TOKEN_MAX;
1138  if (!strcasecmp (atom + 3, "-balance"))
1139  return MAX_BALANCE;
1140  if (!strncasecmp (atom + 3, "-lease-", 7)) {
1141  if (!strcasecmp(atom + 10, "misbalance"))
1142  return MAX_LEASE_MISBALANCE;
1143  if (!strcasecmp(atom + 10, "ownership"))
1144  return MAX_LEASE_OWNERSHIP;
1145  if (!strcasecmp(atom + 10, "time"))
1146  return MAX_LEASE_TIME;
1147  }
1148  if (!strcasecmp(atom + 3, "-life"))
1149  return MAX_LIFE;
1150  if (!strcasecmp (atom + 3, "-transmit-idle"))
1151  return MAX_TRANSMIT_IDLE;
1152  if (!strcasecmp (atom + 3, "-response-delay"))
1153  return MAX_RESPONSE_DELAY;
1154  if (!strcasecmp (atom + 3, "-unacked-updates"))
1155  return MAX_UNACKED_UPDATES;
1156  }
1157  if (!strncasecmp (atom + 1, "in-", 3)) {
1158  if (!strcasecmp (atom + 4, "balance"))
1159  return MIN_BALANCE;
1160  if (!strcasecmp (atom + 4, "lease-time"))
1161  return MIN_LEASE_TIME;
1162  if (!strcasecmp (atom + 4, "secs"))
1163  return MIN_SECS;
1164  break;
1165  }
1166  if (!strncasecmp (atom + 1, "edi", 3)) {
1167  if (!strcasecmp (atom + 4, "a"))
1168  return MEDIA;
1169  if (!strcasecmp (atom + 4, "um"))
1170  return MEDIUM;
1171  break;
1172  }
1173  if (!strcasecmp (atom + 1, "atch"))
1174  return MATCH;
1175  if (!strcasecmp (atom + 1, "embers"))
1176  return MEMBERS;
1177  if (!strcasecmp (atom + 1, "y"))
1178  return MY;
1179  if (!strcasecmp (atom + 1, "clt"))
1180  return MCLT;
1181  break;
1182  case 'n':
1183  if (!strcasecmp (atom + 1, "ormal"))
1184  return NORMAL;
1185  if (!strcasecmp (atom + 1, "ameserver"))
1186  return NAMESERVER;
1187  if (!strcasecmp (atom + 1, "etmask"))
1188  return NETMASK;
1189  if (!strcasecmp (atom + 1, "ever"))
1190  return NEVER;
1191  if (!strcasecmp (atom + 1, "ext-server"))
1192  return NEXT_SERVER;
1193  if (!strcasecmp (atom + 1, "ot"))
1194  return TOKEN_NOT;
1195  if (!strcasecmp (atom + 1, "o"))
1196  return TOKEN_NO;
1197  if (!strcasecmp (atom + 1, "oerror"))
1198  return NS_NOERROR;
1199  if (!strcasecmp (atom + 1, "otauth"))
1200  return NS_NOTAUTH;
1201  if (!strcasecmp (atom + 1, "otimp"))
1202  return NS_NOTIMP;
1203  if (!strcasecmp (atom + 1, "otzone"))
1204  return NS_NOTZONE;
1205  if (!strcasecmp (atom + 1, "xdomain"))
1206  return NS_NXDOMAIN;
1207  if (!strcasecmp (atom + 1, "xrrset"))
1208  return NS_NXRRSET;
1209  if (!strcasecmp (atom + 1, "ull"))
1210  return TOKEN_NULL;
1211  if (!strcasecmp (atom + 1, "ext"))
1212  return TOKEN_NEXT;
1213  if (!strcasecmp (atom + 1, "ew"))
1214  return TOKEN_NEW;
1215  break;
1216  case 'o':
1217  if (!strcasecmp (atom + 1, "mapi"))
1218  return OMAPI;
1219  if (!strcasecmp (atom + 1, "r"))
1220  return OR;
1221  if (!strcasecmp (atom + 1, "n"))
1222  return ON;
1223  if (!strcasecmp (atom + 1, "pen"))
1224  return TOKEN_OPEN;
1225  if (!strcasecmp (atom + 1, "ption"))
1226  return OPTION;
1227  if (!strcasecmp (atom + 1, "ne-lease-per-client"))
1228  return ONE_LEASE_PER_CLIENT;
1229  if (!strcasecmp (atom + 1, "f"))
1230  return OF;
1231  if (!strcasecmp (atom + 1, "wner"))
1232  return OWNER;
1233  break;
1234  case 'p':
1235  if (!strcasecmp (atom + 1, "arse-vendor-option"))
1236  return PARSE_VENDOR_OPT;
1237  if (!strcasecmp (atom + 1, "repend"))
1238  return PREPEND;
1239  if (!strcasecmp(atom + 1, "referred-life"))
1240  return PREFERRED_LIFE;
1241  if (!strcasecmp (atom + 1, "acket"))
1242  return PACKET;
1243  if (!strcasecmp (atom + 1, "ool"))
1244  return POOL;
1245  if (!strcasecmp (atom + 1, "ool6"))
1246  return POOL6;
1247  if (!strcasecmp (atom + 1, "refix6"))
1248  return PREFIX6;
1249  if (!strcasecmp (atom + 1, "seudo"))
1250  return PSEUDO;
1251  if (!strcasecmp (atom + 1, "eer"))
1252  return PEER;
1253  if (!strcasecmp (atom + 1, "rimary"))
1254  return PRIMARY;
1255  if (!strcasecmp (atom + 1, "rimary6"))
1256  return PRIMARY6;
1257  if (!strncasecmp (atom + 1, "artner", 6)) {
1258  if (!atom [7])
1259  return PARTNER;
1260  if (!strcasecmp (atom + 7, "-down"))
1261  return PARTNER_DOWN;
1262  }
1263  if (!strcasecmp (atom + 1, "ort"))
1264  return PORT;
1265  if (!strcasecmp (atom + 1, "otential-conflict"))
1266  return POTENTIAL_CONFLICT;
1267  if (!strcasecmp (atom + 1, "ick-first-value") ||
1268  !strcasecmp (atom + 1, "ick"))
1269  return PICK;
1270  if (!strcasecmp (atom + 1, "aused"))
1271  return PAUSED;
1272  break;
1273  case 'r':
1274  if (!strcasecmp(atom + 1, "ange"))
1275  return RANGE;
1276  if (!strcasecmp(atom + 1, "ange6"))
1277  return RANGE6;
1278  if (isascii(atom[1]) &&
1279  (tolower((unsigned char)atom[1]) == 'e')) {
1280  if (!strcasecmp(atom + 2, "bind"))
1281  return REBIND;
1282  if (!strcasecmp(atom + 2, "boot"))
1283  return REBOOT;
1284  if (!strcasecmp(atom + 2, "contact-interval"))
1285  return RECONTACT_INTERVAL;
1286  if (!strncasecmp(atom + 2, "cover", 5)) {
1287  if (atom[7] == '\0')
1288  return RECOVER;
1289  if (!strcasecmp(atom + 7, "-done"))
1290  return RECOVER_DONE;
1291  if (!strcasecmp(atom + 7, "-wait"))
1292  return RECOVER_WAIT;
1293  break;
1294  }
1295  if (!strcasecmp(atom + 2, "fresh"))
1296  return REFRESH;
1297  if (!strcasecmp(atom + 2, "fused"))
1298  return NS_REFUSED;
1299  if (!strcasecmp(atom + 2, "ject"))
1300  return REJECT;
1301  if (!strcasecmp(atom + 2, "lease"))
1302  return RELEASE;
1303  if (!strcasecmp(atom + 2, "leased"))
1304  return TOKEN_RELEASED;
1305  if (!strcasecmp(atom + 2, "move"))
1306  return REMOVE;
1307  if (!strcasecmp(atom + 2, "new"))
1308  return RENEW;
1309  if (!strcasecmp(atom + 2, "quest"))
1310  return REQUEST;
1311  if (!strcasecmp(atom + 2, "quire"))
1312  return REQUIRE;
1313  if (isascii(atom[2]) &&
1314  (tolower((unsigned char)atom[2]) == 's')) {
1315  if (!strcasecmp(atom + 3, "erved"))
1316  return TOKEN_RESERVED;
1317  if (!strcasecmp(atom + 3, "et"))
1318  return TOKEN_RESET;
1319  if (!strcasecmp(atom + 3,
1320  "olution-interrupted"))
1321  return RESOLUTION_INTERRUPTED;
1322  break;
1323  }
1324  if (!strcasecmp(atom + 2, "try"))
1325  return RETRY;
1326  if (!strcasecmp(atom + 2, "turn"))
1327  return RETURN;
1328  if (!strcasecmp(atom + 2, "verse"))
1329  return REVERSE;
1330  if (!strcasecmp(atom + 2, "wind"))
1331  return REWIND;
1332  break;
1333  }
1334  break;
1335  case 's':
1336  if (!strcasecmp(atom + 1, "cript"))
1337  return SCRIPT;
1338  if (isascii(atom[1]) &&
1339  tolower((unsigned char)atom[1]) == 'e') {
1340  if (!strcasecmp(atom + 2, "arch"))
1341  return SEARCH;
1342  if (isascii(atom[2]) &&
1343  tolower((unsigned char)atom[2]) == 'c') {
1344  if (!strncasecmp(atom + 3, "ond", 3)) {
1345  if (!strcasecmp(atom + 6, "ary"))
1346  return SECONDARY;
1347  if (!strcasecmp(atom + 6, "ary6"))
1348  return SECONDARY6;
1349  if (!strcasecmp(atom + 6, "s"))
1350  return SECONDS;
1351  break;
1352  }
1353  if (!strcasecmp(atom + 3, "ret"))
1354  return SECRET;
1355  break;
1356  }
1357  if (!strncasecmp(atom + 2, "lect", 4)) {
1358  if (atom[6] == '\0')
1359  return SELECT;
1360  if (!strcasecmp(atom + 6, "-timeout"))
1361  return SELECT_TIMEOUT;
1362  break;
1363  }
1364  if (!strcasecmp(atom + 2, "nd"))
1365  return SEND;
1366  if (!strncasecmp(atom + 2, "rv", 2)) {
1367  if (!strncasecmp(atom + 4, "er", 2)) {
1368  if (atom[6] == '\0')
1369  return TOKEN_SERVER;
1370  if (atom[6] == '-') {
1371  if (!strcasecmp(atom + 7,
1372  "duid"))
1373  return SERVER_DUID;
1374  if (!strcasecmp(atom + 7,
1375  "name"))
1376  return SERVER_NAME;
1377  if (!strcasecmp(atom + 7,
1378  "identifier"))
1379  return SERVER_IDENTIFIER;
1380  break;
1381  }
1382  break;
1383  }
1384  if (!strcasecmp(atom + 4, "fail"))
1385  return NS_SERVFAIL;
1386  break;
1387  }
1388  if (!strcasecmp(atom + 2, "t"))
1389  return TOKEN_SET;
1390  break;
1391  }
1392  if (isascii(atom[1]) &&
1393  tolower((unsigned char)atom[1]) == 'h') {
1394  if (!strcasecmp(atom + 2, "ared-network"))
1395  return SHARED_NETWORK;
1396  if (!strcasecmp(atom + 2, "utdown"))
1397  return SHUTDOWN;
1398  break;
1399  }
1400  if (isascii(atom[1]) &&
1401  tolower((unsigned char)atom[1]) == 'i') {
1402  if (!strcasecmp(atom + 2, "addr"))
1403  return SIADDR;
1404  if (!strcasecmp(atom + 2, "gned"))
1405  return SIGNED;
1406  if (!strcasecmp(atom + 2, "ze"))
1407  return SIZE;
1408  break;
1409  }
1410  if (isascii(atom[1]) &&
1411  tolower((unsigned char)atom[1]) == 'p') {
1412  if (isascii(atom[2]) &&
1413  tolower((unsigned char)atom[2]) == 'a') {
1414  if (!strcasecmp(atom + 3, "ce"))
1415  return SPACE;
1416  if (!strcasecmp(atom + 3, "wn"))
1417  return SPAWN;
1418  break;
1419  }
1420  if (!strcasecmp(atom + 2, "lit"))
1421  return SPLIT;
1422  break;
1423  }
1424  if (isascii(atom[1]) &&
1425  tolower((unsigned char)atom[1]) == 't') {
1426  if (isascii(atom[2]) &&
1427  tolower((unsigned char)atom[2]) == 'a') {
1428  if(!strncasecmp(atom + 3, "rt", 2)) {
1429  if (!strcasecmp(atom + 5, "s"))
1430  return STARTS;
1431  if (!strcasecmp(atom + 5, "up"))
1432  return STARTUP;
1433  break;
1434  }
1435  if (isascii(atom[3]) &&
1436  tolower((unsigned char)atom[3]) == 't') {
1437  if (!strcasecmp(atom + 4, "e"))
1438  return STATE;
1439  if (!strcasecmp(atom + 4, "ic"))
1440  return STATIC;
1441  break;
1442  }
1443  }
1444  if (!strcasecmp(atom + 2, "ring"))
1445  return STRING_TOKEN;
1446  break;
1447  }
1448  if (!strncasecmp(atom + 1, "ub", 2)) {
1449  if (!strcasecmp(atom + 3, "class"))
1450  return SUBCLASS;
1451  if (!strcasecmp(atom + 3, "net"))
1452  return SUBNET;
1453  if (!strcasecmp(atom + 3, "net6"))
1454  return SUBNET6;
1455  if (!strcasecmp(atom + 3, "string"))
1456  return SUBSTRING;
1457  break;
1458  }
1459  if (isascii(atom[1]) &&
1460  tolower((unsigned char)atom[1]) == 'u') {
1461  if (!strcasecmp(atom + 2, "ffix"))
1462  return SUFFIX;
1463  if (!strcasecmp(atom + 2, "persede"))
1464  return SUPERSEDE;
1465  }
1466  if (!strcasecmp(atom + 1, "witch"))
1467  return SWITCH;
1468  break;
1469  case 't':
1470  if (!strcasecmp (atom + 1, "imestamp"))
1471  return TIMESTAMP;
1472  if (!strcasecmp (atom + 1, "imeout"))
1473  return TIMEOUT;
1474  if (!strcasecmp (atom + 1, "oken-ring"))
1475  return TOKEN_RING;
1476  if (!strcasecmp (atom + 1, "ext"))
1477  return TEXT;
1478  if (!strcasecmp (atom + 1, "stp"))
1479  return TSTP;
1480  if (!strcasecmp (atom + 1, "sfp"))
1481  return TSFP;
1482  if (!strcasecmp (atom + 1, "ransmission"))
1483  return TRANSMISSION;
1484  if (!strcasecmp(atom + 1, "emporary"))
1485  return TEMPORARY;
1486  break;
1487  case 'u':
1488  if (!strcasecmp (atom + 1, "case"))
1489  return UCASE;
1490  if (!strcasecmp (atom + 1, "nset"))
1491  return UNSET;
1492  if (!strcasecmp (atom + 1, "nsigned"))
1493  return UNSIGNED;
1494  if (!strcasecmp (atom + 1, "id"))
1495  return UID;
1496  if (!strncasecmp (atom + 1, "se", 2)) {
1497  if (!strcasecmp (atom + 3, "r-class"))
1498  return USER_CLASS;
1499  if (!strcasecmp (atom + 3, "-host-decl-names"))
1500  return USE_HOST_DECL_NAMES;
1501  if (!strcasecmp (atom + 3,
1502  "-lease-addr-for-default-route"))
1504  break;
1505  }
1506  if (!strncasecmp (atom + 1, "nknown", 6)) {
1507  if (!strcasecmp (atom + 7, "-clients"))
1508  return UNKNOWN_CLIENTS;
1509  if (!strcasecmp (atom + 7, "-state"))
1510  return UNKNOWN_STATE;
1511  if (!atom [7])
1512  return UNKNOWN;
1513  break;
1514  }
1515  if (!strcasecmp (atom + 1, "nauthenticated"))
1516  return UNAUTHENTICATED;
1517  if (!strcasecmp (atom + 1, "pdate"))
1518  return UPDATE;
1519  break;
1520  case 'v':
1521  if (!strcasecmp (atom + 1, "6relay"))
1522  return V6RELAY;
1523  if (!strcasecmp (atom + 1, "6relopt"))
1524  return V6RELOPT;
1525  if (!strcasecmp (atom + 1, "endor-class"))
1526  return VENDOR_CLASS;
1527  if (!strcasecmp (atom + 1, "endor"))
1528  return VENDOR;
1529  break;
1530  case 'w':
1531  if (!strcasecmp (atom + 1, "ith"))
1532  return WITH;
1533  if (!strcasecmp(atom + 1, "idth"))
1534  return WIDTH;
1535  break;
1536  case 'y':
1537  if (!strcasecmp (atom + 1, "iaddr"))
1538  return YIADDR;
1539  if (!strcasecmp (atom + 1, "xdomain"))
1540  return NS_YXDOMAIN;
1541  if (!strcasecmp (atom + 1, "xrrset"))
1542  return NS_YXRRSET;
1543  break;
1544  case 'z':
1545  if (!strcasecmp (atom + 1, "erolen"))
1546  return ZEROLEN;
1547  if (!strcasecmp (atom + 1, "one"))
1548  return ZONE;
1549  break;
1550  }
1551  return dfv;
1552 }
1553 
Definition: dhctoken.h:100
Definition: dhctoken.h:96
int line
Definition: dhcpd.h:317
Definition: dhctoken.h:266
const char int line
Definition: dhcpd.h:3676
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:320
Definition: dhctoken.h:71
size_t buflen
Definition: dhcpd.h:329
#define MDL
Definition: omapip.h:568
#define DHCP_R_NOTYET
Definition: result.h:49
int tlpos
Definition: dhcpd.h:318
Definition: dhctoken.h:152
Definition: dhctoken.h:137
Definition: dhctoken.h:349
int lpos
Definition: dhcpd.h:316
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:195
Definition: dhctoken.h:251
const char * tlname
Definition: dhcpd.h:294
Definition: dhctoken.h:68
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:443
int lexchar
Definition: dhcrelay.c:51
struct parse * saved_state
Definition: dhcpd.h:332
enum dhcp_token peek_raw_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:454
Definition: dhcpd.h:288
int eol_token
Definition: dhcpd.h:295
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:369
Definition: dhctoken.h:321
Definition: dhctoken.h:165
Definition: dhctoken.h:258
int tline
Definition: dhcpd.h:319
Definition: dhctoken.h:221
Definition: dhctoken.h:228
void dfree(void *, const char *, int)
Definition: alloc.c:131
int tlen
Definition: dhcpd.h:323
Definition: dhctoken.h:223
Definition: dhctoken.h:348
Definition: dhctoken.h:188
Definition: dhctoken.h:203
char line1[81]
Definition: dhcpd.h:314
void cleanup(void)
char * token_line
Definition: dhcpd.h:291
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:159
Definition: dhctoken.h:220
#define EOL
Definition: dhcpd.h:88
char * prev_line
Definition: dhcpd.h:292
Definition: dhctoken.h:347
Definition: dhctoken.h:167
size_t bufsiz
Definition: dhcpd.h:330
size_t bufix
Definition: dhcpd.h:329
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:315
Definition: dhctoken.h:226
Definition: dhctoken.h:206
int ugflag
Definition: dhcpd.h:321
char * cur_line
Definition: dhcpd.h:293
Definition: dhctoken.h:74
Definition: dhctoken.h:145
const char * file
Definition: dhcpd.h:3676
char * name
Definition: dhcpd.h:1016
Definition: dhctoken.h:254
char * inbuf
Definition: dhcpd.h:328
char tokbuf[1500]
Definition: dhcpd.h:324
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:5615
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:322
int file
Definition: dhcpd.h:327
enum dhcp_token next_raw_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:380
Definition: dhctoken.h:224
Definition: dhctoken.h:320