Bring diff from the security/pf port. This has code been tested as a port
for a long time and is run in production use. This is the code present in portversion 2.03 with some additional tweaks. The rather extensive diff accounts for: - locking (to enable pf to work with a giant-free netstack) - byte order difference between OpenBSD and FreeBSD for ip_len/ip_off - conversion from pool(9) to zone(9) - api differences etc. Approved by: bms(mentor) (in general)
This commit is contained in:
parent
3ef891af51
commit
2bbe8ffc9d
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.c,v 1.9 2003/05/14 08:42:00 canacar Exp $ */
|
||||
/*
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
@ -33,14 +34,32 @@
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
#include "bpfilter.h"
|
||||
#include "pflog.h"
|
||||
#elif __FreeBSD__ >= 5
|
||||
#include "opt_bpf.h"
|
||||
#define NBPFILTER DEV_BPF
|
||||
#include "opt_pf.h"
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/sockio.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
@ -54,6 +73,10 @@
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <machine/in_cksum.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#ifndef INET
|
||||
#include <netinet/in.h>
|
||||
@ -64,6 +87,10 @@
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pflog.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define PFLOGNAME "pflog"
|
||||
#endif
|
||||
|
||||
#define PFLOGMTU (32768 + MHLEN + MLEN)
|
||||
|
||||
#ifdef PFLOGDEBUG
|
||||
@ -72,17 +99,89 @@
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
struct pflog_softc pflogif[NPFLOG];
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
void pflog_clone_destroy(struct ifnet *);
|
||||
int pflog_clone_create(struct if_clone *, int);
|
||||
#else
|
||||
void pflogattach(int);
|
||||
#endif
|
||||
int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct rtentry *);
|
||||
int pflogioctl(struct ifnet *, u_long, caddr_t);
|
||||
void pflogrtrequest(int, struct rtentry *, struct sockaddr *);
|
||||
void pflogstart(struct ifnet *);
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
extern int ifqmaxlen;
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
static MALLOC_DEFINE(M_PFLOG, PFLOGNAME, "Packet Filter Logging Interface");
|
||||
static LIST_HEAD(pflog_list, pflog_softc) pflog_list;
|
||||
struct if_clone pflog_cloner = IF_CLONE_INITIALIZER(PFLOGNAME,
|
||||
pflog_clone_create, pflog_clone_destroy, 1, IF_MAXUNIT);
|
||||
|
||||
void
|
||||
pflog_clone_destroy(struct ifnet *ifp)
|
||||
{
|
||||
struct pflog_softc *sc;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
|
||||
/*
|
||||
* Does we really need this?
|
||||
*/
|
||||
IF_DRAIN(&ifp->if_snd);
|
||||
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
LIST_REMOVE(sc, sc_next);
|
||||
free(sc, M_PFLOG);
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
int
|
||||
pflog_clone_create(struct if_clone *ifc, int unit)
|
||||
{
|
||||
struct pflog_softc *sc;
|
||||
|
||||
MALLOC(sc, struct pflog_softc *, sizeof(*sc), M_PFLOG, M_WAITOK|M_ZERO);
|
||||
|
||||
#if (__FreeBSD_version < 501113)
|
||||
sc->sc_if.if_name = PFLOGNAME;
|
||||
sc->sc_if.if_unit = unit;
|
||||
#else
|
||||
if_initname(&sc->sc_if, ifc->ifc_name, unit);
|
||||
#endif
|
||||
sc->sc_if.if_mtu = PFLOGMTU;
|
||||
sc->sc_if.if_ioctl = pflogioctl;
|
||||
sc->sc_if.if_output = pflogoutput;
|
||||
sc->sc_if.if_start = pflogstart;
|
||||
sc->sc_if.if_type = IFT_PFLOG;
|
||||
sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
|
||||
sc->sc_if.if_hdrlen = PFLOG_HDRLEN;
|
||||
sc->sc_if.if_softc = sc;
|
||||
/*
|
||||
* We would get a message like
|
||||
* "in6_ifattach: pflog0 is not multicast capable, IPv6 not enabled".
|
||||
* We need a patch to in6_ifattach() to exclude interface type
|
||||
* IFT_PFLOG.
|
||||
*/
|
||||
if_attach(&sc->sc_if);
|
||||
|
||||
LIST_INSERT_HEAD(&pflog_list, sc, sc_next);
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->sc_if, DLT_PFLOG, PFLOG_HDRLEN);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
#else /* !__FreeBSD__ */
|
||||
void
|
||||
pflogattach(int npflog)
|
||||
{
|
||||
@ -111,6 +210,7 @@ pflogattach(int npflog)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
/*
|
||||
* Start output on the pflog interface.
|
||||
@ -119,14 +219,28 @@ void
|
||||
pflogstart(struct ifnet *ifp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
#if defined(__FreeBSD__) && defined(ALTQ)
|
||||
struct ifaltq *ifq;
|
||||
#else
|
||||
struct ifqueue *ifq;
|
||||
#endif
|
||||
int s;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
ifq = &ifp->if_snd;
|
||||
#endif
|
||||
for (;;) {
|
||||
s = splimp();
|
||||
#if defined(__FreeBSD__)
|
||||
IF_LOCK(ifq);
|
||||
_IF_DROP(ifq);
|
||||
_IF_DEQUEUE(ifq, m);
|
||||
IF_UNLOCK(ifq);
|
||||
#else
|
||||
IF_DROP(&ifp->if_snd);
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
if (m == NULL)
|
||||
return;
|
||||
else
|
||||
@ -188,7 +302,11 @@ pflog_packet(struct ifnet *ifp, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
hdr.af = af;
|
||||
hdr.action = rm->action;
|
||||
hdr.reason = reason;
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version < 501113)
|
||||
snprintf(hdr.ifname, IFNAMSIZ, "%s%d", ifp->if_name, ifp->if_unit);
|
||||
#else
|
||||
memcpy(hdr.ifname, ifp->if_xname, sizeof(hdr.ifname));
|
||||
#endif
|
||||
|
||||
if (am == NULL) {
|
||||
hdr.rulenr = htonl(rm->nr);
|
||||
@ -221,7 +339,12 @@ pflog_packet(struct ifnet *ifp, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
m1.m_len = PFLOG_HDRLEN;
|
||||
m1.m_data = (char *) &hdr;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((!LIST_EMPTY(&pflog_list)), ("pflog: no interface"));
|
||||
ifn = &LIST_FIRST(&pflog_list)->sc_if;
|
||||
#else
|
||||
ifn = &(pflogif[0].sc_if);
|
||||
#endif
|
||||
|
||||
if (ifn->if_bpf)
|
||||
bpf_mtap(ifn->if_bpf, &m1);
|
||||
@ -229,3 +352,43 @@ pflog_packet(struct ifnet *ifp, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
static int
|
||||
pflog_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
LIST_INIT(&pflog_list);
|
||||
if_clone_attach(&pflog_cloner);
|
||||
printf("pflog: $Name: $\n");
|
||||
break;
|
||||
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&pflog_cloner);
|
||||
while (!LIST_EMPTY(&pflog_list))
|
||||
pflog_clone_destroy(
|
||||
&LIST_FIRST(&pflog_list)->sc_if);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static moduledata_t pflog_mod = {
|
||||
"pflog",
|
||||
pflog_modevent,
|
||||
0
|
||||
};
|
||||
|
||||
#define PFLOG_MODVER 1
|
||||
|
||||
DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
|
||||
MODULE_VERSION(pflog, PFLOG_MODVER);
|
||||
#endif /* __FreeBSD__ */
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.h,v 1.9 2003/07/15 20:27:27 dhartmei Exp $ */
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -29,6 +30,9 @@
|
||||
|
||||
struct pflog_softc {
|
||||
struct ifnet sc_if; /* the interface */
|
||||
#if defined(__FreeBSD__)
|
||||
LIST_ENTRY(pflog_softc) sc_next;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* XXX keep in sync with pfvar.h */
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pfsync.c,v 1.6 2003/06/21 09:07:01 djm Exp $ */
|
||||
|
||||
/*
|
||||
@ -26,16 +27,34 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 5
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
#include "bpfilter.h"
|
||||
#include "pfsync.h"
|
||||
#elif __FreeBSD__ >= 5
|
||||
#include "opt_bpf.h"
|
||||
#define NBPFILTER DEV_BPF
|
||||
#include "opt_pf.h"
|
||||
#define NPFSYNC DEV_PFSYNC
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/sockio.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/timeout.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
@ -57,6 +76,10 @@
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pfsync.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define PFSYNCNAME "pfsync"
|
||||
#endif
|
||||
|
||||
#define PFSYNC_MINMTU \
|
||||
(sizeof(struct pfsync_header) + sizeof(struct pf_state))
|
||||
|
||||
@ -67,9 +90,16 @@ int pfsyncdebug;
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
struct pfsync_softc pfsyncif;
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
void pfsync_clone_destroy(struct ifnet *);
|
||||
int pfsync_clone_create(struct if_clone *, int);
|
||||
#else
|
||||
void pfsyncattach(int);
|
||||
#endif
|
||||
void pfsync_setmtu(struct pfsync_softc *sc, int);
|
||||
int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct rtentry *);
|
||||
@ -80,8 +110,79 @@ struct mbuf *pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action);
|
||||
int pfsync_sendout(struct pfsync_softc *sc);
|
||||
void pfsync_timeout(void *v);
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
extern int ifqmaxlen;
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
static MALLOC_DEFINE(M_PFSYNC, PFSYNCNAME, "Packet Filter State Sync. Interface");
|
||||
static LIST_HEAD(pfsync_list, pfsync_softc) pfsync_list;
|
||||
struct if_clone pfsync_cloner = IF_CLONE_INITIALIZER(PFSYNCNAME,
|
||||
pfsync_clone_create, pfsync_clone_destroy, 1, IF_MAXUNIT);
|
||||
|
||||
void
|
||||
pfsync_clone_destroy(struct ifnet *ifp)
|
||||
{
|
||||
struct pfsync_softc *sc;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
callout_stop(&sc->sc_tmo);
|
||||
|
||||
/*
|
||||
* Does we really need this?
|
||||
*/
|
||||
IF_DRAIN(&ifp->if_snd);
|
||||
|
||||
#if NBPFILTER > 0
|
||||
bpfdetach(ifp);
|
||||
#endif
|
||||
if_detach(ifp);
|
||||
LIST_REMOVE(sc, sc_next);
|
||||
free(sc, M_PFSYNC);
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
int
|
||||
pfsync_clone_create(struct if_clone *ifc, int unit)
|
||||
{
|
||||
struct pfsync_softc *sc;
|
||||
|
||||
MALLOC(sc, struct pfsync_softc *, sizeof(*sc), M_PFSYNC,
|
||||
M_WAITOK|M_ZERO);
|
||||
|
||||
sc->sc_count = 8;
|
||||
#if (__FreeBSD_version < 501113)
|
||||
sc->sc_if.if_name = PFSYNCNAME;
|
||||
sc->sc_if.if_unit = unit;
|
||||
#else
|
||||
if_initname(&sc->sc_if, ifc->ifc_name, unit);
|
||||
#endif
|
||||
sc->sc_if.if_ioctl = pfsyncioctl;
|
||||
sc->sc_if.if_output = pfsyncoutput;
|
||||
sc->sc_if.if_start = pfsyncstart;
|
||||
sc->sc_if.if_type = IFT_PFSYNC;
|
||||
sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
|
||||
sc->sc_if.if_hdrlen = PFSYNC_HDRLEN;
|
||||
sc->sc_if.if_baudrate = IF_Mbps(100);
|
||||
sc->sc_if.if_softc = sc;
|
||||
pfsync_setmtu(sc, MCLBYTES);
|
||||
/*
|
||||
* XXX
|
||||
* The 2nd arg. 0 to callout_init(9) shoule be set to CALLOUT_MPSAFE
|
||||
* if Gaint lock is removed from the network stack.
|
||||
*/
|
||||
callout_init(&sc->sc_tmo, 0);
|
||||
if_attach(&sc->sc_if);
|
||||
|
||||
LIST_INSERT_HEAD(&pfsync_list, sc, sc_next);
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->sc_if, DLT_PFSYNC, PFSYNC_HDRLEN);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
#else /* !__FreeBSD__ */
|
||||
void
|
||||
pfsyncattach(int npfsync)
|
||||
{
|
||||
@ -109,6 +210,7 @@ pfsyncattach(int npfsync)
|
||||
bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start output on the pfsync interface.
|
||||
@ -117,12 +219,27 @@ void
|
||||
pfsyncstart(struct ifnet *ifp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
#if defined(__FreeBSD__) && defined(ALTQ)
|
||||
struct ifaltq *ifq;
|
||||
#else
|
||||
struct ifqueue *ifq;
|
||||
#endif
|
||||
int s;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
ifq = &ifp->if_snd;
|
||||
#endif
|
||||
for (;;) {
|
||||
s = splimp();
|
||||
#if defined(__FreeBSD__)
|
||||
IF_LOCK(ifq);
|
||||
_IF_DROP(ifq);
|
||||
_IF_DEQUEUE(ifq, m);
|
||||
IF_UNLOCK(ifq);
|
||||
#else
|
||||
IF_DROP(&ifp->if_snd);
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
if (m == NULL)
|
||||
@ -192,7 +309,9 @@ pfsync_get_mbuf(sc, action)
|
||||
struct pfsync_softc *sc;
|
||||
u_int8_t action;
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
extern int hz;
|
||||
#endif
|
||||
struct pfsync_header *h;
|
||||
struct mbuf *m;
|
||||
int len;
|
||||
@ -223,19 +342,32 @@ pfsync_get_mbuf(sc, action)
|
||||
|
||||
sc->sc_mbuf = m;
|
||||
sc->sc_ptr = (struct pf_state *)((char *)h + PFSYNC_HDRLEN);
|
||||
#if defined(__FreeBSD__)
|
||||
callout_reset(&sc->sc_tmo, hz, pfsync_timeout,
|
||||
LIST_FIRST(&pfsync_list));
|
||||
#else
|
||||
timeout_add(&sc->sc_tmo, hz);
|
||||
#endif
|
||||
|
||||
return (m);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: This function should be called with PF_LOCK held as it references
|
||||
* pf_state.
|
||||
*/
|
||||
int
|
||||
pfsync_pack_state(action, st)
|
||||
u_int8_t action;
|
||||
struct pf_state *st;
|
||||
{
|
||||
#if defined(__FreeBSD__)
|
||||
struct pfsync_softc *sc = LIST_FIRST(&pfsync_list);
|
||||
#else
|
||||
extern struct timeval time;
|
||||
struct ifnet *ifp = &pfsyncif.sc_if;
|
||||
struct pfsync_softc *sc = ifp->if_softc;
|
||||
#endif
|
||||
struct pfsync_header *h;
|
||||
struct pf_state *sp;
|
||||
struct pf_rule *r = st->rule.ptr;
|
||||
@ -246,6 +378,16 @@ pfsync_pack_state(action, st)
|
||||
if (action >= PFSYNC_ACT_MAX)
|
||||
return (EINVAL);
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
* XXX
|
||||
* If we need to check mutex owned, PF_LOCK should be
|
||||
* declared in pflog.ko. :-(
|
||||
*
|
||||
* PF_LOCK_ASSERT();
|
||||
*/
|
||||
KASSERT((!LIST_EMPTY(&pfsync_list)), ("pfsync: no interface"));
|
||||
#endif
|
||||
s = splnet();
|
||||
m = sc->sc_mbuf;
|
||||
if (m == NULL) {
|
||||
@ -278,7 +420,11 @@ pfsync_pack_state(action, st)
|
||||
pf_state_peer_hton(&st->dst, &sp->dst);
|
||||
|
||||
bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
|
||||
#if defined(__FreeBSD__)
|
||||
secs = time_second;
|
||||
#else
|
||||
secs = time.tv_sec;
|
||||
#endif
|
||||
sp->creation = htonl(secs - st->creation);
|
||||
if (st->expire <= secs)
|
||||
sp->expire = htonl(0);
|
||||
@ -310,8 +456,12 @@ int
|
||||
pfsync_clear_state(st)
|
||||
struct pf_state *st;
|
||||
{
|
||||
#if defined(__FreeBSD__)
|
||||
struct pfsync_softc *sc = LIST_FIRST(&pfsync_list);
|
||||
#else
|
||||
struct ifnet *ifp = &pfsyncif.sc_if;
|
||||
struct pfsync_softc *sc = ifp->if_softc;
|
||||
#endif
|
||||
struct mbuf *m = sc->sc_mbuf;
|
||||
int s, ret;
|
||||
|
||||
@ -332,6 +482,7 @@ pfsync_timeout(void *v)
|
||||
struct pfsync_softc *sc = v;
|
||||
int s;
|
||||
|
||||
/* We don't need PF_LOCK/PF_UNLOCK here! */
|
||||
s = splnet();
|
||||
pfsync_sendout(sc);
|
||||
splx(s);
|
||||
@ -344,10 +495,17 @@ pfsync_sendout(sc)
|
||||
struct ifnet *ifp = &sc->sc_if;
|
||||
struct mbuf *m = sc->sc_mbuf;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
callout_stop(&sc->sc_tmo);
|
||||
#else
|
||||
timeout_del(&sc->sc_tmo);
|
||||
#endif
|
||||
sc->sc_mbuf = NULL;
|
||||
sc->sc_ptr = NULL;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT(m != NULL, ("pfsync_sendout: null mbuf"));
|
||||
#endif
|
||||
#if NBPFILTER > 0
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp->if_bpf, m);
|
||||
@ -357,3 +515,44 @@ pfsync_sendout(sc)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
static int
|
||||
pfsync_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
LIST_INIT(&pfsync_list);
|
||||
if_clone_attach(&pfsync_cloner);
|
||||
printf("pfsync: $Name: $\n");
|
||||
break;
|
||||
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&pfsync_cloner);
|
||||
while (!LIST_EMPTY(&pfsync_list))
|
||||
pfsync_clone_destroy(
|
||||
&LIST_FIRST(&pfsync_list)->sc_if);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static moduledata_t pfsync_mod = {
|
||||
"pfsync",
|
||||
pfsync_modevent,
|
||||
0
|
||||
};
|
||||
|
||||
#define PFSYNC_MODVER 1
|
||||
|
||||
DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
|
||||
MODULE_VERSION(pfsync, PFSYNC_MODVER);
|
||||
#endif /* __FreeBSD__ */
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pfsync.h,v 1.2 2002/12/11 18:31:26 mickey Exp $ */
|
||||
|
||||
/*
|
||||
@ -33,10 +34,17 @@
|
||||
struct pfsync_softc {
|
||||
struct ifnet sc_if;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
struct callout sc_tmo;
|
||||
#else
|
||||
struct timeout sc_tmo;
|
||||
#endif
|
||||
struct mbuf *sc_mbuf; /* current cummulative mbuf */
|
||||
struct pf_state *sc_ptr; /* current ongoing state */
|
||||
int sc_count; /* number of states in one mtu */
|
||||
#if defined(__FreeBSD__)
|
||||
LIST_ENTRY(pfsync_softc) sc_next;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_norm.c,v 1.75 2003/08/29 01:49:08 dhartmei Exp $ */
|
||||
|
||||
/*
|
||||
@ -25,7 +26,15 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#include "opt_random_ip_id.h" /* or ip_var does not export it */
|
||||
#include "opt_pf.h"
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#else
|
||||
#include "pflog.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -35,9 +44,13 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/time.h>
|
||||
#if !defined(__FreeBSD__)
|
||||
#include <sys/pool.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
#include <dev/rndvar.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
@ -60,6 +73,49 @@
|
||||
|
||||
#include <net/pfvar.h>
|
||||
|
||||
#if defined(__FreeBSD__) && defined(INET6)
|
||||
/*
|
||||
* XXX: This should go to netinet/ip6.h (KAME)
|
||||
*/
|
||||
/* IPv6 options: common part */
|
||||
struct ip6_opt {
|
||||
u_int8_t ip6o_type;
|
||||
u_int8_t ip6o_len;
|
||||
} __packed;
|
||||
|
||||
/* Jumbo Payload Option */
|
||||
struct ip6_opt_jumbo {
|
||||
u_int8_t ip6oj_type;
|
||||
u_int8_t ip6oj_len;
|
||||
u_int8_t ip6oj_jumbo_len[4];
|
||||
} __packed;
|
||||
|
||||
/* NSAP Address Option */
|
||||
struct ip6_opt_nsap {
|
||||
u_int8_t ip6on_type;
|
||||
u_int8_t ip6on_len;
|
||||
u_int8_t ip6on_src_nsap_len;
|
||||
u_int8_t ip6on_dst_nsap_len;
|
||||
/* followed by source NSAP */
|
||||
/* followed by destination NSAP */
|
||||
} __packed;
|
||||
|
||||
/* Tunnel Limit Option */
|
||||
struct ip6_opt_tunnel {
|
||||
u_int8_t ip6ot_type;
|
||||
u_int8_t ip6ot_len;
|
||||
u_int8_t ip6ot_encap_limit;
|
||||
} __packed;
|
||||
|
||||
/* Router Alert Option */
|
||||
struct ip6_opt_router {
|
||||
u_int8_t ip6or_type;
|
||||
u_int8_t ip6or_len;
|
||||
u_int8_t ip6or_value[2];
|
||||
} __packed;
|
||||
#endif /* __FreeBSD__ && INET6 */
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
struct pf_frent {
|
||||
LIST_ENTRY(pf_frent) fr_next;
|
||||
struct ip *fr_ip;
|
||||
@ -71,12 +127,14 @@ struct pf_frcache {
|
||||
uint16_t fr_off;
|
||||
uint16_t fr_end;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define PFFRAG_SEENLAST 0x0001 /* Seen the last fragment for this */
|
||||
#define PFFRAG_NOBUFFER 0x0002 /* Non-buffering fragment cache */
|
||||
#define PFFRAG_DROP 0x0004 /* Drop all fragments */
|
||||
#define BUFFER_FRAGMENTS(fr) (!((fr)->fr_flags & PFFRAG_NOBUFFER))
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
struct pf_fragment {
|
||||
RB_ENTRY(pf_fragment) fr_entry;
|
||||
TAILQ_ENTRY(pf_fragment) frag_next;
|
||||
@ -94,6 +152,7 @@ struct pf_fragment {
|
||||
LIST_HEAD(pf_cacheq, pf_frcache) fru_cache; /* non-buf */
|
||||
} fr_u;
|
||||
};
|
||||
#endif
|
||||
|
||||
TAILQ_HEAD(pf_fragqueue, pf_fragment) pf_fragqueue;
|
||||
TAILQ_HEAD(pf_cachequeue, pf_fragment) pf_cachequeue;
|
||||
@ -105,6 +164,9 @@ RB_PROTOTYPE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
|
||||
RB_GENERATE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
|
||||
|
||||
/* Private prototypes */
|
||||
#ifndef RANDOM_IP_ID
|
||||
extern u_int16_t ip_randomid(void);
|
||||
#endif
|
||||
void pf_ip2key(struct pf_fragment *, struct ip *);
|
||||
void pf_remove_fragment(struct pf_fragment *);
|
||||
void pf_flush_fragments(void);
|
||||
@ -122,13 +184,28 @@ int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
|
||||
{ printf("%s: ", __func__); printf x ;}
|
||||
|
||||
/* Globals */
|
||||
#if defined(__FreeBSD__)
|
||||
uma_zone_t pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
|
||||
uma_zone_t pf_state_scrub_pl;
|
||||
#else
|
||||
struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
|
||||
struct pool pf_state_scrub_pl;
|
||||
#endif
|
||||
int pf_nfrents, pf_ncache;
|
||||
|
||||
void
|
||||
pf_normalize_init(void)
|
||||
{
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
* XXX
|
||||
* No high water mark support(It's hint not hard limit).
|
||||
* uma_zone_set_max(pf_frag_pl, PFFRAG_FRAG_HIWAT);
|
||||
*/
|
||||
uma_zone_set_max(pf_frent_pl, PFFRAG_FRENT_HIWAT);
|
||||
uma_zone_set_max(pf_cache_pl, PFFRAG_FRCACHE_HIWAT);
|
||||
uma_zone_set_max(pf_cent_pl, PFFRAG_FRCENT_HIWAT);
|
||||
#else
|
||||
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",
|
||||
@ -144,6 +221,7 @@ pf_normalize_init(void)
|
||||
pool_sethardlimit(&pf_frent_pl, PFFRAG_FRENT_HIWAT, NULL, 0);
|
||||
pool_sethardlimit(&pf_cache_pl, PFFRAG_FRCACHE_HIWAT, NULL, 0);
|
||||
pool_sethardlimit(&pf_cent_pl, PFFRAG_FRCENT_HIWAT, NULL, 0);
|
||||
#endif
|
||||
|
||||
TAILQ_INIT(&pf_fragqueue);
|
||||
TAILQ_INIT(&pf_cachequeue);
|
||||
@ -173,11 +251,21 @@ void
|
||||
pf_purge_expired_fragments(void)
|
||||
{
|
||||
struct pf_fragment *frag;
|
||||
#if defined(__FreeBSD__)
|
||||
u_int32_t expire = time_second -
|
||||
pf_default_rule.timeout[PFTM_FRAG];
|
||||
#else
|
||||
u_int32_t expire = time.tv_sec -
|
||||
pf_default_rule.timeout[PFTM_FRAG];
|
||||
#endif
|
||||
|
||||
while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((BUFFER_FRAGMENTS(frag)),
|
||||
("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
|
||||
#else
|
||||
KASSERT(BUFFER_FRAGMENTS(frag));
|
||||
#endif
|
||||
if (frag->fr_timeout > expire)
|
||||
break;
|
||||
|
||||
@ -186,14 +274,26 @@ pf_purge_expired_fragments(void)
|
||||
}
|
||||
|
||||
while ((frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue)) != NULL) {
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((!BUFFER_FRAGMENTS(frag)),
|
||||
("BUFFER_FRAGMENTS(frag) != 0: %s", __FUNCTION__));
|
||||
#else
|
||||
KASSERT(!BUFFER_FRAGMENTS(frag));
|
||||
#endif
|
||||
if (frag->fr_timeout > expire)
|
||||
break;
|
||||
|
||||
DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
|
||||
pf_free_fragment(frag);
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((TAILQ_EMPTY(&pf_cachequeue) ||
|
||||
TAILQ_LAST(&pf_cachequeue, pf_cachequeue) != frag),
|
||||
("!(TAILQ_EMPTY() || TAILQ_LAST() == farg): %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
KASSERT(TAILQ_EMPTY(&pf_cachequeue) ||
|
||||
TAILQ_LAST(&pf_cachequeue, pf_cachequeue) != frag);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,9 +352,17 @@ pf_free_fragment(struct pf_fragment *frag)
|
||||
frcache = LIST_FIRST(&frag->fr_cache)) {
|
||||
LIST_REMOVE(frcache, fr_next);
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((LIST_EMPTY(&frag->fr_cache) ||
|
||||
LIST_FIRST(&frag->fr_cache)->fr_off >
|
||||
frcache->fr_end),
|
||||
("! (LIST_EMPTY() || LIST_FIRST()->fr_off >"
|
||||
" frcache->fr_end): %s", __FUNCTION__));
|
||||
#else
|
||||
KASSERT(LIST_EMPTY(&frag->fr_cache) ||
|
||||
LIST_FIRST(&frag->fr_cache)->fr_off >
|
||||
frcache->fr_end);
|
||||
#endif
|
||||
|
||||
pool_put(&pf_cent_pl, frcache);
|
||||
pf_ncache--;
|
||||
@ -284,7 +392,11 @@ 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? */
|
||||
#if defined(__FreeBSD__)
|
||||
frag->fr_timeout = time_second;
|
||||
#else
|
||||
frag->fr_timeout = time.tv_sec;
|
||||
#endif
|
||||
if (BUFFER_FRAGMENTS(frag)) {
|
||||
TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
|
||||
TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
|
||||
@ -327,7 +439,12 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
u_int16_t ip_len = ntohs(ip->ip_len) - ip->ip_hl * 4;
|
||||
u_int16_t max = ip_len + off;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((*frag == NULL || BUFFER_FRAGMENTS(*frag)),
|
||||
("! (*frag == NULL || BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
|
||||
#else
|
||||
KASSERT(*frag == NULL || BUFFER_FRAGMENTS(*frag));
|
||||
#endif
|
||||
|
||||
/* Strip off ip header */
|
||||
m->m_data += hlen;
|
||||
@ -349,7 +466,11 @@ 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;
|
||||
#if defined(__FreeBSD__)
|
||||
(*frag)->fr_timeout = time_second;
|
||||
#else
|
||||
(*frag)->fr_timeout = time.tv_sec;
|
||||
#endif
|
||||
LIST_INIT(&(*frag)->fr_queue);
|
||||
|
||||
RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
|
||||
@ -370,7 +491,12 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
frep = frea;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((frep != NULL || frea != NULL),
|
||||
("!(frep != NULL || frea != NULL): %s", __FUNCTION__));;
|
||||
#else
|
||||
KASSERT(frep != NULL || frea != NULL);
|
||||
#endif
|
||||
|
||||
if (frep != NULL &&
|
||||
FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl *
|
||||
@ -455,7 +581,11 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
|
||||
/* We have all the data */
|
||||
frent = LIST_FIRST(&(*frag)->fr_queue);
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((frent != NULL), ("frent == NULL: %s", __FUNCTION__));
|
||||
#else
|
||||
KASSERT(frent != NULL);
|
||||
#endif
|
||||
if ((frent->fr_ip->ip_hl << 2) + off > IP_MAXPACKET) {
|
||||
DPFPRINTF(("drop: too big: %d\n", off));
|
||||
pf_free_fragment(*frag);
|
||||
@ -524,7 +654,12 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
u_int16_t max = ip_len + off;
|
||||
int hosed = 0;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((*frag == NULL || !BUFFER_FRAGMENTS(*frag)),
|
||||
("!(*frag == NULL || !BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
|
||||
#else
|
||||
KASSERT(*frag == NULL || !BUFFER_FRAGMENTS(*frag));
|
||||
#endif
|
||||
|
||||
/* Create a new range queue for this packet */
|
||||
if (*frag == NULL) {
|
||||
@ -551,7 +686,11 @@ 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;
|
||||
#if defined(__FreeBSD__)
|
||||
(*frag)->fr_timeout = time_second;
|
||||
#else
|
||||
(*frag)->fr_timeout = time.tv_sec;
|
||||
#endif
|
||||
|
||||
cur->fr_off = off;
|
||||
cur->fr_end = max;
|
||||
@ -577,7 +716,12 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
frp = fra;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((frp != NULL || fra != NULL),
|
||||
("!(frp != NULL || fra != NULL): %s", __FUNCTION__));
|
||||
#else
|
||||
KASSERT(frp != NULL || fra != NULL);
|
||||
#endif
|
||||
|
||||
if (frp != NULL) {
|
||||
int precut;
|
||||
@ -619,10 +763,23 @@ 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.
|
||||
*/
|
||||
#if defined(__FreeBSD__)
|
||||
*m0 = m_dup(m, M_DONTWAIT);
|
||||
/* From KAME Project : We have missed this! */
|
||||
m_adj(*m0, (h->ip_hl << 2) -
|
||||
(*m0)->m_pkthdr.len);
|
||||
#else
|
||||
*m0 = m_copym2(m, 0, h->ip_hl << 2, M_NOWAIT);
|
||||
#endif
|
||||
if (*m0 == NULL)
|
||||
goto no_mem;
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT(((*m0)->m_next == NULL),
|
||||
("(*m0)->m_next != NULL: %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
KASSERT((*m0)->m_next == NULL);
|
||||
#endif
|
||||
m_adj(m, precut + (h->ip_hl << 2));
|
||||
m_cat(*m0, m);
|
||||
m = *m0;
|
||||
@ -637,8 +794,13 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
|
||||
h = mtod(m, struct ip *);
|
||||
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT(((int)m->m_len == ntohs(h->ip_len) - precut),
|
||||
("m->m_len != ntohs(h->ip_len) - precut: %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
KASSERT((int)m->m_len == ntohs(h->ip_len) - precut);
|
||||
#endif
|
||||
h->ip_off = htons(ntohs(h->ip_off) + (precut >> 3));
|
||||
h->ip_len = htons(ntohs(h->ip_len) - precut);
|
||||
} else {
|
||||
@ -693,7 +855,13 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
m->m_pkthdr.len = plen;
|
||||
}
|
||||
h = mtod(m, struct ip *);
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT(((int)m->m_len == ntohs(h->ip_len) - aftercut),
|
||||
("m->m_len != ntohs(h->ip_len) - aftercut: %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
KASSERT((int)m->m_len == ntohs(h->ip_len) - aftercut);
|
||||
#endif
|
||||
h->ip_len = htons(ntohs(h->ip_len) - aftercut);
|
||||
} else {
|
||||
hosed++;
|
||||
@ -731,7 +899,12 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
|
||||
|
||||
} else if (frp && fra->fr_off <= frp->fr_end) {
|
||||
/* Need to merge in a modified 'frp' */
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((cur == NULL), ("cur != NULL: %s",
|
||||
__FUNCTION__));
|
||||
#else
|
||||
KASSERT(cur == NULL);
|
||||
#endif
|
||||
DPFPRINTF(("fragcache[%d]: adjacent(merge "
|
||||
"%d-%d) %d-%d (%d-%d)\n",
|
||||
h->ip_id, frp->fr_off, frp->fr_end, off,
|
||||
@ -1283,7 +1456,7 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, 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);
|
||||
|
||||
@ -1301,7 +1474,12 @@ pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
u_int8_t hdr[60];
|
||||
u_int8_t *opt;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((src->scrub == NULL),
|
||||
("pf_normalize_tcp_init: src->scrub != NULL"));
|
||||
#else
|
||||
KASSERT(src->scrub == NULL);
|
||||
#endif
|
||||
|
||||
src->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT);
|
||||
if (src->scrub == NULL)
|
||||
@ -1385,7 +1563,12 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
u_int8_t *opt;
|
||||
int copyback = 0;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
KASSERT((src->scrub || dst->scrub),
|
||||
("pf_normalize_tcp_statefull: src->scrub && dst->scrub!"));
|
||||
#else
|
||||
KASSERT(src->scrub || dst->scrub);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enforce the minimum TTL seen for this connection. Negate a common
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_osfp.c,v 1.3 2003/08/27 18:23:36 frantzen Exp $ */
|
||||
|
||||
/*
|
||||
@ -36,12 +37,15 @@
|
||||
#include <netinet/ip6.h>
|
||||
#endif /* INET6 */
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
# define DPFPRINTF(format, x...) \
|
||||
if (pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#if defined(__FreeBSD__)
|
||||
typedef uma_zone_t pool_t;
|
||||
#else
|
||||
typedef struct pool pool_t;
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Userland equivalents so we can lend code to tcpdump et al. */
|
||||
@ -55,6 +59,10 @@ typedef struct pool pool_t;
|
||||
# define pool_put(pool, item) free(item)
|
||||
# define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size)
|
||||
|
||||
# if defined(__FreeBSD__)
|
||||
# define NTOHS(x) (x) = ntohs((u_int16_t)(x))
|
||||
# endif
|
||||
|
||||
# ifdef PFDEBUG
|
||||
# include <stdarg.h>
|
||||
# define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
@ -106,7 +114,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct tcphdr *tcp)
|
||||
{
|
||||
struct pf_os_fingerprint fp, *fpresult;
|
||||
int cnt, optlen = 0;
|
||||
u_int8_t *optp;
|
||||
const u_int8_t *optp;
|
||||
|
||||
if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN || (ip->ip_off &
|
||||
htons(IP_OFFMASK)))
|
||||
@ -122,7 +130,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct tcphdr *tcp)
|
||||
|
||||
|
||||
cnt = (tcp->th_off << 2) - sizeof(*tcp);
|
||||
optp = (caddr_t)tcp + sizeof(*tcp);
|
||||
optp = (const u_int8_t *)((const char *)tcp + sizeof(*tcp));
|
||||
for (; cnt > 0; cnt -= optlen, optp += optlen) {
|
||||
if (*optp == TCPOPT_EOL)
|
||||
break;
|
||||
@ -228,16 +236,47 @@ pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os)
|
||||
}
|
||||
|
||||
/* Initialize the OS fingerprint system */
|
||||
#if defined(__FreeBSD__)
|
||||
int
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
pf_osfp_initialize(void)
|
||||
{
|
||||
#if defined(__FreeBSD__) && defined(_KERNEL)
|
||||
int error = ENOMEM;
|
||||
|
||||
do {
|
||||
pf_osfp_entry_pl = pf_osfp_pl = NULL;
|
||||
UMA_CREATE(pf_osfp_entry_pl, struct pf_osfp_entry, "pfospfen");
|
||||
UMA_CREATE(pf_osfp_pl, struct pf_os_fingerprint, "pfosfp");
|
||||
error = 0;
|
||||
} while(0);
|
||||
#else
|
||||
pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0,
|
||||
"pfosfpen", NULL);
|
||||
pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0,
|
||||
"pfosfp", NULL);
|
||||
#endif
|
||||
SLIST_INIT(&pf_osfp_list);
|
||||
#if defined(__FreeBSD__)
|
||||
#if defined(_KERNEL)
|
||||
return (error);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__) && (_KERNEL)
|
||||
void
|
||||
pf_osfp_cleanup(void)
|
||||
{
|
||||
UMA_DESTROY(pf_osfp_entry_pl);
|
||||
UMA_DESTROY(pf_osfp_pl);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Flush the fingerprint list */
|
||||
void
|
||||
pf_osfp_flush(void)
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_table.c,v 1.41 2003/08/22 15:19:23 henning Exp $ */
|
||||
|
||||
/*
|
||||
@ -30,18 +31,33 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/kernel.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/malloc.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#if !defined(__FreeBSD__)
|
||||
#include <netinet/ip_ipsp.h>
|
||||
#endif
|
||||
|
||||
#include <net/pfvar.h>
|
||||
|
||||
#if defined(FreeBSD__)
|
||||
MALLOC_DECLARE(M_RTABLE);
|
||||
#endif
|
||||
|
||||
#define ACCEPT_FLAGS(oklist) \
|
||||
do { \
|
||||
if ((flags & ~(oklist)) & \
|
||||
@ -109,8 +125,13 @@ struct pfr_walktree {
|
||||
|
||||
#define senderr(e) do { rv = (e); goto _bad; } while (0)
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
uma_zone_t pfr_ktable_pl;
|
||||
uma_zone_t pfr_kentry_pl;
|
||||
#else
|
||||
struct pool pfr_ktable_pl;
|
||||
struct pool pfr_kentry_pl;
|
||||
#endif
|
||||
struct sockaddr_in pfr_sin;
|
||||
struct sockaddr_in6 pfr_sin6;
|
||||
union sockaddr_union pfr_mask;
|
||||
@ -172,10 +193,12 @@ int pfr_ktable_cnt;
|
||||
void
|
||||
pfr_initialize(void)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
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;
|
||||
@ -226,7 +249,15 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p, *q;
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xadd = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
long tzero = (long)time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
@ -241,8 +272,14 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
return (ENOMEM);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
p = pfr_lookup_addr(kt, &ad, 1);
|
||||
@ -269,9 +306,17 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
xadd++;
|
||||
}
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
}
|
||||
#else
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
pfr_clean_node_mask(tmpkt, &workq);
|
||||
if (!(flags & PFR_FLAG_DUMMY)) {
|
||||
@ -304,6 +349,9 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xdel = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
@ -316,8 +364,14 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
pfr_mark_addrs(kt);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
p = pfr_lookup_addr(kt, &ad, 1);
|
||||
@ -337,9 +391,17 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
|
||||
xdel++;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
}
|
||||
#else
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (!(flags & PFR_FLAG_DUMMY)) {
|
||||
if (flags & PFR_FLAG_ATOMIC)
|
||||
@ -366,7 +428,15 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p, *q;
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xadd = 0, xdel = 0, xchange = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
long tzero = (long)time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
@ -384,8 +454,14 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
SLIST_INIT(&delq);
|
||||
SLIST_INIT(&changeq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
ad.pfra_fback = PFR_FB_NONE;
|
||||
@ -420,9 +496,17 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
}
|
||||
}
|
||||
_skip:
|
||||
#if defined(__FreeBSD__)
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
}
|
||||
#else
|
||||
if (flags & PFR_FLAG_FEEDBACK)
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
pfr_enqueue_addrs(kt, &delq, &xdel, ENQUEUE_UNMARKED_ONLY);
|
||||
if ((flags & PFR_FLAG_FEEDBACK) && *size2) {
|
||||
@ -434,8 +518,14 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
SLIST_FOREACH(p, &delq, pfrke_workq) {
|
||||
pfr_copyout_addr(&ad, p);
|
||||
ad.pfra_fback = PFR_FB_DELETED;
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&ad, addr+size+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, addr+size+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -477,6 +567,9 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_addr ad;
|
||||
int i, xmatch = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_REPLACE);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
@ -486,8 +579,14 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
return (ESRCH);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
return (EINVAL);
|
||||
if (ADDR_NETWORK(&ad))
|
||||
@ -499,8 +598,14 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
(p->pfrke_not ? PFR_FB_NOTMATCH : PFR_FB_MATCH);
|
||||
if (p != NULL && !p->pfrke_not)
|
||||
xmatch++;
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (nmatch != NULL)
|
||||
*nmatch = xmatch;
|
||||
@ -530,9 +635,18 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
|
||||
w.pfrw_op = PFRW_GET_ADDRS;
|
||||
w.pfrw_addr = addr;
|
||||
w.pfrw_free = kt->pfrkt_cnt;
|
||||
#if defined(__FreeBSD__)
|
||||
rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#else
|
||||
rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#endif
|
||||
if (!rv)
|
||||
#if defined(__FreeBSD__)
|
||||
rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
|
||||
&w);
|
||||
#else
|
||||
rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#endif
|
||||
if (rv)
|
||||
return (rv);
|
||||
|
||||
@ -553,7 +667,14 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
|
||||
struct pfr_walktree w;
|
||||
struct pfr_kentryworkq workq;
|
||||
int rv, s;
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
long tzero = (long)time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC); /* XXX PFR_FLAG_CLSTATS disabled */
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
@ -572,9 +693,18 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
|
||||
w.pfrw_free = kt->pfrkt_cnt;
|
||||
if (flags & PFR_FLAG_ATOMIC)
|
||||
s = splsoftnet();
|
||||
#if defined(__FreeBSD__)
|
||||
rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#else
|
||||
rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#endif
|
||||
if (!rv)
|
||||
#if defined(__FreeBSD__)
|
||||
rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
|
||||
&w);
|
||||
#else
|
||||
rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#endif
|
||||
if (!rv && (flags & PFR_FLAG_CLSTATS)) {
|
||||
pfr_enqueue_addrs(kt, &workq, NULL, 0);
|
||||
pfr_clstats_kentries(&workq, tzero, 0);
|
||||
@ -602,6 +732,9 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_addr ad;
|
||||
int i, rv, s, xzero = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0))
|
||||
@ -611,16 +744,28 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
return (ESRCH);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
p = pfr_lookup_addr(kt, &ad, 1);
|
||||
if (flags & PFR_FLAG_FEEDBACK) {
|
||||
ad.pfra_fback = (p != NULL) ?
|
||||
PFR_FB_CLEARED : PFR_FB_NONE;
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (p != NULL) {
|
||||
SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
|
||||
@ -685,10 +830,20 @@ pfr_enqueue_addrs(struct pfr_ktable *kt, struct pfr_kentryworkq *workq,
|
||||
w.pfrw_op = sweep ? PFRW_SWEEP : PFRW_ENQUEUE;
|
||||
w.pfrw_workq = workq;
|
||||
if (kt->pfrkt_ip4 != NULL)
|
||||
#if defined(__FreeBSD__)
|
||||
if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree,
|
||||
&w))
|
||||
#else
|
||||
if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
|
||||
#endif
|
||||
printf("pfr_enqueue_addrs: IPv4 walktree failed.\n");
|
||||
if (kt->pfrkt_ip6 != NULL)
|
||||
#if defined(__FreeBSD__)
|
||||
if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
|
||||
&w))
|
||||
#else
|
||||
if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
|
||||
#endif
|
||||
printf("pfr_enqueue_addrs: IPv6 walktree failed.\n");
|
||||
if (naddr != NULL)
|
||||
*naddr = w.pfrw_cnt;
|
||||
@ -701,9 +856,17 @@ pfr_mark_addrs(struct pfr_ktable *kt)
|
||||
|
||||
bzero(&w, sizeof(w));
|
||||
w.pfrw_op = PFRW_MARK;
|
||||
#if defined(__FreeBSD__)
|
||||
if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
|
||||
#else
|
||||
if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
|
||||
#endif
|
||||
printf("pfr_mark_addrs: IPv4 walktree failed.\n");
|
||||
#if defined(__FreeBSD__)
|
||||
if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
|
||||
#else
|
||||
if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
|
||||
#endif
|
||||
printf("pfr_mark_addrs: IPv6 walktree failed.\n");
|
||||
}
|
||||
|
||||
@ -727,7 +890,13 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
|
||||
if (ADDR_NETWORK(ad)) {
|
||||
pfr_prepare_network(&mask, ad->pfra_af, ad->pfra_net);
|
||||
s = splsoftnet(); /* rn_lookup makes use of globals */
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
RADIX_NODE_HEAD_LOCK(head);
|
||||
#endif
|
||||
ke = (struct pfr_kentry *)rn_lookup(&sa, &mask, head);
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
RADIX_NODE_HEAD_UNLOCK(head);
|
||||
#endif
|
||||
splx(s);
|
||||
if (ke && KENTRY_RNF_ROOT(ke))
|
||||
ke = NULL;
|
||||
@ -845,13 +1014,28 @@ pfr_reset_feedback(struct pfr_addr *addr, int size)
|
||||
{
|
||||
struct pfr_addr ad;
|
||||
int i;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
break;
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
break;
|
||||
#endif
|
||||
ad.pfra_fback = PFR_FB_NONE;
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&ad, addr+i, sizeof(ad), ec);
|
||||
if (ec)
|
||||
break;
|
||||
#else
|
||||
if (copyout(&ad, addr+i, sizeof(ad)))
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -895,11 +1079,17 @@ pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
|
||||
head = kt->pfrkt_ip6;
|
||||
|
||||
s = splsoftnet();
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
RADIX_NODE_HEAD_LOCK(head);
|
||||
#endif
|
||||
if (KENTRY_NETWORK(ke)) {
|
||||
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
|
||||
rn = rn_addroute(&ke->pfrke_sa, &mask, head, ke->pfrke_node);
|
||||
} else
|
||||
rn = rn_addroute(&ke->pfrke_sa, NULL, head, ke->pfrke_node);
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
RADIX_NODE_HEAD_UNLOCK(head);
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
return (rn == NULL ? -1 : 0);
|
||||
@ -919,11 +1109,17 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
|
||||
head = kt->pfrkt_ip6;
|
||||
|
||||
s = splsoftnet();
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
RADIX_NODE_HEAD_LOCK(head);
|
||||
#endif
|
||||
if (KENTRY_NETWORK(ke)) {
|
||||
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
|
||||
rn = rn_delete(&ke->pfrke_sa, &mask, head);
|
||||
} else
|
||||
rn = rn_delete(&ke->pfrke_sa, NULL, head);
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
RADIX_NODE_HEAD_UNLOCK(head);
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
if (rn == NULL) {
|
||||
@ -954,6 +1150,9 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
struct pfr_kentry *ke = (struct pfr_kentry *)rn;
|
||||
struct pfr_walktree *w = arg;
|
||||
int s;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
switch (w->pfrw_op) {
|
||||
case PFRW_MARK:
|
||||
@ -972,8 +1171,14 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
struct pfr_addr ad;
|
||||
|
||||
pfr_copyout_addr(&ad, ke);
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&ad, w->pfrw_addr, sizeof(ad), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&ad, w->pfrw_addr, sizeof(ad)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
w->pfrw_addr++;
|
||||
}
|
||||
break;
|
||||
@ -991,8 +1196,14 @@ pfr_walktree(struct radix_node *rn, void *arg)
|
||||
splx(s);
|
||||
as.pfras_tzero = ke->pfrke_tzero;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&as, w->pfrw_astats, sizeof(as), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&as, w->pfrw_astats, sizeof(as)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
w->pfrw_astats++;
|
||||
}
|
||||
break;
|
||||
@ -1047,14 +1258,28 @@ 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;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
long tzero = (long)time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
|
||||
SLIST_INIT(&addq);
|
||||
SLIST_INIT(&changeq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK))
|
||||
senderr(EINVAL);
|
||||
key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
|
||||
@ -1127,12 +1352,21 @@ 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;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0))
|
||||
return (EINVAL);
|
||||
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
|
||||
@ -1166,6 +1400,9 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
|
||||
{
|
||||
struct pfr_ktable *p;
|
||||
int n, nn;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ALLRSETS);
|
||||
n = nn = pfr_table_count(filter, flags);
|
||||
@ -1180,8 +1417,14 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
|
||||
continue;
|
||||
if (n-- <= 0)
|
||||
continue;
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&p->pfrkt_t, tbl++, sizeof(*tbl), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyout(&p->pfrkt_t, tbl++, sizeof(*tbl)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
}
|
||||
if (n) {
|
||||
printf("pfr_get_tables: corruption detected (%d).\n", n);
|
||||
@ -1198,7 +1441,15 @@ 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;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
long tzero = (long)time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC|PFR_FLAG_ALLRSETS);
|
||||
/* XXX PFR_FLAG_CLSTATS disabled */
|
||||
@ -1219,10 +1470,18 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
|
||||
continue;
|
||||
if (!(flags & PFR_FLAG_ATOMIC))
|
||||
s = splsoftnet();
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYOUT(&p->pfrkt_ts, tbl++, sizeof(*tbl), ec);
|
||||
if (ec) {
|
||||
splx(s);
|
||||
return (EFAULT);
|
||||
}
|
||||
#else
|
||||
if (copyout(&p->pfrkt_ts, tbl++, sizeof(*tbl))) {
|
||||
splx(s);
|
||||
return (EFAULT);
|
||||
}
|
||||
#endif
|
||||
if (!(flags & PFR_FLAG_ATOMIC))
|
||||
splx(s);
|
||||
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
|
||||
@ -1246,13 +1505,27 @@ 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;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
long tzero = (long)time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_ADDRSTOO);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0))
|
||||
return (EINVAL);
|
||||
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
|
||||
@ -1280,6 +1553,9 @@ 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;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
|
||||
if ((setflag & ~PFR_TFLAG_USRMASK) ||
|
||||
@ -1288,8 +1564,14 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
|
||||
return (EINVAL);
|
||||
SLIST_INIT(&workq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), ec);
|
||||
if (ec)
|
||||
return (EFAULT);
|
||||
#else
|
||||
if (copyin(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_table(&key.pfrkt_t, 0))
|
||||
return (EINVAL);
|
||||
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
|
||||
@ -1370,6 +1652,9 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_addr ad;
|
||||
struct pf_ruleset *rs;
|
||||
int i, rv, xadd = 0, xaddr = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
int ec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_DUMMY|PFR_FLAG_ADDRSTOO);
|
||||
if (size && !(flags & PFR_FLAG_ADDRSTOO))
|
||||
@ -1416,8 +1701,14 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
}
|
||||
SLIST_INIT(&addrq);
|
||||
for (i = 0; i < size; i++) {
|
||||
#if defined(__FreeBSD__)
|
||||
PF_COPYIN(addr+i, &ad, sizeof(ad), ec);
|
||||
if (ec)
|
||||
senderr(EFAULT);
|
||||
#else
|
||||
if (copyin(addr+i, &ad, sizeof(ad)))
|
||||
senderr(EFAULT);
|
||||
#endif
|
||||
if (pfr_validate_addr(&ad))
|
||||
senderr(EINVAL);
|
||||
if (pfr_lookup_addr(shadow, &ad, 1) != NULL)
|
||||
@ -1466,7 +1757,14 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
|
||||
struct pfr_ktableworkq workq;
|
||||
struct pf_ruleset *rs;
|
||||
int s, xadd = 0, xchange = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
long tzero = (long)time_second;
|
||||
#else
|
||||
long tzero = time.tv_sec;
|
||||
#endif
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
|
||||
rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset);
|
||||
@ -1761,10 +2059,21 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
|
||||
pfr_clean_node_mask(kt, &addrq);
|
||||
pfr_destroy_kentries(&addrq);
|
||||
}
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
if (kt->pfrkt_ip4 != NULL) {
|
||||
RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip4);
|
||||
free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
|
||||
}
|
||||
if (kt->pfrkt_ip6 != NULL) {
|
||||
RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip6);
|
||||
free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
|
||||
}
|
||||
#else
|
||||
if (kt->pfrkt_ip4 != NULL)
|
||||
free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
|
||||
if (kt->pfrkt_ip6 != NULL)
|
||||
free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
|
||||
#endif
|
||||
if (kt->pfrkt_shadow != NULL)
|
||||
pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr);
|
||||
if (kt->pfrkt_rs != NULL) {
|
||||
@ -1883,7 +2192,14 @@ pfr_attach_table(struct pf_ruleset *rs, char *name)
|
||||
}
|
||||
kt = pfr_lookup_table(&tbl);
|
||||
if (kt == NULL) {
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
* XXX Is it OK under LP64 environments?
|
||||
*/
|
||||
kt = pfr_create_ktable(&tbl, (long)time_second, 1);
|
||||
#else
|
||||
kt = pfr_create_ktable(&tbl, time.tv_sec, 1);
|
||||
#endif
|
||||
if (kt == NULL)
|
||||
return (NULL);
|
||||
if (ac != NULL) {
|
||||
@ -1917,6 +2233,7 @@ pfr_detach_table(struct pfr_ktable *kt)
|
||||
pfr_setflags_ktable(kt, kt->pfrkt_flags&~PFR_TFLAG_REFERENCED);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
@ -2006,13 +2323,20 @@ pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
#if defined(__FreeBSD__)
|
||||
kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#else
|
||||
rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
|
||||
#endif
|
||||
return w.pfrw_kentry;
|
||||
case AF_INET6:
|
||||
#if defined(__FreeBSD__)
|
||||
kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#else
|
||||
rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
|
||||
#endif
|
||||
return w.pfrw_kentry;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */
|
||||
|
||||
/*
|
||||
@ -38,7 +39,26 @@
|
||||
#include <sys/tree.h>
|
||||
|
||||
#include <net/radix.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#include <vm/uma.h>
|
||||
#else
|
||||
#include <netinet/ip_ipsp.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <netinet/in.h>
|
||||
/*
|
||||
* XXX
|
||||
* If we include <netipsec/keydb.h>, we need _KERNEL definition.
|
||||
* This makes pfctl compilation difficult.
|
||||
*/
|
||||
union sockaddr_union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
};
|
||||
#endif
|
||||
|
||||
#include <netinet/tcp_fsm.h>
|
||||
|
||||
struct ip;
|
||||
@ -119,7 +139,11 @@ struct pf_addr_dyn {
|
||||
struct ifnet *ifp;
|
||||
struct pf_addr *addr;
|
||||
sa_family_t af;
|
||||
#if defined(__FreeBSD__) && defined(HOOK_HACK)
|
||||
eventhandler_tag hook_cookie;
|
||||
#else
|
||||
void *hook_cookie;
|
||||
#endif
|
||||
u_int8_t undefined;
|
||||
};
|
||||
|
||||
@ -129,6 +153,66 @@ struct pf_addr_dyn {
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define splsoftnet() splnet()
|
||||
|
||||
#define PF_NAME "pf"
|
||||
|
||||
#define PR_NOWAIT M_NOWAIT
|
||||
#define pool_get(p, f) uma_zalloc(*(p), (f))
|
||||
#define pool_put(p, o) uma_zfree(*(p), (o))
|
||||
|
||||
#define UMA_CREATE(var, type, desc) \
|
||||
var = uma_zcreate(desc, sizeof(type), \
|
||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); \
|
||||
if (var == NULL) break
|
||||
#define UMA_DESTROY(var) \
|
||||
if(var) uma_zdestroy(var)
|
||||
|
||||
extern struct mtx pf_task_mtx;
|
||||
#if defined(ALTQ)
|
||||
extern struct mtx pf_altq_mtx;
|
||||
extern int pfaltq_ref;
|
||||
#endif
|
||||
|
||||
#define PF_ASSERT(h) mtx_assert(&pf_task_mtx, (h))
|
||||
|
||||
#define PF_LOCK() do { \
|
||||
PF_ASSERT(MA_NOTOWNED); \
|
||||
mtx_lock(&pf_task_mtx); \
|
||||
} while(0)
|
||||
#define PF_UNLOCK() do { \
|
||||
PF_ASSERT(MA_OWNED); \
|
||||
mtx_unlock(&pf_task_mtx); \
|
||||
} while(0)
|
||||
|
||||
#define PF_COPYIN(uaddr, kaddr, len, r) do { \
|
||||
PF_UNLOCK(); \
|
||||
r = copyin((uaddr), (kaddr), (len)); \
|
||||
PF_LOCK(); \
|
||||
} while(0)
|
||||
|
||||
#define PF_COPYOUT(kaddr, uaddr, len, r) do { \
|
||||
PF_UNLOCK(); \
|
||||
r = copyout((kaddr), (uaddr), (len)); \
|
||||
PF_LOCK(); \
|
||||
} while(0)
|
||||
|
||||
extern void init_pf_mutex(void);
|
||||
extern void destroy_pf_mutex(void);
|
||||
|
||||
#define PF_MODVER 1
|
||||
#define PFLOG_MODVER 1
|
||||
#define PFSYNC_MODVER 1
|
||||
|
||||
#define PFLOG_MINVER 1
|
||||
#define PFLOG_PREFVER PFLOG_MODVER
|
||||
#define PFLOG_MAXVER 1
|
||||
#define PFSYNC_MINVER 1
|
||||
#define PFSYNC_PREFVER PFSYNC_MODVER
|
||||
#define PFSYNC_MAXVER 1
|
||||
#endif
|
||||
|
||||
#ifdef INET
|
||||
#ifndef INET6
|
||||
#define PF_INET_ONLY
|
||||
@ -1101,6 +1185,13 @@ struct pfioc_table {
|
||||
#define DIOCOSFPFLUSH _IO('D', 78)
|
||||
#define DIOCOSFPADD _IOWR('D', 79, struct pf_osfp_ioctl)
|
||||
#define DIOCOSFPGET _IOWR('D', 80, struct pf_osfp_ioctl)
|
||||
#if defined(__FreeBSD__)
|
||||
struct pf_ifspeed {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int32_t baudrate;
|
||||
};
|
||||
#define DIOCGIFSPEED _IOWR('D', 81, struct pf_ifspeed)
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
RB_HEAD(pf_state_tree, pf_tree_node);
|
||||
@ -1135,9 +1226,17 @@ extern void pf_calc_skip_steps(struct pf_rulequeue *);
|
||||
extern void pf_rule_set_qid(struct pf_rulequeue *);
|
||||
extern u_int32_t pf_qname_to_qid(char *);
|
||||
extern void pf_update_anchor_rules(void);
|
||||
#if defined(__FreeBSD__)
|
||||
extern uma_zone_t pf_tree_pl, pf_rule_pl, pf_addr_pl;
|
||||
extern uma_zone_t pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
|
||||
extern uma_zone_t pfr_ktable_pl, pfr_kentry_pl;
|
||||
extern uma_zone_t pf_cache_pl, pf_cent_pl;
|
||||
extern uma_zone_t pf_state_scrub_pl;
|
||||
#else
|
||||
extern struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl;
|
||||
extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
|
||||
extern struct pool pf_state_scrub_pl;
|
||||
#endif
|
||||
extern void pf_purge_timeout(void *);
|
||||
extern void pf_purge_expired_states(void);
|
||||
extern int pf_insert_state(struct pf_state *);
|
||||
@ -1234,7 +1333,12 @@ void pf_tag_unref(u_int16_t);
|
||||
int pf_tag_packet(struct mbuf *, struct pf_tag *, int);
|
||||
|
||||
extern struct pf_status pf_status;
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
extern uma_zone_t pf_frent_pl, pf_frag_pl;
|
||||
#else
|
||||
extern struct pool pf_frent_pl, pf_frag_pl;
|
||||
#endif
|
||||
|
||||
struct pf_pool_limit {
|
||||
void *pp;
|
||||
@ -1242,6 +1346,38 @@ struct pf_pool_limit {
|
||||
};
|
||||
extern struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
struct pf_frent {
|
||||
LIST_ENTRY(pf_frent) fr_next;
|
||||
struct ip *fr_ip;
|
||||
struct mbuf *fr_m;
|
||||
};
|
||||
|
||||
struct pf_frcache {
|
||||
LIST_ENTRY(pf_frcache) fr_next;
|
||||
uint16_t fr_off;
|
||||
uint16_t fr_end;
|
||||
};
|
||||
|
||||
struct pf_fragment {
|
||||
RB_ENTRY(pf_fragment) fr_entry;
|
||||
TAILQ_ENTRY(pf_fragment) frag_next;
|
||||
struct in_addr fr_src;
|
||||
struct in_addr fr_dst;
|
||||
u_int8_t fr_p; /* protocol of this fragment */
|
||||
u_int8_t fr_flags; /* status flags */
|
||||
u_int16_t fr_id; /* fragment id for reassemble */
|
||||
u_int16_t fr_max; /* fragment data max */
|
||||
u_int32_t fr_timeout;
|
||||
#define fr_queue fr_u.fru_queue
|
||||
#define fr_cache fr_u.fru_cache
|
||||
union {
|
||||
LIST_HEAD(pf_fragq, pf_frent) fru_queue; /* buffering */
|
||||
LIST_HEAD(pf_cacheq, pf_frcache) fru_cache; /* non-buf */
|
||||
} fr_u;
|
||||
};
|
||||
#endif /* (__FreeBSD__) */
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/* The fingerprint functions can be linked into userland programs (tcpdump) */
|
||||
@ -1255,7 +1391,12 @@ struct pf_osfp_enlist *
|
||||
pf_osfp_fingerprint_hdr(const struct ip *, const struct tcphdr *);
|
||||
void pf_osfp_flush(void);
|
||||
int pf_osfp_get(struct pf_osfp_ioctl *);
|
||||
#if defined(__FreeBSD__)
|
||||
int pf_osfp_initialize(void);
|
||||
void pf_osfp_cleanup(void);
|
||||
#else
|
||||
void pf_osfp_initialize(void);
|
||||
#endif
|
||||
int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t);
|
||||
struct pf_os_fingerprint *
|
||||
pf_osfp_validate(void);
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: in4_cksum.c,v 1.7 2003/06/02 23:28:13 millert Exp $ */
|
||||
/* $KAME: in4_cksum.c,v 1.10 2001/11/30 10:06:15 itojun Exp $ */
|
||||
/* $NetBSD: in_cksum.c,v 1.13 1996/10/13 02:03:03 christos Exp $ */
|
||||
@ -72,6 +73,39 @@
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
|
||||
#if defined(__FreeBSD__) && defined(__i386__)
|
||||
/*
|
||||
* Copied from FreeBSD 5.0 sys/i386/i386/in_cksum.c
|
||||
* XXX
|
||||
* Currently support I386 processor only.
|
||||
* In the long run, we need an optimized cksum routines for each Tier1
|
||||
* architecture. Due to the lack of available hardware except I386 I
|
||||
* can't support other processors now. For those users which use Sparc64,
|
||||
* Alpha processors can use more optimized version in FreeBSD.
|
||||
* See sys/$ARCH/$ARCH/in_cksum.c where $ARCH=`uname -p`
|
||||
*/
|
||||
|
||||
/*
|
||||
* These asm statements require __volatile because they pass information
|
||||
* via the condition codes. GCC does not currently provide a way to specify
|
||||
* the condition codes as an input or output operand.
|
||||
*
|
||||
* The LOAD macro below is effectively a prefetch into cache. GCC will
|
||||
* load the value into a register but will not use it. Since modern CPUs
|
||||
* reorder operations, this will generally take place in parallel with
|
||||
* other calculations.
|
||||
*/
|
||||
#define ADD(n) __asm __volatile \
|
||||
("addl %1, %0" : "+r" (sum) : \
|
||||
"g" (((const u_int32_t *)w)[n / 4]))
|
||||
#define ADDC(n) __asm __volatile \
|
||||
("adcl %1, %0" : "+r" (sum) : \
|
||||
"g" (((const u_int32_t *)w)[n / 4]))
|
||||
#define LOAD(n) __asm __volatile \
|
||||
("" : : "r" (((const u_int32_t *)w)[n / 4]))
|
||||
#define MOP __asm __volatile \
|
||||
("adcl $0, %0" : "+r" (sum))
|
||||
#endif
|
||||
/*
|
||||
* Checksum routine for Internet Protocol family headers (Portable Version).
|
||||
* This is only for IPv4 pseudo header checksum.
|
||||
@ -86,6 +120,11 @@
|
||||
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
|
||||
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
int
|
||||
in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
|
||||
#endif
|
||||
|
||||
int
|
||||
in4_cksum(m, nxt, off, len)
|
||||
struct mbuf *m;
|
||||
@ -158,6 +197,134 @@ in4_cksum(m, nxt, off, len)
|
||||
if (len < mlen)
|
||||
mlen = len;
|
||||
len -= mlen;
|
||||
#if defined(__FreeBSD__) && defined(__i386__)
|
||||
/*
|
||||
* Force to long boundary so we do longword aligned
|
||||
* memory operations
|
||||
*/
|
||||
if (3 & (int) w) {
|
||||
REDUCE;
|
||||
if ((1 & (int) w) && (mlen > 0)) {
|
||||
sum <<= 8;
|
||||
s_util.c[0] = *(char *)w;
|
||||
w = (u_short *)((char *)w + 1);
|
||||
mlen--;
|
||||
byte_swapped = 1;
|
||||
}
|
||||
if ((2 & (int) w) && (mlen >= 2)) {
|
||||
sum += *w++;
|
||||
mlen -= 2;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Advance to a 486 cache line boundary.
|
||||
*/
|
||||
if (4 & (int) w && mlen >= 4) {
|
||||
ADD(0);
|
||||
MOP;
|
||||
w += 2;
|
||||
mlen -= 4;
|
||||
}
|
||||
if (8 & (int) w && mlen >= 8) {
|
||||
ADD(0);
|
||||
ADDC(4);
|
||||
MOP;
|
||||
w += 4;
|
||||
mlen -= 8;
|
||||
}
|
||||
/*
|
||||
* Do as much of the checksum as possible 32 bits at at time.
|
||||
* In fact, this loop is unrolled to make overhead from
|
||||
* branches &c small.
|
||||
*/
|
||||
mlen -= 1;
|
||||
while ((mlen -= 32) >= 0) {
|
||||
/*
|
||||
* Add with carry 16 words and fold in the last
|
||||
* carry by adding a 0 with carry.
|
||||
*
|
||||
* The early ADD(16) and the LOAD(32) are to load
|
||||
* the next 2 cache lines in advance on 486's. The
|
||||
* 486 has a penalty of 2 clock cycles for loading
|
||||
* a cache line, plus whatever time the external
|
||||
* memory takes to load the first word(s) addressed.
|
||||
* These penalties are unavoidable. Subsequent
|
||||
* accesses to a cache line being loaded (and to
|
||||
* other external memory?) are delayed until the
|
||||
* whole load finishes. These penalties are mostly
|
||||
* avoided by not accessing external memory for
|
||||
* 8 cycles after the ADD(16) and 12 cycles after
|
||||
* the LOAD(32). The loop terminates when mlen
|
||||
* is initially 33 (not 32) to guaranteed that
|
||||
* the LOAD(32) is within bounds.
|
||||
*/
|
||||
ADD(16);
|
||||
ADDC(0);
|
||||
ADDC(4);
|
||||
ADDC(8);
|
||||
ADDC(12);
|
||||
LOAD(32);
|
||||
ADDC(20);
|
||||
ADDC(24);
|
||||
ADDC(28);
|
||||
MOP;
|
||||
w += 16;
|
||||
}
|
||||
mlen += 32 + 1;
|
||||
if (mlen >= 32) {
|
||||
ADD(16);
|
||||
ADDC(0);
|
||||
ADDC(4);
|
||||
ADDC(8);
|
||||
ADDC(12);
|
||||
ADDC(20);
|
||||
ADDC(24);
|
||||
ADDC(28);
|
||||
MOP;
|
||||
w += 16;
|
||||
mlen -= 32;
|
||||
}
|
||||
if (mlen >= 16) {
|
||||
ADD(0);
|
||||
ADDC(4);
|
||||
ADDC(8);
|
||||
ADDC(12);
|
||||
MOP;
|
||||
w += 8;
|
||||
mlen -= 16;
|
||||
}
|
||||
if (mlen >= 8) {
|
||||
ADD(0);
|
||||
ADDC(4);
|
||||
MOP;
|
||||
w += 4;
|
||||
mlen -= 8;
|
||||
}
|
||||
if (mlen == 0 && byte_swapped == 0)
|
||||
continue; /* worth 1% maybe ?? */
|
||||
REDUCE;
|
||||
while ((mlen -= 2) >= 0) {
|
||||
sum += *w++;
|
||||
}
|
||||
if (byte_swapped) {
|
||||
REDUCE;
|
||||
sum <<= 8;
|
||||
byte_swapped = 0;
|
||||
if (mlen == -1) {
|
||||
s_util.c[1] = *(char *)w;
|
||||
sum += s_util.s;
|
||||
mlen = 0;
|
||||
} else
|
||||
mlen = -1;
|
||||
} else if (mlen == -1)
|
||||
/*
|
||||
* This mbuf has odd number of bytes.
|
||||
* There could be a word split betwen
|
||||
* this mbuf and the next mbuf.
|
||||
* Save the last byte (to prepend to next mbuf).
|
||||
*/
|
||||
s_util.c[0] = *(char *)w;
|
||||
#else
|
||||
/*
|
||||
* Force to even boundary.
|
||||
*/
|
||||
@ -204,6 +371,7 @@ in4_cksum(m, nxt, off, len)
|
||||
mlen = -1;
|
||||
} else if (mlen == -1)
|
||||
s_util.c[0] = *(u_int8_t *)w;
|
||||
#endif
|
||||
}
|
||||
if (len)
|
||||
printf("cksum4: out of data\n");
|
||||
|
Loading…
Reference in New Issue
Block a user