diff options
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_fil.c | 13 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_fil.h | 3 | ||||
-rw-r--r-- | sys/netinet/ip_fil.c | 13 | ||||
-rw-r--r-- | sys/netinet/ip_fil.h | 3 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 38 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 33 | ||||
-rw-r--r-- | sys/netinet/ipprotosw.h | 6 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 32 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 28 | ||||
-rw-r--r-- | sys/sys/protosw.h | 6 |
10 files changed, 145 insertions, 30 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.c b/sys/contrib/ipfilter/netinet/ip_fil.c index 746df30..e6cdb81 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil.c +++ b/sys/contrib/ipfilter/netinet/ip_fil.c @@ -190,7 +190,8 @@ struct devsw iplsw = { }; #endif /* _BSDI_VERSION >= 199510 && _KERNEL */ -#if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701) +#if defined(__NetBSD__) || defined(__OpenBSD__) || \ + (_BSDI_VERSION >= 199701) || (__FreeBSD_Version >= 50011) # include <sys/conf.h> # if defined(NETBSD_PF) # include <net/pfil.h> @@ -231,7 +232,8 @@ int iplattach() { char *defpass; int s; -# if defined(__sgi) || (defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)) +# if defined(__sgi) || (defined(NETBSD_PF) && \ + ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011))) int error = 0; # endif @@ -253,7 +255,7 @@ int iplattach() return -1; # ifdef NETBSD_PF -# if __NetBSD_Version__ >= 104200000 +# if (__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011) error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); if (error) { @@ -338,7 +340,8 @@ pfil_error: int ipldetach() { int s, i = FR_INQUE|FR_OUTQUE; -#if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000) +#if defined(NETBSD_PF) && \ + ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011)) int error = 0; #endif @@ -372,7 +375,7 @@ int ipldetach() fr_running = 0; # ifdef NETBSD_PF -# if __NetBSD_Version__ >= 104200000 +# if ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011)) error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); if (error) diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h index 0d7ff05..4c24f9c 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil.h +++ b/sys/contrib/ipfilter/netinet/ip_fil.h @@ -468,7 +468,8 @@ typedef struct ipflog { * with this! */ #if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ - (defined(NetBSD1_2) && NetBSD1_2 > 1) + (defined(NetBSD1_2) && NetBSD1_2 > 1) || (defined(__FreeBSD_version) && \ + (__FreeBSD_version >= 500011)) # if (NetBSD >= 199905) # define PFIL_HOOKS # endif diff --git a/sys/netinet/ip_fil.c b/sys/netinet/ip_fil.c index 746df30..e6cdb81 100644 --- a/sys/netinet/ip_fil.c +++ b/sys/netinet/ip_fil.c @@ -190,7 +190,8 @@ struct devsw iplsw = { }; #endif /* _BSDI_VERSION >= 199510 && _KERNEL */ -#if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701) +#if defined(__NetBSD__) || defined(__OpenBSD__) || \ + (_BSDI_VERSION >= 199701) || (__FreeBSD_Version >= 50011) # include <sys/conf.h> # if defined(NETBSD_PF) # include <net/pfil.h> @@ -231,7 +232,8 @@ int iplattach() { char *defpass; int s; -# if defined(__sgi) || (defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)) +# if defined(__sgi) || (defined(NETBSD_PF) && \ + ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011))) int error = 0; # endif @@ -253,7 +255,7 @@ int iplattach() return -1; # ifdef NETBSD_PF -# if __NetBSD_Version__ >= 104200000 +# if (__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011) error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); if (error) { @@ -338,7 +340,8 @@ pfil_error: int ipldetach() { int s, i = FR_INQUE|FR_OUTQUE; -#if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000) +#if defined(NETBSD_PF) && \ + ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011)) int error = 0; #endif @@ -372,7 +375,7 @@ int ipldetach() fr_running = 0; # ifdef NETBSD_PF -# if __NetBSD_Version__ >= 104200000 +# if ((__NetBSD_Version__ >= 104200000) || (__FreeBSD_Version >= 50011)) error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); if (error) diff --git a/sys/netinet/ip_fil.h b/sys/netinet/ip_fil.h index 0d7ff05..4c24f9c 100644 --- a/sys/netinet/ip_fil.h +++ b/sys/netinet/ip_fil.h @@ -468,7 +468,8 @@ typedef struct ipflog { * with this! */ #if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ - (defined(NetBSD1_2) && NetBSD1_2 > 1) + (defined(NetBSD1_2) && NetBSD1_2 > 1) || (defined(__FreeBSD_version) && \ + (__FreeBSD_version >= 500011)) # if (NetBSD >= 199905) # define PFIL_HOOKS # endif diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 6647622..387abd1 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -43,12 +43,14 @@ #include "opt_ipfilter.h" #include "opt_ipstealth.h" #include "opt_ipsec.h" +#include "opt_pfil_hooks.h" #include <stddef.h> #include <sys/param.h> #include <sys/systm.h> #include <sys/mbuf.h> +#include <sys/pfil.h> #include <sys/malloc.h> #include <sys/domain.h> #include <sys/protosw.h> @@ -175,8 +177,6 @@ int fw_enable = 1 ; ip_dn_ctl_t *ip_dn_ctl_ptr; #endif -int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)) = NULL; - /* * We need to save the IP options in case a protocol wants to respond @@ -261,6 +261,11 @@ ip_input(struct mbuf *m) u_int32_t divert_info = 0; /* packet divert/tee info */ #endif struct ip_fw_chain *rule = NULL; +#ifdef PFIL_HOOKS + struct packet_filter_hook *pfh; + struct mbuf *m0; + int rv; +#endif /* PFIL_HOOKS */ #ifdef IPDIVERT /* Get and reset firewall cookie */ @@ -377,17 +382,30 @@ tooshort: #if defined(IPFIREWALL) && defined(DUMMYNET) iphack: #endif + +#ifdef PFIL_HOOKS /* - * Check if we want to allow this packet to be processed. - * Consider it to be bad if not. + * Run through list of hooks for input packets. If there are any + * filters which require that additional packets in the flow are + * not fast-forwarded, they must clear the M_CANFASTFWD flag. + * Note that filters must _never_ set this flag, as another filter + * in the list may have previously cleared it. */ - if (fr_checkp) { - struct mbuf *m1 = m; + m0 = m; + pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); + for (; pfh; pfh = pfh->pfil_link.tqe_next) + if (pfh->pfil_func) { + rv = pfh->pfil_func(ip, hlen, + m->m_pkthdr.rcvif, 0, &m0); + if (rv) + return; + m = m0; + if (m == NULL) + return; + ip = mtod(m, struct ip *); + } +#endif /* PFIL_HOOKS */ - if ((*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m1) || !m1) - return; - ip = mtod(m = m1, struct ip *); - } if (fw_enable && ip_fw_chk_ptr) { #ifdef IPFIREWALL_FORWARD /* diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 450b0d6..a5dd111 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -41,6 +41,7 @@ #include "opt_ipdivert.h" #include "opt_ipfilter.h" #include "opt_ipsec.h" +#include "opt_pfil_hooks.h" #include <sys/param.h> #include <sys/systm.h> @@ -106,7 +107,6 @@ static int ip_setmoptions __P((struct sockopt *, struct ip_moptions **)); int ip_optcopy __P((struct ip *, struct ip *)); -extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); extern struct protosw inetsw[]; @@ -139,6 +139,11 @@ ip_output(m0, opt, ro, flags, imo) struct secpolicy *sp = NULL; #endif u_int16_t divert_cookie; /* firewall cookie */ +#ifdef PFIL_HOOKS + struct packet_filter_hook *pfh; + struct mbuf *m1; + int rv; +#endif /* PFIL_HOOKS */ #ifdef IPFIREWALL_FORWARD int fwd_rewrite_src = 0; #endif @@ -431,13 +436,25 @@ sendit: * - Wrap: fake packet's addr/port <unimpl.> * - Encapsulate: put it in another IP and send out. <unimp.> */ - if (fr_checkp) { - struct mbuf *m1 = m; - - if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1) - goto done; - ip = mtod(m = m1, struct ip *); - } +#ifdef PFIL_HOOKS + /* + * Run through list of hooks for output packets. + */ + m1 = m; + pfh = pfil_hook_get(PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); + for (; pfh; pfh = pfh->pfil_link.tqe_next) + if (pfh->pfil_func) { + rv = pfh->pfil_func(ip, hlen, ifp, 1, &m1); + if (rv) { + error = EHOSTUNREACH; + goto done; + } + m = m1; + if (m == NULL) + goto done; + ip = mtod(m, struct ip *); + } +#endif /* PFIL_HOOKS */ /* * Check with the firewall... diff --git a/sys/netinet/ipprotosw.h b/sys/netinet/ipprotosw.h index 0ecb64d..1d65f0c 100644 --- a/sys/netinet/ipprotosw.h +++ b/sys/netinet/ipprotosw.h @@ -66,6 +66,11 @@ #ifndef _NETINET_IPPROTOSW_H_ #define _NETINET_IPPROTOSW_H_ +/* + * For pfil_head structure. + */ +#include <net/pfil.h> + /* Forward declare these structures referenced from prototypes below. */ struct mbuf; struct proc; @@ -98,6 +103,7 @@ struct ipprotosw { void (*pr_drain) __P((void)); /* flush any excess space possible */ struct pr_usrreqs *pr_usrreqs; /* supersedes pr_usrreq() */ + struct pfil_head pr_pfh; }; #endif /* !_NETINET_IPPROTOSW_H_ */ diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 870bdd9..709276d 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -69,6 +69,7 @@ #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" +#include "opt_pfil_hooks.h" #include <sys/param.h> #include <sys/systm.h> @@ -89,6 +90,9 @@ #include <net/route.h> #include <net/netisr.h> #include <net/intrq.h> +#ifdef PFIL_HOOKS +#include <net/pfil.h> +#endif #include <netinet/in.h> #include <netinet/in_systm.h> @@ -233,6 +237,11 @@ ip6_input(m) u_int32_t rtalert = ~0; int nxt, ours = 0; struct ifnet *deliverifp = NULL; +#ifdef PFIL_HOOKS + struct packet_filter_hook *pfh; + struct mbuf *m0; + int rv; +#endif /* PFIL_HOOKS */ #ifdef IPSEC /* @@ -291,6 +300,29 @@ ip6_input(m) goto bad; } +#ifdef PFIL_HOOKS + /* + * Run through list of hooks for input packets. If there are any + * filters which require that additional packets in the flow are + * not fast-forwarded, they must clear the M_CANFASTFWD flag. + * Note that filters must _never_ set this flag, as another filter + * in the list may have previously cleared it. + */ + m0 = m; + pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh); + for (; pfh; pfh = pfh->pfil_link.tqe_next) + if (pfh->pfil_func) { + rv = pfh->pfil_func(ip6, sizeof(*ip6), + m->m_pkthdr.rcvif, 0, &m0); + if (rv) + return; + m = m0; + if (m == NULL) + return; + ip6 = mtod(m, struct ip6_hdr *); + } +#endif /* PFIL_HOOKS */ + ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; #ifdef IPV6FIREWALL diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index e23ba00..a11475a 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -69,6 +69,7 @@ #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" +#include "opt_pfil_hooks.h" #include <sys/param.h> #include <sys/malloc.h> @@ -83,6 +84,9 @@ #include <net/if.h> #include <net/route.h> +#ifdef PFIL_HOOKS +#include <net/pfil.h> +#endif #include <netinet/in.h> #include <netinet/in_var.h> @@ -157,6 +161,11 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp) struct route_in6 *ro_pmtu = NULL; int hdrsplit = 0; int needipsec = 0; +#ifdef PFIL_HOOKS + struct packet_filter_hook *pfh; + struct mbuf *m1; + int rv; +#endif /* PFIL_HOOKS */ #ifdef IPSEC int needipsectun = 0; struct socket *so; @@ -840,6 +849,25 @@ skip_ipsec2:; m->m_pkthdr.rcvif = NULL; } +#ifdef PFIL_HOOKS + /* + * Run through list of hooks for output packets. + */ + m1 = m; + pfh = pfil_hook_get(PFIL_OUT, &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh); + for (; pfh; pfh = pfh->pfil_link.tqe_next) + if (pfh->pfil_func) { + rv = pfh->pfil_func(ip6, sizeof(*ip6), ifp, 1, &m1); + if (rv) { + error = EHOSTUNREACH; + goto done; + } + m = m1; + if (m == NULL) + goto done; + ip6 = mtod(m, struct ip6_hdr *); + } +#endif /* PFIL_HOOKS */ /* * Send the packet to the outgoing interface. * If necessary, do IPv6 fragmentation before sending. diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 5f23fa3..4f88105 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -37,6 +37,11 @@ #ifndef _SYS_PROTOSW_H_ #define _SYS_PROTOSW_H_ +/* + * For pfil_head structure. + */ +#include <net/pfil.h> + /* Forward declare these structures referenced from prototypes below. */ struct mbuf; struct proc; @@ -92,6 +97,7 @@ struct protosw { void (*pr_drain) __P((void)); /* flush any excess space possible */ struct pr_usrreqs *pr_usrreqs; /* supersedes pr_usrreq() */ + struct pfil_head pr_pfh; }; /*#endif*/ |