summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/parse.y
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-03-02 19:45:05 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-03-02 19:45:05 +0000
commit97d3bc17a77f84f39949facde64b9ce764d17fa6 (patch)
treec4ecba8cd70e15fb00fffd58360f84f1e25a6747 /usr.sbin/bgpd/parse.y
parent5b258471b908015322203a6e9bbf7a85659e9044 (diff)
flesh out the address and prefix parsing, include v6 code, but reject v6
upwards, claudio ok
Diffstat (limited to 'usr.sbin/bgpd/parse.y')
-rw-r--r--usr.sbin/bgpd/parse.y112
1 files changed, 73 insertions, 39 deletions
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index e532266a7b3..2f99598fcf4 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.67 2004/03/01 22:58:12 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.68 2004/03/02 19:45:04 henning Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -91,6 +91,10 @@ typedef struct {
struct filter_peers filter_peers;
struct filter_match filter_match;
struct filter_set filter_set;
+ struct {
+ struct bgpd_addr prefix;
+ u_int8_t len;
+ } prefix;
} v;
int lineno;
} YYSTYPE;
@@ -114,6 +118,7 @@ typedef struct {
%type <v.number> number asnumber optnumber yesno inout
%type <v.string> string
%type <v.addr> address
+%type <v.prefix> prefix
%type <v.u8> action quick direction
%type <v.filter_peers> filter_peer
%type <v.filter_match> filter_match prefixlenop
@@ -227,18 +232,19 @@ conf_main : AS asnumber {
else
YYERROR;
}
- | NETWORK address '/' number filter_set {
+ | NETWORK prefix filter_set {
struct network *n;
- if ((n = calloc(1, sizeof(struct network))) == NULL)
- fatal("new_network");
- memcpy(&n->net.prefix, &$2, sizeof(n->net.prefix));
- if ($4 > 32) {
- yyerror("invalid netmask");
+ if ($2.prefix.af != AF_INET) {
+ yyerror("king bula sez: AF_INET only for now");
YYERROR;
}
- n->net.prefixlen = $4;
- memcpy(&n->net.attrset, &$5,
+ if ((n = calloc(1, sizeof(struct network))) == NULL)
+ fatal("new_network");
+ memcpy(&n->net.prefix, &$2.prefix,
+ sizeof(n->net.prefix));
+ n->net.prefixlen = $2.len;
+ memcpy(&n->net.attrset, &$3,
sizeof(n->net.attrset));
TAILQ_INSERT_TAIL(netconf, n, network_l);
@@ -271,19 +277,38 @@ inout : IN { $$ = 1; }
;
address : STRING {
- int n;
+ u_int8_t len;
- bzero(&$$, sizeof($$));
- $$.af = AF_INET;
- if ((n = inet_pton(AF_INET, $1, &$$.v4)) == -1) {
- yyerror("inet_pton: %s", strerror(errno));
- YYERROR;
- }
- if (n == 0) {
+ if (!host($1, &$$, &len)) {
yyerror("could not parse address spec \"%s\"",
$1);
YYERROR;
}
+
+ if (($$.af == AF_INET && len != 32) ||
+ ($$.af == AF_INET6 && len != 128)) {
+ /* unreachable */
+ yyerror("got prefixlen %u, expected %u",
+ len, $$.af == AF_INET ? 32 : 128);
+ YYERROR;
+ }
+ }
+ ;
+
+prefix : STRING '/' number {
+ char *s;
+
+ if (asprintf(&s, "%s/%u", $1, $3) == -1)
+ fatal(NULL);
+
+ if (!host(s, &$$.prefix, &$$.len)) {
+ free(s);
+ yyerror("could not parse address \"%s/%s\"",
+ $1, $3);
+ YYERROR;
+ }
+
+ free(s);
}
;
@@ -300,7 +325,10 @@ optnumber : /* empty */ { $$ = 0; }
neighbor : { curpeer = new_peer(); }
NEIGHBOR address optnl '{' optnl {
- curpeer->conf.remote_addr.af = AF_INET;
+ if ($3.af != AF_INET) {
+ yyerror("king bula sez: IPv4 transport only");
+ YYERROR;
+ }
memcpy(&curpeer->conf.remote_addr, &$3,
sizeof(curpeer->conf.remote_addr));
if (get_id(curpeer)) {
@@ -467,6 +495,11 @@ filterrule : action quick direction filter_peer filter_match filter_set
{
struct filter_rule r;
+ if ($5.prefix.addr.af && $5.prefix.addr.af != AF_INET) {
+ yyerror("king bula sez: AF_INET only for now");
+ YYERROR;
+ }
+
bzero(&r, sizeof(r));
r.action = $1;
r.quick = $2;
@@ -523,30 +556,31 @@ filter_peer : ANY { $$.peerid = $$.groupid = 0; }
;
filter_match : /* empty */ { bzero(&$$, sizeof($$)); }
- | PREFIX address '/' number {
+ | PREFIX prefix {
bzero(&$$, sizeof($$));
- memcpy(&$$.prefix.addr, &$2, sizeof($$.prefix.addr));
- if ($4 > 32) {
- yyerror("prefixlength must be <= 32");
- YYERROR;
- }
- $$.prefix.len = $4;
+ memcpy(&$$.prefix.addr, &$2.prefix,
+ sizeof($$.prefix.addr));
+ $$.prefix.len = $2.len;
}
- | PREFIX address '/' number PREFIXLEN prefixlenop {
+ | PREFIX prefix PREFIXLEN prefixlenop {
bzero(&$$, sizeof($$));
- memcpy(&$$.prefix.addr, &$2, sizeof($$.prefix.addr));
- if ($4 > 32) {
- yyerror("prefixlength must be <= 32");
- YYERROR;
- }
- $$.prefix.len = $4;
- $$.prefixlen = $6.prefixlen;
- $$.prefixlen.af = AF_INET;
- if ($$.prefixlen.len_max > 32 ||
- $$.prefixlen.len_min > 32) {
- yyerror("prefixlength must be <= 32");
- YYERROR;
- }
+ memcpy(&$$.prefix.addr, &$2.prefix,
+ sizeof($$.prefix.addr));
+ $$.prefix.len = $2.len;
+ $$.prefixlen = $4.prefixlen;
+ $$.prefixlen.af = $2.prefix.af;
+ if ($$.prefixlen.af == AF_INET)
+ if ($$.prefixlen.len_max > 32 ||
+ $$.prefixlen.len_min > 32) {
+ yyerror("prefixlen must be <= 32");
+ YYERROR;
+ }
+ if ($$.prefixlen.af == AF_INET6)
+ if ($$.prefixlen.len_max > 128 ||
+ $$.prefixlen.len_min > 128) {
+ yyerror("prefixlen must be <= 128");
+ YYERROR;
+ }
}
| PREFIXLEN prefixlenop {
bzero(&$$, sizeof($$));