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