add packet filter interface code. see pfil(9) for more details. you
need the PACKET_FILTER option to enable this code. currently, ipfilter version 3.1.1-beta has been converted to use this new interface.
This commit is contained in:
parent
94bfaac456
commit
ae47956db0
127
sys/netinet/in.c
127
sys/netinet/in.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in.c,v 1.29 1996/06/23 12:12:44 mycroft Exp $ */
|
||||
/* $NetBSD: in.c,v 1.30 1996/09/06 05:07:43 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
|
@ -43,12 +43,14 @@
|
|||
#include <sys/socketvar.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/ip_mroute.h>
|
||||
|
@ -62,6 +64,14 @@
|
|||
#define SUBNETSARELOCAL 1
|
||||
#endif
|
||||
int subnetsarelocal = SUBNETSARELOCAL;
|
||||
|
||||
#ifdef PACKET_FILTER
|
||||
LIST_HEAD(, packet_filter_hook) pfil_in_list;
|
||||
LIST_HEAD(, packet_filter_hook) pfil_out_list;
|
||||
LIST_HEAD(, packet_filter_hook) pfil_bad_list;
|
||||
static int done_pfil_init;
|
||||
#endif /* PACKET_FILTER */
|
||||
|
||||
/*
|
||||
* Return 1 if an internet address is for a ``local'' host
|
||||
* (one to which we have a connection). If subnetsarelocal
|
||||
|
@ -555,5 +565,118 @@ in_delmulti(inm)
|
|||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef PACKET_FILTER
|
||||
void pfil_init __P((void));
|
||||
int pfil_list_remove(struct packet_filter_hook *,
|
||||
int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)), int,
|
||||
int);
|
||||
|
||||
void
|
||||
pfil_init()
|
||||
{
|
||||
LIST_INIT(&pfil_in_list);
|
||||
LIST_INIT(&pfil_out_list);
|
||||
LIST_INIT(&pfil_bad_list);
|
||||
done_pfil_init = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* pfil_add_hook() adds a function to the packet filter hook. the
|
||||
* flags are:
|
||||
* PFIL_IN call me on incoming packets
|
||||
* PFIL_OUT call me on outgoing packets
|
||||
* PFIL_BAD call me when rejecting a packet (that was
|
||||
* not already reject by in/out filters).
|
||||
* PFIL_ALL call me on all of the above
|
||||
* PFIL_WAITOK OK to call malloc with M_WAITOK.
|
||||
*/
|
||||
void
|
||||
pfil_add_hook(func, flags)
|
||||
int (*func) __P((void *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
int flags;
|
||||
{
|
||||
struct packet_filter_hook *pfh;
|
||||
|
||||
if (done_pfil_init == 0)
|
||||
pfil_init();
|
||||
|
||||
pfh = (struct packet_filter_hook *)malloc(sizeof(*pfh), M_IFADDR,
|
||||
flags & PFIL_WAITOK ? M_WAITOK : M_NOWAIT);
|
||||
if (pfh == NULL)
|
||||
panic("no memory for packet filter hook");
|
||||
|
||||
pfh->pfil_flags = flags;
|
||||
pfh->pfil_func = func;
|
||||
if (flags & PFIL_IN)
|
||||
LIST_INSERT_HEAD(&pfil_in_list, pfh, pfil_link);
|
||||
if (flags & PFIL_OUT)
|
||||
LIST_INSERT_HEAD(&pfil_out_list, pfh, pfil_link);
|
||||
if (flags & PFIL_BAD)
|
||||
LIST_INSERT_HEAD(&pfil_bad_list, pfh, pfil_link);
|
||||
}
|
||||
|
||||
/*
|
||||
* pfil_remove_hook removes a specific function from the packet filter
|
||||
* hook list.
|
||||
*/
|
||||
void
|
||||
pfil_remove_hook(func, flags)
|
||||
int (*func) __P((void *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
int flags;
|
||||
{
|
||||
|
||||
if (done_pfil_init == 0)
|
||||
pfil_init();
|
||||
|
||||
if (flags & PFIL_IN &&
|
||||
pfil_list_remove(pfil_in_list.lh_first, func, flags, PFIL_IN))
|
||||
return;
|
||||
if (flags & PFIL_OUT &&
|
||||
pfil_list_remove(pfil_out_list.lh_first, func, flags, PFIL_OUT))
|
||||
return;
|
||||
if (flags & PFIL_BAD &&
|
||||
pfil_list_remove(pfil_bad_list.lh_first, func, flags, PFIL_BAD))
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
pfil_list_remove(list, func, flags, flag)
|
||||
struct packet_filter_hook *list;
|
||||
int (*func) __P((void *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
int flags, flag;
|
||||
{
|
||||
struct packet_filter_hook *pfh;
|
||||
|
||||
for (pfh = list; pfh; pfh = pfh->pfil_link.le_next)
|
||||
if (pfh->pfil_func == func) {
|
||||
pfh->pfil_flags &= ~flag;
|
||||
LIST_REMOVE(pfh, pfil_link);
|
||||
if ((flags & PFIL_ALL) == 0) {
|
||||
free(pfh, M_IFADDR);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct packet_filter_hook *
|
||||
pfil_hook_get(flag)
|
||||
int flag;
|
||||
{
|
||||
if (done_pfil_init)
|
||||
switch (flag) {
|
||||
case PFIL_IN:
|
||||
return (pfil_in_list.lh_first);
|
||||
case PFIL_OUT:
|
||||
return (pfil_out_list.lh_first);
|
||||
case PFIL_BAD:
|
||||
return (pfil_bad_list.lh_first);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* PACKET_FILTER */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip.h,v 1.9 1995/05/15 01:22:44 cgd Exp $ */
|
||||
/* $NetBSD: ip.h,v 1.10 1996/09/06 05:07:43 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -160,6 +160,35 @@ struct ip_timestamp {
|
|||
#define IPOPT_SECUR_SECRET 0xd788
|
||||
#define IPOPT_SECUR_TOPSECRET 0x6bc5
|
||||
|
||||
/* we need this for the packet filter structure */
|
||||
#include <sys/queue.h>
|
||||
struct ifnet;
|
||||
|
||||
/*
|
||||
* The packet filter hooks are designed for anything to call them to
|
||||
* possibly intercept the packet.
|
||||
*/
|
||||
struct packet_filter_hook {
|
||||
LIST_ENTRY(packet_filter_hook) pfil_link;
|
||||
int (*pfil_func) __P((void *, int, struct ifnet *, int,
|
||||
struct mbuf **));
|
||||
int pfil_flags;
|
||||
};
|
||||
|
||||
#define PFIL_IN 0x00000001
|
||||
#define PFIL_OUT 0x00000002
|
||||
#define PFIL_BAD 0x00000004
|
||||
#define PFIL_WAITOK 0x00000008
|
||||
#define PFIL_ALL (PFIL_IN|PFIL_OUT|PFIL_BAD)
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct packet_filter_hook *pfil_hook_get __P((int));
|
||||
void pfil_add_hook __P((int (*func) __P((void *, int,
|
||||
struct ifnet *, int, struct mbuf **)), int));
|
||||
void pfil_remove_hook __P((int (*func) __P((void *, int,
|
||||
struct ifnet *, int, struct mbuf **)), int));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
* Internet implementation parameters.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_input.c,v 1.32 1996/08/14 03:46:44 thorpej Exp $ */
|
||||
/* $NetBSD: ip_input.c,v 1.33 1996/09/06 05:07:44 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988, 1993
|
||||
|
@ -153,12 +153,16 @@ struct route ipforward_rt;
|
|||
void
|
||||
ipintr()
|
||||
{
|
||||
register struct ip *ip;
|
||||
register struct ip *ip = NULL;
|
||||
register struct mbuf *m;
|
||||
register struct ipq *fp;
|
||||
register struct in_ifaddr *ia;
|
||||
struct ipqent *ipqe;
|
||||
int hlen, mff, s;
|
||||
int hlen = 0, mff, s;
|
||||
#ifdef PACKET_FILTER
|
||||
struct packet_filter_hook *pfh;
|
||||
struct mbuf *m0;
|
||||
#endif /* PACKET_FILTER */
|
||||
|
||||
next:
|
||||
/*
|
||||
|
@ -237,6 +241,19 @@ next:
|
|||
m_adj(m, ip->ip_len - m->m_pkthdr.len);
|
||||
}
|
||||
|
||||
#ifdef PACKET_FILTER
|
||||
/*
|
||||
* Run through list of hooks for input packets.
|
||||
*/
|
||||
m0 = m;
|
||||
for (pfh = pfil_hook_get(PFIL_IN); pfh; pfh = pfh->pfil_link.le_next)
|
||||
if (pfh->pfil_func) {
|
||||
if (pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0))
|
||||
goto bad;
|
||||
ip = mtod(m = m0, struct ip *);
|
||||
}
|
||||
#endif /* PACKET_FILTER */
|
||||
|
||||
/*
|
||||
* Process options and, if not destined for us,
|
||||
* ship it on. ip_dooptions returns 1 when an
|
||||
|
@ -418,6 +435,14 @@ found:
|
|||
(*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
|
||||
goto next;
|
||||
bad:
|
||||
#ifdef PACKET_FILTER
|
||||
m0 = m;
|
||||
for (pfh = pfil_hook_get(PFIL_BAD); pfh; pfh = pfh->pfil_link.le_next)
|
||||
if (pfh->pfil_func) {
|
||||
(void)pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 2, &m0);
|
||||
ip = mtod(m = m0, struct ip *);
|
||||
}
|
||||
#endif /* PACKET_FILTER */
|
||||
m_freem(m);
|
||||
goto next;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_output.c,v 1.29 1996/02/26 23:17:12 mrg Exp $ */
|
||||
/* $NetBSD: ip_output.c,v 1.30 1996/09/06 05:07:45 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988, 1990, 1993
|
||||
|
@ -92,6 +92,10 @@ ip_output(m0, va_alist)
|
|||
int flags;
|
||||
struct ip_moptions *imo;
|
||||
va_list ap;
|
||||
#ifdef PACKET_FILTER
|
||||
struct packet_filter_hook *pfh;
|
||||
struct mbuf *m1;
|
||||
#endif /* PACKET_FILTER */
|
||||
|
||||
va_start(ap, m0);
|
||||
opt = va_arg(ap, struct mbuf *);
|
||||
|
@ -293,6 +297,20 @@ ip_output(m0, va_alist)
|
|||
} else
|
||||
m->m_flags &= ~M_BCAST;
|
||||
|
||||
#ifdef PACKET_FILTER
|
||||
/*
|
||||
* Run through list of hooks for output packets.
|
||||
*/
|
||||
m1 = m;
|
||||
for (pfh = pfil_hook_get(PFIL_OUT); pfh; pfh = pfh->pfil_link.le_next)
|
||||
if (pfh->pfil_func) {
|
||||
if (pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 1, &m1)) {
|
||||
error = EHOSTUNREACH;
|
||||
goto bad;
|
||||
}
|
||||
ip = mtod(m = m1, struct ip *);
|
||||
}
|
||||
#endif /* PACKET_FILTER */
|
||||
sendit:
|
||||
/*
|
||||
* If small enough for interface, can just send directly.
|
||||
|
@ -398,6 +416,14 @@ done:
|
|||
RTFREE(ro->ro_rt);
|
||||
return (error);
|
||||
bad:
|
||||
#ifdef PACKET_FILTER
|
||||
m1 = m;
|
||||
for (pfh = pfil_hook_get(PFIL_BAD); pfh; pfh = pfh->pfil_link.le_next)
|
||||
if (pfh->pfil_func) {
|
||||
(void)pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 2, &m1);
|
||||
ip = mtod(m = m1, struct ip *);
|
||||
}
|
||||
#endif /* PACKET_FILTER */
|
||||
m_freem(m0);
|
||||
goto done;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue