summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordhartmei <dhartmei@openbsd.org>2002-10-05 21:17:57 +0000
committerdhartmei <dhartmei@openbsd.org>2002-10-05 21:17:57 +0000
commite4cbe364224acdc9b1417f1eb81744db41e5033e (patch)
treeb7cc824dfcbf952b2a4b05c77542810535d58dfb
parentFix a typo ('Your' -> 'You'). Spotted by Julien Bordet. (diff)
downloadwireguard-openbsd-e4cbe364224acdc9b1417f1eb81744db41e5033e.tar.xz
wireguard-openbsd-e4cbe364224acdc9b1417f1eb81744db41e5033e.zip
Allow filtering based on IP header's tos field.
-rw-r--r--sbin/pfctl/parse.y44
-rw-r--r--sbin/pfctl/pfctl_parser.c4
-rw-r--r--share/man/man5/pf.conf.57
-rw-r--r--sys/net/pf.c15
-rw-r--r--sys/net/pfvar.h4
5 files changed, 58 insertions, 16 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index fde971388dc..ab8465d6523 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.154 2002/09/22 15:30:15 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.155 2002/10/05 21:17:57 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -243,7 +243,7 @@ typedef struct {
%token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
%token MINTTL ERROR ALLOWOPTS FASTROUTE ROUTETO DUPTO NO LABEL
-%token NOROUTE FRAGMENT USER GROUP MAXMSS MAXIMUM TTL
+%token NOROUTE FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS
%token FRAGNORM FRAGDROP FRAGCROP
%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE
%token ANTISPOOF FOR
@@ -251,6 +251,7 @@ typedef struct {
%token <v.i> PORTUNARY PORTBINARY
%type <v.interface> interface if_list if_item_not if_item
%type <v.number> number port icmptype icmp6type minttl uid gid maxmss
+%type <v.number> tos
%type <v.i> no dir log af nodf allowopts fragment fragcache
%type <v.b> action flag flags blockspec
%type <v.range> dport rport
@@ -430,7 +431,7 @@ antispoof_iflst : if_item { $$ = $1; }
| antispoof_iflst comma if_item { $3->next = $1; $$ = $3; }
pfrule : action dir logquick interface route af proto fromto
- uids gids flags icmpspec keep fragment allowopts label
+ uids gids flags icmpspec tos keep fragment allowopts label
{
struct pf_rule r;
struct node_state_opt *o;
@@ -466,8 +467,9 @@ pfrule : action dir logquick interface route af proto fromto
}
}
- r.keep_state = $13.action;
- o = $13.options;
+ r.tos = $13;
+ r.keep_state = $14.action;
+ o = $14.options;
while (o) {
struct node_state_opt *p = o;
@@ -495,9 +497,9 @@ pfrule : action dir logquick interface route af proto fromto
free(p);
}
- if ($14)
+ if ($15)
r.rule_flag |= PFRULE_FRAGMENT;
- r.allow_opts = $15;
+ r.allow_opts = $16;
if ($5.rt) {
r.rt = $5.rt;
@@ -525,14 +527,14 @@ pfrule : action dir logquick interface route af proto fromto
}
}
- if ($16) {
- if (strlen($16) >= PF_RULE_LABEL_SIZE) {
+ if ($17) {
+ if (strlen($17) >= PF_RULE_LABEL_SIZE) {
yyerror("rule label too long (max "
"%d chars)", PF_RULE_LABEL_SIZE-1);
YYERROR;
}
- strlcpy(r.label, $16, sizeof(r.label));
- free($16);
+ strlcpy(r.label, $17, sizeof(r.label));
+ free($17);
}
expand_rule(&r, $4, $7, $8.src.host, $8.src.port,
@@ -1125,6 +1127,25 @@ icmp6type : STRING {
}
;
+tos : /* empty */ { $$ = 0; }
+ | TOS STRING {
+ if (!strcmp($2, "lowdelay"))
+ $$ = IPTOS_LOWDELAY;
+ else if (!strcmp($2, "throughput"))
+ $$ = IPTOS_THROUGHPUT;
+ else if (!strcmp($2, "reliability"))
+ $$ = IPTOS_RELIABILITY;
+ else if ($2[0] == '0' && $2[1] == 'x')
+ $$ = strtoul($2, NULL, 16);
+ else
+ $$ = strtoul($2, NULL, 10);
+ if (!$$ || $$ > 255) {
+ yyerror("illegal tos value %s", $2);
+ YYERROR;
+ }
+ }
+ ;
+
keep : /* empty */ {
$$.action = 0;
$$.options = NULL;
@@ -2281,6 +2302,7 @@ lookup(char *s)
{ "state", STATE},
{ "timeout", TIMEOUT},
{ "to", TO},
+ { "tos", TOS},
{ "ttl", TTL},
{ "user", USER},
};
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 8d934140eb3..e063f58f8d6 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.94 2002/07/20 18:58:44 deraadt Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.95 2002/10/05 21:17:57 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -743,6 +743,8 @@ print_rule(struct pf_rule *r)
printf("code %u ", r->code-1);
}
}
+ if (r->tos)
+ printf("tos 0x%2.2x ", r->tos);
if (r->keep_state == PF_STATE_NORMAL)
printf("keep state ");
else if (r->keep_state == PF_STATE_MODULATE)
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
index 14127a20db4..38b2809159f 100644
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pf.conf.5,v 1.90 2002/10/04 10:15:37 henning Exp $
+.\" $OpenBSD: pf.conf.5,v 1.91 2002/10/05 21:17:57 dhartmei Exp $
.\"
.\" Copyright (c) 2002, Daniel Hartmeier
.\" All rights reserved.
@@ -1006,7 +1006,7 @@ pf_rule = action ( "in" | "out" )
[ "on" ifspec ] [ route ] [ af ] [ protospec ]
hosts
[ user ] [ group ] [ flags ]
- [ icmp-type | ipv6-icmp-type ]
+ [ icmp-type | ipv6-icmp-type ] [ tos ]
[ ( "keep" | "modulate" ) "state" [ "(" state-opts ")" ] ]
[ "fragment" ] [ "no-df" ] [ "min-ttl" number ]
[ "max-mss" number ] [ fragmentation ] [ "allow-opts" ]
@@ -1079,6 +1079,9 @@ icmp-type-code = ( icmp-type-name | icmp-type-number )
[ "code" ( icmp-code-name | icmp-code-number ) ] .
icmp-list = icmp-type-code [ [ "," ] icmp-list ] .
+tos = "tos" ( "lowdelay" | "throughput" | "reliability" |
+ [ "0x" ] number ) .
+
state-opts = state-opt [ [ "," ] state-opts ] .
state-opt = ( "max" seconds ) | ( timeout seconds ) .
diff --git a/sys/net/pf.c b/sys/net/pf.c
index f484aafacac..379725adc1f 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.246 2002/10/04 17:45:55 ish Exp $ */
+/* $OpenBSD: pf.c,v 1.247 2002/10/05 21:17:57 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -372,6 +372,7 @@ pf_compare_rules(struct pf_rule *a, struct pf_rule *b)
a->flagset != b->flagset ||
a->rule_flag != b->rule_flag ||
a->min_ttl != b->min_ttl ||
+ a->tos != b->tos ||
a->allow_opts != b->allow_opts)
return (1);
if (PF_ANEQ(&a->src.addr.addr, &b->src.addr.addr, a->af) ||
@@ -1698,6 +1699,8 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], th->th_dport))
r = r->skip[PF_SKIP_DST_PORT];
+ else if (r->tos && !(r->tos & pd->tos))
+ r = TAILQ_NEXT(r, entries);
else if (r->rule_flag & PFRULE_FRAGMENT)
r = TAILQ_NEXT(r, entries);
else if ((r->flagset & th->th_flags) != r->flags)
@@ -1960,6 +1963,8 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], uh->uh_dport))
r = r->skip[PF_SKIP_DST_PORT];
+ else if (r->tos && !(r->tos & pd->tos))
+ r = TAILQ_NEXT(r, entries);
else if (r->rule_flag & PFRULE_FRAGMENT)
r = TAILQ_NEXT(r, entries);
else if (r->uid.op && (lookup != -1 || (lookup =
@@ -2247,6 +2252,8 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = TAILQ_NEXT(r, entries);
else if (r->code && r->code != icmpcode + 1)
r = TAILQ_NEXT(r, entries);
+ else if (r->tos && !(r->tos & pd->tos))
+ r = TAILQ_NEXT(r, entries);
else if (r->rule_flag & PFRULE_FRAGMENT)
r = TAILQ_NEXT(r, entries);
else {
@@ -2463,6 +2470,8 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
!PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
&r->dst.addr.addr, &r->dst.mask, pd->dst, af))
r = r->skip[PF_SKIP_DST_ADDR];
+ else if (r->tos && !(r->tos & pd->tos))
+ r = TAILQ_NEXT(r, entries);
else if (r->rule_flag & PFRULE_FRAGMENT)
r = TAILQ_NEXT(r, entries);
else {
@@ -2586,6 +2595,8 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp,
!PF_AZERO(&r->dst.mask, af) && !PF_MATCHA(r->dst.not,
&r->dst.addr.addr, &r->dst.mask, pd->dst, af))
r = r->skip[PF_SKIP_DST_ADDR];
+ else if (r->tos && !(r->tos & pd->tos))
+ r = TAILQ_NEXT(r, entries);
else if (r->src.port_op || r->dst.port_op ||
r->flagset || r->type || r->code)
r = TAILQ_NEXT(r, entries);
@@ -3881,6 +3892,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
pd.ip_sum = &h->ip_sum;
pd.proto = h->ip_p;
pd.af = AF_INET;
+ pd.tos = h->ip_tos;
pd.tot_len = h->ip_len;
/* handle fragments that didn't get reassembled by normalization */
@@ -4032,6 +4044,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
pd.dst = (struct pf_addr *)&h->ip6_dst;
pd.ip_sum = NULL;
pd.af = AF_INET6;
+ pd.tos = 0;
pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index afbb3f44a0d..8da6466f27b 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.89 2002/08/12 16:41:25 dhartmei Exp $ */
+/* $OpenBSD: pfvar.h,v 1.90 2002/10/05 21:17:57 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -276,6 +276,7 @@ struct pf_rule {
u_int8_t allow_opts;
u_int8_t rt;
u_int8_t return_ttl;
+ u_int8_t tos;
};
#define PFRULE_RETURNRST 0x01
@@ -401,6 +402,7 @@ struct pf_pdesc {
* state code. Easier than tags */
u_int8_t af;
u_int8_t proto;
+ u_int8_t tos;
};
/* flags for RDR options */