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