xref: /freebsd/sbin/dhclient/conflex.c (revision 71c6c44d8d2b62f4e1b6bb5b12fa252314ef116a)
147c08596SBrooks Davis /*	$OpenBSD: conflex.c,v 1.7 2004/09/15 19:02:38 deraadt Exp $	*/
247c08596SBrooks Davis 
347c08596SBrooks Davis /* Lexical scanner for dhcpd config file... */
447c08596SBrooks Davis 
58a16b7a1SPedro F. Giffuni /*-
68a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
78a16b7a1SPedro F. Giffuni  *
847c08596SBrooks Davis  * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
947c08596SBrooks Davis  * All rights reserved.
1047c08596SBrooks Davis  *
1147c08596SBrooks Davis  * Redistribution and use in source and binary forms, with or without
1247c08596SBrooks Davis  * modification, are permitted provided that the following conditions
1347c08596SBrooks Davis  * are met:
1447c08596SBrooks Davis  *
1547c08596SBrooks Davis  * 1. Redistributions of source code must retain the above copyright
1647c08596SBrooks Davis  *    notice, this list of conditions and the following disclaimer.
1747c08596SBrooks Davis  * 2. Redistributions in binary form must reproduce the above copyright
1847c08596SBrooks Davis  *    notice, this list of conditions and the following disclaimer in the
1947c08596SBrooks Davis  *    documentation and/or other materials provided with the distribution.
2047c08596SBrooks Davis  * 3. Neither the name of The Internet Software Consortium nor the names
2147c08596SBrooks Davis  *    of its contributors may be used to endorse or promote products derived
2247c08596SBrooks Davis  *    from this software without specific prior written permission.
2347c08596SBrooks Davis  *
2447c08596SBrooks Davis  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
2547c08596SBrooks Davis  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
2647c08596SBrooks Davis  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2747c08596SBrooks Davis  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2847c08596SBrooks Davis  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
2947c08596SBrooks Davis  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3047c08596SBrooks Davis  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3147c08596SBrooks Davis  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3247c08596SBrooks Davis  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3347c08596SBrooks Davis  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3447c08596SBrooks Davis  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3547c08596SBrooks Davis  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3647c08596SBrooks Davis  * SUCH DAMAGE.
3747c08596SBrooks Davis  *
3847c08596SBrooks Davis  * This software has been written for the Internet Software Consortium
3947c08596SBrooks Davis  * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
4047c08596SBrooks Davis  * Enterprises.  To learn more about the Internet Software Consortium,
4147c08596SBrooks Davis  * see ``http://www.vix.com/isc''.  To learn more about Vixie
4247c08596SBrooks Davis  * Enterprises, see ``http://www.vix.com''.
4347c08596SBrooks Davis  */
4447c08596SBrooks Davis 
458794fdbbSBrooks Davis #include <sys/cdefs.h>
468794fdbbSBrooks Davis __FBSDID("$FreeBSD$");
478794fdbbSBrooks Davis 
4847c08596SBrooks Davis #include <ctype.h>
4947c08596SBrooks Davis 
5047c08596SBrooks Davis #include "dhcpd.h"
5147c08596SBrooks Davis #include "dhctoken.h"
5247c08596SBrooks Davis 
5347c08596SBrooks Davis int lexline;
5447c08596SBrooks Davis int lexchar;
5547c08596SBrooks Davis char *token_line;
56*71c6c44dSEitan Adler static char *prev_line;
57*71c6c44dSEitan Adler static char *cur_line;
5879a1d195SAlan Somers const char *tlname;
5947c08596SBrooks Davis int eol_token;
6047c08596SBrooks Davis 
6147c08596SBrooks Davis static char line1[81];
6247c08596SBrooks Davis static char line2[81];
63afe6f835SAlan Somers static unsigned lpos;
64afe6f835SAlan Somers static unsigned line;
6547c08596SBrooks Davis static int tlpos;
6647c08596SBrooks Davis static int tline;
6747c08596SBrooks Davis static int token;
6847c08596SBrooks Davis static int ugflag;
6947c08596SBrooks Davis static char *tval;
7047c08596SBrooks Davis static char tokbuf[1500];
7147c08596SBrooks Davis 
7247c08596SBrooks Davis static int get_char(FILE *);
7347c08596SBrooks Davis static int get_token(FILE *);
7447c08596SBrooks Davis static void skip_to_eol(FILE *);
7547c08596SBrooks Davis static int read_string(FILE *);
7647c08596SBrooks Davis static int read_number(int, FILE *);
7747c08596SBrooks Davis static int read_num_or_name(int, FILE *);
7847c08596SBrooks Davis static int intern(char *, int);
7947c08596SBrooks Davis 
8047c08596SBrooks Davis void
8179a1d195SAlan Somers new_parse(const char *name)
8247c08596SBrooks Davis {
8347c08596SBrooks Davis 	tlname = name;
8447c08596SBrooks Davis 	lpos = line = 1;
8547c08596SBrooks Davis 	cur_line = line1;
8647c08596SBrooks Davis 	prev_line = line2;
8747c08596SBrooks Davis 	token_line = cur_line;
8847c08596SBrooks Davis 	cur_line[0] = prev_line[0] = 0;
8947c08596SBrooks Davis 	warnings_occurred = 0;
9047c08596SBrooks Davis }
9147c08596SBrooks Davis 
9247c08596SBrooks Davis static int
9347c08596SBrooks Davis get_char(FILE *cfile)
9447c08596SBrooks Davis {
9547c08596SBrooks Davis 	int c = getc(cfile);
9647c08596SBrooks Davis 	if (!ugflag) {
9747c08596SBrooks Davis 		if (c == '\n') {
9847c08596SBrooks Davis 			if (cur_line == line1) {
9947c08596SBrooks Davis 				cur_line = line2;
10047c08596SBrooks Davis 				prev_line = line1;
10147c08596SBrooks Davis 			} else {
10232ceeb31SPedro F. Giffuni 				cur_line = line1;
10332ceeb31SPedro F. Giffuni 				prev_line = line2;
10447c08596SBrooks Davis 			}
10547c08596SBrooks Davis 			line++;
10647c08596SBrooks Davis 			lpos = 1;
10747c08596SBrooks Davis 			cur_line[0] = 0;
10847c08596SBrooks Davis 		} else if (c != EOF) {
1091469b42cSBrooks Davis 			if (lpos < sizeof(line1)) {
11047c08596SBrooks Davis 				cur_line[lpos - 1] = c;
11147c08596SBrooks Davis 				cur_line[lpos] = 0;
11247c08596SBrooks Davis 			}
11347c08596SBrooks Davis 			lpos++;
11447c08596SBrooks Davis 		}
11547c08596SBrooks Davis 	} else
11647c08596SBrooks Davis 		ugflag = 0;
11747c08596SBrooks Davis 	return (c);
11847c08596SBrooks Davis }
11947c08596SBrooks Davis 
12047c08596SBrooks Davis static int
12147c08596SBrooks Davis get_token(FILE *cfile)
12247c08596SBrooks Davis {
12347c08596SBrooks Davis 	int		c, ttok;
12447c08596SBrooks Davis 	static char	tb[2];
12547c08596SBrooks Davis 	int		l, p;
12647c08596SBrooks Davis 
12747c08596SBrooks Davis 	do {
12847c08596SBrooks Davis 		l = line;
12947c08596SBrooks Davis 		p = lpos;
13047c08596SBrooks Davis 
13147c08596SBrooks Davis 		c = get_char(cfile);
13247c08596SBrooks Davis 
13347c08596SBrooks Davis 		if (!(c == '\n' && eol_token) && isascii(c) && isspace(c))
13447c08596SBrooks Davis 			continue;
13547c08596SBrooks Davis 		if (c == '#') {
13647c08596SBrooks Davis 			skip_to_eol(cfile);
13747c08596SBrooks Davis 			continue;
13847c08596SBrooks Davis 		}
13947c08596SBrooks Davis 		if (c == '"') {
14047c08596SBrooks Davis 			lexline = l;
14147c08596SBrooks Davis 			lexchar = p;
14247c08596SBrooks Davis 			ttok = read_string(cfile);
14347c08596SBrooks Davis 			break;
14447c08596SBrooks Davis 		}
14547c08596SBrooks Davis 		if ((isascii(c) && isdigit(c)) || c == '-') {
14647c08596SBrooks Davis 			lexline = l;
14747c08596SBrooks Davis 			lexchar = p;
14847c08596SBrooks Davis 			ttok = read_number(c, cfile);
14947c08596SBrooks Davis 			break;
15047c08596SBrooks Davis 		} else if (isascii(c) && isalpha(c)) {
15147c08596SBrooks Davis 			lexline = l;
15247c08596SBrooks Davis 			lexchar = p;
15347c08596SBrooks Davis 			ttok = read_num_or_name(c, cfile);
15447c08596SBrooks Davis 			break;
15547c08596SBrooks Davis 		} else {
15647c08596SBrooks Davis 			lexline = l;
15747c08596SBrooks Davis 			lexchar = p;
15847c08596SBrooks Davis 			tb[0] = c;
15947c08596SBrooks Davis 			tb[1] = 0;
16047c08596SBrooks Davis 			tval = tb;
16147c08596SBrooks Davis 			ttok = c;
16247c08596SBrooks Davis 			break;
16347c08596SBrooks Davis 		}
16447c08596SBrooks Davis 	} while (1);
16547c08596SBrooks Davis 	return (ttok);
16647c08596SBrooks Davis }
16747c08596SBrooks Davis 
16847c08596SBrooks Davis int
16947c08596SBrooks Davis next_token(char **rval, FILE *cfile)
17047c08596SBrooks Davis {
17147c08596SBrooks Davis 	int	rv;
17247c08596SBrooks Davis 
17347c08596SBrooks Davis 	if (token) {
17447c08596SBrooks Davis 		if (lexline != tline)
17547c08596SBrooks Davis 			token_line = cur_line;
17647c08596SBrooks Davis 		lexchar = tlpos;
17747c08596SBrooks Davis 		lexline = tline;
17847c08596SBrooks Davis 		rv = token;
17947c08596SBrooks Davis 		token = 0;
18047c08596SBrooks Davis 	} else {
18147c08596SBrooks Davis 		rv = get_token(cfile);
18247c08596SBrooks Davis 		token_line = cur_line;
18347c08596SBrooks Davis 	}
18447c08596SBrooks Davis 	if (rval)
18547c08596SBrooks Davis 		*rval = tval;
18647c08596SBrooks Davis 
18747c08596SBrooks Davis 	return (rv);
18847c08596SBrooks Davis }
18947c08596SBrooks Davis 
19047c08596SBrooks Davis int
19147c08596SBrooks Davis peek_token(char **rval, FILE *cfile)
19247c08596SBrooks Davis {
19347c08596SBrooks Davis 	int	x;
19447c08596SBrooks Davis 
19547c08596SBrooks Davis 	if (!token) {
19647c08596SBrooks Davis 		tlpos = lexchar;
19747c08596SBrooks Davis 		tline = lexline;
19847c08596SBrooks Davis 		token = get_token(cfile);
19947c08596SBrooks Davis 		if (lexline != tline)
20047c08596SBrooks Davis 			token_line = prev_line;
20147c08596SBrooks Davis 		x = lexchar;
20247c08596SBrooks Davis 		lexchar = tlpos;
20347c08596SBrooks Davis 		tlpos = x;
20447c08596SBrooks Davis 		x = lexline;
20547c08596SBrooks Davis 		lexline = tline;
20647c08596SBrooks Davis 		tline = x;
20747c08596SBrooks Davis 	}
20847c08596SBrooks Davis 	if (rval)
20947c08596SBrooks Davis 		*rval = tval;
21047c08596SBrooks Davis 
21147c08596SBrooks Davis 	return (token);
21247c08596SBrooks Davis }
21347c08596SBrooks Davis 
21447c08596SBrooks Davis static void
21547c08596SBrooks Davis skip_to_eol(FILE *cfile)
21647c08596SBrooks Davis {
21747c08596SBrooks Davis 	int	c;
21847c08596SBrooks Davis 
21947c08596SBrooks Davis 	do {
22047c08596SBrooks Davis 		c = get_char(cfile);
22147c08596SBrooks Davis 		if (c == EOF)
22247c08596SBrooks Davis 			return;
22347c08596SBrooks Davis 		if (c == '\n')
22447c08596SBrooks Davis 			return;
22547c08596SBrooks Davis 	} while (1);
22647c08596SBrooks Davis }
22747c08596SBrooks Davis 
22847c08596SBrooks Davis static int
22947c08596SBrooks Davis read_string(FILE *cfile)
23047c08596SBrooks Davis {
231afe6f835SAlan Somers 	int	c, bs = 0;
232afe6f835SAlan Somers 	unsigned i;
23347c08596SBrooks Davis 
23447c08596SBrooks Davis 	for (i = 0; i < sizeof(tokbuf); i++) {
23547c08596SBrooks Davis 		c = get_char(cfile);
23647c08596SBrooks Davis 		if (c == EOF) {
23747c08596SBrooks Davis 			parse_warn("eof in string constant");
23847c08596SBrooks Davis 			break;
23947c08596SBrooks Davis 		}
24047c08596SBrooks Davis 		if (bs) {
24147c08596SBrooks Davis 			bs = 0;
242753d6c03SBrooks Davis 			i--;
24347c08596SBrooks Davis 			tokbuf[i] = c;
24447c08596SBrooks Davis 		} else if (c == '\\')
24547c08596SBrooks Davis 			bs = 1;
24647c08596SBrooks Davis 		else if (c == '"')
24747c08596SBrooks Davis 			break;
24847c08596SBrooks Davis 		else
24947c08596SBrooks Davis 			tokbuf[i] = c;
25047c08596SBrooks Davis 	}
25147c08596SBrooks Davis 	/*
25247c08596SBrooks Davis 	 * Normally, I'd feel guilty about this, but we're talking about
25347c08596SBrooks Davis 	 * strings that'll fit in a DHCP packet here...
25447c08596SBrooks Davis 	 */
25547c08596SBrooks Davis 	if (i == sizeof(tokbuf)) {
25647c08596SBrooks Davis 		parse_warn("string constant larger than internal buffer");
25747c08596SBrooks Davis 		i--;
25847c08596SBrooks Davis 	}
25947c08596SBrooks Davis 	tokbuf[i] = 0;
26047c08596SBrooks Davis 	tval = tokbuf;
26147c08596SBrooks Davis 	return (STRING);
26247c08596SBrooks Davis }
26347c08596SBrooks Davis 
26447c08596SBrooks Davis static int
26547c08596SBrooks Davis read_number(int c, FILE *cfile)
26647c08596SBrooks Davis {
26779a1d195SAlan Somers 	int	seenx = 0, _token = NUMBER;
268afe6f835SAlan Somers 	unsigned i = 0;
26947c08596SBrooks Davis 
27047c08596SBrooks Davis 	tokbuf[i++] = c;
27147c08596SBrooks Davis 	for (; i < sizeof(tokbuf); i++) {
27247c08596SBrooks Davis 		c = get_char(cfile);
27347c08596SBrooks Davis 		if (!seenx && c == 'x')
27447c08596SBrooks Davis 			seenx = 1;
27547c08596SBrooks Davis 		else if (!isascii(c) || !isxdigit(c)) {
27647c08596SBrooks Davis 			ungetc(c, cfile);
27747c08596SBrooks Davis 			ugflag = 1;
27847c08596SBrooks Davis 			break;
27947c08596SBrooks Davis 		}
28047c08596SBrooks Davis 		tokbuf[i] = c;
28147c08596SBrooks Davis 	}
28247c08596SBrooks Davis 	if (i == sizeof(tokbuf)) {
28347c08596SBrooks Davis 		parse_warn("numeric token larger than internal buffer");
28447c08596SBrooks Davis 		i--;
28547c08596SBrooks Davis 	}
28647c08596SBrooks Davis 	tokbuf[i] = 0;
28747c08596SBrooks Davis 	tval = tokbuf;
28847c08596SBrooks Davis 
28979a1d195SAlan Somers 	return (_token);
29047c08596SBrooks Davis }
29147c08596SBrooks Davis 
29247c08596SBrooks Davis static int
29347c08596SBrooks Davis read_num_or_name(int c, FILE *cfile)
29447c08596SBrooks Davis {
295afe6f835SAlan Somers 	unsigned i = 0;
29647c08596SBrooks Davis 	int	rv = NUMBER_OR_NAME;
29747c08596SBrooks Davis 
29847c08596SBrooks Davis 	tokbuf[i++] = c;
29947c08596SBrooks Davis 	for (; i < sizeof(tokbuf); i++) {
30047c08596SBrooks Davis 		c = get_char(cfile);
30147c08596SBrooks Davis 		if (!isascii(c) || (c != '-' && c != '_' && !isalnum(c))) {
30247c08596SBrooks Davis 			ungetc(c, cfile);
30347c08596SBrooks Davis 			ugflag = 1;
30447c08596SBrooks Davis 			break;
30547c08596SBrooks Davis 		}
30647c08596SBrooks Davis 		if (!isxdigit(c))
30747c08596SBrooks Davis 			rv = NAME;
30847c08596SBrooks Davis 		tokbuf[i] = c;
30947c08596SBrooks Davis 	}
31047c08596SBrooks Davis 	if (i == sizeof(tokbuf)) {
31147c08596SBrooks Davis 		parse_warn("token larger than internal buffer");
31247c08596SBrooks Davis 		i--;
31347c08596SBrooks Davis 	}
31447c08596SBrooks Davis 	tokbuf[i] = 0;
31547c08596SBrooks Davis 	tval = tokbuf;
31647c08596SBrooks Davis 
31747c08596SBrooks Davis 	return (intern(tval, rv));
31847c08596SBrooks Davis }
31947c08596SBrooks Davis 
32047c08596SBrooks Davis static int
32147c08596SBrooks Davis intern(char *atom, int dfv)
32247c08596SBrooks Davis {
32347c08596SBrooks Davis 	if (!isascii(atom[0]))
32447c08596SBrooks Davis 		return (dfv);
32547c08596SBrooks Davis 
32647c08596SBrooks Davis 	switch (tolower(atom[0])) {
32747c08596SBrooks Davis 	case 'a':
32847c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "lways-reply-rfc1048"))
32947c08596SBrooks Davis 			return (ALWAYS_REPLY_RFC1048);
33047c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ppend"))
33147c08596SBrooks Davis 			return (APPEND);
33247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "llow"))
33347c08596SBrooks Davis 			return (ALLOW);
33447c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "lias"))
33547c08596SBrooks Davis 			return (ALIAS);
33647c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "bandoned"))
33747c08596SBrooks Davis 			return (ABANDONED);
33847c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "uthoritative"))
33947c08596SBrooks Davis 			return (AUTHORITATIVE);
34047c08596SBrooks Davis 		break;
34147c08596SBrooks Davis 	case 'b':
34247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ackoff-cutoff"))
34347c08596SBrooks Davis 			return (BACKOFF_CUTOFF);
34447c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ootp"))
34547c08596SBrooks Davis 			return (BOOTP);
34647c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ooting"))
34747c08596SBrooks Davis 			return (BOOTING);
34847c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "oot-unknown-clients"))
34947c08596SBrooks Davis 			return (BOOT_UNKNOWN_CLIENTS);
350*71c6c44dSEitan Adler 		break;
35147c08596SBrooks Davis 	case 'c':
35247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "lass"))
35347c08596SBrooks Davis 			return (CLASS);
35447c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "iaddr"))
35547c08596SBrooks Davis 			return (CIADDR);
35647c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "lient-identifier"))
35747c08596SBrooks Davis 			return (CLIENT_IDENTIFIER);
35847c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "lient-hostname"))
35947c08596SBrooks Davis 			return (CLIENT_HOSTNAME);
36047c08596SBrooks Davis 		break;
36147c08596SBrooks Davis 	case 'd':
36247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "omain"))
36347c08596SBrooks Davis 			return (DOMAIN);
36447c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "eny"))
36547c08596SBrooks Davis 			return (DENY);
36647c08596SBrooks Davis 		if (!strncasecmp(atom + 1, "efault", 6)) {
36747c08596SBrooks Davis 			if (!atom[7])
36847c08596SBrooks Davis 				return (DEFAULT);
36947c08596SBrooks Davis 			if (!strcasecmp(atom + 7, "-lease-time"))
37047c08596SBrooks Davis 				return (DEFAULT_LEASE_TIME);
37147c08596SBrooks Davis 			break;
37247c08596SBrooks Davis 		}
37347c08596SBrooks Davis 		if (!strncasecmp(atom + 1, "ynamic-bootp", 12)) {
37447c08596SBrooks Davis 			if (!atom[13])
37547c08596SBrooks Davis 				return (DYNAMIC_BOOTP);
37647c08596SBrooks Davis 			if (!strcasecmp(atom + 13, "-lease-cutoff"))
37747c08596SBrooks Davis 				return (DYNAMIC_BOOTP_LEASE_CUTOFF);
37847c08596SBrooks Davis 			if (!strcasecmp(atom + 13, "-lease-length"))
37947c08596SBrooks Davis 				return (DYNAMIC_BOOTP_LEASE_LENGTH);
38047c08596SBrooks Davis 			break;
38147c08596SBrooks Davis 		}
38247c08596SBrooks Davis 		break;
38347c08596SBrooks Davis 	case 'e':
38447c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "thernet"))
38547c08596SBrooks Davis 			return (ETHERNET);
38647c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "nds"))
38747c08596SBrooks Davis 			return (ENDS);
38847c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "xpire"))
38947c08596SBrooks Davis 			return (EXPIRE);
39047c08596SBrooks Davis 		break;
39147c08596SBrooks Davis 	case 'f':
39247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ilename"))
39347c08596SBrooks Davis 			return (FILENAME);
39447c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ixed-address"))
39547c08596SBrooks Davis 			return (FIXED_ADDR);
39647c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ddi"))
39747c08596SBrooks Davis 			return (FDDI);
39847c08596SBrooks Davis 		break;
39947c08596SBrooks Davis 	case 'g':
40047c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "iaddr"))
40147c08596SBrooks Davis 			return (GIADDR);
40247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "roup"))
40347c08596SBrooks Davis 			return (GROUP);
40447c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "et-lease-hostnames"))
40547c08596SBrooks Davis 			return (GET_LEASE_HOSTNAMES);
40647c08596SBrooks Davis 		break;
40747c08596SBrooks Davis 	case 'h':
40847c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ost"))
40947c08596SBrooks Davis 			return (HOST);
41047c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ardware"))
41147c08596SBrooks Davis 			return (HARDWARE);
41247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ostname"))
41347c08596SBrooks Davis 			return (HOSTNAME);
41447c08596SBrooks Davis 		break;
41547c08596SBrooks Davis 	case 'i':
41647c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "nitial-interval"))
41747c08596SBrooks Davis 			return (INITIAL_INTERVAL);
41847c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "nterface"))
41947c08596SBrooks Davis 			return (INTERFACE);
42047c08596SBrooks Davis 		break;
42147c08596SBrooks Davis 	case 'l':
42247c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ease"))
42347c08596SBrooks Davis 			return (LEASE);
42447c08596SBrooks Davis 		break;
42547c08596SBrooks Davis 	case 'm':
42647c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ax-lease-time"))
42747c08596SBrooks Davis 			return (MAX_LEASE_TIME);
42847c08596SBrooks Davis 		if (!strncasecmp(atom + 1, "edi", 3)) {
42947c08596SBrooks Davis 			if (!strcasecmp(atom + 4, "a"))
43047c08596SBrooks Davis 				return (MEDIA);
43147c08596SBrooks Davis 			if (!strcasecmp(atom + 4, "um"))
43247c08596SBrooks Davis 				return (MEDIUM);
43347c08596SBrooks Davis 			break;
43447c08596SBrooks Davis 		}
43547c08596SBrooks Davis 		break;
43647c08596SBrooks Davis 	case 'n':
43747c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ameserver"))
43847c08596SBrooks Davis 			return (NAMESERVER);
43947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "etmask"))
44047c08596SBrooks Davis 			return (NETMASK);
44147c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ext-server"))
44247c08596SBrooks Davis 			return (NEXT_SERVER);
44347c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ot"))
44447c08596SBrooks Davis 			return (TOKEN_NOT);
44547c08596SBrooks Davis 		break;
44647c08596SBrooks Davis 	case 'o':
44747c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ption"))
44847c08596SBrooks Davis 			return (OPTION);
44947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ne-lease-per-client"))
45047c08596SBrooks Davis 			return (ONE_LEASE_PER_CLIENT);
45147c08596SBrooks Davis 		break;
45247c08596SBrooks Davis 	case 'p':
45347c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "repend"))
45447c08596SBrooks Davis 			return (PREPEND);
45547c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "acket"))
45647c08596SBrooks Davis 			return (PACKET);
45747c08596SBrooks Davis 		break;
45847c08596SBrooks Davis 	case 'r':
45947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ange"))
46047c08596SBrooks Davis 			return (RANGE);
46147c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "equest"))
46247c08596SBrooks Davis 			return (REQUEST);
46347c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "equire"))
46447c08596SBrooks Davis 			return (REQUIRE);
46547c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "etry"))
46647c08596SBrooks Davis 			return (RETRY);
46747c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "enew"))
46847c08596SBrooks Davis 			return (RENEW);
46947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ebind"))
47047c08596SBrooks Davis 			return (REBIND);
47147c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "eboot"))
47247c08596SBrooks Davis 			return (REBOOT);
47347c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "eject"))
47447c08596SBrooks Davis 			return (REJECT);
47547c08596SBrooks Davis 		break;
47647c08596SBrooks Davis 	case 's':
47747c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "earch"))
47847c08596SBrooks Davis 			return (SEARCH);
47947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "tarts"))
48047c08596SBrooks Davis 			return (STARTS);
48147c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "iaddr"))
48247c08596SBrooks Davis 			return (SIADDR);
48347c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "ubnet"))
48447c08596SBrooks Davis 			return (SUBNET);
48547c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "hared-network"))
48647c08596SBrooks Davis 			return (SHARED_NETWORK);
48747c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "erver-name"))
48847c08596SBrooks Davis 			return (SERVER_NAME);
48947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "erver-identifier"))
49047c08596SBrooks Davis 			return (SERVER_IDENTIFIER);
49147c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "elect-timeout"))
49247c08596SBrooks Davis 			return (SELECT_TIMEOUT);
49347c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "end"))
49447c08596SBrooks Davis 			return (SEND);
49547c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "cript"))
49647c08596SBrooks Davis 			return (SCRIPT);
49747c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "upersede"))
49847c08596SBrooks Davis 			return (SUPERSEDE);
49947c08596SBrooks Davis 		break;
50047c08596SBrooks Davis 	case 't':
50147c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "imestamp"))
50247c08596SBrooks Davis 			return (TIMESTAMP);
50347c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "imeout"))
50447c08596SBrooks Davis 			return (TIMEOUT);
50547c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "oken-ring"))
50647c08596SBrooks Davis 			return (TOKEN_RING);
50747c08596SBrooks Davis 		break;
50847c08596SBrooks Davis 	case 'u':
50947c08596SBrooks Davis 		if (!strncasecmp(atom + 1, "se", 2)) {
51047c08596SBrooks Davis 			if (!strcasecmp(atom + 3, "r-class"))
51147c08596SBrooks Davis 				return (USER_CLASS);
51247c08596SBrooks Davis 			if (!strcasecmp(atom + 3, "-host-decl-names"))
51347c08596SBrooks Davis 				return (USE_HOST_DECL_NAMES);
51447c08596SBrooks Davis 			if (!strcasecmp(atom + 3,
51547c08596SBrooks Davis 					 "-lease-addr-for-default-route"))
51647c08596SBrooks Davis 				return (USE_LEASE_ADDR_FOR_DEFAULT_ROUTE);
51747c08596SBrooks Davis 			break;
51847c08596SBrooks Davis 		}
51947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "id"))
52047c08596SBrooks Davis 			return (UID);
52147c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "nknown-clients"))
52247c08596SBrooks Davis 			return (UNKNOWN_CLIENTS);
52347c08596SBrooks Davis 		break;
52447c08596SBrooks Davis 	case 'v':
52547c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "endor-class"))
52647c08596SBrooks Davis 			return (VENDOR_CLASS);
52747c08596SBrooks Davis 		break;
52847c08596SBrooks Davis 	case 'y':
52947c08596SBrooks Davis 		if (!strcasecmp(atom + 1, "iaddr"))
53047c08596SBrooks Davis 			return (YIADDR);
53147c08596SBrooks Davis 		break;
53247c08596SBrooks Davis 	}
53347c08596SBrooks Davis 	return (dfv);
53447c08596SBrooks Davis }
535