Commit resolved import of OpenBSD 4.1 pf from perforce.
Approved by: re (kensmith)
This commit is contained in:
parent
b2630c2934
commit
c9a03d91ad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171168
@ -1,6 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.c,v 1.12 2004/05/19 17:50:51 dhartmei Exp $ */
|
||||
|
||||
/* $OpenBSD: if_pflog.c,v 1.22 2006/12/15 09:31:20 otto Exp $ */
|
||||
/*
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr) and
|
||||
@ -38,15 +36,12 @@
|
||||
#ifdef __FreeBSD__
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include "bpfilter.h"
|
||||
#include "pflog.h"
|
||||
#elif __FreeBSD__ >= 5
|
||||
#include "opt_bpf.h"
|
||||
#include "opt_pf.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef DEV_BPF
|
||||
#define NBPFILTER DEV_BPF
|
||||
#else
|
||||
@ -59,14 +54,19 @@
|
||||
#define NPFLOG 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#else /* ! __FreeBSD__ */
|
||||
#include "bpfilter.h"
|
||||
#include "pflog.h"
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sockio.h>
|
||||
@ -75,7 +75,7 @@
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/if_clone.h>
|
||||
#endif
|
||||
#include <net/if_types.h>
|
||||
@ -89,10 +89,6 @@
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <machine/in_cksum.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#ifndef INET
|
||||
#include <netinet/in.h>
|
||||
@ -104,7 +100,7 @@
|
||||
#include <net/if_pflog.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define PFLOGNAME "pflog"
|
||||
#include <machine/in_cksum.h>
|
||||
#endif
|
||||
|
||||
#define PFLOGMTU (32768 + MHLEN + MLEN)
|
||||
@ -115,115 +111,148 @@
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
struct pflog_softc pflogif[NPFLOG];
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static void pflog_clone_destroy(struct ifnet *);
|
||||
static int pflog_clone_create(struct if_clone *, int, caddr_t);
|
||||
#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 *);
|
||||
#ifdef __FreeBSD__
|
||||
static int pflog_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void pflog_clone_destroy(struct ifnet *);
|
||||
#else
|
||||
int pflog_clone_create(struct if_clone *, int);
|
||||
int pflog_clone_destroy(struct ifnet *);
|
||||
#endif
|
||||
|
||||
LIST_HEAD(, pflog_softc) pflogif_list;
|
||||
#ifdef __FreeBSD__
|
||||
IFC_SIMPLE_DECLARE(pflog, 1);
|
||||
#else
|
||||
struct if_clone pflog_cloner =
|
||||
IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
|
||||
#endif
|
||||
|
||||
struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
extern int ifqmaxlen;
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static MALLOC_DEFINE(M_PFLOG, PFLOGNAME, "Packet Filter Logging Interface");
|
||||
static LIST_HEAD(pflog_list, pflog_softc) pflog_list;
|
||||
#define SCP2IFP(sc) ((sc)->sc_ifp)
|
||||
IFC_SIMPLE_DECLARE(pflog, 1);
|
||||
|
||||
static void
|
||||
pflog_clone_destroy(struct ifnet *ifp)
|
||||
void
|
||||
pflogattach(int npflog)
|
||||
{
|
||||
struct pflog_softc *sc;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
|
||||
/*
|
||||
* Does we really need this?
|
||||
*/
|
||||
IF_DRAIN(&ifp->if_snd);
|
||||
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
if_free(ifp);
|
||||
LIST_REMOVE(sc, sc_next);
|
||||
free(sc, M_PFLOG);
|
||||
int i;
|
||||
LIST_INIT(&pflogif_list);
|
||||
for (i = 0; i < PFLOGIFS_MAX; i++)
|
||||
pflogifs[i] = NULL;
|
||||
#ifndef __FreeBSD__
|
||||
(void) pflog_clone_create(&pflog_cloner, 0);
|
||||
#endif
|
||||
if_clone_attach(&pflog_cloner);
|
||||
}
|
||||
|
||||
static int
|
||||
#ifdef __FreeBSD__
|
||||
pflog_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
static int
|
||||
pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param)
|
||||
#else
|
||||
int
|
||||
pflog_clone_create(struct if_clone *ifc, int unit)
|
||||
#endif
|
||||
{
|
||||
struct pflog_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
struct pflog_softc *pflogif;
|
||||
int s;
|
||||
|
||||
MALLOC(sc, struct pflog_softc *, sizeof(*sc), M_PFLOG, M_WAITOK|M_ZERO);
|
||||
ifp = sc->sc_ifp = if_alloc(IFT_PFLOG);
|
||||
if (unit >= PFLOGIFS_MAX)
|
||||
return (EINVAL);
|
||||
|
||||
if ((pflogif = malloc(sizeof(*pflogif), M_DEVBUF, M_NOWAIT)) == NULL)
|
||||
return (ENOMEM);
|
||||
bzero(pflogif, sizeof(*pflogif));
|
||||
|
||||
pflogif->sc_unit = unit;
|
||||
#ifdef __FreeBSD__
|
||||
ifp = pflogif->sc_ifp = if_alloc(IFT_PFLOG);
|
||||
if (ifp == NULL) {
|
||||
free(sc, M_PFLOG);
|
||||
free(pflogif, M_DEVBUF);
|
||||
return (ENOSPC);
|
||||
}
|
||||
|
||||
if_initname(ifp, ifc->ifc_name, unit);
|
||||
#else
|
||||
ifp = &pflogif->sc_if;
|
||||
snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit);
|
||||
#endif
|
||||
ifp->if_softc = pflogif;
|
||||
ifp->if_mtu = PFLOGMTU;
|
||||
ifp->if_ioctl = pflogioctl;
|
||||
ifp->if_output = pflogoutput;
|
||||
ifp->if_start = pflogstart;
|
||||
#ifndef __FreeBSD__
|
||||
ifp->if_type = IFT_PFLOG;
|
||||
#endif
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
ifp->if_hdrlen = PFLOG_HDRLEN;
|
||||
ifp->if_softc = sc;
|
||||
if_attach(ifp);
|
||||
|
||||
LIST_INSERT_HEAD(&pflog_list, sc, sc_next);
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
|
||||
#ifndef __FreeBSD__
|
||||
if_alloc_sadl(ifp);
|
||||
#endif
|
||||
|
||||
#if NBPFILTER > 0
|
||||
#ifdef __FreeBSD__
|
||||
bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
|
||||
#else
|
||||
bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
s = splnet();
|
||||
#ifdef __FreeBSD__
|
||||
PF_LOCK();
|
||||
#endif
|
||||
LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
|
||||
pflogifs[unit] = ifp;
|
||||
#ifdef __FreeBSD__
|
||||
PF_UNLOCK();
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#else /* !__FreeBSD__ */
|
||||
void
|
||||
pflogattach(int npflog)
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static void
|
||||
pflog_clone_destroy(struct ifnet *ifp)
|
||||
#else
|
||||
int
|
||||
pflog_clone_destroy(struct ifnet *ifp)
|
||||
#endif
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
int i;
|
||||
struct pflog_softc *pflogif = ifp->if_softc;
|
||||
int s;
|
||||
|
||||
bzero(pflogif, sizeof(pflogif));
|
||||
|
||||
for (i = 0; i < NPFLOG; i++) {
|
||||
ifp = &pflogif[i].sc_if;
|
||||
snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", i);
|
||||
ifp->if_softc = &pflogif[i];
|
||||
ifp->if_mtu = PFLOGMTU;
|
||||
ifp->if_ioctl = pflogioctl;
|
||||
ifp->if_output = pflogoutput;
|
||||
ifp->if_start = pflogstart;
|
||||
ifp->if_type = IFT_PFLOG;
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
ifp->if_hdrlen = PFLOG_HDRLEN;
|
||||
if_attach(ifp);
|
||||
if_alloc_sadl(ifp);
|
||||
s = splnet();
|
||||
#ifdef __FreeBSD__
|
||||
PF_LOCK();
|
||||
#endif
|
||||
pflogifs[pflogif->sc_unit] = NULL;
|
||||
LIST_REMOVE(pflogif, sc_list);
|
||||
#ifdef __FreeBSD__
|
||||
PF_UNLOCK();
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&pflogif[i].sc_if.if_bpf, ifp, DLT_PFLOG,
|
||||
PFLOG_HDRLEN);
|
||||
bpfdetach(ifp);
|
||||
#endif
|
||||
if_detach(ifp);
|
||||
#ifdef __FreeBSD__
|
||||
if_free(ifp);
|
||||
#endif
|
||||
free(pflogif, M_DEVBUF);
|
||||
#ifndef __FreeBSD__
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
/*
|
||||
* Start output on the pflog interface.
|
||||
@ -241,23 +270,18 @@ pflogstart(struct ifnet *ifp)
|
||||
IF_LOCK(&ifp->if_snd);
|
||||
_IF_DROP(&ifp->if_snd);
|
||||
_IF_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL) {
|
||||
IF_UNLOCK(&ifp->if_snd);
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_freem(m);
|
||||
IF_UNLOCK(&ifp->if_snd);
|
||||
IF_UNLOCK(&ifp->if_snd);
|
||||
#else
|
||||
s = splimp();
|
||||
s = splnet();
|
||||
IF_DROP(&ifp->if_snd);
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
splx(s);
|
||||
#endif
|
||||
|
||||
if (m == NULL)
|
||||
return;
|
||||
else
|
||||
m_freem(m);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,14 +293,6 @@ pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
pflogrtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa)
|
||||
{
|
||||
if (rt)
|
||||
rt->rt_rmx.rmx_mtu = PFLOGMTU;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
@ -308,18 +324,18 @@ pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
int
|
||||
pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
u_int8_t reason, struct pf_rule *rm, struct pf_rule *am,
|
||||
struct pf_ruleset *ruleset)
|
||||
struct pf_ruleset *ruleset, struct pf_pdesc *pd)
|
||||
{
|
||||
#if NBPFILTER > 0
|
||||
struct ifnet *ifn;
|
||||
struct pfloghdr hdr;
|
||||
#ifndef __FreeBSD__
|
||||
struct mbuf m1;
|
||||
#endif
|
||||
|
||||
if (kif == NULL || m == NULL || rm == NULL)
|
||||
if (kif == NULL || m == NULL || rm == NULL || pd == NULL)
|
||||
return (-1);
|
||||
|
||||
if ((ifn = pflogifs[rm->logif]) == NULL || !ifn->if_bpf)
|
||||
return (0);
|
||||
|
||||
bzero(&hdr, sizeof(hdr));
|
||||
hdr.length = PFLOG_REAL_HDRLEN;
|
||||
hdr.af = af;
|
||||
@ -337,6 +353,25 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
strlcpy(hdr.ruleset, ruleset->anchor->name,
|
||||
sizeof(hdr.ruleset));
|
||||
}
|
||||
if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done)
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
* XXX: This should not happen as we force an early lookup
|
||||
* via debug.pfugidhack
|
||||
*/
|
||||
; /* empty */
|
||||
#else
|
||||
pd->lookup.done = pf_socket_lookup(dir, pd);
|
||||
#endif
|
||||
if (pd->lookup.done > 0) {
|
||||
hdr.uid = pd->lookup.uid;
|
||||
hdr.pid = pd->lookup.pid;
|
||||
} else {
|
||||
hdr.uid = UID_MAX;
|
||||
hdr.pid = NO_PID;
|
||||
}
|
||||
hdr.rule_uid = rm->cuid;
|
||||
hdr.rule_pid = rm->cpid;
|
||||
hdr.dir = dir;
|
||||
|
||||
#ifdef INET
|
||||
@ -349,21 +384,13 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
|
||||
}
|
||||
#endif /* INET */
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
m1.m_next = m;
|
||||
m1.m_len = PFLOG_HDRLEN;
|
||||
m1.m_data = (char *) &hdr;
|
||||
#endif
|
||||
|
||||
ifn->if_opackets++;
|
||||
ifn->if_obytes += m->m_pkthdr.len;
|
||||
#ifdef __FreeBSD__
|
||||
KASSERT((!LIST_EMPTY(&pflog_list)), ("pflog: no interface"));
|
||||
ifn = SCP2IFP(LIST_FIRST(&pflog_list));
|
||||
BPF_MTAP2(ifn, &hdr, sizeof(hdr), m);
|
||||
BPF_MTAP2(ifn, &hdr, PFLOG_HDRLEN, m);
|
||||
#else
|
||||
ifn = &(pflogif[0].sc_if);
|
||||
|
||||
if (ifn->if_bpf)
|
||||
bpf_mtap(ifn->if_bpf, &m1);
|
||||
bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
|
||||
BPF_DIRECTION_OUT);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -378,20 +405,17 @@ pflog_modevent(module_t mod, int type, void *data)
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
LIST_INIT(&pflog_list);
|
||||
if_clone_attach(&pflog_cloner);
|
||||
pflogattach(1);
|
||||
PF_LOCK();
|
||||
pflog_packet_ptr = pflog_packet;
|
||||
PF_UNLOCK();
|
||||
break;
|
||||
|
||||
case MOD_UNLOAD:
|
||||
PF_LOCK();
|
||||
pflog_packet_ptr = NULL;
|
||||
PF_UNLOCK();
|
||||
if_clone_detach(&pflog_cloner);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
@ -400,11 +424,7 @@ pflog_modevent(module_t mod, int type, void *data)
|
||||
return error;
|
||||
}
|
||||
|
||||
static moduledata_t pflog_mod = {
|
||||
"pflog",
|
||||
pflog_modevent,
|
||||
0
|
||||
};
|
||||
static moduledata_t pflog_mod = { "pflog", pflog_modevent, 0 };
|
||||
|
||||
#define PFLOG_MODVER 1
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.h,v 1.11 2004/05/19 17:50:51 dhartmei Exp $ */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pflog.h,v 1.14 2006/10/25 11:27:01 henning Exp $ */
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
@ -29,14 +28,19 @@
|
||||
#ifndef _NET_IF_PFLOG_H_
|
||||
#define _NET_IF_PFLOG_H_
|
||||
|
||||
#define PFLOGIFS_MAX 16
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct pflog_softc {
|
||||
#ifdef __FreeBSD__
|
||||
struct ifnet *sc_ifp; /* the interface */
|
||||
LIST_ENTRY(pflog_softc) sc_next;
|
||||
struct ifnet *sc_ifp; /* the interface pointer */
|
||||
#else
|
||||
struct ifnet sc_if; /* the interface */
|
||||
struct ifnet sc_if; /* the interface */
|
||||
#endif
|
||||
int sc_unit;
|
||||
LIST_ENTRY(pflog_softc) sc_list;
|
||||
};
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define PFLOG_RULESET_NAME_SIZE 16
|
||||
|
||||
@ -49,6 +53,10 @@ struct pfloghdr {
|
||||
char ruleset[PFLOG_RULESET_NAME_SIZE];
|
||||
u_int32_t rulenr;
|
||||
u_int32_t subrulenr;
|
||||
uid_t uid;
|
||||
pid_t pid;
|
||||
uid_t rule_uid;
|
||||
pid_t rule_pid;
|
||||
u_int8_t dir;
|
||||
u_int8_t pad[3];
|
||||
};
|
||||
@ -74,20 +82,21 @@ struct old_pfloghdr {
|
||||
struct pf_rule;
|
||||
struct pf_ruleset;
|
||||
struct pfi_kif;
|
||||
struct pf_pdesc;
|
||||
|
||||
typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t,
|
||||
u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *,
|
||||
struct pf_ruleset *);
|
||||
struct pf_ruleset *, struct pf_pdesc *);
|
||||
extern pflog_packet_t *pflog_packet_ptr;
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g) do { \
|
||||
if (pflog_packet_ptr != NULL) \
|
||||
pflog_packet_ptr(i,a,b,c,d,e,f,g); \
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) do { \
|
||||
if (pflog_packet_ptr != NULL) \
|
||||
pflog_packet_ptr(i,a,b,c,d,e,f,g,h); \
|
||||
} while (0)
|
||||
#else
|
||||
#else /* ! __FreeBSD__ */
|
||||
#if NPFLOG > 0
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g) pflog_packet(i,a,b,c,d,e,f,g)
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) pflog_packet(i,a,b,c,d,e,f,g,h)
|
||||
#else
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g) ((void)0)
|
||||
#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) ((void)0)
|
||||
#endif /* NPFLOG > 0 */
|
||||
#endif /* __FreeBSD__ */
|
||||
#endif /* _KERNEL */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: if_pfsync.h,v 1.19 2005/01/20 17:47:38 mcbride Exp $ */
|
||||
/* $OpenBSD: if_pfsync.h,v 1.30 2006/10/31 14:49:01 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Michael Shalayeff
|
||||
@ -36,6 +36,7 @@
|
||||
struct pfsync_state_scrub {
|
||||
u_int16_t pfss_flags;
|
||||
u_int8_t pfss_ttl; /* stashed TTL */
|
||||
#define PFSYNC_SCRUB_FLAG_VALID 0x01
|
||||
u_int8_t scrub_flag;
|
||||
u_int32_t pfss_ts_mod; /* timestamp modulation */
|
||||
} __packed;
|
||||
@ -55,8 +56,7 @@ struct pfsync_state_peer {
|
||||
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];
|
||||
u_int8_t pad[6];
|
||||
} __packed;
|
||||
|
||||
struct pfsync_state {
|
||||
@ -73,8 +73,8 @@ struct pfsync_state {
|
||||
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 packets[2][2];
|
||||
u_int32_t bytes[2][2];
|
||||
u_int32_t creatorid;
|
||||
sa_family_t af;
|
||||
u_int8_t proto;
|
||||
@ -89,6 +89,18 @@ struct pfsync_state {
|
||||
#define PFSYNC_FLAG_COMPRESS 0x01
|
||||
#define PFSYNC_FLAG_STALE 0x02
|
||||
|
||||
#ifdef PFSYNC_TDB
|
||||
struct pfsync_tdb {
|
||||
u_int32_t spi;
|
||||
union sockaddr_union dst;
|
||||
u_int32_t rpl;
|
||||
u_int64_t cur_bytes;
|
||||
u_int8_t sproto;
|
||||
u_int8_t updates;
|
||||
u_int8_t pad[2];
|
||||
} __packed;
|
||||
#endif
|
||||
|
||||
struct pfsync_state_upd {
|
||||
u_int32_t id[2];
|
||||
struct pfsync_state_peer src;
|
||||
@ -144,6 +156,12 @@ union sc_statep {
|
||||
struct pfsync_state_upd_req *r;
|
||||
};
|
||||
|
||||
#ifdef PFSYNC_TDB
|
||||
union sc_tdb_statep {
|
||||
struct pfsync_tdb *t;
|
||||
};
|
||||
#endif
|
||||
|
||||
extern int pfsync_sync_ok;
|
||||
|
||||
struct pfsync_softc {
|
||||
@ -157,10 +175,14 @@ struct pfsync_softc {
|
||||
struct ip_moptions sc_imo;
|
||||
#ifdef __FreeBSD__
|
||||
struct callout sc_tmo;
|
||||
#ifdef PFSYNC_TDB
|
||||
struct callout sc_tdb_tmo;
|
||||
#endif
|
||||
struct callout sc_bulk_tmo;
|
||||
struct callout sc_bulkfail_tmo;
|
||||
#else
|
||||
struct timeout sc_tmo;
|
||||
struct timeout sc_tdb_tmo;
|
||||
struct timeout sc_bulk_tmo;
|
||||
struct timeout sc_bulkfail_tmo;
|
||||
#endif
|
||||
@ -168,28 +190,37 @@ struct pfsync_softc {
|
||||
struct in_addr sc_sendaddr;
|
||||
struct mbuf *sc_mbuf; /* current cumulative mbuf */
|
||||
struct mbuf *sc_mbuf_net; /* current cumulative mbuf */
|
||||
#ifdef PFSYNC_TDB
|
||||
struct mbuf *sc_mbuf_tdb; /* dito for TDB updates */
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
struct ifqueue sc_ifq;
|
||||
struct callout sc_send_tmo;
|
||||
struct task sc_send_task;
|
||||
#endif
|
||||
union sc_statep sc_statep;
|
||||
union sc_statep sc_statep_net;
|
||||
#ifdef PFSYNC_TDB
|
||||
union sc_tdb_statep sc_statep_tdb;
|
||||
#endif
|
||||
u_int32_t sc_ureq_received;
|
||||
u_int32_t sc_ureq_sent;
|
||||
struct pf_state *sc_bulk_send_next;
|
||||
struct pf_state *sc_bulk_terminator;
|
||||
int sc_bulk_tries;
|
||||
int sc_maxcount; /* number of states in mtu */
|
||||
int sc_maxupdates; /* number of updates/state */
|
||||
#ifdef __FreeBSD__
|
||||
LIST_ENTRY(pfsync_softc) sc_next;
|
||||
eventhandler_tag sc_detachtag;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct pfsync_softc *pfsyncif;
|
||||
#endif
|
||||
|
||||
|
||||
struct pfsync_header {
|
||||
u_int8_t version;
|
||||
#define PFSYNC_VERSION 2
|
||||
#define PFSYNC_VERSION 3
|
||||
u_int8_t af;
|
||||
u_int8_t action;
|
||||
#define PFSYNC_ACT_CLR 0 /* clear all states */
|
||||
@ -202,8 +233,10 @@ struct pfsync_header {
|
||||
#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
|
||||
#define PFSYNC_ACT_TDB_UPD 10 /* TDB replay counter update */
|
||||
#define PFSYNC_ACT_MAX 11
|
||||
u_int8_t count;
|
||||
u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
|
||||
} __packed;
|
||||
|
||||
#define PFSYNC_BULKPACKETS 1 /* # of packets per timeout */
|
||||
@ -212,7 +245,7 @@ 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"
|
||||
"UPD REQ", "BLK UPD STAT", "TDB UPD"
|
||||
|
||||
#define PFSYNC_DFLTTL 255
|
||||
|
||||
@ -259,6 +292,13 @@ struct pfsyncreq {
|
||||
(d)->mss = htons((s)->mss); \
|
||||
(d)->state = (s)->state; \
|
||||
(d)->wscale = (s)->wscale; \
|
||||
if ((s)->scrub) { \
|
||||
(d)->scrub.pfss_flags = \
|
||||
htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP); \
|
||||
(d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl; \
|
||||
(d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
|
||||
(d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_peer_ntoh(s,d) do { \
|
||||
@ -269,6 +309,13 @@ struct pfsyncreq {
|
||||
(d)->mss = ntohs((s)->mss); \
|
||||
(d)->state = (s)->state; \
|
||||
(d)->wscale = (s)->wscale; \
|
||||
if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID && \
|
||||
(d)->scrub != NULL) { \
|
||||
(d)->scrub->pfss_flags = \
|
||||
ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP; \
|
||||
(d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl; \
|
||||
(d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_host_hton(s,d) do { \
|
||||
@ -281,6 +328,17 @@ struct pfsyncreq {
|
||||
(d)->port = (s)->port; \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_counter_hton(s,d) do { \
|
||||
d[0] = htonl((s>>32)&0xffffffff); \
|
||||
d[1] = htonl(s&0xffffffff); \
|
||||
} while (0)
|
||||
|
||||
#define pf_state_counter_ntoh(s,d) do { \
|
||||
d = ntohl(s[0]); \
|
||||
d = d<<32; \
|
||||
d += ntohl(s[1]); \
|
||||
} while (0)
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef __FreeBSD__
|
||||
void pfsync_input(struct mbuf *, __unused int);
|
||||
@ -294,7 +352,8 @@ int pfsync_pack_state(u_int8_t, struct pf_state *, int);
|
||||
(st->proto == IPPROTO_PFSYNC)) \
|
||||
st->sync_flags |= PFSTATE_NOSYNC; \
|
||||
else if (!st->sync_flags) \
|
||||
pfsync_pack_state(PFSYNC_ACT_INS, (st), 1); \
|
||||
pfsync_pack_state(PFSYNC_ACT_INS, (st), \
|
||||
PFSYNC_FLAG_COMPRESS); \
|
||||
st->sync_flags &= ~PFSTATE_FROMSYNC; \
|
||||
} while (0)
|
||||
#define pfsync_update_state(st) do { \
|
||||
@ -307,8 +366,10 @@ int pfsync_pack_state(u_int8_t, struct pf_state *, int);
|
||||
if (!st->sync_flags) \
|
||||
pfsync_pack_state(PFSYNC_ACT_DEL, (st), \
|
||||
PFSYNC_FLAG_COMPRESS); \
|
||||
st->sync_flags &= ~PFSTATE_FROMSYNC; \
|
||||
} while (0)
|
||||
#ifdef PFSYNC_TDB
|
||||
int pfsync_update_tdb(struct tdb *, int);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _NET_IF_PFSYNC_H_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_norm.c,v 1.97 2004/09/21 16:59:12 aaron Exp $ */
|
||||
/* add: $OpenBSD: pf_norm.c,v 1.106 2006/03/25 20:55:24 dhartmei Exp $ */
|
||||
/* $OpenBSD: pf_norm.c,v 1.107 2006/04/16 00:59:52 pascoe Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -31,6 +29,10 @@
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#include "opt_pf.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef DEV_PFLOG
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#else
|
||||
@ -493,7 +495,7 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
|
||||
break;
|
||||
}
|
||||
|
||||
/* This fragment is completely overlapped, loose it */
|
||||
/* This fragment is completely overlapped, lose it */
|
||||
next = LIST_NEXT(frea, fr_next);
|
||||
m_freem(frea->fr_m);
|
||||
LIST_REMOVE(frea, fr_next);
|
||||
@ -966,8 +968,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
|
||||
while (r != NULL) {
|
||||
r->evaluations++;
|
||||
if (r->kif != NULL &&
|
||||
(r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
|
||||
if (pfi_kif_match(r->kif, kif) == r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != dir)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
@ -976,19 +977,23 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
else if (r->proto && r->proto != h->ip_p)
|
||||
r = r->skip[PF_SKIP_PROTO].ptr;
|
||||
else if (PF_MISMATCHAW(&r->src.addr,
|
||||
(struct pf_addr *)&h->ip_src.s_addr, AF_INET, r->src.neg))
|
||||
(struct pf_addr *)&h->ip_src.s_addr, AF_INET,
|
||||
r->src.neg, kif))
|
||||
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
|
||||
else if (PF_MISMATCHAW(&r->dst.addr,
|
||||
(struct pf_addr *)&h->ip_dst.s_addr, AF_INET, r->dst.neg))
|
||||
(struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
|
||||
r->dst.neg, NULL))
|
||||
r = r->skip[PF_SKIP_DST_ADDR].ptr;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (r == NULL)
|
||||
if (r == NULL || r->action == PF_NOSCRUB)
|
||||
return (PF_PASS);
|
||||
else
|
||||
r->packets++;
|
||||
else {
|
||||
r->packets[dir == PF_OUT]++;
|
||||
r->bytes[dir == PF_OUT] += pd->tot_len;
|
||||
}
|
||||
|
||||
/* Check for illegal packets */
|
||||
if (hlen < (int)sizeof(struct ip))
|
||||
@ -1061,6 +1066,18 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
if (m == NULL)
|
||||
return (PF_DROP);
|
||||
|
||||
/* use mtag from concatenated mbuf chain */
|
||||
pd->pf_mtag = pf_find_mtag(m);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (pd->pf_mtag == NULL) {
|
||||
printf("%s: pf_find_mtag returned NULL(1)\n", __func__);
|
||||
if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
|
||||
m_freem(m);
|
||||
*m0 = NULL;
|
||||
goto no_mem;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
|
||||
goto drop;
|
||||
|
||||
@ -1069,15 +1086,13 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
/* non-buffering fragment cache (drops or masks overlaps) */
|
||||
int nomem = 0;
|
||||
|
||||
if (dir == PF_OUT) {
|
||||
if (m_tag_find(m, PACKET_TAG_PF_FRAGCACHE, NULL) !=
|
||||
NULL) {
|
||||
/* Already passed the fragment cache in the
|
||||
* input direction. If we continued, it would
|
||||
* appear to be a dup and would be dropped.
|
||||
*/
|
||||
goto fragment_pass;
|
||||
}
|
||||
if (dir == PF_OUT && pd->pf_mtag->flags & PF_TAG_FRAGCACHE) {
|
||||
/*
|
||||
* Already passed the fragment cache in the
|
||||
* input direction. If we continued, it would
|
||||
* appear to be a dup and would be dropped.
|
||||
*/
|
||||
goto fragment_pass;
|
||||
}
|
||||
|
||||
frag = pf_find_fragment(h, &pf_cache_tree);
|
||||
@ -1098,14 +1113,21 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (dir == PF_IN) {
|
||||
struct m_tag *mtag;
|
||||
|
||||
mtag = m_tag_get(PACKET_TAG_PF_FRAGCACHE, 0, M_NOWAIT);
|
||||
if (mtag == NULL)
|
||||
/* use mtag from copied and trimmed mbuf chain */
|
||||
pd->pf_mtag = pf_find_mtag(m);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (pd->pf_mtag == NULL) {
|
||||
printf("%s: pf_find_mtag returned NULL(2)\n", __func__);
|
||||
if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
|
||||
m_freem(m);
|
||||
*m0 = NULL;
|
||||
goto no_mem;
|
||||
m_tag_prepend(m, mtag);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (dir == PF_IN)
|
||||
pd->pf_mtag->flags |= PF_TAG_FRAGCACHE;
|
||||
|
||||
if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
|
||||
goto drop;
|
||||
goto fragment_pass;
|
||||
@ -1154,13 +1176,13 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
no_mem:
|
||||
REASON_SET(reason, PFRES_MEMORY);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
|
||||
return (PF_DROP);
|
||||
|
||||
drop:
|
||||
REASON_SET(reason, PFRES_NORM);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
|
||||
return (PF_DROP);
|
||||
|
||||
bad:
|
||||
@ -1172,7 +1194,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
|
||||
REASON_SET(reason, PFRES_FRAG);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
|
||||
|
||||
return (PF_DROP);
|
||||
}
|
||||
@ -1200,8 +1222,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
|
||||
while (r != NULL) {
|
||||
r->evaluations++;
|
||||
if (r->kif != NULL &&
|
||||
(r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
|
||||
if (pfi_kif_match(r->kif, kif) == r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != dir)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
@ -1212,19 +1233,23 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
|
||||
r = r->skip[PF_SKIP_PROTO].ptr;
|
||||
#endif
|
||||
else if (PF_MISMATCHAW(&r->src.addr,
|
||||
(struct pf_addr *)&h->ip6_src, AF_INET6, r->src.neg))
|
||||
(struct pf_addr *)&h->ip6_src, AF_INET6,
|
||||
r->src.neg, kif))
|
||||
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
|
||||
else if (PF_MISMATCHAW(&r->dst.addr,
|
||||
(struct pf_addr *)&h->ip6_dst, AF_INET6, r->dst.neg))
|
||||
(struct pf_addr *)&h->ip6_dst, AF_INET6,
|
||||
r->dst.neg, NULL))
|
||||
r = r->skip[PF_SKIP_DST_ADDR].ptr;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (r == NULL)
|
||||
if (r == NULL || r->action == PF_NOSCRUB)
|
||||
return (PF_PASS);
|
||||
else
|
||||
r->packets++;
|
||||
else {
|
||||
r->packets[dir == PF_OUT]++;
|
||||
r->bytes[dir == PF_OUT] += pd->tot_len;
|
||||
}
|
||||
|
||||
/* Check for illegal packets */
|
||||
if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len)
|
||||
@ -1336,19 +1361,19 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
|
||||
shortpkt:
|
||||
REASON_SET(reason, PFRES_SHORT);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
|
||||
return (PF_DROP);
|
||||
|
||||
drop:
|
||||
REASON_SET(reason, PFRES_NORM);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
|
||||
return (PF_DROP);
|
||||
|
||||
badfrag:
|
||||
REASON_SET(reason, PFRES_FRAG);
|
||||
if (r != NULL && r->log)
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
|
||||
return (PF_DROP);
|
||||
}
|
||||
#endif /* INET6 */
|
||||
@ -1367,8 +1392,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
|
||||
while (r != NULL) {
|
||||
r->evaluations++;
|
||||
if (r->kif != NULL &&
|
||||
(r->kif != kif && r->kif != kif->pfik_parent) == !r->ifnot)
|
||||
if (pfi_kif_match(r->kif, kif) == r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != dir)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
@ -1376,12 +1400,14 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
|
||||
r = r->skip[PF_SKIP_AF].ptr;
|
||||
else if (r->proto && r->proto != pd->proto)
|
||||
r = r->skip[PF_SKIP_PROTO].ptr;
|
||||
else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, r->src.neg))
|
||||
else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
|
||||
r->src.neg, kif))
|
||||
r = r->skip[PF_SKIP_SRC_ADDR].ptr;
|
||||
else if (r->src.port_op && !pf_match_port(r->src.port_op,
|
||||
r->src.port[0], r->src.port[1], th->th_sport))
|
||||
r = r->skip[PF_SKIP_SRC_PORT].ptr;
|
||||
else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, r->dst.neg))
|
||||
else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
|
||||
r->dst.neg, NULL))
|
||||
r = r->skip[PF_SKIP_DST_ADDR].ptr;
|
||||
else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
|
||||
r->dst.port[0], r->dst.port[1], th->th_dport))
|
||||
@ -1398,8 +1424,10 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
|
||||
|
||||
if (rm == NULL || rm->action == PF_NOSCRUB)
|
||||
return (PF_PASS);
|
||||
else
|
||||
r->packets++;
|
||||
else {
|
||||
r->packets[dir == PF_OUT]++;
|
||||
r->bytes[dir == PF_OUT] += pd->tot_len;
|
||||
}
|
||||
|
||||
if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
|
||||
pd->flags |= PFDESC_TCP_NORM;
|
||||
@ -1461,7 +1489,7 @@ pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
|
||||
tcp_drop:
|
||||
REASON_SET(&reason, PFRES_NORM);
|
||||
if (rm != NULL && r->log)
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL);
|
||||
PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL, pd);
|
||||
return (PF_DROP);
|
||||
}
|
||||
|
||||
@ -1931,7 +1959,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
* timestamps. And require all data packets to contain a timestamp
|
||||
* if the first does. PAWS implicitly requires that all data packets be
|
||||
* timestamped. But I think there are middle-man devices that hijack
|
||||
* TCP streams immedietly after the 3whs and don't timestamp their
|
||||
* TCP streams immediately after the 3whs and don't timestamp their
|
||||
* packets (seen in a WWW accelerator or cache).
|
||||
*/
|
||||
if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_osfp.c,v 1.10 2004/04/09 19:30:41 frantzen Exp $ */
|
||||
/* $OpenBSD: pf_osfp.c,v 1.12 2006/12/13 18:14:10 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
|
||||
@ -18,6 +17,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef _KERNEL
|
||||
@ -33,9 +37,10 @@
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet/ip6.h>
|
||||
#endif /* INET6 */
|
||||
#ifdef _KERNEL
|
||||
#include <netinet6/in6_var.h>
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
# define DPFPRINTF(format, x...) \
|
||||
@ -55,6 +60,7 @@ typedef struct pool pool_t;
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <netdb.h>
|
||||
# define pool_t int
|
||||
# define pool_get(pool, flags) malloc(*(pool))
|
||||
# define pool_put(pool, item) free(item)
|
||||
@ -95,38 +101,96 @@ pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off,
|
||||
const struct tcphdr *tcp)
|
||||
{
|
||||
struct ip *ip;
|
||||
struct ip6_hdr *ip6;
|
||||
char hdr[60];
|
||||
|
||||
/* XXX don't have a fingerprint database for IPv6 :-( */
|
||||
if (pd->af != PF_INET || pd->proto != IPPROTO_TCP || (tcp->th_off << 2)
|
||||
< sizeof(*tcp))
|
||||
if ((pd->af != PF_INET && pd->af != PF_INET6) ||
|
||||
pd->proto != IPPROTO_TCP || (tcp->th_off << 2) < sizeof(*tcp))
|
||||
return (NULL);
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL, pd->af))
|
||||
return (NULL);
|
||||
if (pd->af == PF_INET) {
|
||||
ip = mtod(m, struct ip *);
|
||||
ip6 = (struct ip6_hdr *)NULL;
|
||||
} else {
|
||||
ip = (struct ip *)NULL;
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
}
|
||||
if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL,
|
||||
pd->af)) return (NULL);
|
||||
|
||||
return (pf_osfp_fingerprint_hdr(ip, (struct tcphdr *)hdr));
|
||||
return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr));
|
||||
}
|
||||
#endif /* _KERNEL */
|
||||
|
||||
struct pf_osfp_enlist *
|
||||
pf_osfp_fingerprint_hdr(const struct ip *ip, const struct tcphdr *tcp)
|
||||
pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcp)
|
||||
{
|
||||
struct pf_os_fingerprint fp, *fpresult;
|
||||
int cnt, optlen = 0;
|
||||
const u_int8_t *optp;
|
||||
#ifdef _KERNEL
|
||||
char srcname[128];
|
||||
#else
|
||||
char srcname[NI_MAXHOST];
|
||||
#endif
|
||||
|
||||
if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN || (ip->ip_off &
|
||||
htons(IP_OFFMASK)))
|
||||
if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN)
|
||||
return (NULL);
|
||||
if (ip) {
|
||||
if ((ip->ip_off & htons(IP_OFFMASK)) != 0)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memset(&fp, 0, sizeof(fp));
|
||||
|
||||
fp.fp_psize = ntohs(ip->ip_len);
|
||||
fp.fp_ttl = ip->ip_ttl;
|
||||
if (ip->ip_off & htons(IP_DF))
|
||||
if (ip) {
|
||||
#ifndef _KERNEL
|
||||
struct sockaddr_in sin;
|
||||
#endif
|
||||
|
||||
fp.fp_psize = ntohs(ip->ip_len);
|
||||
fp.fp_ttl = ip->ip_ttl;
|
||||
if (ip->ip_off & htons(IP_DF))
|
||||
fp.fp_flags |= PF_OSFP_DF;
|
||||
#ifdef _KERNEL
|
||||
strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname));
|
||||
#else
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_addr = ip->ip_src;
|
||||
(void)getnameinfo((struct sockaddr *)&sin,
|
||||
sizeof(struct sockaddr_in), srcname, sizeof(srcname),
|
||||
NULL, 0, NI_NUMERICHOST);
|
||||
#endif
|
||||
}
|
||||
#ifdef INET6
|
||||
else if (ip6) {
|
||||
#ifndef _KERNEL
|
||||
struct sockaddr_in6 sin6;
|
||||
#endif
|
||||
|
||||
/* jumbo payload? */
|
||||
fp.fp_psize = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
|
||||
fp.fp_ttl = ip6->ip6_hlim;
|
||||
fp.fp_flags |= PF_OSFP_DF;
|
||||
fp.fp_flags |= PF_OSFP_INET6;
|
||||
#ifdef _KERNEL
|
||||
strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src),
|
||||
sizeof(srcname));
|
||||
#else
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
sin6.sin6_addr = ip6->ip6_src;
|
||||
(void)getnameinfo((struct sockaddr *)&sin6,
|
||||
sizeof(struct sockaddr_in6), srcname, sizeof(srcname),
|
||||
NULL, 0, NI_NUMERICHOST);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return (NULL);
|
||||
fp.fp_wsize = ntohs(tcp->th_win);
|
||||
|
||||
|
||||
@ -189,7 +253,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct tcphdr *tcp)
|
||||
|
||||
DPFPRINTF("fingerprinted %s:%d %d:%d:%d:%d:%llx (%d) "
|
||||
"(TS=%s,M=%s%d,W=%s%d)\n",
|
||||
inet_ntoa(ip->ip_src), ntohs(tcp->th_sport),
|
||||
srcname, ntohs(tcp->th_sport),
|
||||
fp.fp_wsize, fp.fp_ttl, (fp.fp_flags & PF_OSFP_DF) != 0,
|
||||
fp.fp_psize, (long long int)fp.fp_tcpopts, fp.fp_optcnt,
|
||||
(fp.fp_flags & PF_OSFP_TS0) ? "0" : "",
|
||||
|
@ -35,6 +35,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef _KERNEL
|
||||
@ -59,7 +64,11 @@
|
||||
# define DPFPRINTF(format, x...) \
|
||||
if (pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#ifdef __FreeBSD__
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_NOWAIT)
|
||||
#else
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_WAITOK)
|
||||
#endif
|
||||
#define rs_free(x) free(x, M_TEMP)
|
||||
|
||||
#else
|
||||
@ -85,6 +94,8 @@
|
||||
struct pf_anchor_global pf_anchors;
|
||||
struct pf_anchor pf_main_anchor;
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
/* XXX: hum? */
|
||||
int pf_get_ruleset_number(u_int8_t);
|
||||
void pf_init_ruleset(struct pf_ruleset *);
|
||||
int pf_anchor_setup(struct pf_rule *,
|
||||
@ -92,6 +103,7 @@ int pf_anchor_setup(struct pf_rule *,
|
||||
int pf_anchor_copyout(const struct pf_ruleset *,
|
||||
const struct pf_rule *, struct pfioc_rule *);
|
||||
void pf_anchor_remove(struct pf_rule *);
|
||||
#endif
|
||||
|
||||
static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
|
||||
|
||||
@ -184,7 +196,11 @@ pf_find_or_create_ruleset(const char *path)
|
||||
{
|
||||
char *p, *q, *r;
|
||||
struct pf_ruleset *ruleset;
|
||||
#ifdef __FreeBSD__
|
||||
struct pf_anchor *anchor = NULL, *dup, *parent = NULL;
|
||||
#else
|
||||
struct pf_anchor *anchor, *dup, *parent = NULL;
|
||||
#endif
|
||||
|
||||
if (path[0] == 0)
|
||||
return (&pf_main_ruleset);
|
||||
|
@ -1,15 +1,6 @@
|
||||
/* $FreeBSD$ */
|
||||
/* from $OpenBSD: kern_subr.c,v 1.26 2003/10/31 11:10:41 markus Exp $ */
|
||||
/* $NetBSD: kern_subr.c,v 1.15 1996/04/09 17:21:56 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -19,7 +10,7 @@
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -35,93 +26,143 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/md5.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_seq.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <net/pfvar.h>
|
||||
|
||||
/*
|
||||
* This implements additional functions used by pf which can not be ported
|
||||
* easyly. At this point it boils down to mostly the Net/OpenBSD hook
|
||||
* implementation.
|
||||
* Following is where TCP initial sequence number generation occurs.
|
||||
*
|
||||
* BEWARE: this is not locked! Required locking is done by the caller.
|
||||
* There are two places where we must use initial sequence numbers:
|
||||
* 1. In SYN-ACK packets.
|
||||
* 2. In SYN packets.
|
||||
*
|
||||
* All ISNs for SYN-ACK packets are generated by the syncache. See
|
||||
* tcp_syncache.c for details.
|
||||
*
|
||||
* The ISNs in SYN packets must be monotonic; TIME_WAIT recycling
|
||||
* depends on this property. In addition, these ISNs should be
|
||||
* unguessable so as to prevent connection hijacking. To satisfy
|
||||
* the requirements of this situation, the algorithm outlined in
|
||||
* RFC 1948 is used, with only small modifications.
|
||||
*
|
||||
* Implementation details:
|
||||
*
|
||||
* Time is based off the system timer, and is corrected so that it
|
||||
* increases by one megabyte per second. This allows for proper
|
||||
* recycling on high speed LANs while still leaving over an hour
|
||||
* before rollover.
|
||||
*
|
||||
* As reading the *exact* system time is too expensive to be done
|
||||
* whenever setting up a TCP connection, we increment the time
|
||||
* offset in two ways. First, a small random positive increment
|
||||
* is added to isn_offset for each connection that is set up.
|
||||
* Second, the function tcp_isn_tick fires once per clock tick
|
||||
* and increments isn_offset as necessary so that sequence numbers
|
||||
* are incremented at approximately ISN_BYTES_PER_SECOND. The
|
||||
* random positive increments serve only to ensure that the same
|
||||
* exact sequence number is never sent out twice (as could otherwise
|
||||
* happen when a port is recycled in less than the system tick
|
||||
* interval.)
|
||||
*
|
||||
* net.inet.tcp.isn_reseed_interval controls the number of seconds
|
||||
* between seeding of isn_secret. This is normally set to zero,
|
||||
* as reseeding should not be necessary.
|
||||
*
|
||||
* Locking of the global variables isn_secret, isn_last_reseed, isn_offset,
|
||||
* isn_offset_old, and isn_ctx is performed using the TCP pcbinfo lock. In
|
||||
* general, this means holding an exclusive (write) lock.
|
||||
*/
|
||||
|
||||
void *
|
||||
hook_establish(struct hook_desc_head *head, int tail, void (*fn)(void *),
|
||||
void *arg)
|
||||
#define ISN_BYTES_PER_SECOND 1048576
|
||||
#define ISN_STATIC_INCREMENT 4096
|
||||
#define ISN_RANDOM_INCREMENT (4096 - 1)
|
||||
|
||||
static u_char isn_secret[32];
|
||||
static int isn_last_reseed;
|
||||
static u_int32_t isn_offset, isn_offset_old;
|
||||
static MD5_CTX isn_ctx;
|
||||
|
||||
u_int32_t
|
||||
pf_new_isn(struct pf_state *s)
|
||||
{
|
||||
struct hook_desc *hdp;
|
||||
u_int32_t md5_buffer[4];
|
||||
u_int32_t new_isn;
|
||||
struct pf_state_host *src, *dst;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
hook_disestablish(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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run hooks. Startup hooks are invoked right after scheduler_start but
|
||||
* before root is mounted. Shutdown hooks are invoked immediately before the
|
||||
* system is halted or rebooted, i.e. after file systems unmounted,
|
||||
* after crash dump done, etc.
|
||||
*/
|
||||
void
|
||||
dohooks(struct hook_desc_head *head, int flags)
|
||||
{
|
||||
struct hook_desc *hdp;
|
||||
|
||||
if ((flags & HOOK_REMOVE) == 0) {
|
||||
TAILQ_FOREACH(hdp, head, hd_list) {
|
||||
(*hdp->hd_fn)(hdp->hd_arg);
|
||||
}
|
||||
} else {
|
||||
while ((hdp = TAILQ_FIRST(head)) != NULL) {
|
||||
TAILQ_REMOVE(head, hdp, hd_list);
|
||||
(*hdp->hd_fn)(hdp->hd_arg);
|
||||
if ((flags & HOOK_FREE) != 0)
|
||||
free(hdp, M_DEVBUF);
|
||||
}
|
||||
/* Seed if this is the first use, reseed if requested. */
|
||||
if (isn_last_reseed == 0) {
|
||||
read_random(&isn_secret, sizeof(isn_secret));
|
||||
isn_last_reseed = ticks;
|
||||
}
|
||||
|
||||
if (s->direction == PF_IN) {
|
||||
src = &s->ext;
|
||||
dst = &s->gwy;
|
||||
} else {
|
||||
src = &s->lan;
|
||||
dst = &s->ext;
|
||||
}
|
||||
|
||||
/* Compute the md5 hash and return the ISN. */
|
||||
MD5Init(&isn_ctx);
|
||||
MD5Update(&isn_ctx, (u_char *) &dst->port, sizeof(u_short));
|
||||
MD5Update(&isn_ctx, (u_char *) &src->port, sizeof(u_short));
|
||||
#ifdef INET6
|
||||
if (s->af == AF_INET6) {
|
||||
MD5Update(&isn_ctx, (u_char *) &dst->addr,
|
||||
sizeof(struct in6_addr));
|
||||
MD5Update(&isn_ctx, (u_char *) &src->addr,
|
||||
sizeof(struct in6_addr));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
MD5Update(&isn_ctx, (u_char *) &dst->addr,
|
||||
sizeof(struct in_addr));
|
||||
MD5Update(&isn_ctx, (u_char *) &src->addr,
|
||||
sizeof(struct in_addr));
|
||||
}
|
||||
MD5Update(&isn_ctx, (u_char *) &isn_secret, sizeof(isn_secret));
|
||||
MD5Final((u_char *) &md5_buffer, &isn_ctx);
|
||||
new_isn = (tcp_seq) md5_buffer[0];
|
||||
isn_offset += ISN_STATIC_INCREMENT +
|
||||
(arc4random() & ISN_RANDOM_INCREMENT);
|
||||
new_isn += isn_offset;
|
||||
return (new_isn);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pf_table.c,v 1.62 2004/12/07 18:02:04 mcbride Exp $ */
|
||||
/* $OpenBSD: pf_table.c,v 1.68 2006/05/02 10:08:45 dhartmei Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Cedric Berger
|
||||
@ -34,6 +33,9 @@
|
||||
#ifdef __FreeBSD__
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -465,7 +467,8 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
|
||||
int
|
||||
pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
int *size2, int *nadd, int *ndel, int *nchange, int flags)
|
||||
int *size2, int *nadd, int *ndel, int *nchange, int flags,
|
||||
u_int32_t ignore_pfrt_flags)
|
||||
{
|
||||
struct pfr_ktable *kt, *tmpkt;
|
||||
struct pfr_kentryworkq addq, delq, changeq;
|
||||
@ -475,7 +478,8 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
long tzero = time_second;
|
||||
|
||||
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY+PFR_FLAG_FEEDBACK);
|
||||
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
|
||||
if (pfr_validate_table(tbl, ignore_pfrt_flags, flags &
|
||||
PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
kt = pfr_lookup_table(tbl);
|
||||
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
|
||||
@ -875,13 +879,10 @@ 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);
|
||||
#ifdef __FreeBSD__
|
||||
PF_ASSERT(MA_OWNED);
|
||||
#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;
|
||||
@ -1079,17 +1080,14 @@ 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);
|
||||
#ifdef __FreeBSD__
|
||||
PF_ASSERT(MA_OWNED);
|
||||
#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);
|
||||
@ -1109,8 +1107,8 @@ 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);
|
||||
#ifdef __FreeBSD__
|
||||
PF_ASSERT(MA_OWNED);
|
||||
#endif
|
||||
if (KENTRY_NETWORK(ke)) {
|
||||
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
|
||||
@ -1124,9 +1122,6 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
|
||||
rn = rn_delete(&ke->pfrke_sa, NULL, head);
|
||||
#else
|
||||
rn = rn_delete(&ke->pfrke_sa, NULL, head, NULL);
|
||||
#endif
|
||||
#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
|
||||
RADIX_NODE_HEAD_UNLOCK(head);
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
@ -2182,7 +2177,7 @@ pfr_attach_table(struct pf_ruleset *rs, char *name)
|
||||
bzero(&tbl, sizeof(tbl));
|
||||
strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name));
|
||||
if (ac != NULL)
|
||||
strlcpy(tbl.pfrt_anchor, ac->name, sizeof(tbl.pfrt_anchor));
|
||||
strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor));
|
||||
kt = pfr_lookup_table(&tbl);
|
||||
if (kt == NULL) {
|
||||
kt = pfr_create_ktable(&tbl, time_second, 1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: pfvar.h,v 1.213 2005/03/03 07:13:39 dhartmei Exp $ */
|
||||
/* $OpenBSD: pfvar.h,v 1.244 2007/02/23 21:31:51 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -38,11 +38,18 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/tree.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/lock.h>
|
||||
#include <sys/sx.h>
|
||||
#else
|
||||
#include <sys/rwlock.h>
|
||||
#endif
|
||||
|
||||
#include <net/radix.h>
|
||||
#include <net/route.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/if_clone.h>
|
||||
#include <net/pf_mtag.h>
|
||||
#include <vm/uma.h>
|
||||
#else
|
||||
#include <netinet/ip_ipsp.h>
|
||||
@ -55,6 +62,7 @@
|
||||
#include <netinet/tcp_fsm.h>
|
||||
|
||||
struct ip;
|
||||
struct ip6_hdr;
|
||||
#ifdef __FreeBSD__
|
||||
struct inpcb;
|
||||
#endif
|
||||
@ -62,6 +70,13 @@ struct inpcb;
|
||||
#define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0)
|
||||
#define PF_TCPS_PROXY_DST ((TCP_NSTATES)+1)
|
||||
|
||||
#define PF_MD5_DIGEST_LENGTH 16
|
||||
#ifdef MD5_DIGEST_LENGTH
|
||||
#if PF_MD5_DIGEST_LENGTH != MD5_DIGEST_LENGTH
|
||||
#error
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum { PF_INOUT, PF_IN, PF_OUT };
|
||||
enum { PF_LAN_EXT, PF_EXT_GWY, PF_ID };
|
||||
enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
|
||||
@ -74,6 +89,8 @@ enum { PF_DEBUG_NONE, PF_DEBUG_URGENT, PF_DEBUG_MISC, PF_DEBUG_NOISY };
|
||||
enum { PF_CHANGE_NONE, PF_CHANGE_ADD_HEAD, PF_CHANGE_ADD_TAIL,
|
||||
PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER,
|
||||
PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET };
|
||||
enum { PF_GET_NONE, PF_GET_CLR_CNTR };
|
||||
|
||||
/*
|
||||
* Note about PFTM_*: real indices into pf_rule.timeout[] come before
|
||||
* PFTM_MAX, special cases afterwards. See pf_state_expires().
|
||||
@ -85,7 +102,8 @@ enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED,
|
||||
PFTM_OTHER_FIRST_PACKET, PFTM_OTHER_SINGLE,
|
||||
PFTM_OTHER_MULTIPLE, PFTM_FRAG, PFTM_INTERVAL,
|
||||
PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_SRC_NODE,
|
||||
PFTM_TS_DIFF, PFTM_MAX, PFTM_PURGE, PFTM_UNTIL_PACKET };
|
||||
PFTM_TS_DIFF, PFTM_MAX, PFTM_PURGE, PFTM_UNLINKED,
|
||||
PFTM_UNTIL_PACKET };
|
||||
|
||||
/* PFTM default values */
|
||||
#define PFTM_TCP_FIRST_PACKET_VAL 120 /* First TCP packet */
|
||||
@ -108,17 +126,22 @@ enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED,
|
||||
#define PFTM_TS_DIFF_VAL 30 /* Allowed TS diff */
|
||||
|
||||
enum { PF_NOPFROUTE, PF_FASTROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO };
|
||||
enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS, PF_LIMIT_MAX };
|
||||
enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS,
|
||||
PF_LIMIT_TABLES, PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
|
||||
#define PF_POOL_IDMASK 0x0f
|
||||
enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
|
||||
PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
|
||||
enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
|
||||
PF_ADDR_TABLE, PF_ADDR_RTLABEL };
|
||||
PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED };
|
||||
#define PF_POOL_TYPEMASK 0x0f
|
||||
#define PF_POOL_STICKYADDR 0x20
|
||||
#define PF_WSCALE_FLAG 0x80
|
||||
#define PF_WSCALE_MASK 0x0f
|
||||
|
||||
#define PF_LOG 0x01
|
||||
#define PF_LOG_ALL 0x02
|
||||
#define PF_LOG_SOCKET_LOOKUP 0x04
|
||||
|
||||
struct pf_addr {
|
||||
union {
|
||||
struct in_addr v4;
|
||||
@ -169,18 +192,19 @@ struct pf_addr_wrap {
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct pfi_dynaddr {
|
||||
struct pf_addr pfid_addr4;
|
||||
struct pf_addr pfid_mask4;
|
||||
struct pf_addr pfid_addr6;
|
||||
struct pf_addr pfid_mask6;
|
||||
struct pfr_ktable *pfid_kt;
|
||||
struct pfi_kif *pfid_kif;
|
||||
void *pfid_hook_cookie;
|
||||
int pfid_net; /* optional mask, or 128 */
|
||||
int pfid_acnt4; /* address count, IPv4 */
|
||||
int pfid_acnt6; /* address count, IPv6 */
|
||||
sa_family_t pfid_af; /* rule address family */
|
||||
u_int8_t pfid_iflags; /* PFI_AFLAG_* */
|
||||
TAILQ_ENTRY(pfi_dynaddr) entry;
|
||||
struct pf_addr pfid_addr4;
|
||||
struct pf_addr pfid_mask4;
|
||||
struct pf_addr pfid_addr6;
|
||||
struct pf_addr pfid_mask6;
|
||||
struct pfr_ktable *pfid_kt;
|
||||
struct pfi_kif *pfid_kif;
|
||||
void *pfid_hook_cookie;
|
||||
int pfid_net; /* mask or 128 */
|
||||
int pfid_acnt4; /* address count IPv4 */
|
||||
int pfid_acnt6; /* address count IPv6 */
|
||||
sa_family_t pfid_af; /* rule af */
|
||||
u_int8_t pfid_iflags; /* PFI_AFLAG_* */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -246,21 +270,6 @@ extern void destroy_pf_mutex(void);
|
||||
#define PFSYNC_MINVER 1
|
||||
#define PFSYNC_PREFVER PFSYNC_MODVER
|
||||
#define PFSYNC_MAXVER 1
|
||||
|
||||
/* prototyped for pf_subr.c */
|
||||
struct hook_desc {
|
||||
TAILQ_ENTRY(hook_desc) hd_list;
|
||||
void (*hd_fn)(void *);
|
||||
void *hd_arg;
|
||||
};
|
||||
TAILQ_HEAD(hook_desc_head, hook_desc);
|
||||
|
||||
void *hook_establish(struct hook_desc_head *, int, void (*)(void *), void *);
|
||||
void hook_disestablish(struct hook_desc_head *, void *);
|
||||
void dohooks(struct hook_desc_head *, int);
|
||||
|
||||
#define HOOK_REMOVE 0x01
|
||||
#define HOOK_FREE 0x02
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#ifdef INET
|
||||
@ -392,23 +401,26 @@ void dohooks(struct hook_desc_head *, int);
|
||||
#endif /* PF_INET6_ONLY */
|
||||
#endif /* PF_INET_INET6 */
|
||||
|
||||
#define PF_MISMATCHAW(aw, x, af, neg) \
|
||||
( \
|
||||
(((aw)->type == PF_ADDR_NOROUTE && \
|
||||
pf_routable((x), (af))) || \
|
||||
((aw)->type == PF_ADDR_RTLABEL && \
|
||||
!pf_rtlabel_match((x), (af), (aw))) || \
|
||||
((aw)->type == PF_ADDR_TABLE && \
|
||||
!pfr_match_addr((aw)->p.tbl, (x), (af))) || \
|
||||
((aw)->type == PF_ADDR_DYNIFTL && \
|
||||
!pfi_match_addr((aw)->p.dyn, (x), (af))) || \
|
||||
((aw)->type == PF_ADDR_ADDRMASK && \
|
||||
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
|
||||
!PF_MATCHA(0, &(aw)->v.a.addr, \
|
||||
&(aw)->v.a.mask, (x), (af)))) != \
|
||||
(neg) \
|
||||
#define PF_MISMATCHAW(aw, x, af, neg, ifp) \
|
||||
( \
|
||||
(((aw)->type == PF_ADDR_NOROUTE && \
|
||||
pf_routable((x), (af), NULL)) || \
|
||||
(((aw)->type == PF_ADDR_URPFFAILED && (ifp) != NULL && \
|
||||
pf_routable((x), (af), (ifp))) || \
|
||||
((aw)->type == PF_ADDR_RTLABEL && \
|
||||
!pf_rtlabel_match((x), (af), (aw))) || \
|
||||
((aw)->type == PF_ADDR_TABLE && \
|
||||
!pfr_match_addr((aw)->p.tbl, (x), (af))) || \
|
||||
((aw)->type == PF_ADDR_DYNIFTL && \
|
||||
!pfi_match_addr((aw)->p.dyn, (x), (af))) || \
|
||||
((aw)->type == PF_ADDR_ADDRMASK && \
|
||||
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
|
||||
!PF_MATCHA(0, &(aw)->v.a.addr, \
|
||||
&(aw)->v.a.mask, (x), (af))))) != \
|
||||
(neg) \
|
||||
)
|
||||
|
||||
|
||||
struct pf_rule_uid {
|
||||
uid_t uid[2];
|
||||
u_int8_t op;
|
||||
@ -526,6 +538,7 @@ struct pf_os_fingerprint {
|
||||
#define PF_OSFP_MSS_DC 0x0800 /* TCP MSS dont-care */
|
||||
#define PF_OSFP_DF 0x1000 /* IPv4 don't fragment bit */
|
||||
#define PF_OSFP_TS0 0x2000 /* Zero timestamp */
|
||||
#define PF_OSFP_INET6 0x4000 /* IPv6 */
|
||||
u_int8_t fp_optcnt; /* TCP option count */
|
||||
u_int8_t fp_wscale; /* TCP window scaling */
|
||||
u_int8_t fp_ttl; /* IPv4 TTL */
|
||||
@ -581,11 +594,11 @@ struct pf_rule {
|
||||
union pf_rule_ptr skip[PF_SKIP_COUNT];
|
||||
#define PF_RULE_LABEL_SIZE 64
|
||||
char label[PF_RULE_LABEL_SIZE];
|
||||
#define PF_QNAME_SIZE 16
|
||||
#define PF_QNAME_SIZE 64
|
||||
char ifname[IFNAMSIZ];
|
||||
char qname[PF_QNAME_SIZE];
|
||||
char pqname[PF_QNAME_SIZE];
|
||||
#define PF_TAG_NAME_SIZE 16
|
||||
#define PF_TAG_NAME_SIZE 64
|
||||
char tagname[PF_TAG_NAME_SIZE];
|
||||
char match_tagname[PF_TAG_NAME_SIZE];
|
||||
|
||||
@ -595,8 +608,8 @@ struct pf_rule {
|
||||
struct pf_pool rpool;
|
||||
|
||||
u_int64_t evaluations;
|
||||
u_int64_t packets;
|
||||
u_int64_t bytes;
|
||||
u_int64_t packets[2];
|
||||
u_int64_t bytes[2];
|
||||
|
||||
struct pfi_kif *kif;
|
||||
struct pf_anchor *anchor;
|
||||
@ -604,6 +617,7 @@ struct pf_rule {
|
||||
|
||||
pf_osfp_t os_fingerprint;
|
||||
|
||||
int rtableid;
|
||||
u_int32_t timeout[PFTM_MAX];
|
||||
u_int32_t states;
|
||||
u_int32_t max_states;
|
||||
@ -620,6 +634,8 @@ struct pf_rule {
|
||||
u_int32_t rt_listid;
|
||||
u_int32_t nr;
|
||||
u_int32_t prob;
|
||||
uid_t cuid;
|
||||
pid_t cpid;
|
||||
|
||||
u_int16_t return_icmp;
|
||||
u_int16_t return_icmp6;
|
||||
@ -634,6 +650,7 @@ struct pf_rule {
|
||||
u_int8_t action;
|
||||
u_int8_t direction;
|
||||
u_int8_t log;
|
||||
u_int8_t logif;
|
||||
u_int8_t quick;
|
||||
u_int8_t ifnot;
|
||||
u_int8_t match_tag_not;
|
||||
@ -681,9 +698,10 @@ struct pf_rule {
|
||||
|
||||
/* rule flags again */
|
||||
#define PFRULE_IFBOUND 0x00010000 /* if-bound */
|
||||
#define PFRULE_GRBOUND 0x00020000 /* group-bound */
|
||||
|
||||
#define PFSTATE_HIWAT 10000 /* default state table size */
|
||||
#define PFSTATE_ADAPT_START 6000 /* default adaptive timeout start */
|
||||
#define PFSTATE_ADAPT_END 12000 /* default adaptive timeout end */
|
||||
|
||||
|
||||
struct pf_threshold {
|
||||
@ -701,8 +719,8 @@ struct pf_src_node {
|
||||
struct pf_addr raddr;
|
||||
union pf_rule_ptr rule;
|
||||
struct pfi_kif *kif;
|
||||
u_int32_t bytes;
|
||||
u_int32_t packets;
|
||||
u_int64_t bytes[2];
|
||||
u_int64_t packets[2];
|
||||
u_int32_t states;
|
||||
u_int32_t conn;
|
||||
struct pf_threshold conn_rate;
|
||||
@ -744,26 +762,58 @@ struct pf_state_peer {
|
||||
u_int8_t state; /* active state level */
|
||||
u_int8_t wscale; /* window scaling factor */
|
||||
u_int16_t mss; /* Maximum segment size option */
|
||||
u_int8_t tcp_est; /* Did we reach TCPS_ESTABLISHED */
|
||||
struct pf_state_scrub *scrub; /* state is scrubbed */
|
||||
u_int8_t pad[3];
|
||||
};
|
||||
|
||||
TAILQ_HEAD(pf_state_queue, pf_state);
|
||||
|
||||
/* keep synced with struct pf_state, used in RB_FIND */
|
||||
struct pf_state_cmp {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
struct pf_state_host lan;
|
||||
struct pf_state_host gwy;
|
||||
struct pf_state_host ext;
|
||||
sa_family_t af;
|
||||
u_int8_t proto;
|
||||
u_int8_t direction;
|
||||
u_int8_t pad;
|
||||
};
|
||||
|
||||
struct pf_state {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
struct pf_state_host lan;
|
||||
struct pf_state_host gwy;
|
||||
struct pf_state_host ext;
|
||||
sa_family_t af;
|
||||
u_int8_t proto;
|
||||
u_int8_t direction;
|
||||
#ifdef __FreeBSD__
|
||||
u_int8_t local_flags;
|
||||
#define PFSTATE_EXPIRING 0x01
|
||||
#else
|
||||
u_int8_t pad;
|
||||
#endif
|
||||
u_int8_t log;
|
||||
u_int8_t allow_opts;
|
||||
u_int8_t timeout;
|
||||
u_int8_t sync_flags;
|
||||
#define PFSTATE_NOSYNC 0x01
|
||||
#define PFSTATE_FROMSYNC 0x02
|
||||
#define PFSTATE_STALE 0x04
|
||||
union {
|
||||
struct {
|
||||
RB_ENTRY(pf_state) entry_lan_ext;
|
||||
RB_ENTRY(pf_state) entry_ext_gwy;
|
||||
RB_ENTRY(pf_state) entry_id;
|
||||
TAILQ_ENTRY(pf_state) entry_updates;
|
||||
TAILQ_ENTRY(pf_state) entry_list;
|
||||
struct pfi_kif *kif;
|
||||
} s;
|
||||
char ifname[IFNAMSIZ];
|
||||
} u;
|
||||
struct pf_state_host lan;
|
||||
struct pf_state_host gwy;
|
||||
struct pf_state_host ext;
|
||||
struct pf_state_peer src;
|
||||
struct pf_state_peer dst;
|
||||
union pf_rule_ptr rule;
|
||||
@ -773,30 +823,12 @@ struct pf_state {
|
||||
struct pfi_kif *rt_kif;
|
||||
struct pf_src_node *src_node;
|
||||
struct pf_src_node *nat_src_node;
|
||||
u_int64_t packets[2];
|
||||
u_int64_t bytes[2];
|
||||
u_int32_t creation;
|
||||
u_int32_t expire;
|
||||
u_int32_t pfsync_time;
|
||||
u_int32_t packets[2];
|
||||
u_int32_t bytes[2];
|
||||
u_int32_t creatorid;
|
||||
u_int16_t tag;
|
||||
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;
|
||||
#define PFSTATE_NOSYNC 0x01
|
||||
#define PFSTATE_FROMSYNC 0x02
|
||||
#define PFSTATE_STALE 0x04
|
||||
#ifdef __FreeBSD__
|
||||
u_int8_t local_flags;
|
||||
#define PFSTATE_EXPIRING 0x01
|
||||
#define PFSTATE_SRC_CONN 0x02
|
||||
#else
|
||||
u_int8_t pad;
|
||||
#endif
|
||||
};
|
||||
|
||||
TAILQ_HEAD(pf_rulequeue, pf_rule);
|
||||
@ -808,6 +840,8 @@ struct pf_ruleset {
|
||||
struct pf_rulequeue queues[2];
|
||||
struct {
|
||||
struct pf_rulequeue *ptr;
|
||||
struct pf_rule **ptr_array;
|
||||
u_int32_t rcount;
|
||||
u_int32_t ticket;
|
||||
int open;
|
||||
} active, inactive;
|
||||
@ -829,6 +863,7 @@ struct pf_anchor {
|
||||
char path[MAXPATHLEN];
|
||||
struct pf_ruleset ruleset;
|
||||
int refcnt; /* anchor rules */
|
||||
int match;
|
||||
};
|
||||
RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
|
||||
RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
|
||||
@ -954,56 +989,52 @@ RB_HEAD(pf_state_tree_ext_gwy, pf_state);
|
||||
RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state,
|
||||
u.s.entry_ext_gwy, pf_state_compare_ext_gwy);
|
||||
|
||||
struct pfi_if {
|
||||
char pfif_name[IFNAMSIZ];
|
||||
u_int64_t pfif_packets[2][2][2];
|
||||
u_int64_t pfif_bytes[2][2][2];
|
||||
u_int64_t pfif_addcnt;
|
||||
u_int64_t pfif_delcnt;
|
||||
long pfif_tzero;
|
||||
int pfif_states;
|
||||
int pfif_rules;
|
||||
int pfif_flags;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(pfi_grouphead, pfi_kif);
|
||||
TAILQ_HEAD(pfi_statehead, pfi_kif);
|
||||
RB_HEAD(pfi_ifhead, pfi_kif);
|
||||
|
||||
/* keep synced with pfi_kif, used in RB_FIND */
|
||||
struct pfi_kif_cmp {
|
||||
char pfik_name[IFNAMSIZ];
|
||||
};
|
||||
|
||||
struct pfi_kif {
|
||||
struct pfi_if pfik_if;
|
||||
char pfik_name[IFNAMSIZ];
|
||||
RB_ENTRY(pfi_kif) pfik_tree;
|
||||
u_int64_t pfik_packets[2][2][2];
|
||||
u_int64_t pfik_bytes[2][2][2];
|
||||
u_int32_t pfik_tzero;
|
||||
int pfik_flags;
|
||||
struct pf_state_tree_lan_ext pfik_lan_ext;
|
||||
struct pf_state_tree_ext_gwy pfik_ext_gwy;
|
||||
struct pfi_grouphead pfik_grouphead;
|
||||
TAILQ_ENTRY(pfi_kif) pfik_instances;
|
||||
TAILQ_ENTRY(pfi_kif) pfik_w_states;
|
||||
struct hook_desc_head *pfik_ah_head;
|
||||
#ifndef __FreeBSD__
|
||||
void *pfik_ah_cookie;
|
||||
struct pfi_kif *pfik_parent;
|
||||
#endif
|
||||
struct ifnet *pfik_ifp;
|
||||
struct ifg_group *pfik_group;
|
||||
int pfik_states;
|
||||
int pfik_rules;
|
||||
TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs;
|
||||
};
|
||||
|
||||
enum pfi_kif_refs {
|
||||
PFI_KIF_REF_NONE,
|
||||
PFI_KIF_REF_STATE,
|
||||
PFI_KIF_REF_RULE
|
||||
};
|
||||
#define pfik_name pfik_if.pfif_name
|
||||
#define pfik_packets pfik_if.pfif_packets
|
||||
#define pfik_bytes pfik_if.pfif_bytes
|
||||
#define pfik_tzero pfik_if.pfif_tzero
|
||||
#define pfik_flags pfik_if.pfif_flags
|
||||
#define pfik_addcnt pfik_if.pfif_addcnt
|
||||
#define pfik_delcnt pfik_if.pfif_delcnt
|
||||
#define pfik_states pfik_if.pfif_states
|
||||
#define pfik_rules pfik_if.pfif_rules
|
||||
|
||||
#define PFI_IFLAG_GROUP 0x0001 /* group of interfaces */
|
||||
#define PFI_IFLAG_INSTANCE 0x0002 /* single instance */
|
||||
#define PFI_IFLAG_CLONABLE 0x0010 /* clonable group */
|
||||
#define PFI_IFLAG_DYNAMIC 0x0020 /* dynamic group */
|
||||
#define PFI_IFLAG_ATTACHED 0x0040 /* interface attached */
|
||||
#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
|
||||
/* XXX: revisist */
|
||||
#define PFI_IFLAG_SETABLE_MASK 0x0100 /* setable via DIOC{SET,CLR}IFFLAG */
|
||||
#define PFI_IFLAG_PLACEHOLDER 0x8000 /* placeholder group/interface */
|
||||
|
||||
struct pf_pdesc {
|
||||
struct {
|
||||
int done;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pid;
|
||||
} lookup;
|
||||
u_int64_t tot_len; /* Make Mickey money */
|
||||
union {
|
||||
struct tcphdr *tcp;
|
||||
@ -1021,6 +1052,7 @@ struct pf_pdesc {
|
||||
struct pf_addr *dst;
|
||||
struct ether_header
|
||||
*eh;
|
||||
struct pf_mtag *pf_mtag;
|
||||
u_int16_t *ip_sum;
|
||||
u_int32_t p_len; /* total length of payload */
|
||||
u_int16_t flags; /* Let SCRUB trigger behavior in
|
||||
@ -1161,6 +1193,7 @@ struct pf_status {
|
||||
u_int32_t debug;
|
||||
u_int32_t hostid;
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
|
||||
};
|
||||
|
||||
struct cbq_opts {
|
||||
@ -1223,6 +1256,23 @@ struct pf_altq {
|
||||
u_int32_t qid; /* return value */
|
||||
};
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
||||
#define PF_TAG_GENERATED 0x01
|
||||
#define PF_TAG_FRAGCACHE 0x02
|
||||
#define PF_TAG_TRANSLATE_LOCALHOST 0x04
|
||||
|
||||
struct pf_mtag {
|
||||
void *hdr; /* saved hdr pos in mbuf, for ECN */
|
||||
u_int rtableid; /* alternate routing table id */
|
||||
u_int32_t qid; /* queue id */
|
||||
u_int16_t tag; /* tag id */
|
||||
u_int8_t flags;
|
||||
u_int8_t routed;
|
||||
sa_family_t af; /* for ECN */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct pf_tag {
|
||||
u_int16_t tag; /* tag id */
|
||||
};
|
||||
@ -1239,6 +1289,10 @@ struct pf_tagname {
|
||||
#define PFFRAG_FRCENT_HIWAT 50000 /* Number of fragment cache entries */
|
||||
#define PFFRAG_FRCACHE_HIWAT 10000 /* Number of fragment descriptors */
|
||||
|
||||
#define PFR_KTABLE_HIWAT 1000 /* Number of tables */
|
||||
#define PFR_KENTRY_HIWAT 200000 /* Number of table entries */
|
||||
#define PFR_KENTRY_HIWAT_SMALL 100000 /* Number of table entries (tiny hosts) */
|
||||
|
||||
/*
|
||||
* ioctl parameter structures
|
||||
*/
|
||||
@ -1284,6 +1338,13 @@ struct pfioc_state {
|
||||
struct pf_state state;
|
||||
};
|
||||
|
||||
struct pfioc_src_node_kill {
|
||||
/* XXX returns the number of src nodes killed in psnk_af */
|
||||
sa_family_t psnk_af;
|
||||
struct pf_rule_addr psnk_src;
|
||||
struct pf_rule_addr psnk_dst;
|
||||
};
|
||||
|
||||
struct pfioc_state_kill {
|
||||
/* XXX returns the number of states killed in psk_af */
|
||||
sa_family_t psk_af;
|
||||
@ -1391,11 +1452,6 @@ struct pfioc_table {
|
||||
#define pfrio_setflag pfrio_size2
|
||||
#define pfrio_clrflag pfrio_nadd
|
||||
|
||||
|
||||
#define PFI_FLAG_GROUP 0x0001 /* gets groups of interfaces */
|
||||
#define PFI_FLAG_INSTANCE 0x0002 /* gets single interfaces */
|
||||
#define PFI_FLAG_ALLMASK 0x0003
|
||||
|
||||
struct pfioc_iface {
|
||||
char pfiio_name[IFNAMSIZ];
|
||||
void *pfiio_buffer;
|
||||
@ -1474,15 +1530,15 @@ struct pfioc_iface {
|
||||
#define DIOCCLRSRCNODES _IO('D', 85)
|
||||
#define DIOCSETHOSTID _IOWR('D', 86, u_int32_t)
|
||||
#define DIOCIGETIFACES _IOWR('D', 87, struct pfioc_iface)
|
||||
#define DIOCICLRISTATS _IOWR('D', 88, struct pfioc_iface)
|
||||
#define DIOCSETIFFLAG _IOWR('D', 89, struct pfioc_iface)
|
||||
#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
|
||||
#define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill)
|
||||
#ifdef __FreeBSD__
|
||||
struct pf_ifspeed {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int32_t baudrate;
|
||||
};
|
||||
#define DIOCGIFSPEED _IOWR('D', 91, struct pf_ifspeed)
|
||||
#define DIOCGIFSPEED _IOWR('D', 92, struct pf_ifspeed)
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
@ -1494,16 +1550,13 @@ RB_HEAD(pf_state_tree_id, pf_state);
|
||||
RB_PROTOTYPE(pf_state_tree_id, pf_state,
|
||||
entry_id, pf_state_compare_id);
|
||||
extern struct pf_state_tree_id tree_id;
|
||||
extern struct pf_state_queue state_updates;
|
||||
extern struct pf_state_queue state_list;
|
||||
|
||||
extern struct pf_anchor_global pf_anchors;
|
||||
extern struct pf_ruleset pf_main_ruleset;
|
||||
TAILQ_HEAD(pf_poolqueue, pf_pool);
|
||||
extern struct pf_poolqueue pf_pools[2];
|
||||
TAILQ_HEAD(pf_altqqueue, pf_altq);
|
||||
extern struct pf_altqqueue pf_altqs[2];
|
||||
extern struct pf_palist pf_pabuf;
|
||||
extern struct pfi_kif **pfi_index2kif;
|
||||
|
||||
extern u_int32_t ticket_altqs_active;
|
||||
extern u_int32_t ticket_altqs_inactive;
|
||||
@ -1530,26 +1583,22 @@ extern struct pool pf_src_tree_pl, pf_rule_pl;
|
||||
extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
|
||||
extern struct pool pf_state_scrub_pl;
|
||||
#endif
|
||||
extern void pf_purge_timeout(void *);
|
||||
extern void pf_purge_expired_src_nodes(void);
|
||||
extern void pf_purge_expired_states(void);
|
||||
extern void pf_purge_expired_state(struct pf_state *);
|
||||
extern void pf_purge_thread(void *);
|
||||
extern void pf_purge_expired_src_nodes(int);
|
||||
extern void pf_purge_expired_states(u_int32_t);
|
||||
extern void pf_unlink_state(struct pf_state *);
|
||||
extern void pf_free_state(struct pf_state *);
|
||||
extern int pf_insert_state(struct pfi_kif *,
|
||||
struct pf_state *);
|
||||
extern int pf_insert_src_node(struct pf_src_node **,
|
||||
struct pf_rule *, struct pf_addr *,
|
||||
sa_family_t);
|
||||
void pf_src_tree_remove_state(struct pf_state *);
|
||||
extern struct pf_state *pf_find_state_byid(struct pf_state *);
|
||||
extern struct pf_state *pf_find_state_all(struct pf_state *key,
|
||||
extern struct pf_state *pf_find_state_byid(struct pf_state_cmp *);
|
||||
extern struct pf_state *pf_find_state_all(struct pf_state_cmp *key,
|
||||
u_int8_t tree, int *more);
|
||||
extern void pf_print_state(struct pf_state *);
|
||||
extern void pf_print_flags(u_int8_t);
|
||||
extern struct pf_anchor *pf_find_anchor(const char *);
|
||||
extern struct pf_ruleset *pf_find_ruleset(const char *);
|
||||
extern struct pf_ruleset *pf_find_or_create_ruleset(const char *);
|
||||
extern void pf_remove_if_empty_ruleset(
|
||||
struct pf_ruleset *);
|
||||
extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
|
||||
u_int8_t);
|
||||
|
||||
@ -1581,11 +1630,15 @@ void pf_poolmask(struct pf_addr *, struct pf_addr*,
|
||||
void pf_addr_inc(struct pf_addr *, sa_family_t);
|
||||
#endif /* INET6 */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
u_int32_t pf_new_isn(struct pf_state *);
|
||||
#endif
|
||||
void *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *,
|
||||
sa_family_t);
|
||||
void pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t);
|
||||
int pflog_packet(struct pfi_kif *, struct mbuf *, sa_family_t, u_int8_t,
|
||||
u_int8_t, struct pf_rule *, struct pf_rule *, struct pf_ruleset *);
|
||||
u_int8_t, struct pf_rule *, struct pf_rule *, struct pf_ruleset *,
|
||||
struct pf_pdesc *);
|
||||
int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
|
||||
struct pf_addr *, sa_family_t);
|
||||
int pf_match(u_int8_t, u_int32_t, u_int32_t, u_int32_t);
|
||||
@ -1609,8 +1662,13 @@ int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *,
|
||||
u_int32_t
|
||||
pf_state_expires(const struct pf_state *);
|
||||
void pf_purge_expired_fragments(void);
|
||||
int pf_routable(struct pf_addr *addr, sa_family_t af);
|
||||
int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *);
|
||||
int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *);
|
||||
#ifdef __FreeBSD__
|
||||
int pf_socket_lookup(int, struct pf_pdesc *, struct inpcb *);
|
||||
#else
|
||||
int pf_socket_lookup(int, struct pf_pdesc *);
|
||||
#endif
|
||||
void pfr_initialize(void);
|
||||
int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
|
||||
void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
|
||||
@ -1635,7 +1693,7 @@ int pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int pfr_del_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int);
|
||||
int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int *, int *, int *, int);
|
||||
int *, int *, int *, int, u_int32_t);
|
||||
int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
|
||||
int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
|
||||
int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
@ -1648,48 +1706,54 @@ int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
|
||||
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
|
||||
int *, u_int32_t, int);
|
||||
|
||||
extern struct pfi_statehead pfi_statehead;
|
||||
extern struct pfi_kif *pfi_all;
|
||||
|
||||
void pfi_initialize(void);
|
||||
#ifdef __FreeBSD__
|
||||
void pfi_cleanup(void);
|
||||
#endif
|
||||
void pfi_attach_clone(struct if_clone *);
|
||||
struct pfi_kif *pfi_kif_get(const char *);
|
||||
void pfi_kif_ref(struct pfi_kif *, enum pfi_kif_refs);
|
||||
void pfi_kif_unref(struct pfi_kif *, enum pfi_kif_refs);
|
||||
int pfi_kif_match(struct pfi_kif *, struct pfi_kif *);
|
||||
void pfi_attach_ifnet(struct ifnet *);
|
||||
void pfi_detach_ifnet(struct ifnet *);
|
||||
struct pfi_kif *pfi_lookup_create(const char *);
|
||||
struct pfi_kif *pfi_lookup_if(const char *);
|
||||
int pfi_maybe_destroy(struct pfi_kif *);
|
||||
struct pfi_kif *pfi_attach_rule(const char *);
|
||||
void pfi_detach_rule(struct pfi_kif *);
|
||||
void pfi_attach_state(struct pfi_kif *);
|
||||
void pfi_detach_state(struct pfi_kif *);
|
||||
int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t);
|
||||
void pfi_dynaddr_copyout(struct pf_addr_wrap *);
|
||||
void pfi_dynaddr_remove(struct pf_addr_wrap *);
|
||||
void pfi_fill_oldstatus(struct pf_status *);
|
||||
int pfi_clr_istats(const char *, int *, int);
|
||||
int pfi_get_ifaces(const char *, struct pfi_if *, int *, int);
|
||||
int pfi_set_flags(const char *, int);
|
||||
int pfi_clear_flags(const char *, int);
|
||||
void pfi_attach_ifgroup(struct ifg_group *);
|
||||
void pfi_detach_ifgroup(struct ifg_group *);
|
||||
void pfi_group_change(const char *);
|
||||
int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *,
|
||||
sa_family_t);
|
||||
int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t);
|
||||
void pfi_dynaddr_remove(struct pf_addr_wrap *);
|
||||
void pfi_dynaddr_copyout(struct pf_addr_wrap *);
|
||||
void pfi_fill_oldstatus(struct pf_status *);
|
||||
int pfi_clr_istats(const char *);
|
||||
int pfi_get_ifaces(const char *, struct pfi_kif *, int *);
|
||||
int pfi_set_flags(const char *, int);
|
||||
int pfi_clear_flags(const char *, int);
|
||||
|
||||
extern struct pfi_statehead pfi_statehead;
|
||||
|
||||
u_int16_t pf_tagname2tag(char *);
|
||||
void pf_tag2tagname(u_int16_t, char *);
|
||||
void pf_tag_ref(u_int16_t);
|
||||
void pf_tag_unref(u_int16_t);
|
||||
int pf_tag_packet(struct mbuf *, struct pf_tag *, int);
|
||||
u_int32_t pf_qname2qid(char *);
|
||||
void pf_qid2qname(u_int32_t, char *);
|
||||
void pf_qid_unref(u_int32_t);
|
||||
u_int16_t pf_tagname2tag(char *);
|
||||
void pf_tag2tagname(u_int16_t, char *);
|
||||
void pf_tag_ref(u_int16_t);
|
||||
void pf_tag_unref(u_int16_t);
|
||||
int pf_tag_packet(struct mbuf *, struct pf_mtag *, int, int);
|
||||
u_int32_t pf_qname2qid(char *);
|
||||
void pf_qid2qname(u_int32_t, char *);
|
||||
void pf_qid_unref(u_int32_t);
|
||||
#ifndef __FreeBSD__
|
||||
struct pf_mtag *pf_find_mtag(struct mbuf *);
|
||||
struct pf_mtag *pf_get_mtag(struct mbuf *);
|
||||
#endif
|
||||
|
||||
extern struct pf_status pf_status;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
extern uma_zone_t pf_frent_pl, pf_frag_pl;
|
||||
extern struct sx pf_consistency_lock;
|
||||
#else
|
||||
extern struct pool pf_frent_pl, pf_frag_pl;
|
||||
extern struct rwlock pf_consistency_lock;
|
||||
#endif
|
||||
|
||||
struct pf_pool_limit {
|
||||
@ -1732,6 +1796,34 @@ struct pf_fragment {
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
extern struct pf_anchor_global pf_anchors;
|
||||
extern struct pf_anchor pf_main_anchor;
|
||||
#define pf_main_ruleset pf_main_anchor.ruleset
|
||||
|
||||
/* these ruleset functions can be linked into userland programs (pfctl) */
|
||||
int pf_get_ruleset_number(u_int8_t);
|
||||
void pf_init_ruleset(struct pf_ruleset *);
|
||||
int pf_anchor_setup(struct pf_rule *,
|
||||
const struct pf_ruleset *, const char *);
|
||||
int pf_anchor_copyout(const struct pf_ruleset *,
|
||||
const struct pf_rule *, struct pfioc_rule *);
|
||||
void pf_anchor_remove(struct pf_rule *);
|
||||
void pf_remove_if_empty_ruleset(struct pf_ruleset *);
|
||||
struct pf_anchor *pf_find_anchor(const char *);
|
||||
struct pf_ruleset *pf_find_ruleset(const char *);
|
||||
struct pf_ruleset *pf_find_or_create_ruleset(const char *);
|
||||
void pf_rs_initialize(void);
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
/* ?!? */
|
||||
#ifdef _KERNEL
|
||||
int pf_anchor_copyout(const struct pf_ruleset *,
|
||||
const struct pf_rule *, struct pfioc_rule *);
|
||||
void pf_anchor_remove(struct pf_rule *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif
|
||||
|
||||
/* The fingerprint functions can be linked into userland programs (tcpdump) */
|
||||
int pf_osfp_add(struct pf_osfp_ioctl *);
|
||||
#ifdef _KERNEL
|
||||
@ -1740,7 +1832,8 @@ struct pf_osfp_enlist *
|
||||
const struct tcphdr *);
|
||||
#endif /* _KERNEL */
|
||||
struct pf_osfp_enlist *
|
||||
pf_osfp_fingerprint_hdr(const struct ip *, const struct tcphdr *);
|
||||
pf_osfp_fingerprint_hdr(const struct ip *, const struct ip6_hdr *,
|
||||
const struct tcphdr *);
|
||||
void pf_osfp_flush(void);
|
||||
int pf_osfp_get(struct pf_osfp_ioctl *);
|
||||
#ifdef __FreeBSD__
|
||||
|
Loading…
Reference in New Issue
Block a user