summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordhartmei <dhartmei@openbsd.org>2002-09-02 19:42:54 +0000
committerdhartmei <dhartmei@openbsd.org>2002-09-02 19:42:54 +0000
commitc3a420ba8fb48427f54bbe77e4bb978a66e95a76 (patch)
treebc1cb531226d65eedc5bab39cfe6c4ad808a872a
parentMake sure the interface specified with route-to/dup-to/fastroute exists (diff)
downloadwireguard-openbsd-c3a420ba8fb48427f54bbe77e4bb978a66e95a76.tar.xz
wireguard-openbsd-c3a420ba8fb48427f54bbe77e4bb978a66e95a76.zip
Fix parsing of port ranges in translation rules (port a:b -> port c:d).
ok henning@
-rw-r--r--sbin/pfctl/parse.y84
1 files changed, 61 insertions, 23 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 3aae9cc3cf8..42b84750607 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.143 2002/09/02 19:40:31 dhartmei Exp $ */
+/* $OpenBSD: parse.y,v 1.144 2002/09/02 19:42:54 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -161,6 +161,7 @@ int findeol(void);
int yylex(void);
struct node_host *host(char *);
int atoul(char *, u_long *);
+int getservice(char *);
struct sym {
@@ -775,7 +776,7 @@ port : STRING {
if (s == NULL)
s = getservbyname($1, "udp");
if (s == NULL) {
- yyerror("unknown protocol %s", $1);
+ yyerror("unknown port %s", $1);
YYERROR;
}
$$ = s->s_port;
@@ -1178,19 +1179,26 @@ no : /* empty */ { $$ = 0; }
| NO { $$ = 1; }
;
-rport : port {
- $$.a = $1;
- $$.b = $$.t = 0;
- }
- | port ':' port {
- $$.a = $1;
- $$.b = $3;
- $$.t = PF_RPORT_RANGE;
- }
- | port ':' '*' {
- $$.a = $1;
- $$.b = 0;
- $$.t = PF_RPORT_RANGE;
+rport : STRING {
+ char *p = strchr($1, ':');
+
+ if (p == NULL) {
+ if (($$.a = getservice($1)) == -1)
+ YYERROR;
+ $$.b = $$.t = 0;
+ } else if (!strcmp(p+1, "*")) {
+ *p = 0;
+ if (($$.a = getservice($1)) == -1)
+ YYERROR;
+ $$.b = 0;
+ $$.t = PF_RPORT_RANGE;
+ } else {
+ *p++ = 0;
+ if (($$.a = getservice($1)) == -1 ||
+ ($$.b = getservice(p)) == -1)
+ YYERROR;
+ $$.t = PF_RPORT_RANGE;
+ }
}
;
@@ -1435,14 +1443,20 @@ rdrrule : no RDR interface af proto FROM ipspec TO ipspec dport redirection
dport : /* empty */ {
$$.a = $$.b = $$.t = 0;
}
- | PORT port {
- $$.a = $2;
- $$.b = $$.t = 0;
- }
- | PORT port ':' port {
- $$.a = $2;
- $$.b = $4;
- $$.t = PF_DPORT_RANGE;
+ | PORT STRING {
+ char *p = strchr($2, ':');
+
+ if (p == NULL) {
+ if (($$.a = getservice($2)) == -1)
+ YYERROR;
+ $$.b = $$.t = 0;
+ } else {
+ *p++ = 0;
+ if (($$.a = getservice($2)) == -1 ||
+ ($$.b = getservice(p)) == -1)
+ YYERROR;
+ $$.t = PF_DPORT_RANGE;
+ }
}
;
@@ -2726,3 +2740,27 @@ atoul(char *s, u_long *ulvalp)
*ulvalp = ulval;
return (0);
}
+
+int
+getservice(char *n)
+{
+ struct servent *s;
+ u_long ulval;
+
+ if (atoul(n, &ulval) == 0) {
+ if (ulval < 0 || ulval > 65535) {
+ yyerror("illegal port value %d", ulval);
+ return (-1);
+ }
+ return (htons(ulval));
+ } else {
+ s = getservbyname(n, "tcp");
+ if (s == NULL)
+ s = getservbyname(n, "udp");
+ if (s == NULL) {
+ yyerror("unknown port %s", n);
+ return (-1);
+ }
+ return (s->s_port);
+ }
+}