summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-10-13 16:35:23 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-10-13 16:35:23 +0000
commit3bc6f4c74e1cc60c05a1ab152805af447144952a (patch)
tree4a68ea922315ee6f6d1396cafc87ae97f4d0d06f /usr.sbin/bgpd
parent3270c1ab5c203bfd16890aaf55afd4c31904e523 (diff)
in all these programs using the same pfctl-derived parse.y, re-unify the
yylex implementation and the code which interacts with yylex. this also brings the future potential for include support to all of the parsers. in the future please do not silly modifications to one of these files without checking if you are de-unifying the code. checked by developers in all these areas.
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.h3
-rw-r--r--usr.sbin/bgpd/config.c25
-rw-r--r--usr.sbin/bgpd/parse.y184
3 files changed, 110 insertions, 102 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 6d0160646bc..1a9dbf9ce4b 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.219 2007/09/11 17:07:59 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.220 2007/10/13 16:35:19 deraadt Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -738,7 +738,6 @@ void fatalx(const char *) __dead;
int cmdline_symset(char *);
/* config.c */
-int check_file_secrecy(int, const char *);
int host(const char *, struct bgpd_addr *, u_int8_t *);
/* imsg.c */
diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c
index fd87cbfe4fe..49888fbd7a2 100644
--- a/usr.sbin/bgpd/config.c
+++ b/usr.sbin/bgpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.49 2007/01/31 13:04:21 claudio Exp $ */
+/* $OpenBSD: config.c,v 1.50 2007/10/13 16:35:20 deraadt Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -154,29 +154,6 @@ get_bgpid(void)
}
int
-check_file_secrecy(int fd, const char *fname)
-{
- struct stat st;
-
- if (fstat(fd, &st)) {
- log_warn("cannot stat %s", fname);
- return (-1);
- }
-
- if (st.st_uid != 0 && st.st_uid != getuid()) {
- log_warnx("%s: owner not root or current user", fname);
- return (-1);
- }
-
- if (st.st_mode & (S_IRWXG | S_IRWXO)) {
- log_warnx("%s: group/world readable/writeable", fname);
- return (-1);
- }
-
- return (0);
-}
-
-int
host(const char *s, struct bgpd_addr *h, u_int8_t *len)
{
int done = 0;
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 88a7280bbe4..888f7b7bc97 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.209 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.210 2007/10/13 16:35:20 deraadt Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -22,11 +22,13 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
+#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
@@ -38,6 +40,37 @@
#include "mrt.h"
#include "session.h"
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
+
static struct bgpd_config *conf;
static struct mrt_head *mrtconf;
static struct network_head *netconf;
@@ -52,24 +85,6 @@ static struct filter_rule *curgroup_filter[2];
static struct listen_addrs *listen_addrs;
static u_int32_t id;
-TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
-static struct file {
- TAILQ_ENTRY(file) entry;
- FILE *stream;
- char *name;
- int lineno;
- int errors;
-} *file;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-
struct filter_peers_l {
struct filter_peers_l *next;
struct filter_peers p;
@@ -92,7 +107,6 @@ struct filter_match_l {
sa_family_t af;
} fmopts;
-struct file *include_file(const char *);
struct peer *alloc_peer(void);
struct peer *new_peer(void);
struct peer *new_group(void);
@@ -109,19 +123,8 @@ void move_filterset(struct filter_set_head *,
struct filter_set_head *);
struct filter_rule *get_rule(enum action_types);
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entry;
- int used;
- int persist;
- char *nam;
- char *val;
-};
-
-int symset(const char *, const char *, int);
-char *symget(const char *);
-int getcommunity(char *);
-int parsecommunity(char *, int *, int *);
+int getcommunity(char *);
+int parsecommunity(char *, int *, int *);
typedef struct {
union {
@@ -287,7 +290,7 @@ varset : STRING '=' string {
include : INCLUDE STRING {
struct file *nfile;
- if ((nfile = include_file($2)) == NULL) {
+ if ((nfile = pushfile($2, 1)) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -1861,10 +1864,8 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- FILE *f = file->stream;
- struct file *prevfile;
int c, next;
if (parsebuf) {
@@ -1881,13 +1882,18 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
@@ -1898,24 +1904,17 @@ lgetc(int inquot)
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
- while (c == EOF &&
- (prevfile = TAILQ_PREV(file, files, entry)) != NULL) {
- prevfile->errors += file->errors;
- TAILQ_REMOVE(&files, file, entry);
- fclose(f);
- free(file->name);
- free(file);
- file = prevfile;
- f = file->stream;
- c = getc(f);
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
}
-
return (c);
}
@@ -1961,7 +1960,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -2003,21 +2002,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -2099,34 +2098,69 @@ nodigits:
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
struct file *
-include_file(const char *name)
+pushfile(const char *name, int secret)
{
struct file *nfile;
if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
(nfile->name = strdup(name)) == NULL)
return (NULL);
-
if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
- log_warn("%s", nfile->name);
+ free(nfile->name);
+ free(nfile);
return (NULL);
}
-
- if (check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
fclose(nfile->stream);
free(nfile->name);
free(nfile);
return (NULL);
}
-
nfile->lineno = 1;
TAILQ_INSERT_TAIL(&files, nfile, entry);
-
return (nfile);
}
int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
+int
parse_config(char *filename, struct bgpd_config *xconf,
struct mrt_head *xmconf, struct peer **xpeers, struct network_head *nc,
struct filter_head *xfilter_l)
@@ -2138,13 +2172,16 @@ parse_config(char *filename, struct bgpd_config *xconf,
struct filter_rule *r;
int errors = 0;
- if ((file = include_file(filename)) == NULL) {
+ if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
+ fatal(NULL);
+ conf->opts = xconf->opts;
+
+ if ((file = pushfile(filename, 1)) == NULL) {
+ free(conf);
log_warnx("cannot open the main config file!");
return (-1);
}
- if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
- fatal(NULL);
if ((mrtconf = calloc(1, sizeof(struct mrt_head))) == NULL)
fatal(NULL);
if ((listen_addrs = calloc(1, sizeof(struct listen_addrs))) == NULL)
@@ -2166,7 +2203,6 @@ parse_config(char *filename, struct bgpd_config *xconf,
curpeer = NULL;
curgroup = NULL;
id = 1;
- conf->opts = xconf->opts;
/* network list is always empty in the parent */
netconf = nc;
@@ -2176,6 +2212,7 @@ parse_config(char *filename, struct bgpd_config *xconf,
yyparse();
errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
@@ -2258,11 +2295,6 @@ parse_config(char *filename, struct bgpd_config *xconf,
free(peerfilter_l);
free(groupfilter_l);
- TAILQ_REMOVE(&files, file, entry);
- fclose(file->stream);
- free(file->name);
- free(file);
-
return (errors ? -1 : 0);
}