diff options
Diffstat (limited to 'grammar.y.in')
-rw-r--r-- | grammar.y.in | 122 |
1 files changed, 101 insertions, 21 deletions
diff --git a/grammar.y.in b/grammar.y.in index 2360d3c7..77f92afb 100644 --- a/grammar.y.in +++ b/grammar.y.in @@ -110,21 +110,31 @@ struct rtentry; #include "os-proto.h" #endif -#ifdef YYBYACC +/* + * Work around some bugs in Berkeley YACC prior to the 2017-07-09 + * release. + * + * The 2005-05-05 release was the first one to define YYPATCH, so + * we treat any release that either 1) doesn't define YYPATCH or + * 2) defines it to a value < 20170709 as being buggy. + */ +#if defined(YYBYACC) && (!defined(YYPATCH) || YYPATCH < 20170709) /* * Both Berkeley YACC and Bison define yydebug (under whatever name * it has) as a global, but Bison does so only if YYDEBUG is defined. - * Berkeley YACC define it even if YYDEBUG isn't defined; declare it - * here to suppress a warning. + * Berkeley YACC, prior to the 2017-07-09 release, defines it even if + * YYDEBUG isn't defined; declare it here to suppress a warning. The + * 2017-07-09 release fixes that. */ #if !defined(YYDEBUG) extern int yydebug; #endif /* - * In Berkeley YACC, yynerrs (under whatever name it has) is global, - * even if it's building a reentrant parser. In Bison, it's local - * in reentrant parsers. + * In Berkeley YACC, prior to the 2017-07-09 release, yynerrs (under + * whatever name it has) is global, even if it's building a reentrant + * parser. In Bison, and in the Berkeley YACC 2017-07-09 release and + * later, it's local in reentrant parsers. * * Declare it to squelch a warning. */ @@ -424,6 +434,14 @@ DIAG_OFF_BISON_BYACC %% prog: null expr { + /* + * I'm not sure we have a reason to use yynerrs, but it's + * declared, and incremented, whether we need it or not, + * which means tha Clang 15 will give a "used but not + * set" warning. This should suppress the warning for + * yynerrs without suppressing it for other variables. + */ + (void) yynerrs; CHECK_INT_VAL(finish_parse(cstate, $2.b)); } | null @@ -446,25 +464,59 @@ id: nid | paren pid ')' { $$ = $2; } ; nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); } - | HID '/' NUM { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3, - $$.q = $<blk>0.q))); } - | HID NETMASK HID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0, - $$.q = $<blk>0.q))); } + | HID '/' NUM { + CHECK_PTR_VAL($1); + /* Check whether HID/NUM is being used when appropriate */ + $$.q = $<blk>0.q; + if ($$.q.addr == Q_PORT) { + bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length"); + YYABORT; + } else if ($$.q.addr == Q_PORTRANGE) { + bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length"); + YYABORT; + } else if ($$.q.addr == Q_PROTO) { + bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length"); + YYABORT; + } else if ($$.q.addr == Q_PROTOCHAIN) { + bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length"); + YYABORT; + } + CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3, $$.q))); + } + | HID NETMASK HID { + CHECK_PTR_VAL($1); + /* Check whether HID maesk HID is being used when appropriate */ + $$.q = $<blk>0.q; + if ($$.q.addr == Q_PORT) { + bpf_set_error(cstate, "'port' modifier applied to IP address and netmask"); + YYABORT; + } else if ($$.q.addr == Q_PORTRANGE) { + bpf_set_error(cstate, "'portrange' modifier applied to IP address and netmask"); + YYABORT; + } else if ($$.q.addr == Q_PROTO) { + bpf_set_error(cstate, "'proto' modifier applied to IP address and netmask"); + YYABORT; + } else if ($$.q.addr == Q_PROTOCHAIN) { + bpf_set_error(cstate, "'protochain' modifier applied to IP address and netmask"); + YYABORT; + } + CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0, $$.q))); + } | HID { CHECK_PTR_VAL($1); - /* Decide how to parse HID based on proto */ + /* Check whether HID is being used when appropriate */ $$.q = $<blk>0.q; if ($$.q.addr == Q_PORT) { - bpf_set_error(cstate, "'port' modifier applied to ip host"); + bpf_set_error(cstate, "'port' modifier applied to IP address"); YYABORT; } else if ($$.q.addr == Q_PORTRANGE) { - bpf_set_error(cstate, "'portrange' modifier applied to ip host"); + bpf_set_error(cstate, "'portrange' modifier applied to IP address"); YYABORT; } else if ($$.q.addr == Q_PROTO) { - bpf_set_error(cstate, "'proto' modifier applied to ip host"); + bpf_set_error(cstate, "'proto' modifier applied to IP address"); YYABORT; } else if ($$.q.addr == Q_PROTOCHAIN) { - bpf_set_error(cstate, "'protochain' modifier applied to ip host"); + bpf_set_error(cstate, "'protochain' modifier applied to IP address"); YYABORT; } CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q))); @@ -472,10 +524,24 @@ nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$. | HID6 '/' NUM { CHECK_PTR_VAL($1); #ifdef INET6 - CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, NULL, $3, - $$.q = $<blk>0.q))); + /* Check whether HID6/NUM is being used when appropriate */ + $$.q = $<blk>0.q; + if ($$.q.addr == Q_PORT) { + bpf_set_error(cstate, "'port' modifier applied to IP address and prefix length"); + YYABORT; + } else if ($$.q.addr == Q_PORTRANGE) { + bpf_set_error(cstate, "'portrange' modifier applied to IP address and prefix length"); + YYABORT; + } else if ($$.q.addr == Q_PROTO) { + bpf_set_error(cstate, "'proto' modifier applied to IP address and prefix length "); + YYABORT; + } else if ($$.q.addr == Q_PROTOCHAIN) { + bpf_set_error(cstate, "'protochain' modifier applied to IP address and prefix length"); + YYABORT; + } + CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, $3, $$.q))); #else - bpf_set_error(cstate, "'ip6addr/prefixlen' not supported " + bpf_set_error(cstate, "IPv6 addresses not supported " "in this configuration"); YYABORT; #endif /*INET6*/ @@ -483,10 +549,24 @@ nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$. | HID6 { CHECK_PTR_VAL($1); #ifdef INET6 - CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 0, 128, - $$.q = $<blk>0.q))); + /* Check whether HID6 is being used when appropriate */ + $$.q = $<blk>0.q; + if ($$.q.addr == Q_PORT) { + bpf_set_error(cstate, "'port' modifier applied to IP address"); + YYABORT; + } else if ($$.q.addr == Q_PORTRANGE) { + bpf_set_error(cstate, "'portrange' modifier applied to IP address"); + YYABORT; + } else if ($$.q.addr == Q_PROTO) { + bpf_set_error(cstate, "'proto' modifier applied to 'ip6addr/prefixlen"); + YYABORT; + } else if ($$.q.addr == Q_PROTOCHAIN) { + bpf_set_error(cstate, "'protochain' modifier applied to IP address"); + YYABORT; + } + CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 128, $$.q))); #else - bpf_set_error(cstate, "'ip6addr' not supported " + bpf_set_error(cstate, "IPv6 addresses not supported " "in this configuration"); YYABORT; #endif /*INET6*/ |