summaryrefslogtreecommitdiffstats
path: root/sbin/dhclient/conflex.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/dhclient/conflex.c')
-rw-r--r--sbin/dhclient/conflex.c525
1 files changed, 525 insertions, 0 deletions
diff --git a/sbin/dhclient/conflex.c b/sbin/dhclient/conflex.c
new file mode 100644
index 0000000..ee96bfe
--- /dev/null
+++ b/sbin/dhclient/conflex.c
@@ -0,0 +1,525 @@
+/* $OpenBSD: conflex.c,v 1.7 2004/09/15 19:02:38 deraadt Exp $ */
+
+/* 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''.
+ */
+
+#include <ctype.h>
+
+#include "dhcpd.h"
+#include "dhctoken.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];
+
+static int get_char(FILE *);
+static int get_token(FILE *);
+static void skip_to_eol(FILE *);
+static int read_string(FILE *);
+static int read_number(int, FILE *);
+static int read_num_or_name(int, FILE *);
+static int intern(char *, int);
+
+void
+new_parse(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(FILE *cfile)
+{
+ int c = getc(cfile);
+ if (!ugflag) {
+ if (c == '\n') {
+ 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(FILE *cfile)
+{
+ int c, ttok;
+ static char tb[2];
+ int l, p;
+
+ do {
+ l = line;
+ p = lpos;
+
+ c = get_char(cfile);
+
+ if (!(c == '\n' && eol_token) && isascii(c) && isspace(c))
+ continue;
+ if (c == '#') {
+ 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(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;
+
+ return (rv);
+}
+
+int
+peek_token(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;
+
+ return (token);
+}
+
+static void
+skip_to_eol(FILE *cfile)
+{
+ int c;
+
+ do {
+ c = get_char(cfile);
+ if (c == EOF)
+ return;
+ if (c == '\n')
+ return;
+ } while (1);
+}
+
+static int
+read_string(FILE *cfile)
+{
+ int i, c, bs = 0;
+
+ 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(int c, FILE *cfile)
+{
+ int seenx = 0, i = 0, token = NUMBER;
+
+ tokbuf[i++] = c;
+ for (; i < sizeof(tokbuf); i++) {
+ c = get_char(cfile);
+ if (!seenx && c == 'x')
+ seenx = 1;
+ 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(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(char *atom, int dfv)
+{
+ if (!isascii(atom[0]))
+ return (dfv);
+
+ switch (tolower(atom[0])) {
+ case 'a':
+ if (!strcasecmp(atom + 1, "lways-reply-rfc1048"))
+ return (ALWAYS_REPLY_RFC1048);
+ 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);
+ if (!strcasecmp(atom + 1, "uthoritative"))
+ return (AUTHORITATIVE);
+ 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);
+ if (!strcasecmp(atom + 1, "ddi"))
+ return (FDDI);
+ 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);
+ if (!strcasecmp(atom + 1, "ot"))
+ return (TOKEN_NOT);
+ 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 (!strncasecmp(atom + 1, "se", 2)) {
+ if (!strcasecmp(atom + 3, "r-class"))
+ return (USER_CLASS);
+ if (!strcasecmp(atom + 3, "-host-decl-names"))
+ return (USE_HOST_DECL_NAMES);
+ if (!strcasecmp(atom + 3,
+ "-lease-addr-for-default-route"))
+ return (USE_LEASE_ADDR_FOR_DEFAULT_ROUTE);
+ break;
+ }
+ if (!strcasecmp(atom + 1, "id"))
+ return (UID);
+ 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);
+}
OpenPOWER on IntegriCloud