PF from openbsd 3.5. missing features:

- pfsync (due to protocol # assignment issues)
- carp (not really a PF portion, but thought important to mention)
- PF and ALTQ are mutually-exclusive.  this will be sorted out when
  kjc@csl.sony.co.jp updates ALTQ and PF (and API inbetween)

reviewed by matt, christos, perry

torture-test is very welcomed.
This commit is contained in:
itojun 2004-06-22 14:17:07 +00:00
parent 596aec9a47
commit bfcdaa5766
12 changed files with 590 additions and 1583 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.676 2004/06/18 15:02:29 christos Exp $
# $NetBSD: files,v 1.677 2004/06/22 14:17:07 itojun Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -127,6 +127,7 @@ include "netiso/files.netiso"
include "netnatm/files.netnatm"
include "netns/files.netns"
include "netsmb/files.netsmb"
include "net/files.pf"
defflag IPX # IPX network stack
defflag PFIL_HOOKS # pfil(9)

View File

@ -1,3 +1,4 @@
/* $NetBSD: if_pflog.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */
/* $OpenBSD: if_pflog.c,v 1.11 2003/12/31 11:18:25 cedric Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@ -33,6 +34,10 @@
* PURPOSE.
*/
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#endif
#include "bpfilter.h"
#include "pflog.h"
@ -106,8 +111,12 @@ pflogattach(int npflog)
if_alloc_sadl(ifp);
#if NBPFILTER > 0
#ifdef __OpenBSD__
bpfattach(&pflogif[i].sc_if.if_bpf, ifp, DLT_PFLOG,
PFLOG_HDRLEN);
#else
bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
#endif
#endif
}
}
@ -122,7 +131,11 @@ pflogstart(struct ifnet *ifp)
int s;
for (;;) {
#ifdef __OpenBSD__
s = splimp();
#else
s = splnet();
#endif
IF_DROP(&ifp->if_snd);
IF_DEQUEUE(&ifp->if_snd, m);
splx(s);

View File

@ -1,3 +1,4 @@
/* $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 $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>

File diff suppressed because it is too large Load Diff

View File

@ -1,280 +0,0 @@
/* $OpenBSD: if_pfsync.h,v 1.13 2004/03/22 04:54:17 mcbride Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _NET_IF_PFSYNC_H_
#define _NET_IF_PFSYNC_H_
#define PFSYNC_ID_LEN sizeof(u_int64_t)
struct pfsync_state_scrub {
u_int16_t pfss_flags;
u_int8_t pfss_ttl; /* stashed TTL */
u_int8_t scrub_flag;
u_int32_t pfss_ts_mod; /* timestamp modulation */
} __packed;
struct pfsync_state_host {
struct pf_addr addr;
u_int16_t port;
u_int16_t pad[3];
} __packed;
struct pfsync_state_peer {
struct pfsync_state_scrub scrub; /* state is scrubbed */
u_int32_t seqlo; /* Max sequence number sent */
u_int32_t seqhi; /* Max the other end ACKd + win */
u_int32_t seqdiff; /* Sequence number modulator */
u_int16_t max_win; /* largest window (pre scaling) */
u_int16_t mss; /* Maximum segment size option */
u_int8_t state; /* active state level */
u_int8_t wscale; /* window scaling factor */
u_int8_t scrub_flag;
u_int8_t pad[5];
} __packed;
struct pfsync_state {
u_int32_t id[2];
char ifname[IFNAMSIZ];
struct pfsync_state_host lan;
struct pfsync_state_host gwy;
struct pfsync_state_host ext;
struct pfsync_state_peer src;
struct pfsync_state_peer dst;
struct pf_addr rt_addr;
u_int32_t rule;
u_int32_t anchor;
u_int32_t nat_rule;
u_int32_t creation;
u_int32_t expire;
u_int32_t packets[2];
u_int32_t bytes[2];
u_int32_t creatorid;
sa_family_t af;
u_int8_t proto;
u_int8_t direction;
u_int8_t log;
u_int8_t allow_opts;
u_int8_t timeout;
u_int8_t sync_flags;
u_int8_t updates;
} __packed;
struct pfsync_state_upd {
u_int32_t id[2];
struct pfsync_state_peer src;
struct pfsync_state_peer dst;
u_int32_t creatorid;
u_int32_t expire;
u_int8_t timeout;
u_int8_t updates;
u_int8_t pad[6];
} __packed;
struct pfsync_state_del {
u_int32_t id[2];
u_int32_t creatorid;
struct {
u_int8_t state;
} src;
struct {
u_int8_t state;
} dst;
u_int8_t pad[2];
} __packed;
struct pfsync_state_upd_req {
u_int32_t id[2];
u_int32_t creatorid;
u_int32_t pad;
} __packed;
struct pfsync_state_clr {
char ifname[IFNAMSIZ];
u_int32_t creatorid;
u_int32_t pad;
} __packed;
struct pfsync_state_bus {
u_int32_t creatorid;
u_int32_t endtime;
u_int8_t status;
#define PFSYNC_BUS_START 1
#define PFSYNC_BUS_END 2
u_int8_t pad[7];
} __packed;
#ifdef _KERNEL
union sc_statep {
struct pfsync_state *s;
struct pfsync_state_upd *u;
struct pfsync_state_del *d;
struct pfsync_state_clr *c;
struct pfsync_state_bus *b;
struct pfsync_state_upd_req *r;
};
extern int pfsync_sync_ok;
struct pfsync_softc {
struct ifnet sc_if;
struct ifnet *sc_sync_ifp;
struct ip_moptions sc_imo;
struct timeout sc_tmo;
struct timeout sc_bulk_tmo;
struct timeout sc_bulkfail_tmo;
struct in_addr sc_sendaddr;
struct mbuf *sc_mbuf; /* current cummulative mbuf */
struct mbuf *sc_mbuf_net; /* current cummulative mbuf */
union sc_statep sc_statep;
union sc_statep sc_statep_net;
u_int32_t sc_ureq_received;
u_int32_t sc_ureq_sent;
int sc_bulk_tries;
int sc_maxcount; /* number of states in mtu */
int sc_maxupdates; /* number of updates/state */
};
#endif
struct pfsync_header {
u_int8_t version;
#define PFSYNC_VERSION 2
u_int8_t af;
u_int8_t action;
#define PFSYNC_ACT_CLR 0 /* clear all states */
#define PFSYNC_ACT_INS 1 /* insert state */
#define PFSYNC_ACT_UPD 2 /* update state */
#define PFSYNC_ACT_DEL 3 /* delete state */
#define PFSYNC_ACT_UPD_C 4 /* "compressed" state update */
#define PFSYNC_ACT_DEL_C 5 /* "compressed" state delete */
#define PFSYNC_ACT_INS_F 6 /* insert fragment */
#define PFSYNC_ACT_DEL_F 7 /* delete fragments */
#define PFSYNC_ACT_UREQ 8 /* request "uncompressed" state */
#define PFSYNC_ACT_BUS 9 /* Bulk Update Status */
#define PFSYNC_ACT_MAX 10
u_int8_t count;
} __packed;
#define PFSYNC_BULKPACKETS 1 /* # of packets per timeout */
#define PFSYNC_MAX_BULKTRIES 12
#define PFSYNC_HDRLEN sizeof(struct pfsync_header)
#define PFSYNC_ACTIONS \
"CLR ST", "INS ST", "UPD ST", "DEL ST", \
"UPD ST COMP", "DEL ST COMP", "INS FR", "DEL FR", \
"UPD REQ", "BLK UPD STAT"
#define PFSYNC_DFLTTL 255
struct pfsyncstats {
u_long pfsyncs_ipackets; /* total input packets, IPv4 */
u_long pfsyncs_ipackets6; /* total input packets, IPv6 */
u_long pfsyncs_badif; /* not the right interface */
u_long pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */
u_long pfsyncs_hdrops; /* packets shorter than header */
u_long pfsyncs_badver; /* bad (incl unsupp) version */
u_long pfsyncs_badact; /* bad action */
u_long pfsyncs_badlen; /* data length does not match */
u_long pfsyncs_badauth; /* bad authentication */
u_long pfsyncs_badstate; /* insert/lookup failed */
u_long pfsyncs_opackets; /* total output packets, IPv4 */
u_long pfsyncs_opackets6; /* total output packets, IPv6 */
u_long pfsyncs_onomem; /* no memory for an mbuf for a send */
u_long pfsyncs_oerrors; /* ip output error */
};
/*
* Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
*/
struct pfsyncreq {
char pfsyncr_syncif[IFNAMSIZ];
int pfsyncr_maxupdates;
int pfsyncr_authlevel;
};
#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)
#define pf_state_peer_hton(s,d) do { \
(d)->seqlo = htonl((s)->seqlo); \
(d)->seqhi = htonl((s)->seqhi); \
(d)->seqdiff = htonl((s)->seqdiff); \
(d)->max_win = htons((s)->max_win); \
(d)->mss = htons((s)->mss); \
(d)->state = (s)->state; \
(d)->wscale = (s)->wscale; \
} while (0)
#define pf_state_peer_ntoh(s,d) do { \
(d)->seqlo = ntohl((s)->seqlo); \
(d)->seqhi = ntohl((s)->seqhi); \
(d)->seqdiff = ntohl((s)->seqdiff); \
(d)->max_win = ntohs((s)->max_win); \
(d)->mss = ntohs((s)->mss); \
(d)->state = (s)->state; \
(d)->wscale = (s)->wscale; \
} while (0)
#define pf_state_host_hton(s,d) do { \
bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \
(d)->port = (s)->port; \
} while (0)
#define pf_state_host_ntoh(s,d) do { \
bcopy(&(s)->addr, &(d)->addr, sizeof((d)->addr)); \
(d)->port = (s)->port; \
} while (0)
#ifdef _KERNEL
void pfsync_input(struct mbuf *, ...);
int pfsync_clear_states(u_int32_t, char *);
int pfsync_pack_state(u_int8_t, struct pf_state *, int);
#define pfsync_insert_state(st) do { \
if ((st->rule.ptr->rule_flag & PFRULE_NOSYNC) || \
(st->proto == IPPROTO_PFSYNC)) \
st->sync_flags |= PFSTATE_NOSYNC; \
else if (!st->sync_flags) \
pfsync_pack_state(PFSYNC_ACT_INS, (st), 1); \
st->sync_flags &= ~PFSTATE_FROMSYNC; \
} while (0)
#define pfsync_update_state(st) do { \
if (!st->sync_flags) \
pfsync_pack_state(PFSYNC_ACT_UPD, (st), 1); \
st->sync_flags &= ~PFSTATE_FROMSYNC; \
} while (0)
#define pfsync_delete_state(st) do { \
if (!st->sync_flags) \
pfsync_pack_state(PFSYNC_ACT_DEL, (st), 1); \
st->sync_flags &= ~PFSTATE_FROMSYNC; \
} while (0)
#endif
#endif /* _NET_IF_PFSYNC_H_ */

219
sys/dist/pf/net/pf.c vendored
View File

@ -1,3 +1,4 @@
/* $NetBSD: pf.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */
/* $OpenBSD: pf.c,v 1.433 2004/03/26 22:20:57 dhartmei Exp $ */
/*
@ -37,7 +38,11 @@
#include "bpfilter.h"
#include "pflog.h"
#ifdef __OpenBSD__
#include "pfsync.h"
#else
#define NPFSYNC 0
#endif
#include <sys/param.h>
#include <sys/systm.h>
@ -48,6 +53,9 @@
#include <sys/kernel.h>
#include <sys/time.h>
#include <sys/pool.h>
#ifdef __NetBSD__
#include <sys/endian.h>
#endif
#include <net/if.h>
#include <net/if_types.h>
@ -69,7 +77,11 @@
#include <netinet/udp_var.h>
#include <netinet/icmp_var.h>
#ifdef __OpenBSD__
#include <dev/rndvar.h>
#else
#include <sys/rnd.h>
#endif
#include <net/pfvar.h>
#include <net/if_pflog.h>
@ -79,7 +91,10 @@
#ifdef INET6
#include <netinet/ip6.h>
#include <netinet/in_pcb.h>
#include <netinet6/ip6_var.h>
#ifdef __NetBSD__
#include <netinet6/in6_pcb.h>
#endif
#include <netinet/icmp6.h>
#include <netinet6/nd6.h>
#endif /* INET6 */
@ -104,7 +119,11 @@ u_int32_t ticket_altqs_inactive;
int altqs_inactive_open;
u_int32_t ticket_pabuf;
#ifdef __OpenBSD__
struct timeout pf_expire_to; /* expire timeout */
#else
struct callout pf_expire_to; /* expire timeout */
#endif
struct pool pf_src_tree_pl, pf_rule_pl;
struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
@ -659,9 +678,15 @@ pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
}
if (RB_INSERT(pf_state_tree_id, &tree_id, state) != NULL) {
if (pf_status.debug >= PF_DEBUG_MISC) {
#ifdef __OpenBSD__
printf("pf: state insert failed: "
"id: %016llx creatorid: %08x",
betoh64(state->id), ntohl(state->creatorid));
#else
printf("pf: state insert failed: "
"id: %016llx creatorid: %08x",
be64toh(state->id), ntohl(state->creatorid));
#endif
if (state->sync_flags & PFSTATE_FROMSYNC)
printf(" (from sync)");
printf("\n");
@ -684,7 +709,11 @@ pf_insert_state(struct pfi_kif *kif, struct pf_state *state)
void
pf_purge_timeout(void *arg)
{
#ifdef __OpenBSD__
struct timeout *to = arg;
#else
struct callout *to = arg;
#endif
int s;
s = splsoftnet();
@ -693,7 +722,11 @@ pf_purge_timeout(void *arg)
pf_purge_expired_src_nodes();
splx(s);
#ifdef __OpenBSD__
timeout_add(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz);
#else
callout_schedule(to, pf_default_rule.timeout[PFTM_INTERVAL] * hz);
#endif
}
u_int32_t
@ -1181,7 +1214,7 @@ pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
/* Change inner protocol port, fix inner protocol checksum. */
if (ip != NULL) {
u_int16_t oip = *ip;
u_int32_t opc;
u_int32_t opc = 0;
if (pc != NULL)
opc = *pc;
@ -1263,10 +1296,10 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af,
struct m_tag *mtag;
int len, tlen;
#ifdef INET
struct ip *h;
struct ip *h = NULL;
#endif /* INET */
#ifdef INET6
struct ip6_hdr *h6;
struct ip6_hdr *h6 = NULL;
#endif /* INET6 */
struct tcphdr *th;
char *opt;
@ -1287,6 +1320,8 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af,
len = sizeof(struct ip6_hdr) + tlen;
break;
#endif /* INET6 */
default:
return;
}
/* create outgoing mbuf */
@ -1345,6 +1380,9 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af,
th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
break;
#endif /* INET6 */
default:
m_freem(m);
return;
}
/* TCP header */
@ -1391,7 +1429,11 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af,
h6->ip6_vfc |= IPV6_VERSION;
h6->ip6_hlim = IPV6_DEFHLIM;
#ifdef __OpenBSD__
ip6_output(m, NULL, NULL, 0, NULL, NULL);
#else
ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
#endif
break;
#endif /* INET6 */
}
@ -2194,7 +2236,10 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
struct pf_addr *saddr, *daddr;
u_int16_t sport, dport;
struct inpcbtable *tb;
struct inpcb *inp;
struct inpcb *inp = NULL;
#ifdef __NetBSD__
struct in6pcb *in6p = NULL;
#endif
*uid = UID_MAX;
*gid = GID_MAX;
@ -2226,15 +2271,26 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
}
switch (pd->af) {
case AF_INET:
#ifdef __OpenBSD__
inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
if (inp == NULL) {
inp = in_pcblookup_listen(tb, daddr->v4, dport, 0);
if (inp == NULL)
return (0);
}
#else
inp = in_pcblookup_connect(tb, saddr->v4, sport, daddr->v4,
dport);
if (inp == NULL) {
inp = in_pcblookup_bind(tb, daddr->v4, dport);
if (inp == NULL)
return (0);
}
#endif
break;
#ifdef INET6
case AF_INET6:
#ifdef __OpenBSD__
inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
dport);
if (inp == NULL) {
@ -2242,14 +2298,38 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
if (inp == NULL)
return (0);
}
#else
in6p = in6_pcblookup_connect(tb, &saddr->v6, sport, &daddr->v6,
dport, 0);
if (in6p == NULL) {
in6p = in6_pcblookup_bind(tb, &daddr->v6, dport, 0);
if (inp == NULL)
return (0);
}
#endif
break;
#endif /* INET6 */
default:
return (0);
}
#ifdef __OpenBSD__
*uid = inp->inp_socket->so_euid;
*gid = inp->inp_socket->so_egid;
#else
switch (pd->af) {
case AF_INET:
*uid = inp->inp_socket->so_uid;
/* XXX gid */
break;
#ifdef INET6
case AF_INET6:
*uid = in6p->in6p_socket->so_uid;
/* XXX gid */
break;
#endif
}
#endif
return (1);
}
@ -2354,7 +2434,11 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
dst->sin_family = AF_INET;
dst->sin_len = sizeof(*dst);
dst->sin_addr = addr->v4;
#ifdef __OpenBSD__
rtalloc_noclone(&ro, NO_CLONING);
#else
rtalloc(&ro);
#endif
rt = ro.ro_rt;
break;
#endif /* INET */
@ -2366,7 +2450,11 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
dst6->sin6_family = AF_INET6;
dst6->sin6_len = sizeof(*dst6);
dst6->sin6_addr = addr->v6;
#ifdef __OpenBSD__
rtalloc_noclone((struct route *)&ro6, NO_CLONING);
#else
rtalloc((struct route *)&ro6);
#endif
rt = ro6.ro_rt;
break;
#endif /* INET6 */
@ -2532,7 +2620,7 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->log) {
if (rewrite)
m_copyback(m, off, sizeof(*th), th);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
}
@ -2758,7 +2846,7 @@ cleanup:
/* copy back packet headers if we performed NAT operations */
if (rewrite)
m_copyback(m, off, sizeof(*th), th);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
return (PF_PASS);
}
@ -2883,7 +2971,7 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
if (r->log) {
if (rewrite)
m_copyback(m, off, sizeof(*uh), uh);
m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
}
@ -3021,7 +3109,7 @@ cleanup:
/* copy back packet headers if we performed NAT operations */
if (rewrite)
m_copyback(m, off, sizeof(*uh), uh);
m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
return (PF_PASS);
}
@ -3037,9 +3125,9 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pf_ruleset *ruleset = NULL;
struct pf_src_node *nsn = NULL;
u_short reason;
u_int16_t icmpid;
u_int16_t icmpid = 0;
sa_family_t af = pd->af;
u_int8_t icmptype, icmpcode;
u_int8_t icmptype = 0, icmpcode = 0;
int state_icmp = 0;
struct pf_tag *pftag = NULL;
int tag = -1;
@ -3186,7 +3274,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
#ifdef INET6
if (rewrite)
m_copyback(m, off, sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
(caddr_t)pd->hdr.icmp6);
#endif /* INET6 */
PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset);
}
@ -3298,7 +3386,7 @@ cleanup:
/* copy back packet headers if we performed IPv6 NAT operations */
if (rewrite)
m_copyback(m, off, sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
(caddr_t)pd->hdr.icmp6);
#endif /* INET6 */
return (PF_PASS);
@ -4029,10 +4117,10 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
&th->th_sum, &(*state)->lan.addr,
(*state)->lan.port, 0, pd->af);
m_copyback(m, off, sizeof(*th), th);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
} else if (copyback) {
/* Copyback sequence modulation or stateful scrub changes */
m_copyback(m, off, sizeof(*th), th);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
}
return (PF_PASS);
@ -4093,7 +4181,7 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
&uh->uh_sum, &(*state)->lan.addr,
(*state)->lan.port, 1, pd->af);
m_copyback(m, off, sizeof(*uh), uh);
m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
}
return (PF_PASS);
@ -4104,7 +4192,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
{
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
u_int16_t icmpid, *icmpsum;
u_int16_t icmpid = 0, *icmpsum;
u_int8_t icmptype;
int state_icmp = 0;
@ -4183,7 +4271,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
&(*state)->gwy.addr, 0);
m_copyback(m, off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
(caddr_t)pd->hdr.icmp6);
break;
#endif /* INET6 */
}
@ -4203,7 +4291,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
&(*state)->lan.addr, 0);
m_copyback(m, off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
(caddr_t)pd->hdr.icmp6);
break;
#endif /* INET6 */
}
@ -4226,8 +4314,8 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
struct ip6_hdr h2_6;
int terminal = 0;
#endif /* INET6 */
int ipoff2;
int off2;
int ipoff2 = 0;
int off2 = 0;
pd2.af = pd->af;
switch (pd->af) {
@ -4409,22 +4497,22 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
#ifdef INET
case AF_INET:
m_copyback(m, off, ICMP_MINLEN,
pd->hdr.icmp);
(caddr_t)pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2),
&h2);
(caddr_t)&h2);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
m_copyback(m, off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
(caddr_t)pd->hdr.icmp6);
m_copyback(m, ipoff2, sizeof(h2_6),
&h2_6);
(caddr_t)&h2_6);
break;
#endif /* INET6 */
}
m_copyback(m, off2, 8, &th);
m_copyback(m, off2, 8, (caddr_t)&th);
}
return (PF_PASS);
@ -4476,21 +4564,22 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
#ifdef INET
case AF_INET:
m_copyback(m, off, ICMP_MINLEN,
pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2), &h2);
(caddr_t)pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2),
(caddr_t)&h2);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
m_copyback(m, off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
(caddr_t)pd->hdr.icmp6);
m_copyback(m, ipoff2, sizeof(h2_6),
&h2_6);
(caddr_t)&h2_6);
break;
#endif /* INET6 */
}
m_copyback(m, off2, sizeof(uh), &uh);
m_copyback(m, off2, sizeof(uh), (caddr_t)&uh);
}
return (PF_PASS);
@ -4539,9 +4628,10 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
pd2.ip_sum, icmpsum,
pd->ip_sum, 0, AF_INET);
}
m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2), &h2);
m_copyback(m, off2, ICMP_MINLEN, &iih);
m_copyback(m, off, ICMP_MINLEN,
(caddr_t)pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih);
}
return (PF_PASS);
@ -4592,10 +4682,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
pd->ip_sum, 0, AF_INET6);
}
m_copyback(m, off, sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
m_copyback(m, ipoff2, sizeof(h2_6), &h2_6);
(caddr_t)pd->hdr.icmp6);
m_copyback(m, ipoff2, sizeof(h2_6),
(caddr_t)&h2_6);
m_copyback(m, off2, sizeof(struct icmp6_hdr),
&iih);
(caddr_t)&iih);
}
return (PF_PASS);
@ -4639,17 +4730,18 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
#ifdef INET
case AF_INET:
m_copyback(m, off, ICMP_MINLEN,
pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2), &h2);
(caddr_t)pd->hdr.icmp);
m_copyback(m, ipoff2, sizeof(h2),
(caddr_t)&h2);
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
m_copyback(m, off,
sizeof(struct icmp6_hdr),
pd->hdr.icmp6);
(caddr_t)pd->hdr.icmp6);
m_copyback(m, ipoff2, sizeof(h2_6),
&h2_6);
(caddr_t)&h2_6);
break;
#endif /* INET6 */
}
@ -4806,7 +4898,11 @@ pf_routable(struct pf_addr *addr, sa_family_t af)
dst->sin_family = af;
dst->sin_len = sizeof(*dst);
dst->sin_addr = addr->v4;
#ifdef __OpenBSD__
rtalloc_noclone(&ro, NO_CLONING);
#else
rtalloc(&ro);
#endif
if (ro.ro_rt != NULL) {
ret = 1;
@ -4823,7 +4919,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
{
struct mbuf *m0, *m1;
struct route iproute;
struct route *ro;
struct route *ro = NULL;
struct sockaddr_in *dst;
struct ip *ip;
struct ifnet *ifp = NULL;
@ -4831,6 +4927,9 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
struct pf_addr naddr;
struct pf_src_node *sn = NULL;
int error = 0;
#ifdef __NetBSD__
struct tcphdr th;
#endif
if (m == NULL || *m == NULL || r == NULL ||
(dir != PF_IN && dir != PF_OUT) || oifp == NULL)
@ -4845,7 +4944,11 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
goto bad;
m_tag_prepend(m0, mtag);
}
#ifdef __OpenBSD__
m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT);
#else
m0 = m_dup(*m, 0, M_COPYALL, M_NOWAIT);
#endif
if (m0 == NULL)
return;
} else {
@ -4933,6 +5036,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
#endif /* IPSEC */
/* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
#ifdef __OpenBSD__
if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) {
if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
ifp->if_bridge != NULL) {
@ -4946,8 +5050,15 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
m0->m_pkthdr.csum &= ~M_UDPV4_CSUM_OUT; /* Clear */
}
}
#else
m_copydata(m0, sizeof(*ip), sizeof(th), (caddr_t)&th);
th.th_sum = 0;
m_copyback(m0, sizeof(*ip), sizeof(th), (caddr_t)&th);
in4_cksum(m0, IPPROTO_TCP, sizeof(*ip), m0->m_pkthdr.len - sizeof(*ip));
#endif
if (ntohs(ip->ip_len) <= ifp->if_mtu) {
#ifdef __OpenBSD__
if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
ifp->if_bridge == NULL) {
m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT;
@ -4956,11 +5067,17 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
ip->ip_sum = 0;
ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
}
#else
ip->ip_sum = 0;
ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
#endif
#ifdef __OpenBSD__
/* Update relevant hardware checksum stats for TCP/UDP */
if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT)
tcpstat.tcps_outhwcsum++;
else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT)
udpstat.udps_outhwcsum++;
#endif
error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
goto done;
}
@ -5041,7 +5158,11 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
goto bad;
m_tag_prepend(m0, mtag);
}
#ifdef __OpenBSD__
m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT);
#else
m0 = m_dup(*m, 0, M_COPYALL, M_NOWAIT);
#endif
if (m0 == NULL)
return;
} else {
@ -5067,7 +5188,11 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
if (mtag == NULL)
goto bad;
m_tag_prepend(m0, mtag);
#ifdef __OpenBSD__
ip6_output(m0, NULL, NULL, 0, NULL, NULL);
#else
ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
#endif
return;
}
@ -5142,9 +5267,12 @@ int
pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
sa_family_t af)
{
#ifdef __OpenBSD__
u_int16_t flag_ok, flag_bad;
#endif
u_int16_t sum;
#ifdef __OpenBSD__
switch (p) {
case IPPROTO_TCP:
flag_ok = M_TCP_CSUM_IN_OK;
@ -5167,6 +5295,7 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
return (0);
if (m->m_pkthdr.csum & flag_bad)
return (1);
#endif
if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
return (1);
if (m->m_pkthdr.len < off + len)
@ -5198,7 +5327,9 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
return (1);
}
if (sum) {
#ifdef __OpenBSD__
m->m_pkthdr.csum |= flag_bad;
#endif
switch (p) {
case IPPROTO_TCP:
tcpstat.tcps_rcvbadsum++;
@ -5217,7 +5348,9 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
}
return (1);
}
#ifdef __OpenBSD__
m->m_pkthdr.csum |= flag_ok;
#endif
return (0);
}
@ -5242,7 +5375,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
struct pfi_kif *kif;
u_short action, reason = 0, log = 0;
struct mbuf *m = *m0;
struct ip *h;
struct ip *h = NULL;
struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
struct pf_state *s = NULL;
struct pf_ruleset *ruleset = NULL;

View File

@ -1,3 +1,4 @@
/* $NetBSD: pf_if.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */
/* $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */
/*
@ -30,6 +31,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@ -102,6 +107,18 @@ RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
#define PFI_BUFFER_MAX 0x10000
#define PFI_MTYPE M_IFADDR
#ifdef __NetBSD__
static void *hook_establish(struct hook_desc_head *, int, void (*)(void *),
void *);
static void hook_disestablish(struct hook_desc_head *, void *);
#define HOOK_REMOVE 0x01
#define HOOK_FREE 0x02
POOL_INIT(pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, "pfiaddrpl",
&pool_allocator_nointr);
#endif
void
pfi_initialize(void)
{
@ -109,8 +126,10 @@ pfi_initialize(void)
return;
TAILQ_INIT(&pfi_statehead);
#ifdef __OpenBSD__
pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0,
"pfiaddrpl", &pool_allocator_nointr);
#endif
pfi_buffer_max = 64;
pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer),
PFI_MTYPE, M_WAITOK);
@ -184,8 +203,13 @@ pfi_attach_ifnet(struct ifnet *ifp)
q = p->pfik_parent;
p->pfik_ifp = ifp;
p->pfik_flags |= PFI_IFLAG_ATTACHED;
#ifdef __OpenBSD__
p->pfik_ah_cookie =
hook_establish(ifp->if_addrhooks, 1, pfi_kifaddr_update, p);
#else
p->pfik_ah_cookie =
hook_establish(p->pfik_ifaddrhooks, 1, pfi_kifaddr_update, p);
#endif
pfi_index2kif[ifp->if_index] = p;
pfi_dohooks(p);
splx(s);
@ -207,7 +231,11 @@ pfi_detach_ifnet(struct ifnet *ifp)
splx(s);
return;
}
#ifdef __OpenBSD__
hook_disestablish(p->pfik_ifp->if_addrhooks, p->pfik_ah_cookie);
#else
hook_disestablish(p->pfik_ifaddrhooks, p->pfik_ah_cookie);
#endif
q = p->pfik_parent;
p->pfik_ifp = NULL;
p->pfik_flags &= ~PFI_IFLAG_ATTACHED;
@ -563,8 +591,21 @@ pfi_if_create(const char *name, struct pfi_kif *q, int flags)
return (NULL);
}
bzero(p->pfik_ah_head, sizeof(*p->pfik_ah_head));
#ifdef __NetBSD__
p->pfik_ifaddrhooks = malloc(sizeof(*p->pfik_ifaddrhooks), PFI_MTYPE,
M_DONTWAIT);
if (p->pfik_ifaddrhooks == NULL) {
free(p->pfik_ah_head, PFI_MTYPE);
free(p, PFI_MTYPE);
return (NULL);
}
bzero(p->pfik_ifaddrhooks, sizeof(*p->pfik_ifaddrhooks));
#endif
TAILQ_INIT(p->pfik_ah_head);
TAILQ_INIT(&p->pfik_grouphead);
#ifdef __NetBSD__
TAILQ_INIT(p->pfik_ifaddrhooks);
#endif
strlcpy(p->pfik_name, name, sizeof(p->pfik_name));
RB_INIT(&p->pfik_lan_ext);
RB_INIT(&p->pfik_ext_gwy);
@ -627,6 +668,7 @@ pfi_copy_group(char *p, const char *q, int m)
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])];
@ -662,6 +704,13 @@ pfi_dynamic_drivers(void)
}
}
}
#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
@ -809,8 +858,11 @@ pfi_unmask(void *addr)
void
pfi_dohooks(struct pfi_kif *p)
{
#ifdef __OpenBSD__
for (; p != NULL; p = p->pfik_parent)
dohooks(p->pfik_ah_head, 0);
#endif
}
int
@ -838,3 +890,49 @@ pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
}
}
}
/* from openbsd/sys/kern/kern_subr.c */
#ifdef __NetBSD__
static void *
hook_establish(head, tail, fn, arg)
struct hook_desc_head *head;
int tail;
void (*fn)(void *);
void *arg;
{
struct hook_desc *hdp;
hdp = (struct hook_desc *)malloc(sizeof (*hdp), M_DEVBUF, M_NOWAIT);
if (hdp == NULL)
return (NULL);
hdp->hd_fn = fn;
hdp->hd_arg = arg;
if (tail)
TAILQ_INSERT_TAIL(head, hdp, hd_list);
else
TAILQ_INSERT_HEAD(head, hdp, hd_list);
return (hdp);
}
static void
hook_disestablish(head, vhook)
struct hook_desc_head *head;
void *vhook;
{
struct hook_desc *hdp;
#ifdef DIAGNOSTIC
for (hdp = TAILQ_FIRST(head); hdp != NULL;
hdp = TAILQ_NEXT(hdp, hd_list))
if (hdp == vhook)
break;
if (hdp == NULL)
panic("hook_disestablish: hook not established");
#endif
hdp = vhook;
TAILQ_REMOVE(head, hdp, hd_list);
free(hdp, M_DEVBUF);
}
#endif

View File

@ -1,3 +1,4 @@
/* $NetBSD: pf_ioctl.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */
/* $OpenBSD: pf_ioctl.c,v 1.112 2004/03/22 04:54:18 mcbride Exp $ */
/*
@ -35,7 +36,17 @@
*
*/
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#include "opt_altq.h"
#include "opt_pfil_hooks.h"
#endif
#ifdef __OpenBSD__
#include "pfsync.h"
#else
#define NPFSYNC 0
#endif
#include <sys/param.h>
#include <sys/systm.h>
@ -46,9 +57,16 @@
#include <sys/socketvar.h>
#include <sys/kernel.h>
#include <sys/time.h>
#ifdef __OpenBSD__
#include <sys/timeout.h>
#else
#include <sys/callout.h>
#endif
#include <sys/pool.h>
#include <sys/malloc.h>
#ifdef __NetBSD__
#include <sys/conf.h>
#endif
#include <net/if.h>
#include <net/if_types.h>
@ -61,7 +79,9 @@
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#ifdef __OpenBSD__
#include <dev/rndvar.h>
#endif
#include <net/pfvar.h>
#if NPFSYNC > 0
@ -96,7 +116,30 @@ int pf_begin_rules(u_int32_t *, int, char *, char *);
int pf_rollback_rules(u_int32_t, int, char *, char *);
int pf_commit_rules(u_int32_t, int, char *, char *);
#ifdef __NetBSD__
const struct cdevsw pf_cdevsw = {
pfopen, pfclose, noread, nowrite, pfioctl,
nostop, notty, nopoll, nommap, nokqfilter,
};
static int pf_pfil_attach(void);
static int pf_pfil_detach(void);
POOL_INIT(pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
&pool_allocator_nointr);
POOL_INIT(pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
"pfsrctrpl", NULL);
POOL_INIT(pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl", NULL);
POOL_INIT(pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl", NULL);
POOL_INIT(pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
"pfpooladdrpl", NULL);
#endif
#ifdef __OpenBSD__
extern struct timeout pf_expire_to;
#else
extern struct callout pf_expire_to;
#endif
struct pf_rule pf_default_rule;
@ -113,11 +156,23 @@ static void tag_unref(struct pf_tags *, u_int16_t);
#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
#ifdef __NetBSD__
struct pfil_head pf_ioctl_head;
struct pfil_head pf_newif_head;
extern struct pfil_head if_pfil;
#endif
void
pfattach(int num)
{
u_int32_t *timeout = pf_default_rule.timeout;
#ifdef __NetBSD__
pfil_head_register(&pf_ioctl_head);
pfil_head_register(&pf_newif_head);
#endif
#ifdef __OpenBSD__
pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
&pool_allocator_nointr);
pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
@ -128,6 +183,7 @@ pfattach(int num)
NULL);
pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
"pfpooladdrpl", NULL);
#endif
pfr_initialize();
pfi_initialize();
pf_osfp_initialize();
@ -169,8 +225,14 @@ pfattach(int num)
timeout[PFTM_INTERVAL] = 10; /* Expire interval */
timeout[PFTM_SRC_NODE] = 0; /* Source tracking */
#ifdef __OpenBSD__
timeout_set(&pf_expire_to, pf_purge_timeout, &pf_expire_to);
timeout_add(&pf_expire_to, timeout[PFTM_INTERVAL] * hz);
#else
callout_init(&pf_expire_to);
callout_reset(&pf_expire_to, timeout[PFTM_INTERVAL] * hz,
pf_purge_timeout, &pf_expire_to);
#endif
pf_normalize_init();
bzero(&pf_status, sizeof(pf_status));
@ -854,6 +916,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (pf_status.running)
error = EEXIST;
else {
#ifdef __NetBSD__
error = pf_pfil_attach();
if (error)
break;
#endif
pf_status.running = 1;
pf_status.since = time.tv_sec;
if (pf_status.stateid == 0) {
@ -868,6 +935,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (!pf_status.running)
error = ENOENT;
else {
#ifdef __NetBSD__
error = pf_pfil_detach();
if (error)
break;
#endif
pf_status.running = 0;
pf_status.since = time.tv_sec;
DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
@ -1606,11 +1678,16 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
goto fail;
}
#ifdef __OpenBSD__
if (pool_sethardlimit(pf_pool_limits[pl->index].pp,
pl->limit, NULL, 0) != 0) {
error = EBUSY;
goto fail;
}
#else
pool_sethardlimit(pf_pool_limits[pl->index].pp,
pl->limit, NULL, 0);
#endif
old_limit = pf_pool_limits[pl->index].limit;
pf_pool_limits[pl->index].limit = pl->limit;
pl->limit = old_limit;
@ -2653,3 +2730,139 @@ fail:
return (error);
}
#ifdef __NetBSD__
int
pfil4_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
{
/*
* If the packet is out-bound, we can't delay checksums
* here. For in-bound, the checksum has already been
* validated.
*/
if (dir == PFIL_OUT) {
if ((*mp)->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) {
in_delayed_cksum(*mp);
(*mp)->m_pkthdr.csum_flags &=
~(M_CSUM_TCPv4|M_CSUM_UDPv4);
}
}
if (pf_test(dir == PFIL_OUT ? PF_OUT : PF_IN, ifp, mp) != PF_PASS)
return EHOSTUNREACH;
else
return (0);
}
int
pfil6_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
{
if (pf_test6(dir == PFIL_OUT ? PF_OUT : PF_IN, ifp, mp) != PF_PASS)
return EHOSTUNREACH;
else
return (0);
}
extern void pfi_kifaddr_update(void *);
int
pfil_if_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
{
u_long cmd = (u_long)mp;
switch (cmd) {
case 0:
pfi_attach_ifnet(ifp);
break;
case SIOCSIFADDR:
case SIOCGIFALIAS:
case SIOCDIFADDR:
pfi_kifaddr_update((struct ifnet *)arg);
break;
default:
panic("unexpected ioctl");
}
return 0;
}
static int
pf_pfil_attach(void)
{
struct pfil_head *ph_inet;
#ifdef INET6
struct pfil_head *ph_inet6;
#endif
int error;
int i;
error = pfil_add_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF,
&if_pfil);
if (error)
return (error);
ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
if (ph_inet)
error = pfil_add_hook((void *)pfil4_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet);
else
error = ENOENT;
if (error) {
pfil_remove_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF,
&if_pfil);
}
#ifdef INET6
if (error) {
return (error);
}
ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (ph_inet6)
error = pfil_add_hook((void *)pfil6_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet6);
else
error = ENOENT;
if (error) {
pfil_remove_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF,
&if_pfil);
pfil_remove_hook((void *)pfil4_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet);
}
#endif
if (!error) {
for (i = 0; i < if_indexlim; i++) {
if (ifindex2ifnet[i])
pfi_attach_ifnet(ifindex2ifnet[i]);
}
}
return (error);
}
int
pf_pfil_detach(void)
{
struct pfil_head *ph_inet;
#ifdef INET6
struct pfil_head *ph_inet6;
#endif
int i;
for (i = 0; i < if_indexlim; i++) {
if (pfi_index2kif[i])
pfi_detach_ifnet(ifindex2ifnet[i]);
}
pfil_remove_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF,
&if_pfil);
ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
if (ph_inet)
pfil_remove_hook((void *)pfil4_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet);
#ifdef INET6
ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (ph_inet)
pfil_remove_hook((void *)pfil6_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet6);
#endif
return (0);
}
#endif

View File

@ -1,3 +1,4 @@
/* $NetBSD: pf_norm.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $OpenBSD: pf_norm.c,v 1.80 2004/03/09 21:44:41 mcbride Exp $ */
/*
@ -25,6 +26,10 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#endif
#include "pflog.h"
#include <sys/param.h>
@ -37,7 +42,11 @@
#include <sys/time.h>
#include <sys/pool.h>
#ifdef __OpenBSD__
#include <dev/rndvar.h>
#else
#include <sys/rnd.h>
#endif
#include <net/if.h>
#include <net/if_types.h>
#include <net/bpf.h>
@ -126,9 +135,19 @@ struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
struct pool pf_state_scrub_pl;
int pf_nfrents, pf_ncache;
#ifdef __NetBSD__
POOL_INIT(pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent", NULL);
POOL_INIT(pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag", NULL);
POOL_INIT(pf_cache_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrcache", NULL);
POOL_INIT(pf_cent_pl, sizeof(struct pf_frcache), 0, 0, 0, "pffrcent", NULL);
POOL_INIT(pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0,
"pfstscr", NULL);
#endif
void
pf_normalize_init(void)
{
#ifdef __OpenBSD__
pool_init(&pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent",
NULL);
pool_init(&pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag",
@ -139,6 +158,7 @@ pf_normalize_init(void)
NULL);
pool_init(&pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0,
"pfstscr", NULL);
#endif
pool_sethiwat(&pf_frag_pl, PFFRAG_FRAG_HIWAT);
pool_sethardlimit(&pf_frent_pl, PFFRAG_FRENT_HIWAT, NULL, 0);
@ -619,7 +639,11 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
* than this mbuf magic. For my next trick,
* I'll pull a rabbit out of my laptop.
*/
#ifdef __OpenBSD__
*m0 = m_copym2(m, 0, h->ip_hl << 2, M_NOWAIT);
#else
*m0 = m_dup(m, 0, h->ip_hl << 2, M_NOWAIT);
#endif
if (*m0 == NULL)
goto no_mem;
KASSERT((*m0)->m_next == NULL);
@ -1290,7 +1314,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
/* copy back packet headers if we sanitized */
if (rewrite)
m_copyback(m, off, sizeof(*th), th);
m_copyback(m, off, sizeof(*th), (caddr_t)th);
return (PF_PASS);
@ -1482,8 +1506,8 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
/* Copyback the options, caller copys back header */
*writeback = 1;
m_copyback(m, off + sizeof(struct tcphdr),
(th->th_off << 2) - sizeof(struct tcphdr), hdr +
sizeof(struct tcphdr));
(th->th_off << 2) - sizeof(struct tcphdr),
(caddr_t)hdr + sizeof(struct tcphdr));
}
}

View File

@ -1,3 +1,4 @@
/* $NetBSD: pf_osfp.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $OpenBSD: pf_osfp.c,v 1.9 2004/01/04 20:08:42 pvalchev Exp $ */
/*
@ -17,6 +18,10 @@
*
*/
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#endif
#include <sys/param.h>
#include <sys/socket.h>
#ifdef _KERNEL

View File

@ -1,3 +1,4 @@
/* $NetBSD: pf_table.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $OpenBSD: pf_table.c,v 1.47 2004/03/09 21:44:41 mcbride Exp $ */
/*
@ -30,6 +31,10 @@
*
*/
#ifdef _KERNEL_OPT
#include "opt_inet.h"
#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
@ -39,7 +44,9 @@
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#ifdef __OpenBSD__
#include <netinet/ip_ipsp.h>
#endif
#include <net/pfvar.h>
#define ACCEPT_FLAGS(oklist) \
@ -183,13 +190,20 @@ struct pfr_ktablehead pfr_ktables;
struct pfr_table pfr_nulltable;
int pfr_ktable_cnt;
#ifdef __NetBSD__
POOL_INIT(pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0, "pfrktable", NULL);
POOL_INIT(pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0, "pfrkentry", NULL);
#endif
void
pfr_initialize(void)
{
#ifdef __OpenBSD__
pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0,
"pfrktable", NULL);
pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
"pfrkentry", NULL);
#endif
pfr_sin.sin_len = sizeof(pfr_sin);
pfr_sin.sin_family = AF_INET;
@ -204,7 +218,7 @@ pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
{
struct pfr_ktable *kt;
struct pfr_kentryworkq workq;
int s;
int s = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
@ -239,7 +253,7 @@ 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, xadd = 0;
int i, rv, s = 0, xadd = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
@ -317,7 +331,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, xdel = 0;
int i, rv, s = 0, xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
@ -379,7 +393,7 @@ 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, xadd = 0, xdel = 0, xchange = 0;
int i, rv, s = 0, xadd = 0, xdel = 0, xchange = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
@ -567,7 +581,7 @@ 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;
int rv, s = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */
@ -617,7 +631,7 @@ pfr_clr_astats(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, xzero = 0;
int i, rv, s = 0, xzero = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, 0))
@ -1048,7 +1062,7 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p;
int s, xdel = 0;
int s = 0, xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ALLRSETS);
if (pfr_table_count(filter, flags) < 0)
@ -1083,7 +1097,7 @@ 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, xadd = 0;
int i, rv, s = 0, xadd = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
@ -1164,7 +1178,7 @@ pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p, *q, key;
int i, s, xdel = 0;
int i, s = 0, xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
SLIST_INIT(&workq);
@ -1236,7 +1250,7 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
{
struct pfr_ktable *p;
struct pfr_ktableworkq workq;
int s, n, nn;
int s = 0, n, nn;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC|PFR_FLAG_ALLRSETS);
@ -1284,7 +1298,7 @@ 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, xzero = 0;
int i, s = 0, xzero = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ADDRSTOO);
@ -1318,7 +1332,7 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p, *q, key;
int i, s, xchange = 0, xdel = 0;
int i, s = 0, xchange = 0, xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
if ((setflag & ~PFR_TFLAG_USRMASK) ||
@ -1537,7 +1551,7 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
struct pfr_ktable *p;
struct pfr_ktableworkq workq;
struct pf_ruleset *rs;
int s, xadd = 0, xchange = 0;
int s = 0, xadd = 0, xchange = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);

View File

@ -1,3 +1,4 @@
/* $NetBSD: pfvar.h,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $OpenBSD: pfvar.h,v 1.187 2004/03/22 04:54:18 mcbride Exp $ */
/*
@ -38,9 +39,19 @@
#include <sys/tree.h>
#include <net/radix.h>
#ifdef __OpenBSD__
#include <netinet/ip_ipsp.h>
#endif
#include <netinet/tcp_fsm.h>
#ifdef __NetBSD__
union sockaddr_union {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
};
#endif
struct ip;
#define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0)
@ -126,6 +137,15 @@ struct pf_addr_wrap {
#ifdef _KERNEL
#ifdef __NetBSD__
struct hook_desc {
TAILQ_ENTRY(hook_desc) hd_list;
void (*hd_fn)(void *);
void *hd_arg;
};
TAILQ_HEAD(hook_desc_head, hook_desc);
#endif
struct pfi_dynaddr {
struct pf_addr pfid_addr4;
struct pf_addr pfid_mask4;
@ -811,6 +831,9 @@ struct pfi_kif {
struct ifnet *pfik_ifp;
int pfik_states;
int pfik_rules;
#ifdef __NetBSD__
struct hook_desc_head *pfik_ifaddrhooks;
#endif
};
#define pfik_name pfik_if.pfif_name
#define pfik_packets pfik_if.pfif_packets
@ -1449,6 +1472,11 @@ struct pf_pool_limit {
};
extern struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
#ifdef __NetBSD__
int pfil4_wrapper(void *, struct mbuf **, struct ifnet *, int);
int pfil6_wrapper(void *, struct mbuf **, struct ifnet *, int);
int pfil_if_wrapper(void *, struct mbuf **, struct ifnet *, int);
#endif
#endif /* _KERNEL */
/* The fingerprint functions can be linked into userland programs (tcpdump) */