resolve conflicts. (pf from OpenBSD 3.6, kernel part)

This commit is contained in:
yamt 2004-11-14 11:12:16 +00:00
parent 533d14a1b9
commit da18614102
9 changed files with 1455 additions and 857 deletions

View File

@ -1,5 +1,5 @@
/* $NetBSD: if_pflog.c,v 1.4 2004/09/10 08:48:32 yamt Exp $ */
/* $OpenBSD: if_pflog.c,v 1.11 2003/12/31 11:18:25 cedric Exp $ */
/* $NetBSD: if_pflog.c,v 1.5 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: if_pflog.c,v 1.12 2004/05/19 17:50:51 dhartmei Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@ -230,11 +230,9 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
} else {
hdr.rulenr = htonl(am->nr);
hdr.subrulenr = htonl(rm->nr);
if (ruleset != NULL)
memcpy(hdr.ruleset, ruleset->name,
if (ruleset != NULL && ruleset->anchor != NULL)
strlcpy(hdr.ruleset, ruleset->anchor->name,
sizeof(hdr.ruleset));
}
hdr.dir = dir;

View File

@ -1,5 +1,5 @@
/* $NetBSD: if_pflog.h,v 1.2 2004/06/22 14:17:07 itojun Exp $ */
/* $OpenBSD: if_pflog.h,v 1.10 2004/03/19 04:52:04 frantzen Exp $ */
/* $NetBSD: if_pflog.h,v 1.3 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: if_pflog.h,v 1.11 2004/05/19 17:50:51 dhartmei Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -32,10 +32,7 @@ struct pflog_softc {
struct ifnet sc_if; /* the interface */
};
/* XXX keep in sync with pfvar.h */
#ifndef PF_RULESET_NAME_SIZE
#define PF_RULESET_NAME_SIZE 16
#endif
#define PFLOG_RULESET_NAME_SIZE 16
struct pfloghdr {
u_int8_t length;
@ -43,7 +40,7 @@ struct pfloghdr {
u_int8_t action;
u_int8_t reason;
char ifname[IFNAMSIZ];
char ruleset[PF_RULESET_NAME_SIZE];
char ruleset[PFLOG_RULESET_NAME_SIZE];
u_int32_t rulenr;
u_int32_t subrulenr;
u_int8_t dir;

758
sys/dist/pf/net/pf.c vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_if.c,v 1.5 2004/07/26 13:46:43 yamt Exp $ */
/* $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */
/* $NetBSD: pf_if.c,v 1.6 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: pf_if.c,v 1.20 2004/08/15 15:31:46 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -80,10 +80,6 @@ long pfi_update = 1;
struct pfr_addr *pfi_buffer;
int pfi_buffer_cnt;
int pfi_buffer_max;
char pfi_reserved_anchor[PF_ANCHOR_NAME_SIZE] =
PF_RESERVED_ANCHOR;
char pfi_interface_ruleset[PF_RULESET_NAME_SIZE] =
PF_INTERFACE_RULESET;
void pfi_dynaddr_update(void *);
void pfi_kifaddr_update(void *);
@ -97,7 +93,6 @@ void pfi_address_add(struct sockaddr *, int, int);
int pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
struct pfi_kif *pfi_if_create(const char *, struct pfi_kif *, int);
void pfi_copy_group(char *, const char *, int);
void pfi_dynamic_drivers(void);
void pfi_newgroup(const char *, int);
int pfi_skip_if(const char *, struct pfi_kif *, int);
int pfi_unmask(void *);
@ -106,7 +101,6 @@ void pfi_dohooks(struct pfi_kif *);
RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
#define PFI_DYNAMIC_BUSES { "pcmcia", "cardbus", "uhub" }
#define PFI_BUFFER_MAX 0x10000
#define PFI_MTYPE M_IFADDR
@ -133,7 +127,6 @@ pfi_initialize(void)
pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer),
PFI_MTYPE, M_WAITOK);
pfi_self = pfi_if_create("self", NULL, PFI_IFLAG_GROUP);
pfi_dynamic_drivers();
}
#ifdef _LKM
@ -271,7 +264,12 @@ pfi_lookup_create(const char *name)
if (p == NULL) {
pfi_copy_group(key.pfik_name, name, sizeof(key.pfik_name));
q = pfi_lookup_if(key.pfik_name);
if (q != NULL)
if (q == NULL) {
pfi_newgroup(key.pfik_name, PFI_IFLAG_DYNAMIC);
q = pfi_lookup_if(key.pfik_name);
}
p = pfi_lookup_if(name);
if (p == NULL && q != NULL)
p = pfi_if_create(name, q, PFI_IFLAG_INSTANCE);
}
splx(s);
@ -357,8 +355,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
if (dyn->pfid_net != 128)
snprintf(tblname + strlen(tblname),
sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
ruleset = pf_find_or_create_ruleset(pfi_reserved_anchor,
pfi_interface_ruleset);
ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR);
if (ruleset == NULL)
senderr(1);
@ -473,14 +470,14 @@ pfi_instance_add(struct ifnet *ifp, int net, int flags)
}
if (af == AF_INET)
got4 = 1;
else
else if (af == AF_INET6)
got6 = 1;
net2 = net;
if (net2 == 128 && (flags & PFI_AFLAG_NETWORK)) {
if (af == AF_INET) {
net2 = pfi_unmask(&((struct sockaddr_in *)
ia->ifa_netmask)->sin_addr);
} else {
} else if (af == AF_INET6) {
net2 = pfi_unmask(&((struct sockaddr_in6 *)
ia->ifa_netmask)->sin6_addr);
}
@ -639,7 +636,7 @@ pfi_if_create(const char *name, struct pfi_kif *q, int flags)
RB_INIT(&p->pfik_ext_gwy);
p->pfik_flags = flags;
p->pfik_parent = q;
p->pfik_tzero = time.tv_sec;
p->pfik_tzero = time_second;
RB_INSERT(pfi_ifhead, &pfi_ifs, p);
if (q != NULL) {
@ -693,54 +690,6 @@ pfi_copy_group(char *p, const char *q, int m)
*p++ = '\0';
}
void
pfi_dynamic_drivers(void)
{
#ifdef __OpenBSD__
char *buses[] = PFI_DYNAMIC_BUSES;
int nbuses = sizeof(buses)/sizeof(buses[0]);
int enabled[sizeof(buses)/sizeof(buses[0])];
struct device *dev;
struct cfdata *cf;
struct cfdriver *drv;
short *p;
int i;
bzero(enabled, sizeof(enabled));
TAILQ_FOREACH(dev, &alldevs, dv_list) {
if (!(dev->dv_flags & DVF_ACTIVE))
continue;
for (i = 0; i < nbuses; i++)
if (!enabled[i] && !strcmp(buses[i],
dev->dv_cfdata->cf_driver->cd_name))
enabled[i] = 1;
}
for (cf = cfdata; cf->cf_driver; cf++) {
if (cf->cf_driver->cd_class != DV_IFNET)
continue;
for (p = cf->cf_parents; p && *p >= 0; p++) {
if ((drv = cfdata[*p].cf_driver) == NULL)
continue;
for (i = 0; i < nbuses; i++)
if (enabled[i] &&
!strcmp(drv->cd_name, buses[i]))
break;
if (i < nbuses) {
pfi_newgroup(cf->cf_driver->cd_name,
PFI_IFLAG_DYNAMIC);
break;
}
}
}
#else
struct if_clone *ifc;
extern LIST_HEAD(if_cloners, if_clone) if_cloners;
LIST_FOREACH(ifc, &if_cloners, ifc_list)
pfi_newgroup(ifc->ifc_name, PFI_IFLAG_DYNAMIC);
#endif
}
void
pfi_newgroup(const char *name, int flags)
{
@ -787,7 +736,7 @@ pfi_clr_istats(const char *name, int *nzero, int flags)
{
struct pfi_kif *p;
int n = 0, s;
long tzero = time.tv_sec;
long tzero = time_second;
s = splsoftnet();
ACCEPT_FLAGS(PFI_FLAG_GROUP|PFI_FLAG_INSTANCE);
@ -818,7 +767,7 @@ pfi_get_ifaces(const char *name, struct pfi_if *buf, int *size, int flags)
continue;
if (*size > n++) {
if (!p->pfik_tzero)
p->pfik_tzero = boottime.tv_sec;
p->pfik_tzero = time_second;
if (copyout(p, buf++, sizeof(*buf))) {
splx(s);
return (EFAULT);
@ -893,7 +842,9 @@ pfi_dohooks(struct pfi_kif *p)
int
pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
{
if (af == AF_INET) {
switch (af) {
#ifdef INET
case AF_INET:
switch (dyn->pfid_acnt4) {
case 0:
return (0);
@ -903,7 +854,10 @@ pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
default:
return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
}
} else {
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
switch (dyn->pfid_acnt6) {
case 0:
return (0);
@ -913,6 +867,10 @@ pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
default:
return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
}
break;
#endif /* INET6 */
default:
return (0);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_norm.c,v 1.5 2004/11/13 21:13:07 yamt Exp $ */
/* $OpenBSD: pf_norm.c,v 1.80 2004/03/09 21:44:41 mcbride Exp $ */
/* $NetBSD: pf_norm.c,v 1.6 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: pf_norm.c,v 1.96 2004/07/17 00:17:27 frantzen Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@ -123,12 +123,15 @@ struct mbuf *pf_reassemble(struct mbuf **, struct pf_fragment **,
struct pf_frent *, int);
struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
struct pf_fragment **, int, int, int *);
u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t);
int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
struct tcphdr *, int);
#define DPFPRINTF(x) if (pf_status.debug >= PF_DEBUG_MISC) \
{ printf("%s: ", __func__); printf x ;}
#define DPFPRINTF(x) do { \
if (pf_status.debug >= PF_DEBUG_MISC) { \
printf("%s: ", __func__); \
printf x ; \
} \
} while(0)
/* Globals */
struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
@ -205,7 +208,7 @@ void
pf_purge_expired_fragments(void)
{
struct pf_fragment *frag;
u_int32_t expire = time.tv_sec -
u_int32_t expire = time_second -
pf_default_rule.timeout[PFTM_FRAG];
while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
@ -316,7 +319,7 @@ pf_find_fragment(struct ip *ip, struct pf_frag_tree *tree)
frag = RB_FIND(pf_frag_tree, tree, &key);
if (frag != NULL) {
/* XXX Are we sure we want to update the timeout? */
frag->fr_timeout = time.tv_sec;
frag->fr_timeout = time_second;
if (BUFFER_FRAGMENTS(frag)) {
TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
@ -381,7 +384,7 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
(*frag)->fr_dst = frent->fr_ip->ip_dst;
(*frag)->fr_p = frent->fr_ip->ip_p;
(*frag)->fr_id = frent->fr_ip->ip_id;
(*frag)->fr_timeout = time.tv_sec;
(*frag)->fr_timeout = time_second;
LIST_INIT(&(*frag)->fr_queue);
RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
@ -583,7 +586,7 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
(*frag)->fr_dst = h->ip_dst;
(*frag)->fr_p = h->ip_p;
(*frag)->fr_id = h->ip_id;
(*frag)->fr_timeout = time.tv_sec;
(*frag)->fr_timeout = time_second;
cur->fr_off = off;
cur->fr_end = max;
@ -846,7 +849,8 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
}
int
pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason)
pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
struct pf_pdesc *pd)
{
struct mbuf *m = *m0;
struct pf_rule *r;
@ -873,10 +877,10 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason)
else if (r->proto && r->proto != h->ip_p)
r = r->skip[PF_SKIP_PROTO].ptr;
else if (PF_MISMATCHAW(&r->src.addr,
(struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.not))
(struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.neg))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (PF_MISMATCHAW(&r->dst.addr,
(struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.not))
(struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.neg))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else
break;
@ -1012,8 +1016,14 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason)
if (r->min_ttl && h->ip_ttl < r->min_ttl)
h->ip_ttl = r->min_ttl;
if (r->rule_flag & PFRULE_RANDOMID)
if (r->rule_flag & PFRULE_RANDOMID) {
u_int16_t ip_id = h->ip_id;
h->ip_id = ip_randomid();
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
}
if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
pd->flags |= PFDESC_IP_REAS;
return (PF_PASS);
@ -1021,7 +1031,8 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason)
/* Enforce a minimum ttl, may cause endless packet loops */
if (r->min_ttl && h->ip_ttl < r->min_ttl)
h->ip_ttl = r->min_ttl;
if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
pd->flags |= PFDESC_IP_REAS;
return (PF_PASS);
no_mem:
@ -1053,7 +1064,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason)
#ifdef INET6
int
pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
u_short *reason)
u_short *reason, struct pf_pdesc *pd)
{
struct mbuf *m = *m0;
struct pf_rule *r;
@ -1085,10 +1096,10 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
r = r->skip[PF_SKIP_PROTO].ptr;
#endif
else if (PF_MISMATCHAW(&r->src.addr,
(struct pf_addr *)&h->ip6_src, AF_INET6, r->src.not))
(struct pf_addr *)&h->ip6_src, AF_INET6, r->src.neg))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (PF_MISMATCHAW(&r->dst.addr,
(struct pf_addr *)&h->ip6_dst, AF_INET6, r->dst.not))
(struct pf_addr *)&h->ip6_dst, AF_INET6, r->dst.neg))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else
break;
@ -1203,6 +1214,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
goto badfrag;
/* do something about it */
/* remember to set pd->flags |= PFDESC_IP_REAS */
return (PF_PASS);
shortpkt:
@ -1223,7 +1235,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
return (PF_DROP);
}
#endif
#endif /* INET6 */
int
pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
@ -1248,12 +1260,12 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
r = r->skip[PF_SKIP_AF].ptr;
else if (r->proto && r->proto != pd->proto)
r = r->skip[PF_SKIP_PROTO].ptr;
else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.not))
else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
else if (r->src.port_op && !pf_match_port(r->src.port_op,
r->src.port[0], r->src.port[1], th->th_sport))
r = r->skip[PF_SKIP_SRC_PORT].ptr;
else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.not))
else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
r = r->skip[PF_SKIP_DST_ADDR].ptr;
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
r->dst.port[0], r->dst.port[1], th->th_dport))
@ -1309,13 +1321,13 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
th->th_x2 = 0;
nv = *(u_int16_t *)(&th->th_ack + 1);
th->th_sum = pf_cksum_fixup(th->th_sum, ov, nv);
th->th_sum = pf_cksum_fixup(th->th_sum, ov, nv, 0);
rewrite = 1;
}
/* Remove urgent pointer, if TH_URG is not set */
if (!(flags & TH_URG) && th->th_urp) {
th->th_sum = pf_cksum_fixup(th->th_sum, th->th_urp, 0);
th->th_sum = pf_cksum_fixup(th->th_sum, th->th_urp, 0, 0);
th->th_urp = 0;
rewrite = 1;
}
@ -1341,6 +1353,7 @@ int
pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
struct tcphdr *th, struct pf_state_peer *src, struct pf_state_peer *dst)
{
u_int32_t tsval, tsecr;
u_int8_t hdr[60];
u_int8_t *opt;
@ -1394,12 +1407,23 @@ pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
if (opt[1] >= TCPOLEN_TIMESTAMP) {
src->scrub->pfss_flags |=
PFSS_TIMESTAMP;
src->scrub->pfss_ts_mod = arc4random();
src->scrub->pfss_ts_mod =
htonl(arc4random());
/* note PFSS_PAWS not set yet */
memcpy(&tsval, &opt[2],
sizeof(u_int32_t));
memcpy(&tsecr, &opt[6],
sizeof(u_int32_t));
src->scrub->pfss_tsval0 = ntohl(tsval);
src->scrub->pfss_tsval = ntohl(tsval);
src->scrub->pfss_tsecr = ntohl(tsecr);
getmicrouptime(&src->scrub->pfss_last);
}
/* FALLTHROUGH */
default:
hlen -= opt[1];
opt += opt[1];
hlen -= MAX(opt[1], 2);
opt += MAX(opt[1], 2);
break;
}
}
@ -1421,12 +1445,16 @@ pf_normalize_tcp_cleanup(struct pf_state *state)
int
pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
u_short *reason, struct tcphdr *th, struct pf_state_peer *src,
struct pf_state_peer *dst, int *writeback)
u_short *reason, struct tcphdr *th, struct pf_state *state,
struct pf_state_peer *src, struct pf_state_peer *dst, int *writeback)
{
struct timeval uptime;
u_int32_t tsval, tsecr;
u_int tsval_from_last;
u_int8_t hdr[60];
u_int8_t *opt;
int copyback = 0;
int got_ts = 0;
KASSERT(src->scrub || dst->scrub);
@ -1480,37 +1508,51 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
* NAT detection, OS uptime determination or
* reboot detection.
*/
if (got_ts) {
/* Huh? Multiple timestamps!? */
if (pf_status.debug >= PF_DEBUG_MISC) {
DPFPRINTF(("multiple TS??"));
pf_print_state(state);
printf("\n");
}
REASON_SET(reason, PFRES_TS);
return (PF_DROP);
}
if (opt[1] >= TCPOLEN_TIMESTAMP) {
u_int32_t ts_value;
if (src->scrub &&
memcpy(&tsval, &opt[2],
sizeof(u_int32_t));
if (tsval && src->scrub &&
(src->scrub->pfss_flags &
PFSS_TIMESTAMP)) {
memcpy(&ts_value, &opt[2],
sizeof(u_int32_t));
ts_value = htonl(ntohl(ts_value)
+ src->scrub->pfss_ts_mod);
tsval = ntohl(tsval);
pf_change_a(&opt[2],
&th->th_sum, ts_value, 0);
&th->th_sum,
htonl(tsval +
src->scrub->pfss_ts_mod),
0);
copyback = 1;
}
/* Modulate TS reply iff valid (!0) */
memcpy(&ts_value, &opt[6],
memcpy(&tsecr, &opt[6],
sizeof(u_int32_t));
if (ts_value && dst->scrub &&
if (tsecr && dst->scrub &&
(dst->scrub->pfss_flags &
PFSS_TIMESTAMP)) {
ts_value = htonl(ntohl(ts_value)
- dst->scrub->pfss_ts_mod);
tsecr = ntohl(tsecr)
- dst->scrub->pfss_ts_mod;
pf_change_a(&opt[6],
&th->th_sum, ts_value, 0);
&th->th_sum, htonl(tsecr),
0);
copyback = 1;
}
got_ts = 1;
}
/* FALLTHROUGH */
default:
hlen -= opt[1];
opt += opt[1];
hlen -= MAX(opt[1], 2);
opt += MAX(opt[1], 2);
break;
}
}
@ -1524,9 +1566,276 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
}
/*
* Must invalidate PAWS checks on connections idle for too long.
* The fastest allowed timestamp clock is 1ms. That turns out to
* be about 24 days before it wraps. XXX Right now our lowerbound
* TS echo check only works for the first 12 days of a connection
* when the TS has exhausted half its 32bit space
*/
#define TS_MAX_IDLE (24*24*60*60)
#define TS_MAX_CONN (12*24*60*60) /* XXX remove when better tsecr check */
getmicrouptime(&uptime);
if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
(uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
time_second - state->creation > TS_MAX_CONN)) {
if (pf_status.debug >= PF_DEBUG_MISC) {
DPFPRINTF(("src idled out of PAWS\n"));
pf_print_state(state);
printf("\n");
}
src->scrub->pfss_flags = (src->scrub->pfss_flags & ~PFSS_PAWS)
| PFSS_PAWS_IDLED;
}
if (dst->scrub && (dst->scrub->pfss_flags & PFSS_PAWS) &&
uptime.tv_sec - dst->scrub->pfss_last.tv_sec > TS_MAX_IDLE) {
if (pf_status.debug >= PF_DEBUG_MISC) {
DPFPRINTF(("dst idled out of PAWS\n"));
pf_print_state(state);
printf("\n");
}
dst->scrub->pfss_flags = (dst->scrub->pfss_flags & ~PFSS_PAWS)
| PFSS_PAWS_IDLED;
}
if (got_ts && src->scrub && dst->scrub &&
(src->scrub->pfss_flags & PFSS_PAWS) &&
(dst->scrub->pfss_flags & PFSS_PAWS)) {
/* Validate that the timestamps are "in-window".
* RFC1323 describes TCP Timestamp options that allow
* measurement of RTT (round trip time) and PAWS
* (protection against wrapped sequence numbers). PAWS
* gives us a set of rules for rejecting packets on
* long fat pipes (packets that were somehow delayed
* in transit longer than the time it took to send the
* full TCP sequence space of 4Gb). We can use these
* rules and infer a few others that will let us treat
* the 32bit timestamp and the 32bit echoed timestamp
* as sequence numbers to prevent a blind attacker from
* inserting packets into a connection.
*
* RFC1323 tells us:
* - The timestamp on this packet must be greater than
* or equal to the last value echoed by the other
* endpoint. The RFC says those will be discarded
* since it is a dup that has already been acked.
* This gives us a lowerbound on the timestamp.
* timestamp >= other last echoed timestamp
* - The timestamp will be less than or equal to
* the last timestamp plus the time between the
* last packet and now. The RFC defines the max
* clock rate as 1ms. We will allow clocks to be
* up to 10% fast and will allow a total difference
* or 30 seconds due to a route change. And this
* gives us an upperbound on the timestamp.
* timestamp <= last timestamp + max ticks
* We have to be careful here. Windows will send an
* initial timestamp of zero and then initialize it
* to a random value after the 3whs; presumably to
* avoid a DoS by having to call an expensive RNG
* during a SYN flood. Proof MS has at least one
* good security geek.
*
* - The TCP timestamp option must also echo the other
* endpoints timestamp. The timestamp echoed is the
* one carried on the earliest unacknowledged segment
* on the left edge of the sequence window. The RFC
* states that the host will reject any echoed
* timestamps that were larger than any ever sent.
* This gives us an upperbound on the TS echo.
* tescr <= largest_tsval
* - The lowerbound on the TS echo is a little more
* tricky to determine. The other endpoint's echoed
* values will not decrease. But there may be
* network conditions that re-order packets and
* cause our view of them to decrease. For now the
* only lowerbound we can safely determine is that
* the TS echo will never be less than the orginal
* TS. XXX There is probably a better lowerbound.
* Remove TS_MAX_CONN with better lowerbound check.
* tescr >= other original TS
*
* It is also important to note that the fastest
* timestamp clock of 1ms will wrap its 32bit space in
* 24 days. So we just disable TS checking after 24
* days of idle time. We actually must use a 12d
* connection limit until we can come up with a better
* lowerbound to the TS echo check.
*/
struct timeval delta_ts;
int ts_fudge;
/*
* PFTM_TS_DIFF is how many seconds of leeway to allow
* a host's timestamp. This can happen if the previous
* packet got delayed in transit for much longer than
* this packet.
*/
if ((ts_fudge = state->rule.ptr->timeout[PFTM_TS_DIFF]) == 0)
ts_fudge = pf_default_rule.timeout[PFTM_TS_DIFF];
/* Calculate max ticks since the last timestamp */
#define TS_MAXFREQ 1100 /* RFC max TS freq of 1Khz + 10% skew */
#define TS_MICROSECS 1000000 /* microseconds per second */
timersub(&uptime, &src->scrub->pfss_last, &delta_ts);
tsval_from_last = (delta_ts.tv_sec + ts_fudge) * TS_MAXFREQ;
tsval_from_last += delta_ts.tv_usec / (TS_MICROSECS/TS_MAXFREQ);
if ((src->state >= TCPS_ESTABLISHED &&
dst->state >= TCPS_ESTABLISHED) &&
(SEQ_LT(tsval, dst->scrub->pfss_tsecr) ||
SEQ_GT(tsval, src->scrub->pfss_tsval + tsval_from_last) ||
(tsecr && (SEQ_GT(tsecr, dst->scrub->pfss_tsval) ||
SEQ_LT(tsecr, dst->scrub->pfss_tsval0))))) {
/* Bad RFC1323 implementation or an insertion attack.
*
* - Solaris 2.6 and 2.7 are known to send another ACK
* after the FIN,FIN|ACK,ACK closing that carries
* an old timestamp.
*/
DPFPRINTF(("Timestamp failed %c%c%c%c\n",
SEQ_LT(tsval, dst->scrub->pfss_tsecr) ? '0' : ' ',
SEQ_GT(tsval, src->scrub->pfss_tsval +
tsval_from_last) ? '1' : ' ',
SEQ_GT(tsecr, dst->scrub->pfss_tsval) ? '2' : ' ',
SEQ_LT(tsecr, dst->scrub->pfss_tsval0)? '3' : ' '));
DPFPRINTF((" tsval: %" PRIu32 " tsecr: %" PRIu32
" +ticks: %" PRIu32 " idle: %lus %lums\n",
tsval, tsecr, tsval_from_last, delta_ts.tv_sec,
delta_ts.tv_usec / 1000));
DPFPRINTF((" src->tsval: %" PRIu32 " tsecr: %" PRIu32
"\n",
src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
DPFPRINTF((" dst->tsval: %" PRIu32 " tsecr: %" PRIu32
" tsval0: %" PRIu32 "\n",
dst->scrub->pfss_tsval,
dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
if (pf_status.debug >= PF_DEBUG_MISC) {
pf_print_state(state);
pf_print_flags(th->th_flags);
printf("\n");
}
REASON_SET(reason, PFRES_TS);
return (PF_DROP);
}
/* XXX I'd really like to require tsecr but it's optional */
} else if (!got_ts && (th->th_flags & TH_RST) == 0 &&
((src->state == TCPS_ESTABLISHED && dst->state == TCPS_ESTABLISHED)
|| pd->p_len > 0 || (th->th_flags & TH_SYN)) &&
src->scrub && dst->scrub &&
(src->scrub->pfss_flags & PFSS_PAWS) &&
(dst->scrub->pfss_flags & PFSS_PAWS)) {
/* Didn't send a timestamp. Timestamps aren't really useful
* when:
* - connection opening or closing (often not even sent).
* but we must not let an attacker to put a FIN on a
* data packet to sneak it through our ESTABLISHED check.
* - on a TCP reset. RFC suggests not even looking at TS.
* - on an empty ACK. The TS will not be echoed so it will
* probably not help keep the RTT calculation in sync and
* there isn't as much danger when the sequence numbers
* got wrapped. So some stacks don't include TS on empty
* ACKs :-(
*
* To minimize the disruption to mostly RFC1323 conformant
* stacks, we will only require timestamps on data packets.
*
* And what do ya know, we cannot require timestamps on data
* packets. There appear to be devices that do legitimate
* TCP connection hijacking. There are HTTP devices that allow
* a 3whs (with timestamps) and then buffer the HTTP request.
* If the intermediate device has the HTTP response cache, it
* will spoof the response but not bother timestamping its
* packets. So we can look for the presence of a timestamp in
* the first data packet and if there, require it in all future
* packets.
*/
if (pd->p_len > 0 && (src->scrub->pfss_flags & PFSS_DATA_TS)) {
/*
* Hey! Someone tried to sneak a packet in. Or the
* stack changed its RFC1323 behavior?!?!
*/
if (pf_status.debug >= PF_DEBUG_MISC) {
DPFPRINTF(("Did not receive expected RFC1323 "
"timestamp\n"));
pf_print_state(state);
pf_print_flags(th->th_flags);
printf("\n");
}
REASON_SET(reason, PFRES_TS);
return (PF_DROP);
}
}
/*
* We will note if a host sends his data packets with or without
* timestamps. And require all data packets to contain a timestamp
* if the first does. PAWS implicitly requires that all data packets be
* timestamped. But I think there are middle-man devices that hijack
* TCP streams immedietly after the 3whs and don't timestamp their
* packets (seen in a WWW accelerator or cache).
*/
if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
(PFSS_TIMESTAMP|PFSS_DATA_TS|PFSS_DATA_NOTS)) == PFSS_TIMESTAMP) {
if (got_ts)
src->scrub->pfss_flags |= PFSS_DATA_TS;
else {
src->scrub->pfss_flags |= PFSS_DATA_NOTS;
if (pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
(dst->scrub->pfss_flags & PFSS_TIMESTAMP)) {
/* Don't warn if other host rejected RFC1323 */
DPFPRINTF(("Broken RFC1323 stack did not "
"timestamp data packet. Disabled PAWS "
"security.\n"));
pf_print_state(state);
pf_print_flags(th->th_flags);
printf("\n");
}
}
}
/*
* Update PAWS values
*/
if (got_ts && src->scrub && PFSS_TIMESTAMP == (src->scrub->pfss_flags &
(PFSS_PAWS_IDLED|PFSS_TIMESTAMP))) {
getmicrouptime(&src->scrub->pfss_last);
if (SEQ_GEQ(tsval, src->scrub->pfss_tsval) ||
(src->scrub->pfss_flags & PFSS_PAWS) == 0)
src->scrub->pfss_tsval = tsval;
if (tsecr) {
if (SEQ_GEQ(tsecr, src->scrub->pfss_tsecr) ||
(src->scrub->pfss_flags & PFSS_PAWS) == 0)
src->scrub->pfss_tsecr = tsecr;
if ((src->scrub->pfss_flags & PFSS_PAWS) == 0 &&
(SEQ_LT(tsval, src->scrub->pfss_tsval0) ||
src->scrub->pfss_tsval0 == 0)) {
/* tsval0 MUST be the lowest timestamp */
src->scrub->pfss_tsval0 = tsval;
}
/* Only fully initialized after a TS gets echoed */
if ((src->scrub->pfss_flags & PFSS_PAWS) == 0)
src->scrub->pfss_flags |= PFSS_PAWS;
}
}
/* I have a dream.... TCP segment reassembly.... */
return (0);
}
int
pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
int off)
@ -1559,7 +1868,7 @@ pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
mss = (u_int16_t *)(optp + 2);
if ((ntohs(*mss)) > r->max_mss) {
th->th_sum = pf_cksum_fixup(th->th_sum,
*mss, htons(r->max_mss));
*mss, htons(r->max_mss), 0);
*mss = htons(r->max_mss);
rewrite = 1;
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_osfp.c,v 1.3 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: pf_osfp.c,v 1.9 2004/01/04 20:08:42 pvalchev Exp $ */
/* $NetBSD: pf_osfp.c,v 1.4 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: pf_osfp.c,v 1.10 2004/04/09 19:30:41 frantzen Exp $ */
/*
* Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
@ -238,9 +238,9 @@ void
pf_osfp_initialize(void)
{
pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0,
"pfosfpen", NULL);
"pfosfpen", &pool_allocator_nointr);
pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0,
"pfosfp", NULL);
"pfosfp", &pool_allocator_nointr);
SLIST_INIT(&pf_osfp_list);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: pf_table.c,v 1.4 2004/09/09 14:56:00 yamt Exp $ */
/* $OpenBSD: pf_table.c,v 1.47 2004/03/09 21:44:41 mcbride Exp $ */
/* $NetBSD: pf_table.c,v 1.5 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: pf_table.c,v 1.59 2004/07/08 23:17:38 mcbride Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@ -194,9 +194,9 @@ void
pfr_initialize(void)
{
pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0,
"pfrktable", NULL);
"pfrktable", &pool_allocator_oldnointr);
pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
"pfrkentry", NULL);
"pfrkentry", &pool_allocator_oldnointr);
pfr_sin.sin_len = sizeof(pfr_sin);
pfr_sin.sin_family = AF_INET;
@ -255,8 +255,8 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_kentryworkq workq;
struct pfr_kentry *p, *q;
struct pfr_addr ad;
int i, rv, s = 0, xadd = 0;
long tzero = time.tv_sec;
int i, rv, s = 0 /* XXX gcc */, xadd = 0;
long tzero = time_second;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
@ -333,7 +333,7 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_kentryworkq workq;
struct pfr_kentry *p;
struct pfr_addr ad;
int i, rv, s = 0, xdel = 0;
int i, rv, s = 0 /* XXX gcc */, xdel = 0, log = 1;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
@ -343,7 +343,34 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
return (ESRCH);
if (kt->pfrkt_flags & PFR_TFLAG_CONST)
return (EPERM);
pfr_mark_addrs(kt);
/*
* there are two algorithms to choose from here.
* with:
* n: number of addresses to delete
* N: number of addresses in the table
*
* one is O(N) and is better for large 'n'
* one is O(n*LOG(N)) and is better for small 'n'
*
* following code try to decide which one is best.
*/
for (i = kt->pfrkt_cnt; i > 0; i >>= 1)
log++;
if (size > kt->pfrkt_cnt/log) {
/* full table scan */
pfr_mark_addrs(kt);
} else {
/* iterate over addresses to delete */
for (i = 0; i < size; i++) {
if (COPYIN(addr+i, &ad, sizeof(ad)))
return (EFAULT);
if (pfr_validate_addr(&ad))
return (EINVAL);
p = pfr_lookup_addr(kt, &ad, 1);
if (p != NULL)
p->pfrke_mark = 0;
}
}
SLIST_INIT(&workq);
for (i = 0; i < size; i++) {
if (COPYIN(addr+i, &ad, sizeof(ad)))
@ -395,8 +422,9 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_kentryworkq addq, delq, changeq;
struct pfr_kentry *p, *q;
struct pfr_addr ad;
int i, rv, s = 0, xadd = 0, xdel = 0, xchange = 0;
long tzero = time.tv_sec;
int i, rv, s = 0 /* XXX gcc */, xadd = 0, xdel = 0,
xchange = 0;
long tzero = time_second;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
@ -583,8 +611,8 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
struct pfr_ktable *kt;
struct pfr_walktree w;
struct pfr_kentryworkq workq;
int rv, s = 0;
long tzero = time.tv_sec;
int rv, s = 0 /* XXX gcc */;
long tzero = time_second;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */
if (pfr_validate_table(tbl, 0, 0))
@ -682,14 +710,18 @@ pfr_validate_addr(struct pfr_addr *ad)
int i;
switch (ad->pfra_af) {
#ifdef INET
case AF_INET:
if (ad->pfra_net > 32)
return (-1);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
if (ad->pfra_net > 128)
return (-1);
break;
#endif /* INET6 */
default:
return (-1);
}
@ -744,7 +776,7 @@ struct pfr_kentry *
pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
{
union sockaddr_union sa, mask;
struct radix_node_head *head;
struct radix_node_head *head = (void *)0xdeadb;
struct pfr_kentry *ke;
int s;
@ -752,7 +784,7 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
if (ad->pfra_af == AF_INET) {
FILLIN_SIN(sa.sin, ad->pfra_ip4addr);
head = kt->pfrkt_ip4;
} else {
} else if ( ad->pfra_af == AF_INET6 ) {
FILLIN_SIN6(sa.sin6, ad->pfra_ip6addr);
head = kt->pfrkt_ip6;
}
@ -785,7 +817,7 @@ pfr_create_kentry(struct pfr_addr *ad)
if (ad->pfra_af == AF_INET)
FILLIN_SIN(ke->pfrke_sa.sin, ad->pfra_ip4addr);
else
else if (ad->pfra_af == AF_INET6)
FILLIN_SIN6(ke->pfrke_sa.sin6, ad->pfra_ip6addr);
ke->pfrke_af = ad->pfra_af;
ke->pfrke_net = ad->pfra_net;
@ -896,14 +928,14 @@ pfr_prepare_network(union sockaddr_union *sa, int af, int net)
if (af == AF_INET) {
sa->sin.sin_len = sizeof(sa->sin);
sa->sin.sin_family = AF_INET;
sa->sin.sin_addr.s_addr = htonl(-1 << (32-net));
} else {
sa->sin.sin_addr.s_addr = net ? htonl(-1 << (32-net)) : 0;
} else if (af == AF_INET6) {
sa->sin6.sin6_len = sizeof(sa->sin6);
sa->sin6.sin6_family = AF_INET6;
for (i = 0; i < 4; i++) {
if (net <= 32) {
sa->sin6.sin6_addr.s6_addr32[i] =
htonl(-1 << (32-net));
net ? htonl(-1 << (32-net)) : 0;
break;
}
sa->sin6.sin6_addr.s6_addr32[i] = 0xFFFFFFFF;
@ -917,13 +949,13 @@ pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
{
union sockaddr_union mask;
struct radix_node *rn;
struct radix_node_head *head;
struct radix_node_head *head = (void *)0xdeadb;
int s;
bzero(ke->pfrke_node, sizeof(ke->pfrke_node));
if (ke->pfrke_af == AF_INET)
head = kt->pfrkt_ip4;
else
else if (ke->pfrke_af == AF_INET6)
head = kt->pfrkt_ip6;
s = splsoftnet();
@ -942,20 +974,28 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
{
union sockaddr_union mask;
struct radix_node *rn;
struct radix_node_head *head;
struct radix_node_head *head = (void *)0xdeadb;
int s;
if (ke->pfrke_af == AF_INET)
head = kt->pfrkt_ip4;
else
else if (ke->pfrke_af == AF_INET6)
head = kt->pfrkt_ip6;
s = splsoftnet();
if (KENTRY_NETWORK(ke)) {
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
#ifdef __OpenBSD__
rn = rn_delete(&ke->pfrke_sa, &mask, head, NULL);
#else
rn = rn_delete(&ke->pfrke_sa, &mask, head);
#endif
} else
#ifdef __OpenBSD__
rn = rn_delete(&ke->pfrke_sa, NULL, head, NULL);
#else
rn = rn_delete(&ke->pfrke_sa, NULL, head);
#endif
splx(s);
if (rn == NULL) {
@ -976,7 +1016,7 @@ pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke)
ad->pfra_not = ke->pfrke_not;
if (ad->pfra_af == AF_INET)
ad->pfra_ip4addr = ke->pfrke_sa.sin.sin_addr;
else
else if (ad->pfra_af == AF_INET6)
ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr;
}
@ -1045,7 +1085,7 @@ pfr_walktree(struct radix_node *rn, void *arg)
&ke->pfrke_sa, AF_INET);
w->pfrw_dyn->pfid_mask4 = *SUNION2PF(
&pfr_mask, AF_INET);
} else {
} else if (ke->pfrke_af == AF_INET6){
if (w->pfrw_dyn->pfid_acnt6++ > 0)
break;
pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
@ -1099,8 +1139,8 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
{
struct pfr_ktableworkq addq, changeq;
struct pfr_ktable *p, *q, *r, key;
int i, rv, s = 0, xadd = 0;
long tzero = time.tv_sec;
int i, rv, s = 0 /* XXX gcc */, xadd = 0;
long tzero = time_second;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
SLIST_INIT(&addq);
@ -1128,7 +1168,6 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
/* find or create root table */
bzero(key.pfrkt_anchor, sizeof(key.pfrkt_anchor));
bzero(key.pfrkt_ruleset, sizeof(key.pfrkt_ruleset));
r = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
if (r != NULL) {
p->pfrkt_root = r;
@ -1252,8 +1291,8 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
{
struct pfr_ktable *p;
struct pfr_ktableworkq workq;
int s = 0, n, nn;
long tzero = time.tv_sec;
int s = 0 /* XXX gcc */, n, nn;
long tzero = time_second;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC|PFR_FLAG_ALLRSETS);
/* XXX PFR_FLAG_CLSTATS disabled */
@ -1300,8 +1339,8 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p, key;
int i, s = 0, xzero = 0;
long tzero = time.tv_sec;
int i, s = 0 /* XXX gcc */, xzero = 0;
long tzero = time_second;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ADDRSTOO);
SLIST_INIT(&workq);
@ -1391,7 +1430,7 @@ pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags)
int xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_DUMMY);
rs = pf_find_or_create_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset);
rs = pf_find_or_create_ruleset(trs->pfrt_anchor);
if (rs == NULL)
return (ENOMEM);
SLIST_INIT(&workq);
@ -1433,7 +1472,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK,
flags & PFR_FLAG_USERIOCTL))
return (EINVAL);
rs = pf_find_ruleset(tbl->pfrt_anchor, tbl->pfrt_ruleset);
rs = pf_find_ruleset(tbl->pfrt_anchor);
if (rs == NULL || !rs->topen || ticket != rs->tticket)
return (EBUSY);
tbl->pfrt_flags |= PFR_TFLAG_INACTIVE;
@ -1524,7 +1563,7 @@ pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags)
int xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_DUMMY);
rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset);
rs = pf_find_ruleset(trs->pfrt_anchor);
if (rs == NULL || !rs->topen || ticket != rs->tticket)
return (0);
SLIST_INIT(&workq);
@ -1553,11 +1592,11 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
struct pfr_ktable *p, *q;
struct pfr_ktableworkq workq;
struct pf_ruleset *rs;
int s = 0, xadd = 0, xchange = 0;
long tzero = time.tv_sec;
int s = 0 /* XXX gcc */, xadd = 0, xchange = 0;
long tzero = time_second;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset);
rs = pf_find_ruleset(trs->pfrt_anchor);
if (rs == NULL || !rs->topen || ticket != rs->tticket)
return (EBUSY);
@ -1675,18 +1714,12 @@ int
pfr_table_count(struct pfr_table *filter, int flags)
{
struct pf_ruleset *rs;
struct pf_anchor *ac;
if (flags & PFR_FLAG_ALLRSETS)
return (pfr_ktable_cnt);
if (filter->pfrt_ruleset[0]) {
rs = pf_find_ruleset(filter->pfrt_anchor,
filter->pfrt_ruleset);
return ((rs != NULL) ? rs->tables : -1);
}
if (filter->pfrt_anchor[0]) {
ac = pf_find_anchor(filter->pfrt_anchor);
return ((ac != NULL) ? ac->tables : -1);
rs = pf_find_ruleset(filter->pfrt_anchor);
return ((rs != NULL) ? rs->tables : -1);
}
return (pf_main_ruleset.tables);
}
@ -1696,13 +1729,7 @@ pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags)
{
if (flags & PFR_FLAG_ALLRSETS)
return (0);
if (strncmp(filter->pfrt_anchor, kt->pfrkt_anchor,
PF_ANCHOR_NAME_SIZE))
return (1);
if (!filter->pfrt_ruleset[0])
return (0);
if (strncmp(filter->pfrt_ruleset, kt->pfrkt_ruleset,
PF_RULESET_NAME_SIZE))
if (strcmp(filter->pfrt_anchor, kt->pfrkt_anchor))
return (1);
return (0);
}
@ -1810,16 +1837,13 @@ pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset)
kt->pfrkt_t = *tbl;
if (attachruleset) {
rs = pf_find_or_create_ruleset(tbl->pfrt_anchor,
tbl->pfrt_ruleset);
rs = pf_find_or_create_ruleset(tbl->pfrt_anchor);
if (!rs) {
pfr_destroy_ktable(kt, 0);
return (NULL);
}
kt->pfrkt_rs = rs;
rs->tables++;
if (rs->anchor != NULL)
rs->anchor->tables++;
}
if (!rn_inithead((void **)&kt->pfrkt_ip4,
@ -1863,8 +1887,6 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr);
if (kt->pfrkt_rs != NULL) {
kt->pfrkt_rs->tables--;
if (kt->pfrkt_rs->anchor != NULL)
kt->pfrkt_rs->anchor->tables--;
pf_remove_if_empty_ruleset(kt->pfrkt_rs);
}
pool_put(&pfr_ktable_pl, kt);
@ -1877,11 +1899,7 @@ pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
if ((d = strncmp(p->pfrkt_name, q->pfrkt_name, PF_TABLE_NAME_SIZE)))
return (d);
if ((d = strncmp(p->pfrkt_anchor, q->pfrkt_anchor,
PF_ANCHOR_NAME_SIZE)))
return (d);
return (strncmp(p->pfrkt_ruleset, q->pfrkt_ruleset,
PF_RULESET_NAME_SIZE));
return (strcmp(p->pfrkt_anchor, q->pfrkt_anchor));
}
struct pfr_ktable *
@ -1904,18 +1922,22 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
return (0);
switch (af) {
#ifdef INET
case AF_INET:
pfr_sin.sin_addr.s_addr = a->addr32[0];
ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
#endif /* INET6 */
}
match = (ke && !ke->pfrke_not);
if (match)
@ -1937,18 +1959,24 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
return;
switch (af) {
#ifdef INET
case AF_INET:
pfr_sin.sin_addr.s_addr = a->addr32[0];
ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
#endif /* INET6 */
default:
;
}
if ((ke == NULL || ke->pfrke_not) != notrule) {
if (op_pass != PFR_OP_PASS)
@ -1972,18 +2000,15 @@ pfr_attach_table(struct pf_ruleset *rs, char *name)
bzero(&tbl, sizeof(tbl));
strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name));
if (ac != NULL) {
if (ac != NULL)
strlcpy(tbl.pfrt_anchor, ac->name, sizeof(tbl.pfrt_anchor));
strlcpy(tbl.pfrt_ruleset, rs->name, sizeof(tbl.pfrt_ruleset));
}
kt = pfr_lookup_table(&tbl);
if (kt == NULL) {
kt = pfr_create_ktable(&tbl, time.tv_sec, 1);
kt = pfr_create_ktable(&tbl, time_second, 1);
if (kt == NULL)
return (NULL);
if (ac != NULL) {
bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor));
bzero(tbl.pfrt_ruleset, sizeof(tbl.pfrt_ruleset));
rt = pfr_lookup_table(&tbl);
if (rt == NULL) {
rt = pfr_create_ktable(&tbl, 0, 1);
@ -2016,13 +2041,15 @@ int
pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
struct pf_addr **raddr, struct pf_addr **rmask, sa_family_t af)
{
struct pfr_kentry *ke, *ke2;
struct pf_addr *addr;
struct pfr_kentry *ke, *ke2 = (void *)0xdeadb;
struct pf_addr *addr = (void *)0xdeadb;
union sockaddr_union mask;
int idx = -1, use_counter = 0;
addr = (af == AF_INET) ? (struct pf_addr *)&pfr_sin.sin_addr :
(struct pf_addr *)&pfr_sin6.sin6_addr;
if (af == AF_INET)
addr = (struct pf_addr *)&pfr_sin.sin_addr;
else if (af == AF_INET6)
addr = (struct pf_addr *)&pfr_sin6.sin6_addr;
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
kt = kt->pfrkt_root;
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
@ -2065,9 +2092,12 @@ _next_block:
}
for (;;) {
/* we don't want to use a nested block */
ke2 = (struct pfr_kentry *)(af == AF_INET ?
rn_match(&pfr_sin, kt->pfrkt_ip4) :
rn_match(&pfr_sin6, kt->pfrkt_ip6));
if (af == AF_INET)
ke2 = (struct pfr_kentry *)rn_match(&pfr_sin,
kt->pfrkt_ip4);
else if (af == AF_INET6)
ke2 = (struct pfr_kentry *)rn_match(&pfr_sin6,
kt->pfrkt_ip6);
/* no need to check KENTRY_RNF_ROOT() here */
if (ke2 == ke) {
/* lookup return the same block - perfect */
@ -2100,12 +2130,16 @@ pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
w.pfrw_cnt = idx;
switch (af) {
#ifdef INET
case AF_INET:
rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
return (w.pfrw_kentry);
#endif /* INET */
#ifdef INET6
case AF_INET6:
rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
return (w.pfrw_kentry);
#endif /* INET6 */
default:
return (NULL);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: pfvar.h,v 1.5 2004/09/28 00:14:02 dyoung Exp $ */
/* $OpenBSD: pfvar.h,v 1.187 2004/03/22 04:54:18 mcbride Exp $ */
/* $NetBSD: pfvar.h,v 1.6 2004/11/14 11:12:16 yamt Exp $ */
/* $OpenBSD: pfvar.h,v 1.202 2004/07/12 00:50:22 itojun Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -34,6 +34,7 @@
#ifndef _NET_PFVAR_H_
#define _NET_PFVAR_H_
#include <sys/param.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/tree.h>
@ -80,7 +81,7 @@ enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED,
PFTM_OTHER_FIRST_PACKET, PFTM_OTHER_SINGLE,
PFTM_OTHER_MULTIPLE, PFTM_FRAG, PFTM_INTERVAL,
PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_SRC_NODE,
PFTM_MAX, PFTM_PURGE, PFTM_UNTIL_PACKET };
PFTM_TS_DIFF, PFTM_MAX, PFTM_PURGE, PFTM_UNTIL_PACKET };
enum { PF_NOPFROUTE, PF_FASTROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO };
enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS, PF_LIMIT_MAX };
#define PF_POOL_IDMASK 0x0f
@ -294,7 +295,7 @@ struct pfi_dynaddr {
#endif /* PF_INET6_ONLY */
#endif /* PF_INET_INET6 */
#define PF_MISMATCHAW(aw, x, af, not) \
#define PF_MISMATCHAW(aw, x, af, neg) \
( \
(((aw)->type == PF_ADDR_NOROUTE && \
pf_routable((x), (af))) || \
@ -306,7 +307,7 @@ struct pfi_dynaddr {
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
!PF_MATCHA(0, &(aw)->v.a.addr, \
&(aw)->v.a.mask, (x), (af)))) != \
(not) \
(neg) \
)
struct pf_rule_uid {
@ -322,7 +323,7 @@ struct pf_rule_gid {
struct pf_rule_addr {
struct pf_addr_wrap addr;
u_int16_t port[2];
u_int8_t not;
u_int8_t neg;
u_int8_t port_op;
};
@ -464,6 +465,8 @@ union pf_rule_ptr {
u_int32_t nr;
};
#define PF_ANCHOR_NAME_SIZE 64
struct pf_rule {
struct pf_rule_addr src;
struct pf_rule_addr dst;
@ -483,8 +486,6 @@ struct pf_rule {
char ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
char pqname[PF_QNAME_SIZE];
#define PF_ANCHOR_NAME_SIZE 16
char anchorname[PF_ANCHOR_NAME_SIZE];
#define PF_TAG_NAME_SIZE 16
char tagname[PF_TAG_NAME_SIZE];
char match_tagname[PF_TAG_NAME_SIZE];
@ -511,6 +512,7 @@ struct pf_rule {
u_int32_t pqid;
u_int32_t rt_listid;
u_int32_t nr;
u_int32_t prob;
u_int16_t return_icmp;
u_int16_t return_icmp6;
@ -545,6 +547,8 @@ struct pf_rule {
u_int8_t rt;
u_int8_t return_ttl;
u_int8_t tos;
u_int8_t anchor_relative;
u_int8_t anchor_wildcard;
};
/* rule flags */
@ -588,11 +592,19 @@ struct pf_src_node {
#define PFSNODE_HIWAT 10000 /* default source node table size */
struct pf_state_scrub {
struct timeval pfss_last; /* time received last packet */
u_int32_t pfss_tsecr; /* last echoed timestamp */
u_int32_t pfss_tsval; /* largest timestamp */
u_int32_t pfss_tsval0; /* original timestamp */
u_int16_t pfss_flags;
#define PFSS_TIMESTAMP 0x0001 /* modulate timestamp */
u_int8_t pfss_ttl; /* stashed TTL */
#define PFSS_TIMESTAMP 0x0001 /* modulate timestamp */
#define PFSS_PAWS 0x0010 /* stricter PAWS checks */
#define PFSS_PAWS_IDLED 0x0020 /* was idle too long. no PAWS */
#define PFSS_DATA_TS 0x0040 /* timestamp on data packets */
#define PFSS_DATA_NOTS 0x0080 /* no timestamp on data packets */
u_int8_t pfss_ttl; /* stashed TTL */
u_int8_t pad;
u_int32_t pfss_ts_mod; /* timestamp modulation */
u_int32_t pfss_ts_mod; /* timestamp modulation */
};
struct pf_state_host {
@ -661,9 +673,6 @@ TAILQ_HEAD(pf_rulequeue, pf_rule);
struct pf_anchor;
struct pf_ruleset {
TAILQ_ENTRY(pf_ruleset) entries;
#define PF_RULESET_NAME_SIZE 16
char name[PF_RULESET_NAME_SIZE];
struct {
struct pf_rulequeue queues[2];
struct {
@ -678,19 +687,22 @@ struct pf_ruleset {
int topen;
};
TAILQ_HEAD(pf_rulesetqueue, pf_ruleset);
RB_HEAD(pf_anchor_global, pf_anchor);
RB_HEAD(pf_anchor_node, pf_anchor);
struct pf_anchor {
TAILQ_ENTRY(pf_anchor) entries;
RB_ENTRY(pf_anchor) entry_global;
RB_ENTRY(pf_anchor) entry_node;
struct pf_anchor *parent;
struct pf_anchor_node children;
char name[PF_ANCHOR_NAME_SIZE];
struct pf_rulesetqueue rulesets;
int tables;
char path[MAXPATHLEN];
struct pf_ruleset ruleset;
int refcnt; /* anchor rules */
};
TAILQ_HEAD(pf_anchorqueue, pf_anchor);
RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
#define PF_RESERVED_ANCHOR "_pf"
#define PF_INTERFACE_RULESET "_if"
#define PFR_TFLAG_PERSIST 0x00000001
#define PFR_TFLAG_CONST 0x00000002
@ -703,8 +715,7 @@ TAILQ_HEAD(pf_anchorqueue, pf_anchor);
#define PFR_TFLAG_ALLMASK 0x0000003F
struct pfr_table {
char pfrt_anchor[PF_ANCHOR_NAME_SIZE];
char pfrt_ruleset[PF_RULESET_NAME_SIZE];
char pfrt_anchor[MAXPATHLEN];
char pfrt_name[PF_TABLE_NAME_SIZE];
u_int32_t pfrt_flags;
u_int8_t pfrt_fback;
@ -867,11 +878,14 @@ struct pf_pdesc {
struct pf_rule *nat_rule; /* nat/rdr rule applied to packet */
struct pf_addr *src;
struct pf_addr *dst;
struct ether_header
*eh;
u_int16_t *ip_sum;
u_int32_t p_len; /* total length of payload */
u_int16_t flags; /* Let SCRUB trigger behavior in
* state code. Easier than tags */
#define PFDESC_TCP_NORM 0x0001 /* TCP shall be statefully scrubbed */
#define PFDESC_IP_REAS 0x0002 /* IP frags would've been reassembled */
sa_family_t af;
u_int8_t proto;
u_int8_t tos;
@ -888,7 +902,8 @@ struct pf_pdesc {
#define PFRES_SHORT 3 /* Dropping short packet */
#define PFRES_NORM 4 /* Dropping by normalizer */
#define PFRES_MEMORY 5 /* Dropped due to lacking mem */
#define PFRES_MAX 6 /* total+1 */
#define PFRES_TS 6 /* Bad TCP Timestamp (RFC1323) */
#define PFRES_MAX 7 /* total+1 */
#define PFRES_NAMES { \
"match", \
@ -897,6 +912,7 @@ struct pf_pdesc {
"short", \
"normalize", \
"memory", \
"bad-timestamp", \
NULL \
}
@ -1056,8 +1072,7 @@ struct pfioc_pooladdr {
u_int8_t r_action;
u_int8_t r_last;
u_int8_t af;
char anchor[PF_ANCHOR_NAME_SIZE];
char ruleset[PF_RULESET_NAME_SIZE];
char anchor[MAXPATHLEN];
struct pf_pooladdr addr;
};
@ -1066,8 +1081,8 @@ struct pfioc_rule {
u_int32_t ticket;
u_int32_t pool_ticket;
u_int32_t nr;
char anchor[PF_ANCHOR_NAME_SIZE];
char ruleset[PF_RULESET_NAME_SIZE];
char anchor[MAXPATHLEN];
char anchor_call[MAXPATHLEN];
struct pf_rule rule;
};
@ -1148,15 +1163,10 @@ struct pfioc_qstats {
u_int8_t scheduler;
};
struct pfioc_anchor {
u_int32_t nr;
char name[PF_ANCHOR_NAME_SIZE];
};
struct pfioc_ruleset {
u_int32_t nr;
char anchor[PF_ANCHOR_NAME_SIZE];
char name[PF_RULESET_NAME_SIZE];
char path[MAXPATHLEN];
char name[PF_ANCHOR_NAME_SIZE];
};
#define PF_RULESET_ALTQ (PF_RULESET_MAX)
@ -1166,8 +1176,7 @@ struct pfioc_trans {
int esize; /* size of each element in bytes */
struct pfioc_trans_e {
int rs_num;
char anchor[PF_ANCHOR_NAME_SIZE];
char ruleset[PF_RULESET_NAME_SIZE];
char anchor[MAXPATHLEN];
u_int32_t ticket;
} *array;
};
@ -1224,9 +1233,7 @@ struct pfioc_iface {
#define DIOCSTART _IO ('D', 1)
#define DIOCSTOP _IO ('D', 2)
#define DIOCBEGINRULES _IOWR('D', 3, struct pfioc_rule)
#define DIOCADDRULE _IOWR('D', 4, struct pfioc_rule)
#define DIOCCOMMITRULES _IOWR('D', 5, struct pfioc_rule)
#define DIOCGETRULES _IOWR('D', 6, struct pfioc_rule)
#define DIOCGETRULE _IOWR('D', 7, struct pfioc_rule)
/* XXX cut 8 - 17 */
@ -1249,9 +1256,7 @@ struct pfioc_iface {
#define DIOCKILLSTATES _IOWR('D', 41, struct pfioc_state_kill)
#define DIOCSTARTALTQ _IO ('D', 42)
#define DIOCSTOPALTQ _IO ('D', 43)
#define DIOCBEGINALTQS _IOWR('D', 44, u_int32_t)
#define DIOCADDALTQ _IOWR('D', 45, struct pfioc_altq)
#define DIOCCOMMITALTQS _IOWR('D', 46, u_int32_t)
#define DIOCGETALTQS _IOWR('D', 47, struct pfioc_altq)
#define DIOCGETALTQ _IOWR('D', 48, struct pfioc_altq)
#define DIOCCHANGEALTQ _IOWR('D', 49, struct pfioc_altq)
@ -1261,8 +1266,7 @@ struct pfioc_iface {
#define DIOCGETADDRS _IOWR('D', 53, struct pfioc_pooladdr)
#define DIOCGETADDR _IOWR('D', 54, struct pfioc_pooladdr)
#define DIOCCHANGEADDR _IOWR('D', 55, struct pfioc_pooladdr)
#define DIOCGETANCHORS _IOWR('D', 56, struct pfioc_anchor)
#define DIOCGETANCHOR _IOWR('D', 57, struct pfioc_anchor)
/* XXX cut 55 - 57 */
#define DIOCGETRULESETS _IOWR('D', 58, struct pfioc_ruleset)
#define DIOCGETRULESET _IOWR('D', 59, struct pfioc_ruleset)
#define DIOCRCLRTABLES _IOWR('D', 60, struct pfioc_table)
@ -1280,8 +1284,6 @@ struct pfioc_iface {
#define DIOCRCLRASTATS _IOWR('D', 72, struct pfioc_table)
#define DIOCRTSTADDRS _IOWR('D', 73, struct pfioc_table)
#define DIOCRSETTFLAGS _IOWR('D', 74, struct pfioc_table)
#define DIOCRINABEGIN _IOWR('D', 75, struct pfioc_table)
#define DIOCRINACOMMIT _IOWR('D', 76, struct pfioc_table)
#define DIOCRINADEFINE _IOWR('D', 77, struct pfioc_table)
#define DIOCOSFPFLUSH _IO('D', 78)
#define DIOCOSFPADD _IOWR('D', 79, struct pf_osfp_ioctl)
@ -1306,7 +1308,7 @@ RB_PROTOTYPE(pf_state_tree_id, pf_state,
extern struct pf_state_tree_id tree_id;
extern struct pf_state_queue state_updates;
extern struct pf_anchorqueue pf_anchors;
extern struct pf_anchor_global pf_anchors;
extern struct pf_ruleset pf_main_ruleset;
TAILQ_HEAD(pf_poolqueue, pf_pool);
extern struct pf_poolqueue pf_pools[2];
@ -1328,13 +1330,13 @@ extern int pf_tbladdr_setup(struct pf_ruleset *,
extern void pf_tbladdr_remove(struct pf_addr_wrap *);
extern void pf_tbladdr_copyout(struct pf_addr_wrap *);
extern void pf_calc_skip_steps(struct pf_rulequeue *);
extern void pf_update_anchor_rules(void);
extern struct pool pf_src_tree_pl, pf_rule_pl;
extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
extern struct pool pf_state_scrub_pl;
extern void pf_purge_timeout(void *);
extern void pf_purge_expired_src_nodes(void);
extern void pf_purge_expired_states(void);
extern void pf_purge_expired_state(struct pf_state *);
extern int pf_insert_state(struct pfi_kif *,
struct pf_state *);
extern int pf_insert_src_node(struct pf_src_node **,
@ -1344,13 +1346,15 @@ void pf_src_tree_remove_state(struct pf_state *);
extern struct pf_state *pf_find_state_byid(struct pf_state *);
extern struct pf_state *pf_find_state_all(struct pf_state *key,
u_int8_t tree, int *more);
extern void pf_print_state(struct pf_state *);
extern void pf_print_flags(u_int8_t);
extern struct pf_anchor *pf_find_anchor(const char *);
extern struct pf_ruleset *pf_find_ruleset(char *, char *);
extern struct pf_ruleset *pf_find_or_create_ruleset(
char[PF_ANCHOR_NAME_SIZE],
char[PF_RULESET_NAME_SIZE]);
extern struct pf_ruleset *pf_find_ruleset(const char *);
extern struct pf_ruleset *pf_find_or_create_ruleset(const char *);
extern void pf_remove_if_empty_ruleset(
struct pf_ruleset *);
extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
u_int8_t);
extern struct ifnet *sync_ifp;
extern struct pf_rule pf_default_rule;
@ -1360,11 +1364,11 @@ void pf_rm_rule(struct pf_rulequeue *,
struct pf_rule *);
#ifdef INET
int pf_test(int, struct ifnet *, struct mbuf **);
int pf_test(int, struct ifnet *, struct mbuf **, struct ether_header *);
#endif /* INET */
#ifdef INET6
int pf_test6(int, struct ifnet *, struct mbuf **);
int pf_test6(int, struct ifnet *, struct mbuf **, struct ether_header *);
void pf_poolmask(struct pf_addr *, struct pf_addr*,
struct pf_addr *, struct pf_addr *, u_int8_t);
void pf_addr_inc(struct pf_addr *, sa_family_t);
@ -1386,16 +1390,18 @@ void pf_normalize_init(void);
#ifdef _LKM
void pf_normalize_destroy(void);
#endif
int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *);
int pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *);
int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *,
struct pf_pdesc *);
int pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *,
struct pf_pdesc *);
int pf_normalize_tcp(int, struct pfi_kif *, struct mbuf *, int, int, void *,
struct pf_pdesc *);
void pf_normalize_tcp_cleanup(struct pf_state *);
int pf_normalize_tcp_init(struct mbuf *, int, struct pf_pdesc *,
struct tcphdr *, struct pf_state_peer *, struct pf_state_peer *);
int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *,
u_short *, struct tcphdr *, struct pf_state_peer *,
struct pf_state_peer *, int *);
u_short *, struct tcphdr *, struct pf_state *,
struct pf_state_peer *, struct pf_state_peer *, int *);
u_int32_t
pf_state_expires(const struct pf_state *);
void pf_purge_expired_fragments(void);
@ -1486,6 +1492,30 @@ int pfil4_wrapper(void *, struct mbuf **, struct ifnet *, int);
int pfil6_wrapper(void *, struct mbuf **, struct ifnet *, int);
int pfil_ifnet_wrapper(void *, struct mbuf **, struct ifnet *, int);
int pfil_ifaddr_wrapper(void *, struct mbuf **, struct ifnet *, int);
#endif
/*
* misc compatibility stuffs
*/
#if !defined(PRIu32)
#define PRIu32 "u" /* XXX */
#endif
#if !defined(__OpenBSD__)
#include <sys/kernel.h> /* mono_time */
static __inline void getmicrouptime(struct timeval *);
static __inline void
getmicrouptime(struct timeval *tvp)
{
int s;
s = splclock();
*tvp = mono_time;
splx(s);
}
#define time_second time.tv_sec
#define m_copym2 m_dup
#define pool_allocator_oldnointr pool_allocator_nointr
#endif
#endif /* _KERNEL */