svn commit: r185886 - vendor-sys/pf/dist/net
Max Laier
mlaier at FreeBSD.org
Wed Dec 10 13:22:58 PST 2008
Author: mlaier
Date: Wed Dec 10 21:22:57 2008
New Revision: 185886
URL: http://svn.freebsd.org/changeset/base/185886
Log:
Import OPENBSD_4_3_BASE
Modified:
vendor-sys/pf/dist/net/if_pflog.c
vendor-sys/pf/dist/net/if_pfsync.c
vendor-sys/pf/dist/net/if_pfsync.h
vendor-sys/pf/dist/net/pf.c
vendor-sys/pf/dist/net/pf_if.c
vendor-sys/pf/dist/net/pf_ioctl.c
vendor-sys/pf/dist/net/pf_norm.c
vendor-sys/pf/dist/net/pf_osfp.c
vendor-sys/pf/dist/net/pf_table.c
vendor-sys/pf/dist/net/pfvar.h
Modified: vendor-sys/pf/dist/net/if_pflog.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pflog.c Wed Dec 10 21:22:15 2008 (r185885)
+++ vendor-sys/pf/dist/net/if_pflog.c Wed Dec 10 21:22:57 2008 (r185886)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pflog.c,v 1.24 2007/05/26 17:13:30 jason Exp $ */
+/* $OpenBSD: if_pflog.c,v 1.27 2007/12/20 02:53:02 brad Exp $ */
/*
* The authors of this code are John Ioannidis (ji at tla.org),
* Angelos D. Keromytis (kermit at csd.uch.gr) and
@@ -107,9 +107,9 @@ pflog_clone_create(struct if_clone *ifc,
if (unit >= PFLOGIFS_MAX)
return (EINVAL);
- if ((pflogif = malloc(sizeof(*pflogif), M_DEVBUF, M_NOWAIT)) == NULL)
+ if ((pflogif = malloc(sizeof(*pflogif),
+ M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
return (ENOMEM);
- bzero(pflogif, sizeof(*pflogif));
pflogif->sc_unit = unit;
ifp = &pflogif->sc_if;
@@ -191,9 +191,6 @@ int
pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
switch (cmd) {
- case SIOCSIFADDR:
- case SIOCAIFADDR:
- case SIOCSIFDSTADDR:
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP)
ifp->if_flags |= IFF_RUNNING;
@@ -201,7 +198,7 @@ pflogioctl(struct ifnet *ifp, u_long cmd
ifp->if_flags &= ~IFF_RUNNING;
break;
default:
- return (EINVAL);
+ return (ENOTTY);
}
return (0);
Modified: vendor-sys/pf/dist/net/if_pfsync.c
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:22:15 2008 (r185885)
+++ vendor-sys/pf/dist/net/if_pfsync.c Wed Dec 10 21:22:57 2008 (r185886)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.89 2008/01/12 17:08:33 mpf Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -36,6 +36,7 @@
#include <sys/ioctl.h>
#include <sys/timeout.h>
#include <sys/kernel.h>
+#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -45,6 +46,7 @@
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
#include <netinet/tcp_seq.h>
+#include <sys/pool.h>
#ifdef INET
#include <netinet/in_systm.h>
@@ -124,9 +126,9 @@ pfsync_clone_create(struct if_clone *ifc
return (EINVAL);
pfsync_sync_ok = 1;
- if ((pfsyncif = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT)) == NULL)
+ if ((pfsyncif = malloc(sizeof(*pfsyncif), M_DEVBUF,
+ M_NOWAIT|M_ZERO)) == NULL)
return (ENOMEM);
- bzero(pfsyncif, sizeof(*pfsyncif));
pfsyncif->sc_mbuf = NULL;
pfsyncif->sc_mbuf_net = NULL;
pfsyncif->sc_mbuf_tdb = NULL;
@@ -140,6 +142,10 @@ pfsync_clone_create(struct if_clone *ifc
pfsyncif->sc_ureq_sent = 0;
pfsyncif->sc_bulk_send_next = NULL;
pfsyncif->sc_bulk_terminator = NULL;
+ pfsyncif->sc_imo.imo_membership = (struct in_multi **)malloc(
+ (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
+ M_WAITOK|M_ZERO);
+ pfsyncif->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
ifp = &pfsyncif->sc_if;
snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
ifp->if_softc = pfsyncif;
@@ -171,10 +177,21 @@ pfsync_clone_create(struct if_clone *ifc
int
pfsync_clone_destroy(struct ifnet *ifp)
{
+ struct pfsync_softc *sc = ifp->if_softc;
+
+ timeout_del(&sc->sc_tmo);
+ timeout_del(&sc->sc_tdb_tmo);
+ timeout_del(&sc->sc_bulk_tmo);
+ timeout_del(&sc->sc_bulkfail_tmo);
+#if NCARP > 0
+ if (!pfsync_sync_ok)
+ carp_group_demote_adj(&sc->sc_if, -1);
+#endif
#if NBPFILTER > 0
bpfdetach(ifp);
#endif
if_detach(ifp);
+ free(pfsyncif->sc_imo.imo_membership, M_IPMOPTS);
free(pfsyncif, M_DEVBUF);
pfsyncif = NULL;
return (0);
@@ -461,9 +478,9 @@ pfsync_input(struct mbuf *m, ...)
sp->direction > PF_OUT ||
(sp->af != AF_INET && sp->af != AF_INET6)) {
if (pf_status.debug >= PF_DEBUG_MISC)
- printf("pfsync_insert: PFSYNC_ACT_INS: "
+ printf("pfsync_input: PFSYNC_ACT_INS: "
"invalid value\n");
- pfsyncstats.pfsyncs_badstate++;
+ pfsyncstats.pfsyncs_badval++;
continue;
}
@@ -495,9 +512,9 @@ pfsync_input(struct mbuf *m, ...)
sp->src.state > PF_TCPS_PROXY_DST ||
sp->dst.state > PF_TCPS_PROXY_DST) {
if (pf_status.debug >= PF_DEBUG_MISC)
- printf("pfsync_insert: PFSYNC_ACT_UPD: "
+ printf("pfsync_input: PFSYNC_ACT_UPD: "
"invalid value\n");
- pfsyncstats.pfsyncs_badstate++;
+ pfsyncstats.pfsyncs_badval++;
continue;
}
@@ -559,7 +576,7 @@ pfsync_input(struct mbuf *m, ...)
: "partial"), sfail,
betoh64(st->id),
ntohl(st->creatorid));
- pfsyncstats.pfsyncs_badstate++;
+ pfsyncstats.pfsyncs_stale++;
if (!(sp->sync_flags & PFSTATE_STALE)) {
/* we have a better state, send it */
@@ -626,10 +643,10 @@ pfsync_input(struct mbuf *m, ...)
up->src.state > PF_TCPS_PROXY_DST ||
up->dst.state > PF_TCPS_PROXY_DST) {
if (pf_status.debug >= PF_DEBUG_MISC)
- printf("pfsync_insert: "
+ printf("pfsync_input: "
"PFSYNC_ACT_UPD_C: "
"invalid value\n");
- pfsyncstats.pfsyncs_badstate++;
+ pfsyncstats.pfsyncs_badval++;
continue;
}
@@ -685,7 +702,7 @@ pfsync_input(struct mbuf *m, ...)
"creatorid: %08x\n", sfail,
betoh64(st->id),
ntohl(st->creatorid));
- pfsyncstats.pfsyncs_badstate++;
+ pfsyncstats.pfsyncs_stale++;
/* we have a better state, send it out */
if ((!stale || update_requested) &&
@@ -1750,3 +1767,22 @@ pfsync_update_tdb(struct tdb *tdb, int o
return (ret);
}
#endif
+
+int
+pfsync_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
+ size_t newlen)
+{
+ /* All sysctl names at this level are terminal. */
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case PFSYNCCTL_STATS:
+ if (newp != NULL)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ &pfsyncstats, sizeof(pfsyncstats)));
+ default:
+ return (ENOPROTOOPT);
+ }
+}
Modified: vendor-sys/pf/dist/net/if_pfsync.h
==============================================================================
--- vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:22:15 2008 (r185885)
+++ vendor-sys/pf/dist/net/if_pfsync.h Wed Dec 10 21:22:57 2008 (r185886)
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.h,v 1.31 2007/05/31 04:11:42 mcbride Exp $ */
+/* $OpenBSD: if_pfsync.h,v 1.32 2007/12/14 18:33:37 deraadt Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -86,6 +86,17 @@ struct pfsync_state_bus {
u_int8_t pad[7];
} __packed;
+/*
+ * Names for PFSYNC sysctl objects
+ */
+#define PFSYNCCTL_STATS 1 /* PFSYNC stats */
+#define PFSYNCCTL_MAXID 2
+
+#define PFSYNCCTL_NAMES { \
+ { 0, 0 }, \
+ { "stats", CTLTYPE_STRUCT }, \
+}
+
#ifdef _KERNEL
union sc_statep {
@@ -255,6 +266,8 @@ struct pfsyncreq {
void pfsync_input(struct mbuf *, ...);
int pfsync_clear_states(u_int32_t, char *);
int pfsync_pack_state(u_int8_t, struct pf_state *, int);
+int pfsync_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+
#define pfsync_insert_state(st) do { \
if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \
(st->state_key->proto == IPPROTO_PFSYNC)) \
Modified: vendor-sys/pf/dist/net/pf.c
==============================================================================
--- vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:22:15 2008 (r185885)
+++ vendor-sys/pf/dist/net/pf.c Wed Dec 10 21:22:57 2008 (r185886)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.552 2007/08/21 15:57:27 dhartmei Exp $ */
+/* $OpenBSD: pf.c,v 1.567 2008/02/20 23:40:13 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -51,6 +51,8 @@
#include <sys/proc.h>
#include <sys/rwlock.h>
+#include <crypto/md5.h>
+
#include <net/if.h>
#include <net/if_types.h>
#include <net/bpf.h>
@@ -110,6 +112,11 @@ u_int32_t ticket_altqs_inactive;
int altqs_inactive_open;
u_int32_t ticket_pabuf;
+MD5_CTX pf_tcp_secret_ctx;
+u_char pf_tcp_secret[16];
+int pf_tcp_secret_init;
+int pf_tcp_iss_off;
+
struct pf_anchor_stackframe {
struct pf_ruleset *rs;
struct pf_rule *r;
@@ -160,6 +167,7 @@ struct pf_rule *pf_get_translation(stru
void pf_attach_state(struct pf_state_key *,
struct pf_state *, int);
void pf_detach_state(struct pf_state *, int);
+u_int32_t pf_tcp_iss(struct pf_pdesc *);
int pf_test_rule(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
@@ -214,7 +222,7 @@ int pf_check_proto_cksum(struct mbuf
int pf_addr_wrap_neq(struct pf_addr_wrap *,
struct pf_addr_wrap *);
struct pf_state *pf_find_state(struct pfi_kif *,
- struct pf_state_key_cmp *, u_int8_t);
+ struct pf_state_key_cmp *, u_int);
int pf_src_connlimit(struct pf_state **);
void pf_stateins_err(const char *, struct pf_state *,
struct pfi_kif *);
@@ -233,10 +241,7 @@ struct pf_pool_limit pf_pool_limits[PF_L
#define STATE_LOOKUP() \
do { \
- if (direction == PF_IN) \
- *state = pf_find_state(kif, &key, PF_EXT_GWY); \
- else \
- *state = pf_find_state(kif, &key, PF_LAN_EXT); \
+ *state = pf_find_state(kif, &key, direction); \
if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
return (PF_DROP); \
if (direction == PF_OUT && \
@@ -526,19 +531,19 @@ pf_find_state_byid(struct pf_state_cmp *
}
struct pf_state *
-pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int8_t tree)
+pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir)
{
struct pf_state_key *sk;
struct pf_state *s;
pf_status.fcounters[FCNT_STATE_SEARCH]++;
- switch (tree) {
- case PF_LAN_EXT:
+ switch (dir) {
+ case PF_OUT:
sk = RB_FIND(pf_state_tree_lan_ext, &pf_statetbl_lan_ext,
(struct pf_state_key *)key);
break;
- case PF_EXT_GWY:
+ case PF_IN:
sk = RB_FIND(pf_state_tree_ext_gwy, &pf_statetbl_ext_gwy,
(struct pf_state_key *)key);
break;
@@ -556,19 +561,19 @@ pf_find_state(struct pfi_kif *kif, struc
}
struct pf_state *
-pf_find_state_all(struct pf_state_key_cmp *key, u_int8_t tree, int *more)
+pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more)
{
struct pf_state_key *sk;
struct pf_state *s, *ret = NULL;
pf_status.fcounters[FCNT_STATE_SEARCH]++;
- switch (tree) {
- case PF_LAN_EXT:
+ switch (dir) {
+ case PF_OUT:
sk = RB_FIND(pf_state_tree_lan_ext,
&pf_statetbl_lan_ext, (struct pf_state_key *)key);
break;
- case PF_EXT_GWY:
+ case PF_IN:
sk = RB_FIND(pf_state_tree_ext_gwy,
&pf_statetbl_ext_gwy, (struct pf_state_key *)key);
break;
@@ -819,6 +824,8 @@ pf_insert_state(struct pfi_kif *kif, str
TAILQ_FOREACH(sp, &cur->states, next)
if (sp->kif == kif) { /* collision! */
pf_stateins_err("tree_lan_ext", s, kif);
+ pf_detach_state(s,
+ PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
return (-1);
}
pf_detach_state(s, PF_DT_SKIP_LANEXT|PF_DT_SKIP_EXTGWY);
@@ -961,10 +968,8 @@ pf_src_tree_remove_state(struct pf_state
u_int32_t timeout;
if (s->src_node != NULL) {
- if (s->state_key->proto == IPPROTO_TCP) {
- if (s->src.tcp_est)
- --s->src_node->conn;
- }
+ if (s->src.tcp_est)
+ --s->src_node->conn;
if (--s->src_node->states <= 0) {
timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
if (!timeout)
@@ -1295,6 +1300,7 @@ pf_addr_wrap_neq(struct pf_addr_wrap *aw
return (1);
switch (aw1->type) {
case PF_ADDR_ADDRMASK:
+ case PF_ADDR_RANGE:
if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
return (1);
if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
@@ -1598,7 +1604,7 @@ pf_send_tcp(const struct pf_rule *r, sa_
m->m_pkthdr.pf.tag = rtag;
if (r != NULL && r->rtableid >= 0)
- m->m_pkthdr.pf.rtableid = m->m_pkthdr.pf.rtableid;
+ m->m_pkthdr.pf.rtableid = r->rtableid;
#ifdef ALTQ
if (r != NULL && r->qid) {
@@ -1790,6 +1796,44 @@ pf_match_addr(u_int8_t n, struct pf_addr
}
}
+/*
+ * Return 1 if b <= a <= e, otherwise return 0.
+ */
+int
+pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
+ struct pf_addr *a, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if ((a->addr32[0] < b->addr32[0]) ||
+ (a->addr32[0] > e->addr32[0]))
+ return (0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ int i;
+
+ /* check a >= b */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] > b->addr32[i])
+ break;
+ else if (a->addr32[i] < b->addr32[i])
+ return (0);
+ /* check a <= e */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] < e->addr32[i])
+ break;
+ else if (a->addr32[i] > e->addr32[i])
+ return (0);
+ break;
+ }
+#endif /* INET6 */
+ }
+ return (1);
+}
+
int
pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
{
@@ -2267,15 +2311,15 @@ pf_get_sport(sa_family_t af, u_int8_t pr
if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
proto == IPPROTO_ICMP)) {
key.gwy.port = dport;
- if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
+ if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
return (0);
} else if (low == 0 && high == 0) {
key.gwy.port = *nport;
- if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL)
+ if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
return (0);
} else if (low == high) {
key.gwy.port = htons(low);
- if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) {
+ if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
*nport = htons(low);
return (0);
}
@@ -2292,7 +2336,7 @@ pf_get_sport(sa_family_t af, u_int8_t pr
/* low <= cut <= high */
for (tmp = cut; tmp <= high; ++(tmp)) {
key.gwy.port = htons(tmp);
- if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
+ if (pf_find_state_all(&key, PF_IN, NULL) ==
NULL) {
*nport = htons(tmp);
return (0);
@@ -2300,7 +2344,7 @@ pf_get_sport(sa_family_t af, u_int8_t pr
}
for (tmp = cut - 1; tmp >= low; --(tmp)) {
key.gwy.port = htons(tmp);
- if (pf_find_state_all(&key, PF_EXT_GWY, NULL) ==
+ if (pf_find_state_all(&key, PF_IN, NULL) ==
NULL) {
*nport = htons(tmp);
return (0);
@@ -2836,6 +2880,34 @@ pf_alloc_state_key(struct pf_state *s)
return (sk);
}
+u_int32_t
+pf_tcp_iss(struct pf_pdesc *pd)
+{
+ MD5_CTX ctx;
+ u_int32_t digest[4];
+
+ if (pf_tcp_secret_init == 0) {
+ arc4random_bytes(pf_tcp_secret, sizeof(pf_tcp_secret));
+ MD5Init(&pf_tcp_secret_ctx);
+ MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret, sizeof(pf_tcp_secret));
+ pf_tcp_secret_init = 1;
+ }
+ ctx = pf_tcp_secret_ctx;
+
+ MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof(u_short));
+ MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof(u_short));
+ if (pd->af == AF_INET6) {
+ MD5Update(&ctx, (char *)&pd->src->v6, sizeof(struct in6_addr));
+ MD5Update(&ctx, (char *)&pd->dst->v6, sizeof(struct in6_addr));
+ } else {
+ MD5Update(&ctx, (char *)&pd->src->v4, sizeof(struct in_addr));
+ MD5Update(&ctx, (char *)&pd->dst->v4, sizeof(struct in_addr));
+ }
+ MD5Final((u_char *)digest, &ctx);
+ pf_tcp_iss_off += 4096;
+ return (digest[0] + tcp_iss + pf_tcp_iss_off);
+}
+
int
pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h,
@@ -3077,7 +3149,8 @@ pf_test_rule(struct pf_rule **rm, struct
!pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
pd->lookup.gid))
r = TAILQ_NEXT(r, entries);
- else if (r->prob && r->prob <= arc4random())
+ else if (r->prob && r->prob <=
+ (arc4random() % (UINT_MAX - 1) + 1))
r = TAILQ_NEXT(r, entries);
else if (r->match_tag && !pf_match_tag(m, r, &tag))
r = TAILQ_NEXT(r, entries);
@@ -3203,10 +3276,22 @@ pf_test_rule(struct pf_rule **rm, struct
(r->rule_flag & PFRULE_RETURN)) &&
!(th->th_flags & TH_RST)) {
u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
- struct ip *h = mtod(m, struct ip *);
+ int len = 0;
+ struct ip *h4;
+ struct ip6_hdr *h6;
+
+ switch (af) {
+ case AF_INET:
+ h4 = mtod(m, struct ip *);
+ len = ntohs(h4->ip_len) - off;
+ break;
+ case AF_INET6:
+ h6 = mtod(m, struct ip6_hdr *);
+ len = ntohs(h6->ip6_plen) - (off - sizeof(*h6));
+ break;
+ }
- if (pf_check_proto_cksum(m, off,
- ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET))
+ if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af))
REASON_SET(&reason, PFRES_PROTCKSUM);
else {
if (th->th_flags & TH_SYN)
@@ -3218,10 +3303,12 @@ pf_test_rule(struct pf_rule **rm, struct
ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
}
- } else if ((af == AF_INET) && r->return_icmp)
+ } else if (pd->proto != IPPROTO_ICMP && af == AF_INET &&
+ r->return_icmp)
pf_send_icmp(m, r->return_icmp >> 8,
r->return_icmp & 255, af, r);
- else if ((af == AF_INET6) && r->return_icmp6)
+ else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 &&
+ r->return_icmp6)
pf_send_icmp(m, r->return_icmp6 >> 8,
r->return_icmp6 & 255, af, r);
}
@@ -3237,7 +3324,6 @@ pf_test_rule(struct pf_rule **rm, struct
if (!state_icmp && (r->keep_state || nr != NULL ||
(pd->flags & PFDESC_TCP_NORM))) {
/* create new state */
- u_int16_t len;
struct pf_state *s = NULL;
struct pf_state_key *sk = NULL;
struct pf_src_node *sn = NULL;
@@ -3296,15 +3382,14 @@ cleanup:
s->log |= nr->log & PF_LOG_ALL;
switch (pd->proto) {
case IPPROTO_TCP:
- len = pd->tot_len - off - (th->th_off << 2);
s->src.seqlo = ntohl(th->th_seq);
- s->src.seqhi = s->src.seqlo + len + 1;
+ s->src.seqhi = s->src.seqlo + pd->p_len + 1;
if ((th->th_flags & (TH_SYN|TH_ACK)) ==
TH_SYN && r->keep_state == PF_STATE_MODULATE) {
/* Generate sequence number modulator */
- while ((s->src.seqdiff =
- tcp_rndiss_next() - s->src.seqlo) == 0)
- ;
+ if ((s->src.seqdiff = pf_tcp_iss(pd) -
+ s->src.seqlo) == 0)
+ s->src.seqdiff = 1;
pf_change_a(&th->th_seq, &th->th_sum,
htonl(s->src.seqlo + s->src.seqdiff), 0);
rewrite = 1;
@@ -3525,11 +3610,20 @@ pf_test_fragment(struct pf_rule **rm, in
r = r->skip[PF_SKIP_DST_ADDR].ptr;
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->os_fingerprint != PF_OSFP_ANY)
+ else if (r->os_fingerprint != PF_OSFP_ANY)
+ r = TAILQ_NEXT(r, entries);
+ else if (pd->proto == IPPROTO_UDP &&
+ (r->src.port_op || r->dst.port_op))
r = TAILQ_NEXT(r, entries);
- else if (r->prob && r->prob <= arc4random())
+ else if (pd->proto == IPPROTO_TCP &&
+ (r->src.port_op || r->dst.port_op || r->flagset))
+ r = TAILQ_NEXT(r, entries);
+ else if ((pd->proto == IPPROTO_ICMP ||
+ pd->proto == IPPROTO_ICMPV6) &&
+ (r->type || r->code))
+ r = TAILQ_NEXT(r, entries);
+ else if (r->prob && r->prob <=
+ (arc4random() % (UINT_MAX - 1) + 1))
r = TAILQ_NEXT(r, entries);
else if (r->match_tag && !pf_match_tag(m, r, &tag))
r = TAILQ_NEXT(r, entries);
@@ -3698,6 +3792,22 @@ pf_test_state_tcp(struct pf_state **stat
}
}
+ if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) &&
+ dst->state >= TCPS_FIN_WAIT_2 &&
+ src->state >= TCPS_FIN_WAIT_2) {
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+ printf("pf: state reuse ");
+ pf_print_state(*state);
+ pf_print_flags(th->th_flags);
+ printf("\n");
+ }
+ /* XXX make sure it's the same direction ?? */
+ (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
+ pf_unlink_state(*state);
+ *state = NULL;
+ return (PF_DROP);
+ }
+
if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
sws = src->wscale & PF_WSCALE_MASK;
dws = dst->wscale & PF_WSCALE_MASK;
@@ -3724,7 +3834,8 @@ pf_test_state_tcp(struct pf_state **stat
/* Deferred generation of sequence number modulator */
if (dst->seqdiff && !src->seqdiff) {
- while ((src->seqdiff = tcp_rndiss_next() - seq) == 0)
+ /* use random iss for the TCP server */
+ while ((src->seqdiff = arc4random() - seq) == 0)
;
ack = ntohl(th->th_ack) - dst->seqdiff;
pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
@@ -3842,7 +3953,8 @@ pf_test_state_tcp(struct pf_state **stat
(ackskew <= (MAXACKWINDOW << sws)) &&
/* Acking not more than one window forward */
((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
- (orig_seq == src->seqlo + 1) || (pd->flags & PFDESC_IP_REAS) == 0)) {
+ (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo) ||
+ (pd->flags & PFDESC_IP_REAS) == 0)) {
/* Require an exact/+1 sequence match on resets when possible */
if (dst->scrub || src->scrub) {
@@ -3937,9 +4049,12 @@ pf_test_state_tcp(struct pf_state **stat
pf_print_state(*state);
pf_print_flags(th->th_flags);
printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
- "pkts=%llu:%llu\n", seq, orig_seq, ack, pd->p_len,
- ackskew, (*state)->packets[0],
- (*state)->packets[1]);
+ "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack,
+ pd->p_len, ackskew, (*state)->packets[0],
+ (*state)->packets[1],
+ direction == PF_IN ? "in" : "out",
+ direction == (*state)->state_key->direction ?
+ "fwd" : "rev");
}
if (dst->scrub || src->scrub) {
Modified: vendor-sys/pf/dist/net/pf_if.c
==============================================================================
--- vendor-sys/pf/dist/net/pf_if.c Wed Dec 10 21:22:15 2008 (r185885)
+++ vendor-sys/pf/dist/net/pf_if.c Wed Dec 10 21:22:57 2008 (r185886)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_if.c,v 1.47 2007/07/13 09:17:48 markus Exp $ */
+/* $OpenBSD: pf_if.c,v 1.51 2007/11/07 17:28:40 mpf Exp $ */
/*
* Copyright 2005 Henning Brauer <henning at openbsd.org>
@@ -41,6 +41,7 @@
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/time.h>
+#include <sys/pool.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -110,10 +111,9 @@ pfi_kif_get(const char *kif_name)
return (kif);
/* create new one */
- if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT)) == NULL)
+ if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT|M_ZERO)) == NULL)
return (NULL);
- bzero(kif, sizeof(*kif));
strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
kif->pfik_tzero = time_second;
TAILQ_INIT(&kif->pfik_dynaddrs);
@@ -603,49 +603,57 @@ pfi_if_compare(struct pfi_kif *p, struct
}
void
-pfi_fill_oldstatus(struct pf_status *pfs)
+pfi_update_status(const char *name, struct pf_status *pfs)
{
struct pfi_kif *p;
struct pfi_kif_cmp key;
+ struct ifg_member p_member, *ifgm;
+ TAILQ_HEAD(, ifg_member) ifg_members;
int i, j, k, s;
- strlcpy(key.pfik_name, pfs->ifname, sizeof(key.pfik_name));
+ strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
s = splsoftnet();
p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key);
if (p == NULL) {
splx(s);
return;
}
- bzero(pfs->pcounters, sizeof(pfs->pcounters));
- bzero(pfs->bcounters, sizeof(pfs->bcounters));
- for (i = 0; i < 2; i++)
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++) {
- pfs->pcounters[i][j][k] =
- p->pfik_packets[i][j][k];
- pfs->bcounters[i][j] +=
- p->pfik_bytes[i][j][k];
- }
- splx(s);
-}
-
-int
-pfi_clr_istats(const char *name)
-{
- struct pfi_kif *p;
- int s;
+ if (p->pfik_group != NULL) {
+ bcopy(&p->pfik_group->ifg_members, &ifg_members,
+ sizeof(ifg_members));
+ } else {
+ /* build a temporary list for p only */
+ bzero(&p_member, sizeof(p_member));
+ p_member.ifgm_ifp = p->pfik_ifp;
+ TAILQ_INIT(&ifg_members);
+ TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
+ }
+ if (pfs) {
+ bzero(pfs->pcounters, sizeof(pfs->pcounters));
+ bzero(pfs->bcounters, sizeof(pfs->bcounters));
+ }
+ TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
+ if (ifgm->ifgm_ifp == NULL)
+ continue;
+ p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
- s = splsoftnet();
- RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
- if (pfi_skip_if(name, p))
+ /* just clear statistics */
+ if (pfs == NULL) {
+ bzero(p->pfik_packets, sizeof(p->pfik_packets));
+ bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
+ p->pfik_tzero = time_second;
continue;
- bzero(p->pfik_packets, sizeof(p->pfik_packets));
- bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
- p->pfik_tzero = time_second;
+ }
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++) {
+ pfs->pcounters[i][j][k] +=
+ p->pfik_packets[i][j][k];
+ pfs->bcounters[i][j] +=
+ p->pfik_bytes[i][j][k];
+ }
}
splx(s);
-
- return (0);
}
int
Modified: vendor-sys/pf/dist/net/pf_ioctl.c
==============================================================================
--- vendor-sys/pf/dist/net/pf_ioctl.c Wed Dec 10 21:22:15 2008 (r185885)
+++ vendor-sys/pf/dist/net/pf_ioctl.c Wed Dec 10 21:22:57 2008 (r185886)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.182 2007/06/24 11:17:13 mcbride Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.193 2007/12/02 12:08:04 pascoe Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -160,7 +160,7 @@ pfattach(int num)
pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
- if (ctob(physmem) <= 100*1024*1024)
+ if (ptoa(physmem) <= 100*1024*1024)
pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit =
PFR_KENTRY_HIWAT_SMALL;
@@ -379,11 +379,9 @@ tagname2tag(struct pf_tags *head, char *
return (0);
/* allocate and fill new struct pf_tagname */
- tag = (struct pf_tagname *)malloc(sizeof(struct pf_tagname),
- M_TEMP, M_NOWAIT);
+ tag = malloc(sizeof(*tag), M_TEMP, M_NOWAIT|M_ZERO);
if (tag == NULL)
return (0);
- bzero(tag, sizeof(struct pf_tagname));
strlcpy(tag->name, tagname, sizeof(tag->name));
tag->tag = new_tagid;
tag->ref++;
@@ -912,7 +910,6 @@ pf_state_import(struct pfsync_state *sp,
/* copy to state */
memcpy(&s->id, &sp->id, sizeof(sp->id));
s->creatorid = sp->creatorid;
- strlcpy(sp->ifname, s->kif->pfik_name, sizeof(sp->ifname));
pf_state_peer_from_pfsync(&sp->src, &s->src);
pf_state_peer_from_pfsync(&sp->dst, &s->dst);
@@ -921,6 +918,9 @@ pf_state_import(struct pfsync_state *sp,
s->anchor.ptr = NULL;
s->rt_kif = NULL;
s->creation = time_second;
+ s->expire = time_second;
+ if (sp->expire > 0)
+ s->expire -= pf_default_rule.timeout[sp->timeout] - sp->expire;
s->pfsync_time = 0;
s->packets[0] = s->packets[1] = 0;
s->bytes[0] = s->bytes[1] = 0;
@@ -1633,7 +1633,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
case DIOCADDSTATE: {
struct pfioc_state *ps = (struct pfioc_state *)addr;
- struct pfsync_state *sp = (struct pfsync_state *)ps->state;
+ struct pfsync_state *sp = &ps->state;
struct pf_state *s;
struct pf_state_key *sk;
struct pfi_kif *kif;
@@ -1650,6 +1650,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
}
bzero(s, sizeof(struct pf_state));
if ((sk = pf_alloc_state_key(s)) == NULL) {
+ pool_put(&pf_state_pl, s);
error = ENOMEM;
break;
}
@@ -1664,30 +1665,28 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
if (pf_insert_state(kif, s)) {
pfi_kif_unref(kif, PFI_KIF_REF_NONE);
pool_put(&pf_state_pl, s);
- pool_put(&pf_state_key_pl, sk);
- error = ENOMEM;
+ error = EEXIST;
+ break;
}
+ pf_default_rule.states++;
break;
}
case DIOCGETSTATE: {
struct pfioc_state *ps = (struct pfioc_state *)addr;
struct pf_state *s;
- u_int32_t nr;
+ struct pf_state_cmp id_key;
- nr = 0;
- RB_FOREACH(s, pf_state_tree_id, &tree_id) {
- if (nr >= ps->nr)
- break;
- nr++;
- }
+ bcopy(ps->state.id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = ps->state.creatorid;
+
+ s = pf_find_state_byid(&id_key);
if (s == NULL) {
- error = EBUSY;
+ error = ENOENT;
break;
}
- pf_state_export((struct pfsync_state *)&ps->state,
- s->state_key, s);
+ pf_state_export(&ps->state, s->state_key, s);
break;
}
@@ -1735,7 +1734,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
case DIOCGETSTATUS: {
struct pf_status *s = (struct pf_status *)addr;
bcopy(&pf_status, s, sizeof(struct pf_status));
- pfi_fill_oldstatus(s);
+ pfi_update_status(s->ifname, s);
break;
}
@@ -1746,10 +1745,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
bzero(pf_status.ifname, IFNAMSIZ);
break;
}
- if (ifunit(pi->ifname) == NULL) {
- error = EINVAL;
- break;
- }
strlcpy(pf_status.ifname, pi->ifname, IFNAMSIZ);
break;
}
@@ -1760,7 +1755,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
bzero(pf_status.scounters, sizeof(pf_status.scounters));
pf_status.since = time_second;
if (*pf_status.ifname)
- pfi_clr_istats(pf_status.ifname);
+ pfi_update_status(pf_status.ifname, NULL);
break;
}
@@ -1793,13 +1788,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
key.ext.port = pnl->dport;
PF_ACPY(&key.gwy.addr, &pnl->saddr, pnl->af);
key.gwy.port = pnl->sport;
- state = pf_find_state_all(&key, PF_EXT_GWY, &m);
+ state = pf_find_state_all(&key, PF_IN, &m);
} else {
PF_ACPY(&key.lan.addr, &pnl->daddr, pnl->af);
key.lan.port = pnl->dport;
PF_ACPY(&key.ext.addr, &pnl->saddr, pnl->af);
key.ext.port = pnl->sport;
- state = pf_find_state_all(&key, PF_LAN_EXT, &m);
+ state = pf_find_state_all(&key, PF_OUT, &m);
}
if (m > 1)
error = E2BIG; /* more than one state */
@@ -1968,6 +1963,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
pool_put(&pf_altq_pl, altq);
break;
}
+ altq->altq_disc = NULL;
TAILQ_FOREACH(a, pf_altqs_inactive, entries) {
if (strncmp(a->ifname, altq->ifname,
IFNAMSIZ) == 0 && a->qname[0] == 0) {
@@ -2547,10 +2543,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
error = ENODEV;
goto fail;
}
- ioe = (struct pfioc_trans_e *)malloc(sizeof(*ioe),
- M_TEMP, M_WAITOK);
- table = (struct pfr_table *)malloc(sizeof(*table),
- M_TEMP, M_WAITOK);
+ ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+ table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
for (i = 0; i < io->size; i++) {
if (copyin(io->array+i, ioe, sizeof(*ioe))) {
free(table, M_TEMP);
@@ -2616,10 +2610,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
error = ENODEV;
goto fail;
}
- ioe = (struct pfioc_trans_e *)malloc(sizeof(*ioe),
- M_TEMP, M_WAITOK);
- table = (struct pfr_table *)malloc(sizeof(*table),
- M_TEMP, M_WAITOK);
+ ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+ table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
for (i = 0; i < io->size; i++) {
if (copyin(io->array+i, ioe, sizeof(*ioe))) {
free(table, M_TEMP);
@@ -2680,10 +2672,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
error = ENODEV;
goto fail;
}
- ioe = (struct pfioc_trans_e *)malloc(sizeof(*ioe),
- M_TEMP, M_WAITOK);
- table = (struct pfr_table *)malloc(sizeof(*table),
- M_TEMP, M_WAITOK);
+ ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+ table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
/* first makes sure everything will succeed */
for (i = 0; i < io->size; i++) {
if (copyin(io->array+i, ioe, sizeof(*ioe))) {
Modified: vendor-sys/pf/dist/net/pf_norm.c
==============================================================================
--- vendor-sys/pf/dist/net/pf_norm.c Wed Dec 10 21:22:15 2008 (r185885)
+++ vendor-sys/pf/dist/net/pf_norm.c Wed Dec 10 21:22:57 2008 (r185886)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.109 2007/05/28 17:16:39 henning Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.111 2007/12/30 10:32:24 mglocker Exp $ */
/*
* Copyright 2001 Niels Provos <provos at citi.umich.edu>
@@ -115,7 +115,7 @@ struct mbuf *pf_reassemble(struct mbuf
struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
struct pf_fragment **, int, int, int *);
int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
- struct tcphdr *, int);
+ struct tcphdr *, int, sa_family_t);
#define DPFPRINTF(x) do { \
if (pf_status.debug >= PF_DEBUG_MISC) { \
@@ -1316,7 +1316,7 @@ pf_normalize_tcp(int dir, struct pfi_kif
}
/* Process options */
- if (r->max_mss && pf_normalize_tcpopt(r, m, th, off))
+ if (r->max_mss && pf_normalize_tcpopt(r, m, th, off, pd->af))
rewrite = 1;
/* copy back packet headers if we sanitized */
@@ -1819,17 +1819,21 @@ pf_normalize_tcp_stateful(struct mbuf *m
int
pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
- int off)
+ int off, sa_family_t af)
{
u_int16_t *mss;
int thoff;
int opt, cnt, optlen = 0;
int rewrite = 0;
- u_char *optp;
+ u_char opts[MAX_TCPOPTLEN];
+ u_char *optp = opts;
thoff = th->th_off << 2;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-vendor
mailing list