mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-14 07:15:58 +08:00
Remove obsolete PF files
This commit is contained in:
@@ -1,437 +0,0 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/* $OpenBSD: if_pflog.c,v 1.26 2007/10/18 21:58:18 mpf Exp $ */
|
||||
/*
|
||||
* The authors of this code are John Ioannidis (ji@tla.org),
|
||||
* Angelos D. Keromytis (kermit@csd.uch.gr) and
|
||||
* Niels Provos (provos@physnet.uni-hamburg.de).
|
||||
*
|
||||
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
|
||||
* in November 1995.
|
||||
*
|
||||
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
|
||||
* by Angelos D. Keromytis.
|
||||
*
|
||||
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
*
|
||||
* Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
|
||||
* and Niels Provos.
|
||||
* Copyright (c) 2001, Angelos D. Keromytis, Niels Provos.
|
||||
*
|
||||
* Permission to use, copy, and modify this software with or without fee
|
||||
* is hereby granted, provided that this entire notice is included in
|
||||
* all copies of any software which is or includes a copy or
|
||||
* modification of this software.
|
||||
* You may use this code under the GNU public license if you so wish. Please
|
||||
* contribute changes back to the authors under this freer than GPL license
|
||||
* so that we may further the use of strong encryption without limitations to
|
||||
* all.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
|
||||
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <rtems/bsd/local/opt_inet.h>
|
||||
#include <rtems/bsd/local/opt_inet6.h>
|
||||
#include <rtems/bsd/local/opt_bpf.h>
|
||||
#include <rtems/bsd/local/opt_pf.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef DEV_BPF
|
||||
#define NBPFILTER DEV_BPF
|
||||
#else
|
||||
#define NBPFILTER 0
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFLOG
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#else
|
||||
#define NPFLOG 0
|
||||
#endif
|
||||
|
||||
#else /* ! __FreeBSD__ */
|
||||
#include "bpfilter.h"
|
||||
#include "pflog.h"
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#include <rtems/bsd/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>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <net/if_clone.h>
|
||||
#endif
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <net/bpf.h>
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef INET
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
#endif /* INET6 */
|
||||
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pflog.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#ifdef INET
|
||||
#include <machine/in_cksum.h>
|
||||
#endif /* INET */
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#define PFLOGMTU (32768 + MHLEN + MLEN)
|
||||
|
||||
#ifdef PFLOGDEBUG
|
||||
#define DPRINTF(x) do { if (pflogdebug) printf x ; } while (0)
|
||||
#else
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
void pflogattach(int);
|
||||
int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
#ifdef __FreeBSD__
|
||||
struct route *);
|
||||
#else
|
||||
struct rtentry *);
|
||||
#endif
|
||||
int pflogioctl(struct ifnet *, u_long, caddr_t);
|
||||
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 */
|
||||
|
||||
void
|
||||
pflogattach(int npflog)
|
||||
{
|
||||
int i;
|
||||
LIST_INIT(&pflogif_list);
|
||||
for (i = 0; i < PFLOGIFS_MAX; i++)
|
||||
pflogifs[i] = NULL;
|
||||
if_clone_attach(&pflog_cloner);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
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 ifnet *ifp;
|
||||
struct pflog_softc *pflogif;
|
||||
int s;
|
||||
|
||||
if (unit >= PFLOGIFS_MAX)
|
||||
return (EINVAL);
|
||||
|
||||
if ((pflogif = malloc(sizeof(*pflogif),
|
||||
M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
pflogif->sc_unit = unit;
|
||||
#ifdef __FreeBSD__
|
||||
ifp = pflogif->sc_ifp = if_alloc(IFT_PFLOG);
|
||||
if (ifp == NULL) {
|
||||
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;
|
||||
if_attach(ifp);
|
||||
#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__
|
||||
/* XXX: Why pf(4) lock?! Better add a pflog lock?! */
|
||||
PF_LOCK();
|
||||
#endif
|
||||
LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
|
||||
pflogifs[unit] = ifp;
|
||||
#ifdef __FreeBSD__
|
||||
PF_UNLOCK();
|
||||
#endif
|
||||
splx(s);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static void
|
||||
pflog_clone_destroy(struct ifnet *ifp)
|
||||
#else
|
||||
int
|
||||
pflog_clone_destroy(struct ifnet *ifp)
|
||||
#endif
|
||||
{
|
||||
struct pflog_softc *pflogif = ifp->if_softc;
|
||||
int s;
|
||||
|
||||
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
|
||||
bpfdetach(ifp);
|
||||
#endif
|
||||
if_detach(ifp);
|
||||
#ifdef __FreeBSD__
|
||||
if_free(ifp);
|
||||
#endif
|
||||
free(pflogif, M_DEVBUF);
|
||||
#ifndef __FreeBSD__
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Start output on the pflog interface.
|
||||
*/
|
||||
void
|
||||
pflogstart(struct ifnet *ifp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
#ifndef __FreeBSD__
|
||||
int s;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
#ifdef __FreeBSD__
|
||||
IF_LOCK(&ifp->if_snd);
|
||||
_IF_DROP(&ifp->if_snd);
|
||||
_IF_DEQUEUE(&ifp->if_snd, m);
|
||||
IF_UNLOCK(&ifp->if_snd);
|
||||
#else
|
||||
s = splnet();
|
||||
IF_DROP(&ifp->if_snd);
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
splx(s);
|
||||
#endif
|
||||
|
||||
if (m == NULL)
|
||||
return;
|
||||
else
|
||||
m_freem(m);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
#ifdef __FreeBSD__
|
||||
struct route *rt)
|
||||
#else
|
||||
struct rtentry *rt)
|
||||
#endif
|
||||
{
|
||||
m_freem(m);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
#ifdef __FreeBSD__
|
||||
if (ifp->if_flags & IFF_UP)
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
else
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
#else
|
||||
if (ifp->if_flags & IFF_UP)
|
||||
ifp->if_flags |= IFF_RUNNING;
|
||||
else
|
||||
ifp->if_flags &= ~IFF_RUNNING;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
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_pdesc *pd)
|
||||
{
|
||||
#if NBPFILTER > 0
|
||||
struct ifnet *ifn;
|
||||
struct pfloghdr hdr;
|
||||
|
||||
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;
|
||||
hdr.action = rm->action;
|
||||
hdr.reason = reason;
|
||||
memcpy(hdr.ifname, kif->pfik_name, sizeof(hdr.ifname));
|
||||
|
||||
if (am == NULL) {
|
||||
hdr.rulenr = htonl(rm->nr);
|
||||
hdr.subrulenr = 1;
|
||||
} else {
|
||||
hdr.rulenr = htonl(am->nr);
|
||||
hdr.subrulenr = htonl(rm->nr);
|
||||
if (ruleset != NULL && ruleset->anchor != NULL)
|
||||
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
|
||||
if (af == AF_INET && dir == PF_OUT) {
|
||||
struct ip *ip;
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
ip->ip_sum = 0;
|
||||
ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
|
||||
}
|
||||
#endif /* INET */
|
||||
|
||||
ifn->if_opackets++;
|
||||
ifn->if_obytes += m->m_pkthdr.len;
|
||||
#ifdef __FreeBSD__
|
||||
BPF_MTAP2(ifn, &hdr, PFLOG_HDRLEN, m);
|
||||
#else
|
||||
bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
|
||||
BPF_DIRECTION_OUT);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static int
|
||||
pflog_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER);
|
||||
#endif /* __FreeBSD__ */
|
@@ -1,101 +0,0 @@
|
||||
/* $OpenBSD: if_pflog.h,v 1.13 2006/10/23 12:46:09 henning Exp $ */
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PFLOG_H_
|
||||
#define _NET_IF_PFLOG_H_
|
||||
|
||||
#define PFLOGIFS_MAX 16
|
||||
|
||||
struct pflog_softc {
|
||||
#ifdef __FreeBSD__
|
||||
struct ifnet *sc_ifp; /* the interface pointer */
|
||||
#else
|
||||
struct ifnet sc_if; /* the interface */
|
||||
#endif
|
||||
int sc_unit;
|
||||
LIST_ENTRY(pflog_softc) sc_list;
|
||||
};
|
||||
|
||||
#define PFLOG_RULESET_NAME_SIZE 16
|
||||
|
||||
struct pfloghdr {
|
||||
u_int8_t length;
|
||||
sa_family_t af;
|
||||
u_int8_t action;
|
||||
u_int8_t reason;
|
||||
char ifname[IFNAMSIZ];
|
||||
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];
|
||||
};
|
||||
|
||||
#define PFLOG_HDRLEN sizeof(struct pfloghdr)
|
||||
/* minus pad, also used as a signature */
|
||||
#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad)
|
||||
|
||||
/* XXX remove later when old format logs are no longer needed */
|
||||
struct old_pfloghdr {
|
||||
u_int32_t af;
|
||||
char ifname[IFNAMSIZ];
|
||||
short rnr;
|
||||
u_short reason;
|
||||
u_short action;
|
||||
u_short dir;
|
||||
};
|
||||
#define OLD_PFLOG_HDRLEN sizeof(struct old_pfloghdr)
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef __FreeBSD__
|
||||
struct pf_rule;
|
||||
struct pf_ruleset;
|
||||
struct pfi_kif;
|
||||
struct pf_pdesc;
|
||||
|
||||
#if 0
|
||||
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_pdesc *);
|
||||
extern pflog_packet_t *pflog_packet_ptr;
|
||||
#endif
|
||||
#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 /* ! __FreeBSD__ */
|
||||
#if NPFLOG > 0
|
||||
#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,h) ((void)0)
|
||||
#endif /* NPFLOG > 0 */
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _NET_IF_PFLOG_H_ */
|
@@ -1,126 +0,0 @@
|
||||
/* $OpenBSD: if_pflow.h,v 1.5 2009/02/27 11:09:36 gollo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
|
||||
* Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PFLOW_H_
|
||||
#define _NET_IF_PFLOW_H_
|
||||
|
||||
#define PFLOW_ID_LEN sizeof(u_int64_t)
|
||||
|
||||
#define PFLOW_MAXFLOWS 30
|
||||
#define PFLOW_VERSION 5
|
||||
#define PFLOW_ENGINE_TYPE 42
|
||||
#define PFLOW_ENGINE_ID 42
|
||||
#define PFLOW_MAXBYTES 0xffffffff
|
||||
#define PFLOW_TIMEOUT 30
|
||||
|
||||
struct pflow_flow {
|
||||
u_int32_t src_ip;
|
||||
u_int32_t dest_ip;
|
||||
u_int32_t nexthop_ip;
|
||||
u_int16_t if_index_in;
|
||||
u_int16_t if_index_out;
|
||||
u_int32_t flow_packets;
|
||||
u_int32_t flow_octets;
|
||||
u_int32_t flow_start;
|
||||
u_int32_t flow_finish;
|
||||
u_int16_t src_port;
|
||||
u_int16_t dest_port;
|
||||
u_int8_t pad1;
|
||||
u_int8_t tcp_flags;
|
||||
u_int8_t protocol;
|
||||
u_int8_t tos;
|
||||
u_int16_t src_as;
|
||||
u_int16_t dest_as;
|
||||
u_int8_t src_mask;
|
||||
u_int8_t dest_mask;
|
||||
u_int16_t pad2;
|
||||
} __packed;
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
extern int pflow_ok;
|
||||
|
||||
struct pflow_softc {
|
||||
struct ifnet sc_if;
|
||||
struct ifnet *sc_pflow_ifp;
|
||||
|
||||
unsigned int sc_count;
|
||||
unsigned int sc_maxcount;
|
||||
u_int64_t sc_gcounter;
|
||||
struct ip_moptions sc_imo;
|
||||
#ifdef __FreeBSD__
|
||||
struct callout sc_tmo;
|
||||
#else
|
||||
struct timeout sc_tmo;
|
||||
#endif
|
||||
struct in_addr sc_sender_ip;
|
||||
u_int16_t sc_sender_port;
|
||||
struct in_addr sc_receiver_ip;
|
||||
u_int16_t sc_receiver_port;
|
||||
struct mbuf *sc_mbuf; /* current cumulative mbuf */
|
||||
SLIST_ENTRY(pflow_softc) sc_next;
|
||||
};
|
||||
|
||||
extern struct pflow_softc *pflowif;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
struct pflow_header {
|
||||
u_int16_t version;
|
||||
u_int16_t count;
|
||||
u_int32_t uptime_ms;
|
||||
u_int32_t time_sec;
|
||||
u_int32_t time_nanosec;
|
||||
u_int32_t flow_sequence;
|
||||
u_int8_t engine_type;
|
||||
u_int8_t engine_id;
|
||||
u_int8_t reserved1;
|
||||
u_int8_t reserved2;
|
||||
} __packed;
|
||||
|
||||
#define PFLOW_HDRLEN sizeof(struct pflow_header)
|
||||
|
||||
struct pflowstats {
|
||||
u_int64_t pflow_flows;
|
||||
u_int64_t pflow_packets;
|
||||
u_int64_t pflow_onomem;
|
||||
u_int64_t pflow_oerrors;
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration structure for SIOCSETPFLOW SIOCGETPFLOW
|
||||
*/
|
||||
struct pflowreq {
|
||||
struct in_addr sender_ip;
|
||||
struct in_addr receiver_ip;
|
||||
u_int16_t receiver_port;
|
||||
u_int16_t addrmask;
|
||||
#define PFLOW_MASK_SRCIP 0x01
|
||||
#define PFLOW_MASK_DSTIP 0x02
|
||||
#define PFLOW_MASK_DSTPRT 0x04
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
int export_pflow(struct pf_state *);
|
||||
int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NET_IF_PFLOW_H_ */
|
File diff suppressed because it is too large
Load Diff
@@ -1,324 +0,0 @@
|
||||
/* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Michael Shalayeff
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_PFSYNC_H_
|
||||
#define _NET_IF_PFSYNC_H_
|
||||
|
||||
#define PFSYNC_VERSION 5
|
||||
#define PFSYNC_DFLTTL 255
|
||||
|
||||
#define PFSYNC_ACT_CLR 0 /* clear all states */
|
||||
#define PFSYNC_ACT_INS 1 /* insert state */
|
||||
#define PFSYNC_ACT_INS_ACK 2 /* ack of insterted state */
|
||||
#define PFSYNC_ACT_UPD 3 /* update state */
|
||||
#define PFSYNC_ACT_UPD_C 4 /* "compressed" update state */
|
||||
#define PFSYNC_ACT_UPD_REQ 5 /* request "uncompressed" state */
|
||||
#define PFSYNC_ACT_DEL 6 /* delete state */
|
||||
#define PFSYNC_ACT_DEL_C 7 /* "compressed" delete state */
|
||||
#define PFSYNC_ACT_INS_F 8 /* insert fragment */
|
||||
#define PFSYNC_ACT_DEL_F 9 /* delete fragments */
|
||||
#define PFSYNC_ACT_BUS 10 /* bulk update status */
|
||||
#define PFSYNC_ACT_TDB 11 /* TDB replay counter update */
|
||||
#define PFSYNC_ACT_EOF 12 /* end of frame */
|
||||
#define PFSYNC_ACT_MAX 13
|
||||
|
||||
#define PFSYNC_ACTIONS "CLR ST", \
|
||||
"INS ST", \
|
||||
"INS ST ACK", \
|
||||
"UPD ST", \
|
||||
"UPD ST COMP", \
|
||||
"UPD ST REQ", \
|
||||
"DEL ST", \
|
||||
"DEL ST COMP", \
|
||||
"INS FR", \
|
||||
"DEL FR", \
|
||||
"BULK UPD STAT", \
|
||||
"TDB UPD", \
|
||||
"EOF"
|
||||
|
||||
#define PFSYNC_HMAC_LEN 20
|
||||
|
||||
/*
|
||||
* A pfsync frame is built from a header followed by several sections which
|
||||
* are all prefixed with their own subheaders. Frames must be terminated with
|
||||
* an EOF subheader.
|
||||
*
|
||||
* | ... |
|
||||
* | IP header |
|
||||
* +============================+
|
||||
* | pfsync_header |
|
||||
* +----------------------------+
|
||||
* | pfsync_subheader |
|
||||
* +----------------------------+
|
||||
* | first action fields |
|
||||
* | ... |
|
||||
* +----------------------------+
|
||||
* | pfsync_subheader |
|
||||
* +----------------------------+
|
||||
* | second action fields |
|
||||
* | ... |
|
||||
* +----------------------------+
|
||||
* | EOF pfsync_subheader |
|
||||
* +----------------------------+
|
||||
* | HMAC |
|
||||
* +============================+
|
||||
*/
|
||||
|
||||
/*
|
||||
* Frame header
|
||||
*/
|
||||
|
||||
struct pfsync_header {
|
||||
u_int8_t version;
|
||||
u_int8_t _pad;
|
||||
u_int16_t len;
|
||||
u_int8_t pfcksum[PF_MD5_DIGEST_LENGTH];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Frame region subheader
|
||||
*/
|
||||
|
||||
struct pfsync_subheader {
|
||||
u_int8_t action;
|
||||
u_int8_t _pad;
|
||||
u_int16_t count;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* CLR
|
||||
*/
|
||||
|
||||
struct pfsync_clr {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* INS, UPD, DEL
|
||||
*/
|
||||
|
||||
/* these use struct pfsync_state in pfvar.h */
|
||||
|
||||
/*
|
||||
* INS_ACK
|
||||
*/
|
||||
|
||||
struct pfsync_ins_ack {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* UPD_C
|
||||
*/
|
||||
|
||||
struct pfsync_upd_c {
|
||||
u_int64_t id;
|
||||
struct pfsync_state_peer src;
|
||||
struct pfsync_state_peer dst;
|
||||
u_int32_t creatorid;
|
||||
u_int32_t expire;
|
||||
u_int8_t timeout;
|
||||
u_int8_t _pad[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* UPD_REQ
|
||||
*/
|
||||
|
||||
struct pfsync_upd_req {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* DEL_C
|
||||
*/
|
||||
|
||||
struct pfsync_del_c {
|
||||
u_int64_t id;
|
||||
u_int32_t creatorid;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* INS_F, DEL_F
|
||||
*/
|
||||
|
||||
/* not implemented (yet) */
|
||||
|
||||
/*
|
||||
* BUS
|
||||
*/
|
||||
|
||||
struct pfsync_bus {
|
||||
u_int32_t creatorid;
|
||||
u_int32_t endtime;
|
||||
u_int8_t status;
|
||||
#define PFSYNC_BUS_START 1
|
||||
#define PFSYNC_BUS_END 2
|
||||
u_int8_t _pad[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* EOF
|
||||
*/
|
||||
|
||||
struct pfsync_eof {
|
||||
u_int8_t hmac[PFSYNC_HMAC_LEN];
|
||||
} __packed;
|
||||
|
||||
#define PFSYNC_HDRLEN sizeof(struct pfsync_header)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Names for PFSYNC sysctl objects
|
||||
*/
|
||||
#define PFSYNCCTL_STATS 1 /* PFSYNC stats */
|
||||
#define PFSYNCCTL_MAXID 2
|
||||
|
||||
#define PFSYNCCTL_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "stats", CTLTYPE_STRUCT }, \
|
||||
}
|
||||
|
||||
struct pfsyncstats {
|
||||
u_int64_t pfsyncs_ipackets; /* total input packets, IPv4 */
|
||||
u_int64_t pfsyncs_ipackets6; /* total input packets, IPv6 */
|
||||
u_int64_t pfsyncs_badif; /* not the right interface */
|
||||
u_int64_t pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */
|
||||
u_int64_t pfsyncs_hdrops; /* packets shorter than hdr */
|
||||
u_int64_t pfsyncs_badver; /* bad (incl unsupp) version */
|
||||
u_int64_t pfsyncs_badact; /* bad action */
|
||||
u_int64_t pfsyncs_badlen; /* data length does not match */
|
||||
u_int64_t pfsyncs_badauth; /* bad authentication */
|
||||
u_int64_t pfsyncs_stale; /* stale state */
|
||||
u_int64_t pfsyncs_badval; /* bad values */
|
||||
u_int64_t pfsyncs_badstate; /* insert/lookup failed */
|
||||
|
||||
u_int64_t pfsyncs_opackets; /* total output packets, IPv4 */
|
||||
u_int64_t pfsyncs_opackets6; /* total output packets, IPv6 */
|
||||
u_int64_t pfsyncs_onomem; /* no memory for an mbuf */
|
||||
u_int64_t pfsyncs_oerrors; /* ip output error */
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
|
||||
*/
|
||||
struct pfsyncreq {
|
||||
char pfsyncr_syncdev[IFNAMSIZ];
|
||||
struct in_addr pfsyncr_syncpeer;
|
||||
int pfsyncr_maxupdates;
|
||||
int pfsyncr_authlevel;
|
||||
};
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
|
||||
#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* this shows where a pf state is with respect to the syncing.
|
||||
*/
|
||||
#define PFSYNC_S_INS 0x00
|
||||
#define PFSYNC_S_IACK 0x01
|
||||
#define PFSYNC_S_UPD 0x02
|
||||
#define PFSYNC_S_UPD_C 0x03
|
||||
#define PFSYNC_S_DEL 0x04
|
||||
#define PFSYNC_S_COUNT 0x05
|
||||
|
||||
#define PFSYNC_S_DEFER 0xfe
|
||||
#define PFSYNC_S_NONE 0xff
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
void pfsync_input(struct mbuf *, __unused int);
|
||||
#else
|
||||
void pfsync_input(struct mbuf *, ...);
|
||||
#endif
|
||||
int pfsync_sysctl(int *, u_int, void *, size_t *,
|
||||
void *, size_t);
|
||||
|
||||
#define PFSYNC_SI_IOCTL 0x01
|
||||
#define PFSYNC_SI_CKSUM 0x02
|
||||
#define PFSYNC_SI_ACK 0x04
|
||||
int pfsync_state_import(struct pfsync_state *, u_int8_t);
|
||||
#ifndef __FreeBSD__
|
||||
void pfsync_state_export(struct pfsync_state *,
|
||||
struct pf_state *);
|
||||
#endif
|
||||
|
||||
void pfsync_insert_state(struct pf_state *);
|
||||
void pfsync_update_state(struct pf_state *);
|
||||
void pfsync_delete_state(struct pf_state *);
|
||||
void pfsync_clear_states(u_int32_t, const char *);
|
||||
|
||||
#ifdef notyet
|
||||
void pfsync_update_tdb(struct tdb *, int);
|
||||
void pfsync_delete_tdb(struct tdb *);
|
||||
#endif
|
||||
|
||||
int pfsync_defer(struct pf_state *, struct mbuf *);
|
||||
|
||||
int pfsync_up(void);
|
||||
int pfsync_state_in_use(struct pf_state *);
|
||||
#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,800 +0,0 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/* $OpenBSD: pf_lb.c,v 1.2 2009/02/12 02:13:15 sthen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
* Copyright (c) 2002 - 2008 Henning Brauer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Effort sponsored in part by the Defense Advanced Research Projects
|
||||
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
* Materiel Command, USAF, under agreement number F30602-01-2-0537.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <rtems/bsd/local/opt_inet.h>
|
||||
#include <rtems/bsd/local/opt_inet6.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <rtems/bsd/local/opt_bpf.h>
|
||||
#include <rtems/bsd/local/opt_pf.h>
|
||||
|
||||
#ifdef DEV_BPF
|
||||
#define NBPFILTER DEV_BPF
|
||||
#else
|
||||
#define NBPFILTER 0
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFLOG
|
||||
#define NPFLOG DEV_PFLOG
|
||||
#else
|
||||
#define NPFLOG 0
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFSYNC
|
||||
#define NPFSYNC DEV_PFSYNC
|
||||
#else
|
||||
#define NPFSYNC 0
|
||||
#endif
|
||||
|
||||
#ifdef DEV_PFLOW
|
||||
#define NPFLOW DEV_PFLOW
|
||||
#else
|
||||
#define NPFLOW 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include "bpfilter.h"
|
||||
#include "pflog.h"
|
||||
#include "pfsync.h"
|
||||
#include "pflow.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/pool.h>
|
||||
#endif
|
||||
#include <sys/proc.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/kthread.h>
|
||||
#include <rtems/bsd/sys/lock.h>
|
||||
#include <sys/sx.h>
|
||||
#else
|
||||
#include <sys/rwlock.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/md5.h>
|
||||
#else
|
||||
#include <crypto/md5.h>
|
||||
#endif
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/route.h>
|
||||
#include <net/radix_mpath.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/udp_var.h>
|
||||
#include <netinet/icmp_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#include <dev/rndvar.h>
|
||||
#endif
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pflog.h>
|
||||
#include <net/if_pflow.h>
|
||||
|
||||
#if NPFSYNC > 0
|
||||
#include <net/if_pfsync.h>
|
||||
#endif /* NPFSYNC > 0 */
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet6/nd6.h>
|
||||
#endif /* INET6 */
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
|
||||
#else
|
||||
#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
void pf_hash(struct pf_addr *, struct pf_addr *,
|
||||
struct pf_poolhashkey *, sa_family_t);
|
||||
struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
|
||||
int, int, struct pfi_kif *,
|
||||
struct pf_addr *, u_int16_t, struct pf_addr *,
|
||||
u_int16_t, int);
|
||||
int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
|
||||
struct pf_addr *, uint16_t, struct pf_addr *, uint16_t,
|
||||
struct pf_addr *, uint16_t*, uint16_t, uint16_t,
|
||||
struct pf_src_node **);
|
||||
|
||||
#define mix(a,b,c) \
|
||||
do { \
|
||||
a -= b; a -= c; a ^= (c >> 13); \
|
||||
b -= c; b -= a; b ^= (a << 8); \
|
||||
c -= a; c -= b; c ^= (b >> 13); \
|
||||
a -= b; a -= c; a ^= (c >> 12); \
|
||||
b -= c; b -= a; b ^= (a << 16); \
|
||||
c -= a; c -= b; c ^= (b >> 5); \
|
||||
a -= b; a -= c; a ^= (c >> 3); \
|
||||
b -= c; b -= a; b ^= (a << 10); \
|
||||
c -= a; c -= b; c ^= (b >> 15); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* hash function based on bridge_hash in if_bridge.c
|
||||
*/
|
||||
void
|
||||
pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
|
||||
struct pf_poolhashkey *key, sa_family_t af)
|
||||
{
|
||||
u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
|
||||
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
a += inaddr->addr32[0];
|
||||
b += key->key32[1];
|
||||
mix(a, b, c);
|
||||
hash->addr32[0] = c + key->key32[2];
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
a += inaddr->addr32[0];
|
||||
b += inaddr->addr32[2];
|
||||
mix(a, b, c);
|
||||
hash->addr32[0] = c;
|
||||
a += inaddr->addr32[1];
|
||||
b += inaddr->addr32[3];
|
||||
c += key->key32[1];
|
||||
mix(a, b, c);
|
||||
hash->addr32[1] = c;
|
||||
a += inaddr->addr32[2];
|
||||
b += inaddr->addr32[1];
|
||||
c += key->key32[2];
|
||||
mix(a, b, c);
|
||||
hash->addr32[2] = c;
|
||||
a += inaddr->addr32[3];
|
||||
b += inaddr->addr32[0];
|
||||
c += key->key32[3];
|
||||
mix(a, b, c);
|
||||
hash->addr32[3] = c;
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
}
|
||||
|
||||
struct pf_rule *
|
||||
pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
|
||||
int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
|
||||
struct pf_addr *daddr, u_int16_t dport, int rs_num)
|
||||
{
|
||||
struct pf_rule *r, *rm = NULL;
|
||||
struct pf_ruleset *ruleset = NULL;
|
||||
int tag = -1;
|
||||
int rtableid = -1;
|
||||
int asd = 0;
|
||||
|
||||
r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
|
||||
while (r && rm == NULL) {
|
||||
struct pf_rule_addr *src = NULL, *dst = NULL;
|
||||
struct pf_addr_wrap *xdst = NULL;
|
||||
|
||||
if (r->action == PF_BINAT && direction == PF_IN) {
|
||||
src = &r->dst;
|
||||
if (r->rpool.cur != NULL)
|
||||
xdst = &r->rpool.cur->addr;
|
||||
} else {
|
||||
src = &r->src;
|
||||
dst = &r->dst;
|
||||
}
|
||||
|
||||
r->evaluations++;
|
||||
if (pfi_kif_match(r->kif, kif) == r->ifnot)
|
||||
r = r->skip[PF_SKIP_IFP].ptr;
|
||||
else if (r->direction && r->direction != direction)
|
||||
r = r->skip[PF_SKIP_DIR].ptr;
|
||||
else if (r->af && r->af != pd->af)
|
||||
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(&src->addr, saddr, pd->af,
|
||||
src->neg, kif, M_GETFIB(m)))
|
||||
r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
|
||||
PF_SKIP_DST_ADDR].ptr;
|
||||
else if (src->port_op && !pf_match_port(src->port_op,
|
||||
src->port[0], src->port[1], sport))
|
||||
r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
|
||||
PF_SKIP_DST_PORT].ptr;
|
||||
else if (dst != NULL &&
|
||||
PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL,
|
||||
M_GETFIB(m)))
|
||||
r = r->skip[PF_SKIP_DST_ADDR].ptr;
|
||||
else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
|
||||
0, NULL, M_GETFIB(m)))
|
||||
r = TAILQ_NEXT(r, entries);
|
||||
else if (dst != NULL && dst->port_op &&
|
||||
!pf_match_port(dst->port_op, dst->port[0],
|
||||
dst->port[1], dport))
|
||||
r = r->skip[PF_SKIP_DST_PORT].ptr;
|
||||
#ifdef __FreeBSD__
|
||||
else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
|
||||
#else
|
||||
else if (r->match_tag && !pf_match_tag(m, r, &tag))
|
||||
#endif
|
||||
r = TAILQ_NEXT(r, entries);
|
||||
else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
|
||||
IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
|
||||
off, pd->hdr.tcp), r->os_fingerprint)))
|
||||
r = TAILQ_NEXT(r, entries);
|
||||
else {
|
||||
if (r->tag)
|
||||
tag = r->tag;
|
||||
if (r->rtableid >= 0)
|
||||
rtableid = r->rtableid;
|
||||
if (r->anchor == NULL) {
|
||||
rm = r;
|
||||
} else
|
||||
pf_step_into_anchor(&asd, &ruleset, rs_num,
|
||||
&r, NULL, NULL);
|
||||
}
|
||||
if (r == NULL)
|
||||
pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
|
||||
NULL, NULL);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag))
|
||||
#else
|
||||
if (pf_tag_packet(m, tag, rtableid))
|
||||
#endif
|
||||
return (NULL);
|
||||
if (rm != NULL && (rm->action == PF_NONAT ||
|
||||
rm->action == PF_NORDR || rm->action == PF_NOBINAT))
|
||||
return (NULL);
|
||||
return (rm);
|
||||
}
|
||||
|
||||
int
|
||||
pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
|
||||
struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr,
|
||||
uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low,
|
||||
uint16_t high, struct pf_src_node **sn)
|
||||
{
|
||||
struct pf_state_key_cmp key;
|
||||
struct pf_addr init_addr;
|
||||
uint16_t cut;
|
||||
|
||||
bzero(&init_addr, sizeof(init_addr));
|
||||
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
|
||||
return (1);
|
||||
|
||||
if (proto == IPPROTO_ICMP) {
|
||||
low = 1;
|
||||
high = 65535;
|
||||
}
|
||||
|
||||
bzero(&key,sizeof(key));
|
||||
key.af = af;
|
||||
key.proto = proto;
|
||||
key.port[0] = dport;
|
||||
PF_ACPY(&key.addr[0], daddr, key.af);
|
||||
|
||||
do {
|
||||
PF_ACPY(&key.addr[1], naddr, key.af);
|
||||
|
||||
/*
|
||||
* port search; start random, step;
|
||||
* similar 2 portloop in in_pcbbind
|
||||
*/
|
||||
if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
|
||||
proto == IPPROTO_ICMP) || (low == 0 && high == 0)) {
|
||||
/*
|
||||
* XXX bug: icmp state don't use the id on both sides.
|
||||
* (traceroute -l through nat)
|
||||
*/
|
||||
key.port[1] = sport;
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
|
||||
*nport = sport;
|
||||
return (0);
|
||||
}
|
||||
} else if (low == high) {
|
||||
key.port[1] = htons(low);
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
|
||||
*nport = htons(low);
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
uint16_t tmp;
|
||||
|
||||
if (low > high) {
|
||||
tmp = low;
|
||||
low = high;
|
||||
high = tmp;
|
||||
}
|
||||
/* low < high */
|
||||
#ifdef __FreeBSD__
|
||||
cut = htonl(arc4random()) % (1 + high - low) + low;
|
||||
#else
|
||||
cut = arc4random_uniform(1 + high - low) + low;
|
||||
#endif
|
||||
/* low <= cut <= high */
|
||||
for (tmp = cut; tmp <= high; ++(tmp)) {
|
||||
key.port[1] = htons(tmp);
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) ==
|
||||
#ifdef __FreeBSD__
|
||||
NULL) {
|
||||
#else
|
||||
NULL && !in_baddynamic(tmp, proto)) {
|
||||
#endif
|
||||
*nport = htons(tmp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
for (tmp = cut - 1; tmp >= low; --(tmp)) {
|
||||
key.port[1] = htons(tmp);
|
||||
if (pf_find_state_all(&key, PF_IN, NULL) ==
|
||||
#ifdef __FreeBSD__
|
||||
NULL) {
|
||||
#else
|
||||
NULL && !in_baddynamic(tmp, proto)) {
|
||||
#endif
|
||||
*nport = htons(tmp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (r->rpool.opts & PF_POOL_TYPEMASK) {
|
||||
case PF_POOL_RANDOM:
|
||||
case PF_POOL_ROUNDROBIN:
|
||||
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
|
||||
return (1);
|
||||
break;
|
||||
case PF_POOL_NONE:
|
||||
case PF_POOL_SRCHASH:
|
||||
case PF_POOL_BITMASK:
|
||||
default:
|
||||
return (1);
|
||||
}
|
||||
} while (! PF_AEQ(&init_addr, naddr, af) );
|
||||
return (1); /* none available */
|
||||
}
|
||||
|
||||
int
|
||||
pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
|
||||
struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
|
||||
{
|
||||
unsigned char hash[16];
|
||||
struct pf_pool *rpool = &r->rpool;
|
||||
struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
|
||||
struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
|
||||
struct pf_pooladdr *acur = rpool->cur;
|
||||
struct pf_src_node k;
|
||||
|
||||
if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
|
||||
(r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
|
||||
k.af = af;
|
||||
PF_ACPY(&k.addr, saddr, af);
|
||||
if (r->rule_flag & PFRULE_RULESRCTRACK ||
|
||||
r->rpool.opts & PF_POOL_STICKYADDR)
|
||||
k.rule.ptr = r;
|
||||
else
|
||||
k.rule.ptr = NULL;
|
||||
#ifdef __FreeBSD__
|
||||
V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
|
||||
*sn = RB_FIND(pf_src_tree, &V_tree_src_tracking, &k);
|
||||
#else
|
||||
pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
|
||||
*sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
|
||||
#endif
|
||||
if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
|
||||
PF_ACPY(naddr, &(*sn)->raddr, af);
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC) {
|
||||
#endif
|
||||
printf("pf_map_addr: src tracking maps ");
|
||||
pf_print_host(&k.addr, 0, af);
|
||||
printf(" to ");
|
||||
pf_print_host(naddr, 0, af);
|
||||
printf("\n");
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
|
||||
return (1);
|
||||
if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
|
||||
(rpool->opts & PF_POOL_TYPEMASK) !=
|
||||
PF_POOL_ROUNDROBIN)
|
||||
return (1);
|
||||
raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
|
||||
rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
|
||||
(rpool->opts & PF_POOL_TYPEMASK) !=
|
||||
PF_POOL_ROUNDROBIN)
|
||||
return (1);
|
||||
raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
|
||||
rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
} else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
|
||||
if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
|
||||
return (1); /* unsupported */
|
||||
} else {
|
||||
raddr = &rpool->cur->addr.v.a.addr;
|
||||
rmask = &rpool->cur->addr.v.a.mask;
|
||||
}
|
||||
|
||||
switch (rpool->opts & PF_POOL_TYPEMASK) {
|
||||
case PF_POOL_NONE:
|
||||
PF_ACPY(naddr, raddr, af);
|
||||
break;
|
||||
case PF_POOL_BITMASK:
|
||||
PF_POOLMASK(naddr, raddr, rmask, saddr, af);
|
||||
break;
|
||||
case PF_POOL_RANDOM:
|
||||
if (init_addr != NULL && PF_AZERO(init_addr, af)) {
|
||||
switch (af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
rpool->counter.addr32[0] = htonl(arc4random());
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (rmask->addr32[3] != 0xffffffff)
|
||||
rpool->counter.addr32[3] =
|
||||
htonl(arc4random());
|
||||
else
|
||||
break;
|
||||
if (rmask->addr32[2] != 0xffffffff)
|
||||
rpool->counter.addr32[2] =
|
||||
htonl(arc4random());
|
||||
else
|
||||
break;
|
||||
if (rmask->addr32[1] != 0xffffffff)
|
||||
rpool->counter.addr32[1] =
|
||||
htonl(arc4random());
|
||||
else
|
||||
break;
|
||||
if (rmask->addr32[0] != 0xffffffff)
|
||||
rpool->counter.addr32[0] =
|
||||
htonl(arc4random());
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
|
||||
PF_ACPY(init_addr, naddr, af);
|
||||
|
||||
} else {
|
||||
PF_AINC(&rpool->counter, af);
|
||||
PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
|
||||
}
|
||||
break;
|
||||
case PF_POOL_SRCHASH:
|
||||
pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
|
||||
PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
|
||||
break;
|
||||
case PF_POOL_ROUNDROBIN:
|
||||
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
|
||||
if (!pfr_pool_get(rpool->cur->addr.p.tbl,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af))
|
||||
goto get_addr;
|
||||
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
|
||||
if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af))
|
||||
goto get_addr;
|
||||
} else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
|
||||
goto get_addr;
|
||||
|
||||
try_next:
|
||||
if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
|
||||
rpool->cur = TAILQ_FIRST(&rpool->list);
|
||||
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
|
||||
rpool->tblidx = -1;
|
||||
if (pfr_pool_get(rpool->cur->addr.p.tbl,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af)) {
|
||||
/* table contains no address of type 'af' */
|
||||
if (rpool->cur != acur)
|
||||
goto try_next;
|
||||
return (1);
|
||||
}
|
||||
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
|
||||
rpool->tblidx = -1;
|
||||
if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
|
||||
&rpool->tblidx, &rpool->counter,
|
||||
&raddr, &rmask, af)) {
|
||||
/* table contains no address of type 'af' */
|
||||
if (rpool->cur != acur)
|
||||
goto try_next;
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
raddr = &rpool->cur->addr.v.a.addr;
|
||||
rmask = &rpool->cur->addr.v.a.mask;
|
||||
PF_ACPY(&rpool->counter, raddr, af);
|
||||
}
|
||||
|
||||
get_addr:
|
||||
PF_ACPY(naddr, &rpool->counter, af);
|
||||
if (init_addr != NULL && PF_AZERO(init_addr, af))
|
||||
PF_ACPY(init_addr, naddr, af);
|
||||
PF_AINC(&rpool->counter, af);
|
||||
break;
|
||||
}
|
||||
if (*sn != NULL)
|
||||
PF_ACPY(&(*sn)->raddr, naddr, af);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (V_pf_status.debug >= PF_DEBUG_MISC &&
|
||||
#else
|
||||
if (pf_status.debug >= PF_DEBUG_MISC &&
|
||||
#endif
|
||||
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
|
||||
printf("pf_map_addr: selected address ");
|
||||
pf_print_host(naddr, 0, af);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct pf_rule *
|
||||
pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
|
||||
struct pfi_kif *kif, struct pf_src_node **sn,
|
||||
struct pf_state_key **skw, struct pf_state_key **sks,
|
||||
struct pf_state_key **skp, struct pf_state_key **nkp,
|
||||
struct pf_addr *saddr, struct pf_addr *daddr,
|
||||
u_int16_t sport, u_int16_t dport)
|
||||
{
|
||||
struct pf_rule *r = NULL;
|
||||
|
||||
|
||||
if (direction == PF_OUT) {
|
||||
r = pf_match_translation(pd, m, off, direction, kif, saddr,
|
||||
sport, daddr, dport, PF_RULESET_BINAT);
|
||||
if (r == NULL)
|
||||
r = pf_match_translation(pd, m, off, direction, kif,
|
||||
saddr, sport, daddr, dport, PF_RULESET_NAT);
|
||||
} else {
|
||||
r = pf_match_translation(pd, m, off, direction, kif, saddr,
|
||||
sport, daddr, dport, PF_RULESET_RDR);
|
||||
if (r == NULL)
|
||||
r = pf_match_translation(pd, m, off, direction, kif,
|
||||
saddr, sport, daddr, dport, PF_RULESET_BINAT);
|
||||
}
|
||||
|
||||
if (r != NULL) {
|
||||
struct pf_addr *naddr;
|
||||
u_int16_t *nport;
|
||||
|
||||
if (pf_state_key_setup(pd, r, skw, sks, skp, nkp,
|
||||
saddr, daddr, sport, dport))
|
||||
return r;
|
||||
|
||||
/* XXX We only modify one side for now. */
|
||||
naddr = &(*nkp)->addr[1];
|
||||
nport = &(*nkp)->port[1];
|
||||
|
||||
switch (r->action) {
|
||||
case PF_NONAT:
|
||||
case PF_NOBINAT:
|
||||
case PF_NORDR:
|
||||
return (NULL);
|
||||
case PF_NAT:
|
||||
if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, daddr,
|
||||
dport, naddr, nport, r->rpool.proxy_port[0],
|
||||
r->rpool.proxy_port[1], sn)) {
|
||||
DPFPRINTF(PF_DEBUG_MISC,
|
||||
("pf: NAT proxy port allocation "
|
||||
"(%u-%u) failed\n",
|
||||
r->rpool.proxy_port[0],
|
||||
r->rpool.proxy_port[1]));
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
case PF_BINAT:
|
||||
switch (direction) {
|
||||
case PF_OUT:
|
||||
if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
|
||||
switch (pd->af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (r->rpool.cur->addr.p.dyn->
|
||||
pfid_acnt4 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr4,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_mask4,
|
||||
saddr, AF_INET);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (r->rpool.cur->addr.p.dyn->
|
||||
pfid_acnt6 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_addr6,
|
||||
&r->rpool.cur->addr.p.dyn->
|
||||
pfid_mask6,
|
||||
saddr, AF_INET6);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
} else
|
||||
PF_POOLMASK(naddr,
|
||||
&r->rpool.cur->addr.v.a.addr,
|
||||
&r->rpool.cur->addr.v.a.mask,
|
||||
saddr, pd->af);
|
||||
break;
|
||||
case PF_IN:
|
||||
if (r->src.addr.type == PF_ADDR_DYNIFTL) {
|
||||
switch (pd->af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (r->src.addr.p.dyn->
|
||||
pfid_acnt4 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_addr4,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_mask4,
|
||||
daddr, AF_INET);
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (r->src.addr.p.dyn->
|
||||
pfid_acnt6 < 1)
|
||||
return (NULL);
|
||||
PF_POOLMASK(naddr,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_addr6,
|
||||
&r->src.addr.p.dyn->
|
||||
pfid_mask6,
|
||||
daddr, AF_INET6);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
} else
|
||||
PF_POOLMASK(naddr,
|
||||
&r->src.addr.v.a.addr,
|
||||
&r->src.addr.v.a.mask, daddr,
|
||||
pd->af);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PF_RDR: {
|
||||
if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
|
||||
return (NULL);
|
||||
if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
|
||||
PF_POOL_BITMASK)
|
||||
PF_POOLMASK(naddr, naddr,
|
||||
&r->rpool.cur->addr.v.a.mask, daddr,
|
||||
pd->af);
|
||||
|
||||
if (r->rpool.proxy_port[1]) {
|
||||
u_int32_t tmp_nport;
|
||||
|
||||
tmp_nport = ((ntohs(dport) -
|
||||
ntohs(r->dst.port[0])) %
|
||||
(r->rpool.proxy_port[1] -
|
||||
r->rpool.proxy_port[0] + 1)) +
|
||||
r->rpool.proxy_port[0];
|
||||
|
||||
/* wrap around if necessary */
|
||||
if (tmp_nport > 65535)
|
||||
tmp_nport -= 65535;
|
||||
*nport = htons((u_int16_t)tmp_nport);
|
||||
} else if (r->rpool.proxy_port[0])
|
||||
*nport = htons(r->rpool.proxy_port[0]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Translation was a NOP.
|
||||
* Pretend there was no match.
|
||||
*/
|
||||
if (!bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) {
|
||||
#ifdef __FreeBSD__
|
||||
pool_put(&V_pf_state_key_pl, *nkp);
|
||||
pool_put(&V_pf_state_key_pl, *skp);
|
||||
#else
|
||||
pool_put(&pf_state_key_pl, *nkp);
|
||||
pool_put(&pf_state_key_pl, *skp);
|
||||
#endif
|
||||
*skw = *sks = *nkp = *skp = NULL;
|
||||
*sn = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
@@ -1,84 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NET_PF_MTAG_H_
|
||||
#define _NET_PF_MTAG_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define PF_TAG_GENERATED 0x01
|
||||
#define PF_TAG_FRAGCACHE 0x02
|
||||
#define PF_TAG_TRANSLATE_LOCALHOST 0x04
|
||||
#define PF_PACKET_LOOPED 0x08
|
||||
#define PF_FASTFWD_OURS_PRESENT 0x10
|
||||
|
||||
struct pf_mtag {
|
||||
void *hdr; /* saved hdr pos in mbuf, for ECN */
|
||||
void *statekey; /* pf stackside statekey */
|
||||
u_int32_t qid; /* queue id */
|
||||
u_int rtableid; /* alternate routing table id */
|
||||
u_int16_t tag; /* tag id */
|
||||
u_int8_t flags;
|
||||
u_int8_t routed;
|
||||
};
|
||||
|
||||
static __inline struct pf_mtag *pf_find_mtag(struct mbuf *);
|
||||
static __inline struct pf_mtag *pf_get_mtag(struct mbuf *);
|
||||
|
||||
static __inline struct pf_mtag *
|
||||
pf_find_mtag(struct mbuf *m)
|
||||
{
|
||||
struct m_tag *mtag;
|
||||
|
||||
if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
return ((struct pf_mtag *)(mtag + 1));
|
||||
}
|
||||
|
||||
static __inline struct pf_mtag *
|
||||
pf_get_mtag(struct mbuf *m)
|
||||
{
|
||||
struct m_tag *mtag;
|
||||
|
||||
if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) {
|
||||
mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag),
|
||||
M_NOWAIT);
|
||||
if (mtag == NULL)
|
||||
return (NULL);
|
||||
bzero(mtag + 1, sizeof(struct pf_mtag));
|
||||
m_tag_prepend(m, mtag);
|
||||
}
|
||||
|
||||
return ((struct pf_mtag *)(mtag + 1));
|
||||
}
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _NET_PF_MTAG_H_ */
|
File diff suppressed because it is too large
Load Diff
@@ -1,708 +0,0 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/* $OpenBSD: pf_osfp.c,v 1.14 2008/06/12 18:17:01 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef _KERNEL
|
||||
#include <sys/systm.h>
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/pool.h>
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
#include <sys/mbuf.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
|
||||
#include <netinet/ip6.h>
|
||||
#ifdef _KERNEL
|
||||
#include <netinet6/in6_var.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef __FreeBSD__
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (V_pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#else
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#endif
|
||||
#ifdef __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. */
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#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)
|
||||
#define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size)
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define NTOHS(x) (x) = ntohs((u_int16_t)(x))
|
||||
#endif
|
||||
|
||||
#ifdef PFDEBUG
|
||||
#include <sys/stdarg.h>
|
||||
#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
#else
|
||||
#define DPFPRINTF(format, x...) ((void)0)
|
||||
#endif /* PFDEBUG */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
SLIST_HEAD(pf_osfp_list, pf_os_fingerprint);
|
||||
VNET_DEFINE(struct pf_osfp_list, pf_osfp_list);
|
||||
#define V_pf_osfp_list VNET(pf_osfp_list)
|
||||
VNET_DEFINE(pool_t, pf_osfp_entry_pl);
|
||||
#define pf_osfp_entry_pl VNET(pf_osfp_entry_pl)
|
||||
VNET_DEFINE(pool_t, pf_osfp_pl);
|
||||
#define pf_osfp_pl VNET(pf_osfp_pl)
|
||||
#else
|
||||
SLIST_HEAD(pf_osfp_list, pf_os_fingerprint) pf_osfp_list;
|
||||
pool_t pf_osfp_entry_pl;
|
||||
pool_t pf_osfp_pl;
|
||||
#endif
|
||||
|
||||
struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *,
|
||||
struct pf_os_fingerprint *, u_int8_t);
|
||||
struct pf_os_fingerprint *pf_osfp_find_exact(struct pf_osfp_list *,
|
||||
struct pf_os_fingerprint *);
|
||||
void pf_osfp_insert(struct pf_osfp_list *,
|
||||
struct pf_os_fingerprint *);
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Passively fingerprint the OS of the host (IPv4 TCP SYN packets only)
|
||||
* Returns the list of possible OSes.
|
||||
*/
|
||||
struct pf_osfp_enlist *
|
||||
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];
|
||||
|
||||
if ((pd->af != PF_INET && pd->af != PF_INET6) ||
|
||||
pd->proto != IPPROTO_TCP || (tcp->th_off << 2) < sizeof(*tcp))
|
||||
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, ip6, (struct tcphdr *)hdr));
|
||||
}
|
||||
#endif /* _KERNEL */
|
||||
|
||||
struct pf_osfp_enlist *
|
||||
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)
|
||||
return (NULL);
|
||||
if (ip) {
|
||||
if ((ip->ip_off & htons(IP_OFFMASK)) != 0)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memset(&fp, 0, sizeof(fp));
|
||||
|
||||
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
|
||||
#ifdef __rtems__
|
||||
char ip6buf[INET6_ADDRSTRLEN];
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/* 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
|
||||
#ifndef __rtems__
|
||||
strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src),
|
||||
sizeof(srcname));
|
||||
#else /* __rtems__ */
|
||||
strlcpy(srcname, ip6_sprintf(ip6buf, (struct in6_addr *)&ip6->ip6_src),
|
||||
sizeof(srcname));
|
||||
#endif /* __rtems__ */
|
||||
#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);
|
||||
|
||||
|
||||
cnt = (tcp->th_off << 2) - sizeof(*tcp);
|
||||
optp = (const u_int8_t *)((const char *)tcp + sizeof(*tcp));
|
||||
for (; cnt > 0; cnt -= optlen, optp += optlen) {
|
||||
if (*optp == TCPOPT_EOL)
|
||||
break;
|
||||
|
||||
fp.fp_optcnt++;
|
||||
if (*optp == TCPOPT_NOP) {
|
||||
fp.fp_tcpopts = (fp.fp_tcpopts << PF_OSFP_TCPOPT_BITS) |
|
||||
PF_OSFP_TCPOPT_NOP;
|
||||
optlen = 1;
|
||||
} else {
|
||||
if (cnt < 2)
|
||||
return (NULL);
|
||||
optlen = optp[1];
|
||||
if (optlen > cnt || optlen < 2)
|
||||
return (NULL);
|
||||
switch (*optp) {
|
||||
case TCPOPT_MAXSEG:
|
||||
if (optlen >= TCPOLEN_MAXSEG)
|
||||
memcpy(&fp.fp_mss, &optp[2],
|
||||
sizeof(fp.fp_mss));
|
||||
fp.fp_tcpopts = (fp.fp_tcpopts <<
|
||||
PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_MSS;
|
||||
NTOHS(fp.fp_mss);
|
||||
break;
|
||||
case TCPOPT_WINDOW:
|
||||
if (optlen >= TCPOLEN_WINDOW)
|
||||
memcpy(&fp.fp_wscale, &optp[2],
|
||||
sizeof(fp.fp_wscale));
|
||||
NTOHS(fp.fp_wscale);
|
||||
fp.fp_tcpopts = (fp.fp_tcpopts <<
|
||||
PF_OSFP_TCPOPT_BITS) |
|
||||
PF_OSFP_TCPOPT_WSCALE;
|
||||
break;
|
||||
case TCPOPT_SACK_PERMITTED:
|
||||
fp.fp_tcpopts = (fp.fp_tcpopts <<
|
||||
PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_SACK;
|
||||
break;
|
||||
case TCPOPT_TIMESTAMP:
|
||||
if (optlen >= TCPOLEN_TIMESTAMP) {
|
||||
u_int32_t ts;
|
||||
memcpy(&ts, &optp[2], sizeof(ts));
|
||||
if (ts == 0)
|
||||
fp.fp_flags |= PF_OSFP_TS0;
|
||||
|
||||
}
|
||||
fp.fp_tcpopts = (fp.fp_tcpopts <<
|
||||
PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_TS;
|
||||
break;
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
optlen = MAX(optlen, 1); /* paranoia */
|
||||
}
|
||||
|
||||
DPFPRINTF("fingerprinted %s:%d %d:%d:%d:%d:%llx (%d) "
|
||||
"(TS=%s,M=%s%d,W=%s%d)\n",
|
||||
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" : "",
|
||||
(fp.fp_flags & PF_OSFP_MSS_MOD) ? "%" :
|
||||
(fp.fp_flags & PF_OSFP_MSS_DC) ? "*" : "",
|
||||
fp.fp_mss,
|
||||
(fp.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" :
|
||||
(fp.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
|
||||
fp.fp_wscale);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if ((fpresult = pf_osfp_find(&V_pf_osfp_list, &fp,
|
||||
#else
|
||||
if ((fpresult = pf_osfp_find(&pf_osfp_list, &fp,
|
||||
#endif
|
||||
PF_OSFP_MAXTTL_OFFSET)))
|
||||
return (&fpresult->fp_oses);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Match a fingerprint ID against a list of OSes */
|
||||
int
|
||||
pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os)
|
||||
{
|
||||
struct pf_osfp_entry *entry;
|
||||
int os_class, os_version, os_subtype;
|
||||
int en_class, en_version, en_subtype;
|
||||
|
||||
if (os == PF_OSFP_ANY)
|
||||
return (1);
|
||||
if (list == NULL) {
|
||||
DPFPRINTF("osfp no match against %x\n", os);
|
||||
return (os == PF_OSFP_UNKNOWN);
|
||||
}
|
||||
PF_OSFP_UNPACK(os, os_class, os_version, os_subtype);
|
||||
SLIST_FOREACH(entry, list, fp_entry) {
|
||||
PF_OSFP_UNPACK(entry->fp_os, en_class, en_version, en_subtype);
|
||||
if ((os_class == PF_OSFP_ANY || en_class == os_class) &&
|
||||
(os_version == PF_OSFP_ANY || en_version == os_version) &&
|
||||
(os_subtype == PF_OSFP_ANY || en_subtype == os_subtype)) {
|
||||
DPFPRINTF("osfp matched %s %s %s %x==%x\n",
|
||||
entry->fp_class_nm, entry->fp_version_nm,
|
||||
entry->fp_subtype_nm, os, entry->fp_os);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
DPFPRINTF("fingerprint 0x%x didn't match\n", os);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Initialize the OS fingerprint system */
|
||||
#ifdef __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);
|
||||
|
||||
SLIST_INIT(&V_pf_osfp_list);
|
||||
#else
|
||||
pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0,
|
||||
"pfosfpen", &pool_allocator_nointr);
|
||||
pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0,
|
||||
"pfosfp", &pool_allocator_nointr);
|
||||
SLIST_INIT(&pf_osfp_list);
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#ifdef _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)
|
||||
{
|
||||
struct pf_os_fingerprint *fp;
|
||||
struct pf_osfp_entry *entry;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
while ((fp = SLIST_FIRST(&V_pf_osfp_list))) {
|
||||
SLIST_REMOVE_HEAD(&V_pf_osfp_list, fp_next);
|
||||
#else
|
||||
while ((fp = SLIST_FIRST(&pf_osfp_list))) {
|
||||
SLIST_REMOVE_HEAD(&pf_osfp_list, fp_next);
|
||||
#endif
|
||||
while ((entry = SLIST_FIRST(&fp->fp_oses))) {
|
||||
SLIST_REMOVE_HEAD(&fp->fp_oses, fp_entry);
|
||||
pool_put(&pf_osfp_entry_pl, entry);
|
||||
}
|
||||
pool_put(&pf_osfp_pl, fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add a fingerprint */
|
||||
int
|
||||
pf_osfp_add(struct pf_osfp_ioctl *fpioc)
|
||||
{
|
||||
struct pf_os_fingerprint *fp, fpadd;
|
||||
struct pf_osfp_entry *entry;
|
||||
|
||||
memset(&fpadd, 0, sizeof(fpadd));
|
||||
fpadd.fp_tcpopts = fpioc->fp_tcpopts;
|
||||
fpadd.fp_wsize = fpioc->fp_wsize;
|
||||
fpadd.fp_psize = fpioc->fp_psize;
|
||||
fpadd.fp_mss = fpioc->fp_mss;
|
||||
fpadd.fp_flags = fpioc->fp_flags;
|
||||
fpadd.fp_optcnt = fpioc->fp_optcnt;
|
||||
fpadd.fp_wscale = fpioc->fp_wscale;
|
||||
fpadd.fp_ttl = fpioc->fp_ttl;
|
||||
|
||||
#if 0 /* XXX RYAN wants to fix logging */
|
||||
DPFPRINTF("adding osfp %s %s %s = %s%d:%d:%d:%s%d:0x%llx %d "
|
||||
"(TS=%s,M=%s%d,W=%s%d) %x\n",
|
||||
fpioc->fp_os.fp_class_nm, fpioc->fp_os.fp_version_nm,
|
||||
fpioc->fp_os.fp_subtype_nm,
|
||||
(fpadd.fp_flags & PF_OSFP_WSIZE_MOD) ? "%" :
|
||||
(fpadd.fp_flags & PF_OSFP_WSIZE_MSS) ? "S" :
|
||||
(fpadd.fp_flags & PF_OSFP_WSIZE_MTU) ? "T" :
|
||||
(fpadd.fp_flags & PF_OSFP_WSIZE_DC) ? "*" : "",
|
||||
fpadd.fp_wsize,
|
||||
fpadd.fp_ttl,
|
||||
(fpadd.fp_flags & PF_OSFP_DF) ? 1 : 0,
|
||||
(fpadd.fp_flags & PF_OSFP_PSIZE_MOD) ? "%" :
|
||||
(fpadd.fp_flags & PF_OSFP_PSIZE_DC) ? "*" : "",
|
||||
fpadd.fp_psize,
|
||||
(long long int)fpadd.fp_tcpopts, fpadd.fp_optcnt,
|
||||
(fpadd.fp_flags & PF_OSFP_TS0) ? "0" : "",
|
||||
(fpadd.fp_flags & PF_OSFP_MSS_MOD) ? "%" :
|
||||
(fpadd.fp_flags & PF_OSFP_MSS_DC) ? "*" : "",
|
||||
fpadd.fp_mss,
|
||||
(fpadd.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" :
|
||||
(fpadd.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
|
||||
fpadd.fp_wscale,
|
||||
fpioc->fp_os.fp_os);
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if ((fp = pf_osfp_find_exact(&V_pf_osfp_list, &fpadd))) {
|
||||
#else
|
||||
if ((fp = pf_osfp_find_exact(&pf_osfp_list, &fpadd))) {
|
||||
#endif
|
||||
SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
|
||||
if (PF_OSFP_ENTRY_EQ(entry, &fpioc->fp_os))
|
||||
return (EEXIST);
|
||||
}
|
||||
if ((entry = pool_get(&pf_osfp_entry_pl,
|
||||
#ifdef __FreeBSD__
|
||||
PR_NOWAIT)) == NULL)
|
||||
#else
|
||||
PR_WAITOK|PR_LIMITFAIL)) == NULL)
|
||||
#endif
|
||||
return (ENOMEM);
|
||||
} else {
|
||||
if ((fp = pool_get(&pf_osfp_pl,
|
||||
#ifdef __FreeBSD__
|
||||
PR_NOWAIT)) == NULL)
|
||||
#else
|
||||
PR_WAITOK|PR_LIMITFAIL)) == NULL)
|
||||
#endif
|
||||
return (ENOMEM);
|
||||
memset(fp, 0, sizeof(*fp));
|
||||
fp->fp_tcpopts = fpioc->fp_tcpopts;
|
||||
fp->fp_wsize = fpioc->fp_wsize;
|
||||
fp->fp_psize = fpioc->fp_psize;
|
||||
fp->fp_mss = fpioc->fp_mss;
|
||||
fp->fp_flags = fpioc->fp_flags;
|
||||
fp->fp_optcnt = fpioc->fp_optcnt;
|
||||
fp->fp_wscale = fpioc->fp_wscale;
|
||||
fp->fp_ttl = fpioc->fp_ttl;
|
||||
SLIST_INIT(&fp->fp_oses);
|
||||
if ((entry = pool_get(&pf_osfp_entry_pl,
|
||||
#ifdef __FreeBSD__
|
||||
PR_NOWAIT)) == NULL) {
|
||||
#else
|
||||
PR_WAITOK|PR_LIMITFAIL)) == NULL) {
|
||||
#endif
|
||||
pool_put(&pf_osfp_pl, fp);
|
||||
return (ENOMEM);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
pf_osfp_insert(&V_pf_osfp_list, fp);
|
||||
#else
|
||||
pf_osfp_insert(&pf_osfp_list, fp);
|
||||
#endif
|
||||
}
|
||||
memcpy(entry, &fpioc->fp_os, sizeof(*entry));
|
||||
|
||||
/* Make sure the strings are NUL terminated */
|
||||
entry->fp_class_nm[sizeof(entry->fp_class_nm)-1] = '\0';
|
||||
entry->fp_version_nm[sizeof(entry->fp_version_nm)-1] = '\0';
|
||||
entry->fp_subtype_nm[sizeof(entry->fp_subtype_nm)-1] = '\0';
|
||||
|
||||
SLIST_INSERT_HEAD(&fp->fp_oses, entry, fp_entry);
|
||||
|
||||
#ifdef PFDEBUG
|
||||
if ((fp = pf_osfp_validate()))
|
||||
printf("Invalid fingerprint list\n");
|
||||
#endif /* PFDEBUG */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/* Find a fingerprint in the list */
|
||||
struct pf_os_fingerprint *
|
||||
pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
|
||||
u_int8_t ttldiff)
|
||||
{
|
||||
struct pf_os_fingerprint *f;
|
||||
|
||||
#define MATCH_INT(_MOD, _DC, _field) \
|
||||
if ((f->fp_flags & _DC) == 0) { \
|
||||
if ((f->fp_flags & _MOD) == 0) { \
|
||||
if (f->_field != find->_field) \
|
||||
continue; \
|
||||
} else { \
|
||||
if (f->_field == 0 || find->_field % f->_field) \
|
||||
continue; \
|
||||
} \
|
||||
}
|
||||
|
||||
SLIST_FOREACH(f, list, fp_next) {
|
||||
if (f->fp_tcpopts != find->fp_tcpopts ||
|
||||
f->fp_optcnt != find->fp_optcnt ||
|
||||
f->fp_ttl < find->fp_ttl ||
|
||||
f->fp_ttl - find->fp_ttl > ttldiff ||
|
||||
(f->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)) !=
|
||||
(find->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)))
|
||||
continue;
|
||||
|
||||
MATCH_INT(PF_OSFP_PSIZE_MOD, PF_OSFP_PSIZE_DC, fp_psize)
|
||||
MATCH_INT(PF_OSFP_MSS_MOD, PF_OSFP_MSS_DC, fp_mss)
|
||||
MATCH_INT(PF_OSFP_WSCALE_MOD, PF_OSFP_WSCALE_DC, fp_wscale)
|
||||
if ((f->fp_flags & PF_OSFP_WSIZE_DC) == 0) {
|
||||
if (f->fp_flags & PF_OSFP_WSIZE_MSS) {
|
||||
if (find->fp_mss == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Some "smart" NAT devices and DSL routers will tweak the MSS size and
|
||||
* will set it to whatever is suitable for the link type.
|
||||
*/
|
||||
#define SMART_MSS 1460
|
||||
if ((find->fp_wsize % find->fp_mss ||
|
||||
find->fp_wsize / find->fp_mss !=
|
||||
f->fp_wsize) &&
|
||||
(find->fp_wsize % SMART_MSS ||
|
||||
find->fp_wsize / SMART_MSS !=
|
||||
f->fp_wsize))
|
||||
continue;
|
||||
} else if (f->fp_flags & PF_OSFP_WSIZE_MTU) {
|
||||
if (find->fp_mss == 0)
|
||||
continue;
|
||||
|
||||
#define MTUOFF (sizeof(struct ip) + sizeof(struct tcphdr))
|
||||
#define SMART_MTU (SMART_MSS + MTUOFF)
|
||||
if ((find->fp_wsize % (find->fp_mss + MTUOFF) ||
|
||||
find->fp_wsize / (find->fp_mss + MTUOFF) !=
|
||||
f->fp_wsize) &&
|
||||
(find->fp_wsize % SMART_MTU ||
|
||||
find->fp_wsize / SMART_MTU !=
|
||||
f->fp_wsize))
|
||||
continue;
|
||||
} else if (f->fp_flags & PF_OSFP_WSIZE_MOD) {
|
||||
if (f->fp_wsize == 0 || find->fp_wsize %
|
||||
f->fp_wsize)
|
||||
continue;
|
||||
} else {
|
||||
if (f->fp_wsize != find->fp_wsize)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return (f);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Find an exact fingerprint in the list */
|
||||
struct pf_os_fingerprint *
|
||||
pf_osfp_find_exact(struct pf_osfp_list *list, struct pf_os_fingerprint *find)
|
||||
{
|
||||
struct pf_os_fingerprint *f;
|
||||
|
||||
SLIST_FOREACH(f, list, fp_next) {
|
||||
if (f->fp_tcpopts == find->fp_tcpopts &&
|
||||
f->fp_wsize == find->fp_wsize &&
|
||||
f->fp_psize == find->fp_psize &&
|
||||
f->fp_mss == find->fp_mss &&
|
||||
f->fp_flags == find->fp_flags &&
|
||||
f->fp_optcnt == find->fp_optcnt &&
|
||||
f->fp_wscale == find->fp_wscale &&
|
||||
f->fp_ttl == find->fp_ttl)
|
||||
return (f);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Insert a fingerprint into the list */
|
||||
void
|
||||
pf_osfp_insert(struct pf_osfp_list *list, struct pf_os_fingerprint *ins)
|
||||
{
|
||||
struct pf_os_fingerprint *f, *prev = NULL;
|
||||
|
||||
/* XXX need to go semi tree based. can key on tcp options */
|
||||
|
||||
SLIST_FOREACH(f, list, fp_next)
|
||||
prev = f;
|
||||
if (prev)
|
||||
SLIST_INSERT_AFTER(prev, ins, fp_next);
|
||||
else
|
||||
SLIST_INSERT_HEAD(list, ins, fp_next);
|
||||
}
|
||||
|
||||
/* Fill a fingerprint by its number (from an ioctl) */
|
||||
int
|
||||
pf_osfp_get(struct pf_osfp_ioctl *fpioc)
|
||||
{
|
||||
struct pf_os_fingerprint *fp;
|
||||
struct pf_osfp_entry *entry;
|
||||
int num = fpioc->fp_getnum;
|
||||
int i = 0;
|
||||
|
||||
|
||||
memset(fpioc, 0, sizeof(*fpioc));
|
||||
#ifdef __FreeBSD__
|
||||
SLIST_FOREACH(fp, &V_pf_osfp_list, fp_next) {
|
||||
#else
|
||||
SLIST_FOREACH(fp, &pf_osfp_list, fp_next) {
|
||||
#endif
|
||||
SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
|
||||
if (i++ == num) {
|
||||
fpioc->fp_mss = fp->fp_mss;
|
||||
fpioc->fp_wsize = fp->fp_wsize;
|
||||
fpioc->fp_flags = fp->fp_flags;
|
||||
fpioc->fp_psize = fp->fp_psize;
|
||||
fpioc->fp_ttl = fp->fp_ttl;
|
||||
fpioc->fp_wscale = fp->fp_wscale;
|
||||
fpioc->fp_getnum = num;
|
||||
memcpy(&fpioc->fp_os, entry,
|
||||
sizeof(fpioc->fp_os));
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
|
||||
/* Validate that each signature is reachable */
|
||||
struct pf_os_fingerprint *
|
||||
pf_osfp_validate(void)
|
||||
{
|
||||
struct pf_os_fingerprint *f, *f2, find;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
SLIST_FOREACH(f, &V_pf_osfp_list, fp_next) {
|
||||
#else
|
||||
SLIST_FOREACH(f, &pf_osfp_list, fp_next) {
|
||||
#endif
|
||||
memcpy(&find, f, sizeof(find));
|
||||
|
||||
/* We do a few MSS/th_win percolations to make things unique */
|
||||
if (find.fp_mss == 0)
|
||||
find.fp_mss = 128;
|
||||
if (f->fp_flags & PF_OSFP_WSIZE_MSS)
|
||||
find.fp_wsize *= find.fp_mss;
|
||||
else if (f->fp_flags & PF_OSFP_WSIZE_MTU)
|
||||
find.fp_wsize *= (find.fp_mss + 40);
|
||||
else if (f->fp_flags & PF_OSFP_WSIZE_MOD)
|
||||
find.fp_wsize *= 2;
|
||||
#ifdef __FreeBSD__
|
||||
if (f != (f2 = pf_osfp_find(&V_pf_osfp_list, &find, 0))) {
|
||||
#else
|
||||
if (f != (f2 = pf_osfp_find(&pf_osfp_list, &find, 0))) {
|
||||
#endif
|
||||
if (f2)
|
||||
printf("Found \"%s %s %s\" instead of "
|
||||
"\"%s %s %s\"\n",
|
||||
SLIST_FIRST(&f2->fp_oses)->fp_class_nm,
|
||||
SLIST_FIRST(&f2->fp_oses)->fp_version_nm,
|
||||
SLIST_FIRST(&f2->fp_oses)->fp_subtype_nm,
|
||||
SLIST_FIRST(&f->fp_oses)->fp_class_nm,
|
||||
SLIST_FIRST(&f->fp_oses)->fp_version_nm,
|
||||
SLIST_FIRST(&f->fp_oses)->fp_subtype_nm);
|
||||
else
|
||||
printf("Couldn't find \"%s %s %s\"\n",
|
||||
SLIST_FIRST(&f->fp_oses)->fp_class_nm,
|
||||
SLIST_FIRST(&f->fp_oses)->fp_version_nm,
|
||||
SLIST_FIRST(&f->fp_oses)->fp_subtype_nm);
|
||||
return (f);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
@@ -1,459 +0,0 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/* $OpenBSD: pf_ruleset.c,v 1.2 2008/12/18 15:31:37 dhill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
* Copyright (c) 2002,2003 Henning Brauer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Effort sponsored in part by the Defense Advanced Research Projects
|
||||
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
* Materiel Command, USAF, under agreement number F30602-01-2-0537.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef _KERNEL
|
||||
# include <sys/systm.h>
|
||||
#endif /* _KERNEL */
|
||||
#include <sys/mbuf.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet/ip6.h>
|
||||
#endif /* INET6 */
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef __FreeBSD__
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (V_pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#else
|
||||
#define DPFPRINTF(format, x...) \
|
||||
if (pf_status.debug >= PF_DEBUG_NOISY) \
|
||||
printf(format , ##x)
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_NOWAIT|M_ZERO)
|
||||
#else
|
||||
#define rs_malloc(x) malloc(x, M_TEMP, M_WAITOK|M_CANFAIL|M_ZERO)
|
||||
#endif
|
||||
#define rs_free(x) free(x, M_TEMP)
|
||||
|
||||
#else
|
||||
/* Userland equivalents so we can lend code to pfctl et al. */
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define rs_malloc(x) calloc(1, x)
|
||||
#define rs_free(x) free(x)
|
||||
|
||||
#ifdef PFDEBUG
|
||||
#include <sys/stdarg.h>
|
||||
#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
|
||||
#else
|
||||
#define DPFPRINTF(format, x...) ((void)0)
|
||||
#endif /* PFDEBUG */
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(_KERNEL)
|
||||
#undef V_pf_anchors
|
||||
#define V_pf_anchors pf_anchors
|
||||
|
||||
#undef pf_main_ruleset
|
||||
#define pf_main_ruleset pf_main_anchor.ruleset
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) && defined(_KERNEL)
|
||||
VNET_DEFINE(struct pf_anchor_global, pf_anchors);
|
||||
VNET_DEFINE(struct pf_anchor, pf_main_anchor);
|
||||
#else
|
||||
struct pf_anchor_global pf_anchors;
|
||||
struct pf_anchor pf_main_anchor;
|
||||
#endif
|
||||
|
||||
static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
|
||||
|
||||
RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
|
||||
RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
|
||||
|
||||
static __inline int
|
||||
pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
|
||||
{
|
||||
int c = strcmp(a->path, b->path);
|
||||
|
||||
return (c ? (c < 0 ? -1 : 1) : 0);
|
||||
}
|
||||
|
||||
int
|
||||
pf_get_ruleset_number(u_int8_t action)
|
||||
{
|
||||
switch (action) {
|
||||
case PF_SCRUB:
|
||||
case PF_NOSCRUB:
|
||||
return (PF_RULESET_SCRUB);
|
||||
break;
|
||||
case PF_PASS:
|
||||
case PF_DROP:
|
||||
return (PF_RULESET_FILTER);
|
||||
break;
|
||||
case PF_NAT:
|
||||
case PF_NONAT:
|
||||
return (PF_RULESET_NAT);
|
||||
break;
|
||||
case PF_BINAT:
|
||||
case PF_NOBINAT:
|
||||
return (PF_RULESET_BINAT);
|
||||
break;
|
||||
case PF_RDR:
|
||||
case PF_NORDR:
|
||||
return (PF_RULESET_RDR);
|
||||
break;
|
||||
default:
|
||||
return (PF_RULESET_MAX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pf_init_ruleset(struct pf_ruleset *ruleset)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(ruleset, 0, sizeof(struct pf_ruleset));
|
||||
for (i = 0; i < PF_RULESET_MAX; i++) {
|
||||
TAILQ_INIT(&ruleset->rules[i].queues[0]);
|
||||
TAILQ_INIT(&ruleset->rules[i].queues[1]);
|
||||
ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
|
||||
ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
|
||||
}
|
||||
}
|
||||
|
||||
struct pf_anchor *
|
||||
pf_find_anchor(const char *path)
|
||||
{
|
||||
struct pf_anchor *key, *found;
|
||||
|
||||
key = (struct pf_anchor *)rs_malloc(sizeof(*key));
|
||||
if (key == NULL)
|
||||
return (NULL);
|
||||
strlcpy(key->path, path, sizeof(key->path));
|
||||
#ifdef __FreeBSD__
|
||||
found = RB_FIND(pf_anchor_global, &V_pf_anchors, key);
|
||||
#else
|
||||
found = RB_FIND(pf_anchor_global, &pf_anchors, key);
|
||||
#endif
|
||||
rs_free(key);
|
||||
return (found);
|
||||
}
|
||||
|
||||
struct pf_ruleset *
|
||||
pf_find_ruleset(const char *path)
|
||||
{
|
||||
struct pf_anchor *anchor;
|
||||
|
||||
while (*path == '/')
|
||||
path++;
|
||||
if (!*path)
|
||||
return (&pf_main_ruleset);
|
||||
anchor = pf_find_anchor(path);
|
||||
if (anchor == NULL)
|
||||
return (NULL);
|
||||
else
|
||||
return (&anchor->ruleset);
|
||||
}
|
||||
|
||||
struct pf_ruleset *
|
||||
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);
|
||||
while (*path == '/')
|
||||
path++;
|
||||
ruleset = pf_find_ruleset(path);
|
||||
if (ruleset != NULL)
|
||||
return (ruleset);
|
||||
p = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
strlcpy(p, path, MAXPATHLEN);
|
||||
while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
|
||||
*q = 0;
|
||||
if ((ruleset = pf_find_ruleset(p)) != NULL) {
|
||||
parent = ruleset->anchor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (q == NULL)
|
||||
q = p;
|
||||
else
|
||||
q++;
|
||||
strlcpy(p, path, MAXPATHLEN);
|
||||
if (!*q) {
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
while ((r = strchr(q, '/')) != NULL || *q) {
|
||||
if (r != NULL)
|
||||
*r = 0;
|
||||
if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
|
||||
(parent != NULL && strlen(parent->path) >=
|
||||
MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)) {
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
anchor = (struct pf_anchor *)rs_malloc(sizeof(*anchor));
|
||||
if (anchor == NULL) {
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
RB_INIT(&anchor->children);
|
||||
strlcpy(anchor->name, q, sizeof(anchor->name));
|
||||
if (parent != NULL) {
|
||||
strlcpy(anchor->path, parent->path,
|
||||
sizeof(anchor->path));
|
||||
strlcat(anchor->path, "/", sizeof(anchor->path));
|
||||
}
|
||||
strlcat(anchor->path, anchor->name, sizeof(anchor->path));
|
||||
#ifdef __FreeBSD__
|
||||
if ((dup = RB_INSERT(pf_anchor_global, &V_pf_anchors, anchor)) !=
|
||||
#else
|
||||
if ((dup = RB_INSERT(pf_anchor_global, &pf_anchors, anchor)) !=
|
||||
#endif
|
||||
NULL) {
|
||||
printf("pf_find_or_create_ruleset: RB_INSERT1 "
|
||||
"'%s' '%s' collides with '%s' '%s'\n",
|
||||
anchor->path, anchor->name, dup->path, dup->name);
|
||||
rs_free(anchor);
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
if (parent != NULL) {
|
||||
anchor->parent = parent;
|
||||
if ((dup = RB_INSERT(pf_anchor_node, &parent->children,
|
||||
anchor)) != NULL) {
|
||||
printf("pf_find_or_create_ruleset: "
|
||||
"RB_INSERT2 '%s' '%s' collides with "
|
||||
"'%s' '%s'\n", anchor->path, anchor->name,
|
||||
dup->path, dup->name);
|
||||
#ifdef __FreeBSD__
|
||||
RB_REMOVE(pf_anchor_global, &V_pf_anchors,
|
||||
#else
|
||||
RB_REMOVE(pf_anchor_global, &pf_anchors,
|
||||
#endif
|
||||
anchor);
|
||||
rs_free(anchor);
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
pf_init_ruleset(&anchor->ruleset);
|
||||
anchor->ruleset.anchor = anchor;
|
||||
parent = anchor;
|
||||
if (r != NULL)
|
||||
q = r + 1;
|
||||
else
|
||||
*q = 0;
|
||||
}
|
||||
rs_free(p);
|
||||
return (&anchor->ruleset);
|
||||
}
|
||||
|
||||
void
|
||||
pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
|
||||
{
|
||||
struct pf_anchor *parent;
|
||||
int i;
|
||||
|
||||
while (ruleset != NULL) {
|
||||
if (ruleset == &pf_main_ruleset || ruleset->anchor == NULL ||
|
||||
!RB_EMPTY(&ruleset->anchor->children) ||
|
||||
ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||
|
||||
ruleset->topen)
|
||||
return;
|
||||
for (i = 0; i < PF_RULESET_MAX; ++i)
|
||||
if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
|
||||
!TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
|
||||
ruleset->rules[i].inactive.open)
|
||||
return;
|
||||
#ifdef __FreeBSD__
|
||||
RB_REMOVE(pf_anchor_global, &V_pf_anchors, ruleset->anchor);
|
||||
#else
|
||||
RB_REMOVE(pf_anchor_global, &pf_anchors, ruleset->anchor);
|
||||
#endif
|
||||
if ((parent = ruleset->anchor->parent) != NULL)
|
||||
RB_REMOVE(pf_anchor_node, &parent->children,
|
||||
ruleset->anchor);
|
||||
rs_free(ruleset->anchor);
|
||||
if (parent == NULL)
|
||||
return;
|
||||
ruleset = &parent->ruleset;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
|
||||
const char *name)
|
||||
{
|
||||
char *p, *path;
|
||||
struct pf_ruleset *ruleset;
|
||||
|
||||
r->anchor = NULL;
|
||||
r->anchor_relative = 0;
|
||||
r->anchor_wildcard = 0;
|
||||
if (!name[0])
|
||||
return (0);
|
||||
path = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (path == NULL)
|
||||
return (1);
|
||||
if (name[0] == '/')
|
||||
strlcpy(path, name + 1, MAXPATHLEN);
|
||||
else {
|
||||
/* relative path */
|
||||
r->anchor_relative = 1;
|
||||
if (s->anchor == NULL || !s->anchor->path[0])
|
||||
path[0] = 0;
|
||||
else
|
||||
strlcpy(path, s->anchor->path, MAXPATHLEN);
|
||||
while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
|
||||
if (!path[0]) {
|
||||
printf("pf_anchor_setup: .. beyond root\n");
|
||||
rs_free(path);
|
||||
return (1);
|
||||
}
|
||||
if ((p = strrchr(path, '/')) != NULL)
|
||||
*p = 0;
|
||||
else
|
||||
path[0] = 0;
|
||||
r->anchor_relative++;
|
||||
name += 3;
|
||||
}
|
||||
if (path[0])
|
||||
strlcat(path, "/", MAXPATHLEN);
|
||||
strlcat(path, name, MAXPATHLEN);
|
||||
}
|
||||
if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
|
||||
r->anchor_wildcard = 1;
|
||||
*p = 0;
|
||||
}
|
||||
ruleset = pf_find_or_create_ruleset(path);
|
||||
rs_free(path);
|
||||
if (ruleset == NULL || ruleset->anchor == NULL) {
|
||||
printf("pf_anchor_setup: ruleset\n");
|
||||
return (1);
|
||||
}
|
||||
r->anchor = ruleset->anchor;
|
||||
r->anchor->refcnt++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pf_anchor_copyout(const struct pf_ruleset *rs, const struct pf_rule *r,
|
||||
struct pfioc_rule *pr)
|
||||
{
|
||||
pr->anchor_call[0] = 0;
|
||||
if (r->anchor == NULL)
|
||||
return (0);
|
||||
if (!r->anchor_relative) {
|
||||
strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
|
||||
strlcat(pr->anchor_call, r->anchor->path,
|
||||
sizeof(pr->anchor_call));
|
||||
} else {
|
||||
char *a, *p;
|
||||
int i;
|
||||
|
||||
a = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (a == NULL)
|
||||
return (1);
|
||||
if (rs->anchor == NULL)
|
||||
a[0] = 0;
|
||||
else
|
||||
strlcpy(a, rs->anchor->path, MAXPATHLEN);
|
||||
for (i = 1; i < r->anchor_relative; ++i) {
|
||||
if ((p = strrchr(a, '/')) == NULL)
|
||||
p = a;
|
||||
*p = 0;
|
||||
strlcat(pr->anchor_call, "../",
|
||||
sizeof(pr->anchor_call));
|
||||
}
|
||||
if (strncmp(a, r->anchor->path, strlen(a))) {
|
||||
printf("pf_anchor_copyout: '%s' '%s'\n", a,
|
||||
r->anchor->path);
|
||||
rs_free(a);
|
||||
return (1);
|
||||
}
|
||||
if (strlen(r->anchor->path) > strlen(a))
|
||||
strlcat(pr->anchor_call, r->anchor->path + (a[0] ?
|
||||
strlen(a) + 1 : 0), sizeof(pr->anchor_call));
|
||||
rs_free(a);
|
||||
}
|
||||
if (r->anchor_wildcard)
|
||||
strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
|
||||
sizeof(pr->anchor_call));
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pf_anchor_remove(struct pf_rule *r)
|
||||
{
|
||||
if (r->anchor == NULL)
|
||||
return;
|
||||
if (r->anchor->refcnt <= 0) {
|
||||
printf("pf_anchor_remove: broken refcount\n");
|
||||
r->anchor = NULL;
|
||||
return;
|
||||
}
|
||||
if (!--r->anchor->refcnt)
|
||||
pf_remove_if_empty_ruleset(&r->anchor->ruleset);
|
||||
r->anchor = NULL;
|
||||
}
|
@@ -1,170 +0,0 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/bsd/local/opt_inet.h>
|
||||
#include <rtems/bsd/local/opt_inet6.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <rtems/bsd/sys/param.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/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>
|
||||
|
||||
/*
|
||||
* Following is where TCP initial sequence number generation occurs.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define ISN_BYTES_PER_SECOND 1048576
|
||||
#define ISN_STATIC_INCREMENT 4096
|
||||
#define ISN_RANDOM_INCREMENT (4096 - 1)
|
||||
|
||||
static u_char pf_isn_secret[32];
|
||||
static int pf_isn_last_reseed;
|
||||
static u_int32_t pf_isn_offset;
|
||||
|
||||
u_int32_t
|
||||
pf_new_isn(struct pf_state *s)
|
||||
{
|
||||
MD5_CTX isn_ctx;
|
||||
u_int32_t md5_buffer[4];
|
||||
u_int32_t new_isn;
|
||||
struct pf_state_host *src, *dst;
|
||||
|
||||
/* Seed if this is the first use, reseed if requested. */
|
||||
if (pf_isn_last_reseed == 0) {
|
||||
read_random(&pf_isn_secret, sizeof(pf_isn_secret));
|
||||
pf_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 *) &pf_isn_secret, sizeof(pf_isn_secret));
|
||||
MD5Final((u_char *) &md5_buffer, &isn_ctx);
|
||||
new_isn = (tcp_seq) md5_buffer[0];
|
||||
pf_isn_offset += ISN_STATIC_INCREMENT +
|
||||
(arc4random() & ISN_RANDOM_INCREMENT);
|
||||
new_isn += pf_isn_offset;
|
||||
return (new_isn);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,122 +0,0 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
|
||||
/* $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 $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1999 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
|
||||
#include <machine/in_cksum.h>
|
||||
|
||||
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
|
||||
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; (void)ADDCARRY(sum);}
|
||||
|
||||
int in4_cksum(struct mbuf *, u_int8_t, int, int);
|
||||
|
||||
int
|
||||
in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len)
|
||||
{
|
||||
union {
|
||||
struct ipovly ipov;
|
||||
u_int16_t w[10];
|
||||
} u;
|
||||
union {
|
||||
u_int16_t s[2];
|
||||
u_int32_t l;
|
||||
} l_util;
|
||||
|
||||
u_int16_t *w;
|
||||
int psum;
|
||||
int sum = 0;
|
||||
|
||||
if (nxt != 0) {
|
||||
/* pseudo header */
|
||||
if (off < sizeof(struct ipovly))
|
||||
panic("in4_cksum: offset too short");
|
||||
if (m->m_len < sizeof(struct ip))
|
||||
panic("in4_cksum: bad mbuf chain");
|
||||
bzero(&u.ipov, sizeof(u.ipov));
|
||||
u.ipov.ih_len = htons(len);
|
||||
u.ipov.ih_pr = nxt;
|
||||
u.ipov.ih_src = mtod(m, struct ip *)->ip_src;
|
||||
u.ipov.ih_dst = mtod(m, struct ip *)->ip_dst;
|
||||
w = u.w;
|
||||
/* assumes sizeof(ipov) == 20 */
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; sum += w[4];
|
||||
sum += w[5]; sum += w[6]; sum += w[7]; sum += w[8]; sum += w[9];
|
||||
}
|
||||
|
||||
psum = in_cksum_skip(m, len + off, off);
|
||||
psum = ~psum & 0xffff;
|
||||
sum += psum;
|
||||
REDUCE;
|
||||
return (~sum & 0xffff);
|
||||
}
|
Reference in New Issue
Block a user