summaryrefslogtreecommitdiff
path: root/usr.sbin/dhcp/common/conflex.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1998-08-18 03:43:37 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1998-08-18 03:43:37 +0000
commit6721997719c217c13c5bcc48fb334d17e129236a (patch)
tree3ec16130a607c32af8527f49cd7bf849c8db39b6 /usr.sbin/dhcp/common/conflex.c
parent0b7cd0b79ac9bf9c298be7a92d3a7a15acf362fb (diff)
ISC dhcp, needs security audit for sure
Diffstat (limited to 'usr.sbin/dhcp/common/conflex.c')
-rw-r--r--usr.sbin/dhcp/common/conflex.c548
1 files changed, 548 insertions, 0 deletions
diff --git a/usr.sbin/dhcp/common/conflex.c b/usr.sbin/dhcp/common/conflex.c
new file mode 100644
index 00000000000..4855a973400
--- /dev/null
+++ b/usr.sbin/dhcp/common/conflex.c
@@ -0,0 +1,548 @@
+/* conflex.c
+
+ Lexical scanner for dhcpd config file... */
+
+/*
+ * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises. To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''. To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"$Id: conflex.c,v 1.1 1998/08/18 03:43:25 deraadt Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
+#endif /* not lint */
+
+#include "dhcpd.h"
+#include "dhctoken.h"
+#include <ctype.h>
+
+int lexline;
+int lexchar;
+char *token_line;
+char *prev_line;
+char *cur_line;
+char *tlname;
+int eol_token;
+
+static char line1 [81];
+static char line2 [81];
+static int lpos;
+static int line;
+static int tlpos;
+static int tline;
+static int token;
+static int ugflag;
+static char *tval;
+static char tokbuf [1500];
+
+#ifdef OLD_LEXER
+char comments [4096];
+int comment_index;
+#endif
+
+
+static int get_char PROTO ((FILE *));
+static int get_token PROTO ((FILE *));
+static void skip_to_eol PROTO ((FILE *));
+static int read_string PROTO ((FILE *));
+static int read_number PROTO ((int, FILE *));
+static int read_num_or_name PROTO ((int, FILE *));
+static int intern PROTO ((char *, int));
+
+void new_parse (name)
+ char *name;
+{
+ tlname = name;
+ lpos = line = 1;
+ cur_line = line1;
+ prev_line = line2;
+ token_line = cur_line;
+ cur_line [0] = prev_line [0] = 0;
+ warnings_occurred = 0;
+}
+
+static int get_char (cfile)
+ FILE *cfile;
+{
+ int c = getc (cfile);
+ if (!ugflag) {
+ if (c == EOL) {
+ if (cur_line == line1) {
+ cur_line = line2;
+ prev_line = line1;
+ } else {
+ cur_line = line2;
+ prev_line = line1;
+ }
+ line++;
+ lpos = 1;
+ cur_line [0] = 0;
+ } else if (c != EOF) {
+ if (lpos <= 81) {
+ cur_line [lpos - 1] = c;
+ cur_line [lpos] = 0;
+ }
+ lpos++;
+ }
+ } else
+ ugflag = 0;
+ return c;
+}
+
+static int get_token (cfile)
+ FILE *cfile;
+{
+ int c;
+ int ttok;
+ static char tb [2];
+ int l, p, u;
+
+ do {
+ l = line;
+ p = lpos;
+ u = ugflag;
+
+ c = get_char (cfile);
+#ifdef OLD_LEXER
+ if (c == '\n' && p == 1 && !u
+ && comment_index < sizeof comments)
+ comments [comment_index++] = '\n';
+#endif
+
+ if (!(c == '\n' && eol_token) && isascii (c) && isspace (c))
+ continue;
+ if (c == '#') {
+#ifdef OLD_LEXER
+ if (comment_index < sizeof comments)
+ comments [comment_index++] = '#';
+#endif
+ skip_to_eol (cfile);
+ continue;
+ }
+ if (c == '"') {
+ lexline = l;
+ lexchar = p;
+ ttok = read_string (cfile);
+ break;
+ }
+ if ((isascii (c) && isdigit (c)) || c == '-') {
+ lexline = l;
+ lexchar = p;
+ ttok = read_number (c, cfile);
+ break;
+ } else if (isascii (c) && isalpha (c)) {
+ lexline = l;
+ lexchar = p;
+ ttok = read_num_or_name (c, cfile);
+ break;
+ } else {
+ lexline = l;
+ lexchar = p;
+ tb [0] = c;
+ tb [1] = 0;
+ tval = tb;
+ ttok = c;
+ break;
+ }
+ } while (1);
+ return ttok;
+}
+
+int next_token (rval, cfile)
+ char **rval;
+ FILE *cfile;
+{
+ int rv;
+
+ if (token) {
+ if (lexline != tline)
+ token_line = cur_line;
+ lexchar = tlpos;
+ lexline = tline;
+ rv = token;
+ token = 0;
+ } else {
+ rv = get_token (cfile);
+ token_line = cur_line;
+ }
+ if (rval)
+ *rval = tval;
+#ifdef DEBUG_TOKENS
+ fprintf (stderr, "%s:%d ", tval, rv);
+#endif
+ return rv;
+}
+
+int peek_token (rval, cfile)
+ char **rval;
+ FILE *cfile;
+{
+ int x;
+
+ if (!token) {
+ tlpos = lexchar;
+ tline = lexline;
+ token = get_token (cfile);
+ if (lexline != tline)
+ token_line = prev_line;
+ x = lexchar; lexchar = tlpos; tlpos = x;
+ x = lexline; lexline = tline; tline = x;
+ }
+ if (rval)
+ *rval = tval;
+#ifdef DEBUG_TOKENS
+ fprintf (stderr, "(%s:%d) ", tval, token);
+#endif
+ return token;
+}
+
+static void skip_to_eol (cfile)
+ FILE *cfile;
+{
+ int c;
+ do {
+ c = get_char (cfile);
+ if (c == EOF)
+ return;
+#ifdef OLD_LEXER
+ if (comment_index < sizeof (comments))
+ comments [comment_index++] = c;
+#endif
+ if (c == EOL) {
+ return;
+ }
+ } while (1);
+}
+
+static int read_string (cfile)
+ FILE *cfile;
+{
+ int i;
+ int bs = 0;
+ int c;
+
+ for (i = 0; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (c == EOF) {
+ parse_warn ("eof in string constant");
+ break;
+ }
+ if (bs) {
+ bs = 0;
+ tokbuf [i] = c;
+ } else if (c == '\\')
+ bs = 1;
+ else if (c == '"')
+ break;
+ else
+ tokbuf [i] = c;
+ }
+ /* Normally, I'd feel guilty about this, but we're talking about
+ strings that'll fit in a DHCP packet here... */
+ if (i == sizeof tokbuf) {
+ parse_warn ("string constant larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return STRING;
+}
+
+static int read_number (c, cfile)
+ int c;
+ FILE *cfile;
+{
+ int seenx = 0;
+ int i = 0;
+ int token = NUMBER;
+
+ tokbuf [i++] = c;
+ for (; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (!seenx && c == 'x') {
+ seenx = 1;
+#ifndef OLD_LEXER
+ } else if (isascii (c) && !isxdigit (c) &&
+ (c == '-' || c == '_' || isalpha (c))) {
+ token = NAME;
+ } else if (isascii (c) && !isdigit (c) && isxdigit (c)) {
+ token = NUMBER_OR_NAME;
+#endif
+ } else if (!isascii (c) || !isxdigit (c)) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ break;
+ }
+ tokbuf [i] = c;
+ }
+ if (i == sizeof tokbuf) {
+ parse_warn ("numeric token larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return token;
+}
+
+static int read_num_or_name (c, cfile)
+ int c;
+ FILE *cfile;
+{
+ int i = 0;
+ int rv = NUMBER_OR_NAME;
+ tokbuf [i++] = c;
+ for (; i < sizeof tokbuf; i++) {
+ c = get_char (cfile);
+ if (!isascii (c) ||
+ (c != '-' && c != '_' && !isalnum (c))) {
+ ungetc (c, cfile);
+ ugflag = 1;
+ break;
+ }
+ if (!isxdigit (c))
+ rv = NAME;
+ tokbuf [i] = c;
+ }
+ if (i == sizeof tokbuf) {
+ parse_warn ("token larger than internal buffer");
+ --i;
+ }
+ tokbuf [i] = 0;
+ tval = tokbuf;
+ return intern (tval, rv);
+}
+
+static int intern (atom, dfv)
+ char *atom;
+ int dfv;
+{
+ if (!isascii (atom [0]))
+ return dfv;
+
+ switch (tolower (atom [0])) {
+ case 'a':
+ if (!strcasecmp (atom + 1, "ppend"))
+ return APPEND;
+ if (!strcasecmp (atom + 1, "llow"))
+ return ALLOW;
+ if (!strcasecmp (atom + 1, "lias"))
+ return ALIAS;
+ if (!strcasecmp (atom + 1, "bandoned"))
+ return ABANDONED;
+ break;
+ case 'b':
+ if (!strcasecmp (atom + 1, "ackoff-cutoff"))
+ return BACKOFF_CUTOFF;
+ if (!strcasecmp (atom + 1, "ootp"))
+ return BOOTP;
+ if (!strcasecmp (atom + 1, "ooting"))
+ return BOOTING;
+ if (!strcasecmp (atom + 1, "oot-unknown-clients"))
+ return BOOT_UNKNOWN_CLIENTS;
+ case 'c':
+ if (!strcasecmp (atom + 1, "lass"))
+ return CLASS;
+ if (!strcasecmp (atom + 1, "iaddr"))
+ return CIADDR;
+ if (!strcasecmp (atom + 1, "lient-identifier"))
+ return CLIENT_IDENTIFIER;
+ if (!strcasecmp (atom + 1, "lient-hostname"))
+ return CLIENT_HOSTNAME;
+ break;
+ case 'd':
+ if (!strcasecmp (atom + 1, "omain"))
+ return DOMAIN;
+ if (!strcasecmp (atom + 1, "eny"))
+ return DENY;
+ if (!strncasecmp (atom + 1, "efault", 6)) {
+ if (!atom [7])
+ return DEFAULT;
+ if (!strcasecmp (atom + 7, "-lease-time"))
+ return DEFAULT_LEASE_TIME;
+ break;
+ }
+ if (!strncasecmp (atom + 1, "ynamic-bootp", 12)) {
+ if (!atom [13])
+ return DYNAMIC_BOOTP;
+ if (!strcasecmp (atom + 13, "-lease-cutoff"))
+ return DYNAMIC_BOOTP_LEASE_CUTOFF;
+ if (!strcasecmp (atom + 13, "-lease-length"))
+ return DYNAMIC_BOOTP_LEASE_LENGTH;
+ break;
+ }
+ break;
+ case 'e':
+ if (!strcasecmp (atom + 1, "thernet"))
+ return ETHERNET;
+ if (!strcasecmp (atom + 1, "nds"))
+ return ENDS;
+ if (!strcasecmp (atom + 1, "xpire"))
+ return EXPIRE;
+ break;
+ case 'f':
+ if (!strcasecmp (atom + 1, "ilename"))
+ return FILENAME;
+ if (!strcasecmp (atom + 1, "ixed-address"))
+ return FIXED_ADDR;
+ break;
+ case 'g':
+ if (!strcasecmp (atom + 1, "iaddr"))
+ return GIADDR;
+ if (!strcasecmp (atom + 1, "roup"))
+ return GROUP;
+ if (!strcasecmp (atom + 1, "et-lease-hostnames"))
+ return GET_LEASE_HOSTNAMES;
+ break;
+ case 'h':
+ if (!strcasecmp (atom + 1, "ost"))
+ return HOST;
+ if (!strcasecmp (atom + 1, "ardware"))
+ return HARDWARE;
+ if (!strcasecmp (atom + 1, "ostname"))
+ return HOSTNAME;
+ break;
+ case 'i':
+ if (!strcasecmp (atom + 1, "nitial-interval"))
+ return INITIAL_INTERVAL;
+ if (!strcasecmp (atom + 1, "nterface"))
+ return INTERFACE;
+ break;
+ case 'l':
+ if (!strcasecmp (atom + 1, "ease"))
+ return LEASE;
+ break;
+ case 'm':
+ if (!strcasecmp (atom + 1, "ax-lease-time"))
+ return MAX_LEASE_TIME;
+ if (!strncasecmp (atom + 1, "edi", 3)) {
+ if (!strcasecmp (atom + 4, "a"))
+ return MEDIA;
+ if (!strcasecmp (atom + 4, "um"))
+ return MEDIUM;
+ break;
+ }
+ break;
+ case 'n':
+ if (!strcasecmp (atom + 1, "ameserver"))
+ return NAMESERVER;
+ if (!strcasecmp (atom + 1, "etmask"))
+ return NETMASK;
+ if (!strcasecmp (atom + 1, "ext-server"))
+ return NEXT_SERVER;
+ break;
+ case 'o':
+ if (!strcasecmp (atom + 1, "ption"))
+ return OPTION;
+ if (!strcasecmp (atom + 1, "ne-lease-per-client"))
+ return ONE_LEASE_PER_CLIENT;
+ break;
+ case 'p':
+ if (!strcasecmp (atom + 1, "repend"))
+ return PREPEND;
+ if (!strcasecmp (atom + 1, "acket"))
+ return PACKET;
+ break;
+ case 'r':
+ if (!strcasecmp (atom + 1, "ange"))
+ return RANGE;
+ if (!strcasecmp (atom + 1, "equest"))
+ return REQUEST;
+ if (!strcasecmp (atom + 1, "equire"))
+ return REQUIRE;
+ if (!strcasecmp (atom + 1, "etry"))
+ return RETRY;
+ if (!strcasecmp (atom + 1, "enew"))
+ return RENEW;
+ if (!strcasecmp (atom + 1, "ebind"))
+ return REBIND;
+ if (!strcasecmp (atom + 1, "eboot"))
+ return REBOOT;
+ if (!strcasecmp (atom + 1, "eject"))
+ return REJECT;
+ break;
+ case 's':
+ if (!strcasecmp (atom + 1, "earch"))
+ return SEARCH;
+ if (!strcasecmp (atom + 1, "tarts"))
+ return STARTS;
+ if (!strcasecmp (atom + 1, "iaddr"))
+ return SIADDR;
+ if (!strcasecmp (atom + 1, "ubnet"))
+ return SUBNET;
+ if (!strcasecmp (atom + 1, "hared-network"))
+ return SHARED_NETWORK;
+ if (!strcasecmp (atom + 1, "erver-name"))
+ return SERVER_NAME;
+ if (!strcasecmp (atom + 1, "erver-identifier"))
+ return SERVER_IDENTIFIER;
+ if (!strcasecmp (atom + 1, "elect-timeout"))
+ return SELECT_TIMEOUT;
+ if (!strcasecmp (atom + 1, "end"))
+ return SEND;
+ if (!strcasecmp (atom + 1, "cript"))
+ return SCRIPT;
+ if (!strcasecmp (atom + 1, "upersede"))
+ return SUPERSEDE;
+ break;
+ case 't':
+ if (!strcasecmp (atom + 1, "imestamp"))
+ return TIMESTAMP;
+ if (!strcasecmp (atom + 1, "imeout"))
+ return TIMEOUT;
+ if (!strcasecmp (atom + 1, "oken-ring"))
+ return TOKEN_RING;
+ break;
+ case 'u':
+ if (!strcasecmp (atom + 1, "id"))
+ return UID;
+ if (!strcasecmp (atom + 1, "ser-class"))
+ return USER_CLASS;
+ if (!strcasecmp (atom + 1, "se-host-decl-names"))
+ return USE_HOST_DECL_NAMES;
+ if (!strcasecmp (atom + 1, "nknown-clients"))
+ return UNKNOWN_CLIENTS;
+ break;
+ case 'v':
+ if (!strcasecmp (atom + 1, "endor-class"))
+ return VENDOR_CLASS;
+ break;
+ case 'y':
+ if (!strcasecmp (atom + 1, "iaddr"))
+ return YIADDR;
+ break;
+ }
+ return dfv;
+}