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