summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordhartmei <dhartmei@openbsd.org>2001-12-10 18:08:11 +0000
committerdhartmei <dhartmei@openbsd.org>2001-12-10 18:08:11 +0000
commit80edb1f0b0b6bc8e9107a6db5ff4df765625d48a (patch)
tree9c1ab2e29179e7f2df97ac8140efd693eeb8e234
parentNo need for uvm_useracc here now. vslock catches those problems. (diff)
downloadwireguard-openbsd-80edb1f0b0b6bc8e9107a6db5ff4df765625d48a.tar.xz
wireguard-openbsd-80edb1f0b0b6bc8e9107a6db5ff4df765625d48a.zip
Add stateful filtering for other (non-TCP/UDP/ICMP) protocol, based on
source/destination addresses/ports only. Add RDR for ICMP. Add NAT/RDR/BINAT for other protocols. Destination and redirection port(s) are now optional for RDR rules. Not specifying destination port(s) means 'redirect all ports', not specifying redirection port(s) means 'redirect to the original port'.
-rw-r--r--sbin/pfctl/parse.y19
-rw-r--r--sbin/pfctl/pfctl.88
-rw-r--r--sbin/pfctl/pfctl.c5
-rw-r--r--sbin/pfctl/pfctl_parser.c96
-rw-r--r--sys/net/pf.c241
-rw-r--r--sys/net/pfvar.h7
6 files changed, 298 insertions, 78 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 3e4b367ba8f..f90fc6bb594 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.46 2001/12/05 17:11:54 dhartmei Exp $ */
+/* $OpenBSD: parse.y,v 1.47 2001/12/10 18:08:12 dhartmei Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -921,11 +921,21 @@ rdrrule : RDR interface proto FROM ipspec TO ipspec dport ARROW address rport
rdr.rport = $11.a;
rdr.opts |= $11.t;
+ if (rdr.proto && rdr.proto != IPPROTO_TCP &&
+ rdr.proto != IPPROTO_UDP &&
+ (rdr.dport || rdr.dport2 || rdr.rport)) {
+ yyerror("rdr ports are only valid for proto tcp/udp");
+ YYERROR;
+ }
+
pfctl_add_rdr(pf, &rdr);
}
;
-dport : PORT port {
+dport : /* empty */ {
+ $$.a = $$.b = $$.t = 0;
+ }
+ | PORT port {
$$.a = $2;
$$.b = $$.t = 0;
}
@@ -936,7 +946,10 @@ dport : PORT port {
}
;
-rport : PORT port {
+rport : /* empty */ {
+ $$.a = $$.b = $$.t = 0;
+ }
+ | PORT port {
$$.a = $2;
$$.b = $$.t = 0;
}
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
index 212e091bd75..e10bea3b1ca 100644
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pfctl.8,v 1.34 2001/10/11 00:53:21 dhartmei Exp $
+.\" $OpenBSD: pfctl.8,v 1.35 2001/12/10 18:08:12 dhartmei Exp $
.\"
.\" Copyright (c) 2001 Kjell Wooding. All rights reserved.
.\"
@@ -213,6 +213,12 @@ The state after the first packet.
The state after an icmp error came back in response to an icmp packet.
.El
.Pp
+Other protocols are handled similarly to UDP:
+.Bl -tag -width "t other.multiple " -compact
+.It Fl t Ar other.first
+.It Fl t Ar other.single
+.It Fl t Ar other.multiple
+.El
.Bd -literal
Example:
# Timeout established connections after an hour of inactivity
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index c231a2e6232..3f242510653 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.47 2001/10/04 21:54:15 dhartmei Exp $ */
+/* $OpenBSD: pfctl.c,v 1.48 2001/12/10 18:08:12 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -94,6 +94,9 @@ static const struct {
{ "udp.multiple", PFTM_UDP_MULTIPLE },
{ "icmp.first", PFTM_ICMP_FIRST_PACKET },
{ "icmp.error", PFTM_ICMP_ERROR_REPLY },
+ { "other.first", PFTM_OTHER_FIRST_PACKET },
+ { "other.single", PFTM_OTHER_SINGLE },
+ { "other.multiple", PFTM_OTHER_MULTIPLE },
{ "frag", PFTM_FRAG },
{ "interval", PFTM_INTERVAL },
{ NULL, 0 }};
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 6a3853b3f1b..5a598cfda01 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.55 2001/12/01 16:44:45 frantzen Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.56 2001/12/10 18:08:12 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -296,10 +296,12 @@ print_host(struct pf_state_host *h, int af)
u_int16_t p = ntohs(h->port);
print_addr(&h->addr, NULL, af);
- if (af == AF_INET)
- printf(":%u", p);
- else
- printf("[%u]", p);
+ if (p) {
+ if (af == AF_INET)
+ printf(":%u", p);
+ else
+ printf("[%u]", p);
+ }
}
@@ -365,6 +367,13 @@ print_nat(struct pf_nat *n)
printf("! ");
printf("%s ", n->ifname);
}
+ if (n->proto) {
+ struct protoent *p = getprotobynumber(n->proto);
+ if (n != NULL)
+ printf("proto %s ", p->p_name);
+ else
+ printf("proto %u ", n->proto);
+ }
printf("from ");
if (!PF_AZERO(&n->saddr, n->af) || !PF_AZERO(&n->smask, n->af)) {
if (n->snot)
@@ -383,18 +392,6 @@ print_nat(struct pf_nat *n)
printf("any ");
printf("-> ");
print_addr(&n->raddr, NULL, n->af);
- printf(" ");
- switch (n->proto) {
- case IPPROTO_TCP:
- printf("proto tcp");
- break;
- case IPPROTO_UDP:
- printf("proto udp");
- break;
- case IPPROTO_ICMP:
- printf("proto icmp");
- break;
- }
printf("\n");
}
@@ -406,16 +403,12 @@ print_binat(struct pf_binat *b)
printf("on ");
printf("%s ", b->ifname);
}
- switch (b->proto) {
- case IPPROTO_TCP:
- printf("proto tcp ");
- break;
- case IPPROTO_UDP:
- printf("proto udp ");
- break;
- case IPPROTO_ICMP:
- printf("proto icmp ");
- break;
+ if (b->proto) {
+ struct protoent *p = getprotobynumber(b->proto);
+ if (p != NULL)
+ printf("proto %s ", p->p_name);
+ else
+ printf("proto %u ", b->proto);
}
printf("from ");
print_addr(&b->saddr, NULL, b->af);
@@ -443,13 +436,12 @@ print_rdr(struct pf_rdr *r)
printf("! ");
printf("%s ", r->ifname);
}
- switch (r->proto) {
- case IPPROTO_TCP:
- printf("proto tcp ");
- break;
- case IPPROTO_UDP:
- printf("proto udp ");
- break;
+ if (r->proto) {
+ struct protoent *p = getprotobynumber(r->proto);
+ if (p != NULL)
+ printf("proto %s ", p->p_name);
+ else
+ printf("proto %u ", r->proto);
}
printf("from ");
if (!PF_AZERO(&r->saddr, r->af) || !PF_AZERO(&r->smask, r->af)) {
@@ -467,15 +459,19 @@ print_rdr(struct pf_rdr *r)
printf(" ");
} else
printf("any ");
- printf("port %u", ntohs(r->dport));
- if (r->opts & PF_DPORT_RANGE)
- printf(":%u", ntohs(r->dport2));
+ if (r->dport) {
+ printf("port %u", ntohs(r->dport));
+ if (r->opts & PF_DPORT_RANGE)
+ printf(":%u", ntohs(r->dport2));
+ }
printf(" -> ");
print_addr(&r->raddr, NULL, r->af);
printf(" ");
- printf("port %u", ntohs(r->rport));
- if (r->opts & PF_RPORT_RANGE)
- printf(":*");
+ if (r->rport) {
+ printf("port %u", ntohs(r->rport));
+ if (r->opts & PF_RPORT_RANGE)
+ printf(":*");
+ }
printf("\n");
}
@@ -534,6 +530,7 @@ void
print_state(struct pf_state *s, int opts)
{
struct pf_state_peer *src, *dst;
+ struct protoent *p;
u_int8_t hrs, min, sec;
if (s->direction == PF_OUT) {
@@ -543,21 +540,10 @@ print_state(struct pf_state *s, int opts)
src = &s->dst;
dst = &s->src;
}
- switch (s->proto) {
- case IPPROTO_TCP:
- printf("TCP ");
- break;
- case IPPROTO_UDP:
- printf("UDP ");
- break;
- case IPPROTO_ICMPV6:
- case IPPROTO_ICMP:
- printf("ICMP ");
- break;
- default:
- printf("???? ");
- break;
- }
+ if ((p = getprotobynumber(s->proto)) != NULL)
+ printf("%s ", p->p_name);
+ else
+ printf("%u ", s->proto);
if (PF_ANEQ(&s->lan.addr, &s->gwy.addr, s->af) ||
(s->lan.port != s->gwy.port)) {
print_host(&s->lan, s->af);
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 4d5345401bf..1b811219848 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.176 2001/12/03 18:47:46 dhartmei Exp $ */
+/* $OpenBSD: pf.c,v 1.177 2001/12/10 18:08:11 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -153,6 +153,10 @@ int pftm_udp_multiple = 60; /* Bidirectional */
int pftm_icmp_first_packet = 20; /* First ICMP packet */
int pftm_icmp_error_reply = 10; /* Got error response */
+int pftm_other_first_packet = 60; /* First packet */
+int pftm_other_single = 30; /* Unidirectional */
+int pftm_other_multiple = 60; /* Bidirectional */
+
int pftm_frag = 30; /* Fragment expire */
int pftm_interval = 10; /* expire interval */
@@ -163,7 +167,8 @@ int *pftm_timeouts[PFTM_MAX] = { &pftm_tcp_first_packet,
&pftm_tcp_closed, &pftm_udp_first_packet,
&pftm_udp_single, &pftm_udp_multiple,
&pftm_icmp_first_packet, &pftm_icmp_error_reply,
- &pftm_frag, &pftm_interval };
+ &pftm_other_first_packet, &pftm_other_single,
+ &pftm_other_multiple, &pftm_frag, &pftm_interval };
struct pool pf_tree_pl, pf_rule_pl, pf_nat_pl, pf_sport_pl;
@@ -241,6 +246,8 @@ int pf_test_state_udp(struct pf_state **, int,
int pf_test_state_icmp(struct pf_state **, int,
struct ifnet *, struct mbuf *, int, int,
void *, struct pf_pdesc *);
+int pf_test_state_other(struct pf_state **, int,
+ struct ifnet *, struct pf_pdesc *);
void *pf_pull_hdr(struct mbuf *, int, void *, int,
u_short *, u_short *, int);
void pf_calc_skip_steps(struct pf_rulequeue *);
@@ -2710,7 +2717,7 @@ pf_get_rdr(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr,
(!r->af || r->af == af) &&
PF_MATCHA(r->snot, &r->saddr, &r->smask, saddr, af) &&
PF_MATCHA(r->dnot, &r->daddr, &r->dmask, daddr, af) &&
- ((!r->dport2 && dport == r->dport) ||
+ ((!r->dport2 && (!r->dport || dport == r->dport)) ||
(r->dport2 && (ntohs(dport) >= ntohs(r->dport)) &&
ntohs(dport) <= ntohs(r->dport2))))
rm = r;
@@ -2779,8 +2786,10 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
bport = th->th_dport;
if (rdr->opts & PF_RPORT_RANGE)
nport = pf_map_port_range(rdr, th->th_dport);
- else
+ else if (rdr->rport)
nport = rdr->rport;
+ else
+ nport = bport;
PF_ACPY(&baddr, daddr, af);
pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
&th->th_sum, &rdr->raddr, nport, 0, af);
@@ -3002,8 +3011,10 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
bport = uh->uh_dport;
if (rdr->opts & PF_RPORT_RANGE)
nport = pf_map_port_range(rdr, uh->uh_dport);
- else
+ else if (rdr->rport)
nport = rdr->rport;
+ else
+ nport = bport;
PF_ACPY(&baddr, daddr, af);
pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
@@ -3095,10 +3106,8 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
if ((*rm != NULL && (*rm)->keep_state) || nat != NULL ||
binat != NULL || rdr != NULL) {
/* create new state */
- u_int16_t len;
struct pf_state *s;
- len = pd->tot_len - off - sizeof(*uh);
s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL) {
if (nport && nat != NULL)
@@ -3167,6 +3176,7 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
{
struct pf_nat *nat = NULL;
struct pf_binat *binat = NULL;
+ struct pf_rdr *rdr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst, baddr;
struct pf_rule *r;
u_short reason;
@@ -3237,8 +3247,28 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
}
}
} else {
+ /* check incoming packet for RDR */
+ if ((rdr = pf_get_rdr(ifp, pd->proto,
+ saddr, daddr, 0, af)) != NULL) {
+ PF_ACPY(&baddr, daddr, af);
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ pf_change_a(&daddr->v4.s_addr,
+ pd->ip_sum, rdr->raddr.v4.s_addr, 0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
+ &rdr->raddr, 0);
+ rewrite++;
+ break;
+#endif /* INET6 */
+ }
+ }
/* check incoming packet for BINAT */
- if ((binat = pf_get_binat(PF_IN, ifp, IPPROTO_ICMP,
+ else if ((binat = pf_get_binat(PF_IN, ifp, IPPROTO_ICMP,
daddr, saddr, af)) != NULL) {
PF_ACPY(&baddr, daddr, af);
switch (af) {
@@ -3307,12 +3337,11 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
return (PF_DROP);
}
- if ((*rm != NULL && (*rm)->keep_state) || nat != NULL || binat != NULL) {
+ if ((*rm != NULL && (*rm)->keep_state) || nat != NULL ||
+ rdr != NULL || binat != NULL) {
/* create new state */
- u_int16_t len;
struct pf_state *s;
- len = pd->tot_len - off - ICMP_MINLEN;
s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL)
return (PF_DROP);
@@ -3338,7 +3367,7 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->lan.port = icmpid;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = icmpid;
- if (binat != NULL)
+ if (binat != NULL || rdr != NULL)
PF_ACPY(&s->gwy.addr, &baddr, af);
else
PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
@@ -3376,8 +3405,10 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
struct mbuf *m, void *h, struct pf_pdesc *pd)
{
struct pf_rule *r;
+ struct pf_nat *nat = NULL;
struct pf_binat *binat = NULL;
- struct pf_addr *saddr = pd->src, *daddr = pd->dst;
+ struct pf_rdr *rdr = NULL;
+ struct pf_addr *saddr = pd->src, *daddr = pd->dst, baddr;
u_int8_t af = pd->af;
*rm = NULL;
@@ -3386,6 +3417,7 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
/* check outgoing packet for BINAT */
if ((binat = pf_get_binat(PF_OUT, ifp, pd->proto,
saddr, daddr, af)) != NULL) {
+ PF_ACPY(&baddr, saddr, af);
switch (af) {
#ifdef INET
case AF_INET:
@@ -3400,10 +3432,47 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
#endif /* INET6 */
}
}
+ /* check outgoing packet for NAT */
+ else if ((nat = pf_get_nat(ifp, pd->proto,
+ saddr, daddr, af)) != NULL) {
+ PF_ACPY(&baddr, saddr, af);
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ pf_change_a(&saddr->v4.s_addr,
+ pd->ip_sum, nat->raddr.v4.s_addr, 0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ PF_ACPY(saddr, &nat->raddr, af);
+ break;
+#endif /* INET6 */
+ }
+ }
} else {
+ /* check incoming packet for RDR */
+ if ((rdr = pf_get_rdr(ifp, pd->proto,
+ saddr, daddr, 0, af)) != NULL) {
+ PF_ACPY(&baddr, daddr, af);
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ pf_change_a(&daddr->v4.s_addr,
+ pd->ip_sum, rdr->raddr.v4.s_addr, 0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ PF_ACPY(daddr, &rdr->raddr, af);
+ break;
+#endif /* INET6 */
+ }
+ }
/* check incoming packet for BINAT */
- if ((binat = pf_get_binat(PF_IN, ifp, pd->proto,
+ else if ((binat = pf_get_binat(PF_IN, ifp, pd->proto,
daddr, saddr, af)) != NULL) {
+ PF_ACPY(&baddr, daddr, af);
switch (af) {
#ifdef INET
case AF_INET:
@@ -3461,6 +3530,60 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
if ((*rm)->action != PF_PASS)
return (PF_DROP);
}
+
+ if ((*rm != NULL && (*rm)->keep_state) || nat != NULL ||
+ rdr != NULL || binat != NULL) {
+ /* create new state */
+ struct pf_state *s;
+
+ s = pool_get(&pf_state_pl, PR_NOWAIT);
+ if (s == NULL)
+ return (PF_DROP);
+
+ s->rule = *rm;
+ s->allow_opts = *rm && (*rm)->allow_opts;
+ s->log = *rm && ((*rm)->log & 2);
+ s->proto = pd->proto;
+ s->direction = direction;
+ s->af = af;
+ if (direction == PF_OUT) {
+ PF_ACPY(&s->gwy.addr, saddr, af);
+ s->gwy.port = 0;
+ PF_ACPY(&s->ext.addr, daddr, af);
+ s->ext.port = 0;
+ if (nat != NULL || binat != NULL)
+ PF_ACPY(&s->lan.addr, &baddr, af);
+ else
+ PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
+ s->lan.port = 0;
+ } else {
+ PF_ACPY(&s->lan.addr, daddr, af);
+ s->lan.port = 0;
+ PF_ACPY(&s->ext.addr, saddr, af);
+ s->ext.port = 0;
+ if (binat != NULL || rdr != NULL)
+ PF_ACPY(&s->gwy.addr, &baddr, af);
+ else
+ PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
+ s->gwy.port = 0;
+ }
+ s->src.seqlo = 0;
+ s->src.seqhi = 0;
+ s->src.seqdiff = 0;
+ s->src.max_win = 0;
+ s->src.state = 1;
+ s->dst.seqlo = 0;
+ s->dst.seqhi = 0;
+ s->dst.seqdiff = 0;
+ s->dst.max_win = 0;
+ s->dst.state = 0;
+ s->creation = pftv.tv_sec;
+ s->expire = pftv.tv_sec + pftm_other_first_packet;
+ s->packets = 1;
+ s->bytes = pd->tot_len;
+ pf_insert_state(s);
+ }
+
return (PF_PASS);
}
@@ -4280,6 +4403,89 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct ifnet *ifp,
}
}
+int
+pf_test_state_other(struct pf_state **state, int direction, struct ifnet *ifp,
+ struct pf_pdesc *pd)
+{
+ struct pf_state_peer *src, *dst;
+ struct pf_tree_key key;
+
+ key.af = pd->af;
+ key.proto = pd->proto;
+ PF_ACPY(&key.addr[0], pd->src, key.af);
+ PF_ACPY(&key.addr[1], pd->dst, key.af);
+ key.port[0] = 0;
+ key.port[1] = 0;
+
+ if (direction == PF_IN)
+ *state = pf_find_state(tree_ext_gwy, &key);
+ else
+ *state = pf_find_state(tree_lan_ext, &key);
+ if (*state == NULL)
+ return (PF_DROP);
+
+ if (direction == (*state)->direction) {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ } else {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ }
+
+ (*state)->packets++;
+ (*state)->bytes += pd->tot_len;
+
+ /* update states */
+ if (src->state < 1)
+ src->state = 1;
+ if (dst->state == 1)
+ dst->state = 2;
+
+ /* update expire time */
+ if (src->state == 2 && dst->state == 2)
+ (*state)->expire = pftv.tv_sec + pftm_other_multiple;
+ else
+ (*state)->expire = pftv.tv_sec + pftm_other_single;
+
+ /* translate source/destination address, if necessary */
+ if (STATE_TRANSLATE(*state)) {
+ if (direction == PF_OUT)
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+ pf_change_a(&pd->src->v4.s_addr,
+ pd->ip_sum, (*state)->gwy.addr.v4.s_addr, 0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ PF_ACPY(pd->src, &(*state)->gwy.addr, pd->af);
+ break;
+#endif /* INET6 */
+ }
+ else
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+ pf_change_a(&pd->dst->v4.s_addr,
+ pd->ip_sum, (*state)->lan.addr.v4.s_addr, 0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ PF_ACPY(pd->dst, &(*state)->lan.addr, pd->af);
+ break;
+#endif /* INET6 */
+ }
+ }
+
+ if ((*state)->rule != NULL) {
+ (*state)->rule->packets++;
+ (*state)->rule->bytes += pd->tot_len;
+ }
+ return (PF_PASS);
+}
+
/*
* ipoff and off are measured from the start of the mbuf chain.
* h must be at "ipoff" on the mbuf chain.
@@ -4716,7 +4922,12 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
}
default:
- action = pf_test_other(&r, dir, ifp, m, h, &pd);
+ action = pf_test_state_other(&s, dir, ifp, &pd);
+ if (action == PF_PASS) {
+ r = s->rule;
+ log = s->log;
+ } else if (s == NULL)
+ action = pf_test_other(&r, dir, ifp, m, h, &pd);
break;
}
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index ce65e0d3637..6d58c30dde1 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.56 2001/11/26 16:50:26 jasoni Exp $ */
+/* $OpenBSD: pfvar.h,v 1.57 2001/12/10 18:08:11 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -47,8 +47,9 @@ enum { PF_CHANGE_ADD_HEAD=1, PF_CHANGE_ADD_TAIL=2,
enum { PFTM_TCP_FIRST_PACKET=0, PFTM_TCP_OPENING=1, PFTM_TCP_ESTABLISHED=2,
PFTM_TCP_CLOSING=3, PFTM_TCP_FIN_WAIT=4, PFTM_TCP_CLOSED=5,
PFTM_UDP_FIRST_PACKET=6, PFTM_UDP_SINGLE=7, PFTM_UDP_MULTIPLE=8,
- PFTM_ICMP_FIRST_PACKET=9, PFTM_ICMP_ERROR_REPLY=10, PFTM_FRAG=11,
- PFTM_INTERVAL=12, PFTM_MAX=13 };
+ PFTM_ICMP_FIRST_PACKET=9, PFTM_ICMP_ERROR_REPLY=10,
+ PFTM_OTHER_FIRST_PACKET=11, PFTM_OTHER_SINGLE=12,
+ PFTM_OTHER_MULTIPLE=13, PFTM_FRAG=14, PFTM_INTERVAL=15, PFTM_MAX=16 };
enum { PF_FASTROUTE=1, PF_ROUTETO=2, PF_DUPTO=3 };
struct pf_addr {