diff options
author | ngie <ngie@FreeBSD.org> | 2015-10-05 03:26:51 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2015-10-05 03:26:51 +0000 |
commit | e1dd16d965b177f109afb771e59432e36f335d0a (patch) | |
tree | 15db092a5401cf329f1bff9d3bf700d1fde0f121 /contrib/ipfilter/mli_ipl.c | |
parent | 115d008392113efc6f844baa7cc407e9eaae63db (diff) | |
download | FreeBSD-src-e1dd16d965b177f109afb771e59432e36f335d0a.zip FreeBSD-src-e1dd16d965b177f109afb771e59432e36f335d0a.tar.gz |
Revert r288682
I meant to do this on ^/user/ngie/more-tests
Pointyhat to: ngie (use svn info next time...)
Diffstat (limited to 'contrib/ipfilter/mli_ipl.c')
-rw-r--r-- | contrib/ipfilter/mli_ipl.c | 683 |
1 files changed, 683 insertions, 0 deletions
diff --git a/contrib/ipfilter/mli_ipl.c b/contrib/ipfilter/mli_ipl.c new file mode 100644 index 0000000..2a0024c --- /dev/null +++ b/contrib/ipfilter/mli_ipl.c @@ -0,0 +1,683 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * (C)opyright 1997 by Marc Boucher. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ + +/* TODO: (MARCXXX) + - ipl_init failure -> open ENODEV or whatever + - prevent multiple LKM loads + - surround access to ifnet structures by IFNET_LOCK()/IFNET_UNLOCK() ? + - m != m1 problem +*/ + +#include <sys/types.h> +#include <sys/conf.h> +#ifdef IPFILTER_LKM +#include <sys/mload.h> +#endif +#include <sys/systm.h> +#include <sys/errno.h> +#include <net/if.h> +#include <net/route.h> +#include <netinet/in.h> +#ifdef IFF_DRVRLOCK /* IRIX6 */ +#include <sys/hashing.h> +#include <netinet/in_var.h> +#endif +#include <sys/mbuf.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/ip_var.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <netinet/tcpip.h> +#include <netinet/ip_icmp.h> +#include <netinet/ipfilter.h> +#include "ipl.h" +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_nat.h" + +#ifndef MBUF_IS_CLUSTER +# define MBUF_IS_CLUSTER(m) ((m)->m_flags & MCL_CLUSTER) +#endif +#undef IPFDEBUG /* #define IPFDEBUG 9 */ + +#ifdef IPFILTER_LKM +u_int ipldevflag = D_MP; +char *iplmversion = M_VERSION; +#else +u_int ipfilterdevflag = D_MP; +char *ipfiltermversion = M_VERSION; +#endif + +ipfmutex_t ipl_mutex, ipfi_mutex, ipf_rw, ipf_stinsert, ipf_auth_mx; +ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; +ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; +ipfrwlock_t ipf_global, ipf_mutex, ipf_ipidfrag, ipf_frcache, ipf_tokens; + +int (*ipf_checkp) __P((struct ip *, int, void *, int, mb_t **)); + +#ifdef IPFILTER_LKM +static int *ipff_addr = 0; +static int ipff_value; +static __psunsigned_t *ipfk_addr = 0; +static __psunsigned_t ipfk_code[4]; +#endif +static void nifattach(); +static void nifdetach(); + +typedef struct nif { + struct nif *nf_next; + struct ifnet *nf_ifp; +#if (IRIX < 60500) + int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *); +#else + int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *, + struct rtentry *); +#endif + char nf_name[LIFNAMSIZ]; + int nf_unit; +} nif_t; + +static nif_t *nif_head = 0; +static int nif_interfaces = 0; +extern int in_interfaces; +#if IRIX >= 60500 +toid_t ipf_timer_id; +#endif + +extern ipnat_t *nat_list; + +#ifdef IPFDEBUG +static void ipf_dumppacket(m) + struct mbuf *m; +{ + u_char *s; + char *t, line[80]; + int len, off, i; + + off = 0; + + while (m != NULL) { + len = M_LEN(m); + s = mtod(m, u_char *); + printf("mbuf 0x%lx len %d flags %x type %d\n", + m, len, m->m_flags, m->m_type); + printf("dat 0x%lx off 0x%lx/%d s 0x%lx next 0x%lx\n", + m->m_dat, m->m_off, m->m_off, s, m->m_next); + while (len > 0) { + t = line; + for (i = 0; (i < 16) && (len > 0); len--, i++) + sprintf(t, " %02x", *s++), t += strlen(t); + *s = '\0'; + printf("mbuf:%x:%s\n", off, line); + off += 16; + } + m = m->m_next; + } +} +#endif + + +static int +#if IRIX < 60500 +ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst) +#else +ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, + struct rtentry *rt) +#endif +{ +#if (IPFDEBUG >= 0) + static unsigned int cnt = 0; +#endif + nif_t *nif; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + for (nif = nif_head; nif; nif = nif->nf_next) + if (nif->nf_ifp == ifp) + break; + MUTEX_EXIT(&ipfi_mutex); + + if (nif == NULL) { + printf("IP Filter: ipl_if_output intf %x NOT FOUND\n", ifp); + return ENETDOWN; + } + +#if (IPFDEBUG >= 7) + if ((++cnt % 200) == 0) + printf("IP Filter: ipl_if_output(ifp=0x%lx, m=0x%lx, dst=0x%lx), m_type=%d m_flags=0x%lx m_off=0x%lx\n", ifp, m, dst, m->m_type, (u_long)m->m_flags, m->m_off); +#endif + + if (ipf_checkp) { + struct mbuf *m1 = m; + struct ip *ip; + int hlen; + + switch(m->m_type) + { + case MT_HEADER: + if (m->m_len == 0) { + if (m->m_next == NULL) + break; + m = m->m_next; + } + /* FALLTHROUGH */ + case MT_DATA: + if (!MBUF_IS_CLUSTER(m) && + ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + break; + } + if (m->m_len < sizeof(char)) { +#if (IPFDEBUG >= 3) + printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags); +#endif + break; + } + ip = mtod(m, struct ip *); + if (ip->ip_v != IPVERSION) { +#if (IPFDEBUG >= 2) + ipf_dumppacket(m); + printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + break; + } + + hlen = ip->ip_hl << 2; + if ((*ipf_checkp)(ip, hlen, ifp, 1, &m1) || (m1 == NULL)) + return EHOSTUNREACH; + + m = m1; + break; + + default: +#if (IPFDEBUG >= 2) + printf("IP Filter: ipl_if_output: bad m_type=%d m_flags=0x%lxm_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + break; + } + } +#if (IRIX < 60500) + return (*nif->nf_output)(ifp, m, dst); +#else + return (*nif->nf_output)(ifp, m, dst, rt); +#endif +} + +int + + +#if !defined(IPFILTER_LKM) && (IRIX >= 60500) +ipfilter_kernel(struct ifnet *rcvif, struct mbuf *m) +#else +ipl_kernel(struct ifnet *rcvif, struct mbuf *m) +#endif +{ +#if (IPFDEBUG >= 7) + static unsigned int cnt = 0; + + if ((++cnt % 200) == 0) + printf("IP Filter: ipl_kernel(rcvif=0x%lx, m=0x%lx\n", + rcvif, m); +#endif + + if (ipf_running <= 0) + return IPF_ACCEPTIT; + + /* + * Check if we want to allow this packet to be processed. + * Consider it to be bad if not. + */ + if (ipf_checkp) { + struct mbuf *m1 = m; + struct ip *ip; + int hlen; + + if ((m->m_type != MT_DATA) && (m->m_type != MT_HEADER)) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_kernel: bad m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + return IPF_ACCEPTIT; + } + + if (!MBUF_IS_CLUSTER(m) && + ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_kernel: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + return IPF_ACCEPTIT; + } + + if (m->m_len < sizeof(char)) { +#if (IPFDEBUG >= 1) + printf("IP Filter: ipl_kernel: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags); +#endif + return IPF_ACCEPTIT; + } + + ip = mtod(m, struct ip *); + if (ip->ip_v != IPVERSION) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_kernel: bad ip_v\n"); +#endif + m_freem(m); + return IPF_DROPIT; + } + + ip->ip_len = htons(ip->ip_len); + ip->ip_off = htons(ip->ip_off); + hlen = ip->ip_hl << 2; + if ((*ipf_checkp)(ip, hlen, rcvif, 0, &m1) || !m1) + return IPF_DROPIT; + ip = mtod(m1, struct ip *); + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + +#if (IPFDEBUG >= 2) + if (m != m1) + printf("IP Filter: ipl_kernel: m != m1\n"); +#endif + } + + return IPF_ACCEPTIT; +} + +int +ipl_ipfilter_attach(void) +{ +#if defined(IPFILTER_LKM) + __psunsigned_t *addr_ff, *addr_fk; + + st_findaddr("ipfilterflag", &addr_ff); +# if (IPFDEBUG >= 1) + printf("IP Filter: st_findaddr ipfilterflag=0x%lx\n", addr_ff); +# endif + if (!addr_ff) + return ESRCH; + + st_findaddr("ipfilter_kernel", &addr_fk); +# if (IPFDEBUG >= 1) + printf("IP Filter: st_findaddr ipfilter_kernel=0x%lx\n", addr_fk); +# endif + if (!addr_fk) + return ESRCH; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + + ipff_addr = (int *)addr_ff; + + ipff_value = *ipff_addr; + *ipff_addr = 0; + + + ipfk_addr = addr_fk; + + bcopy(ipfk_addr, ipfk_code, sizeof(ipfk_code)); + + /* write a "li t4, ipl_kernel" instruction */ + ipfk_addr[0] = 0x3c0c0000 | + (((__psunsigned_t)ipl_kernel >> 16) & 0xffff); + ipfk_addr[1] = 0x358c0000 | + ((__psunsigned_t)ipl_kernel & 0xffff); + /* write a "jr t4" instruction" */ + ipfk_addr[2] = 0x01800008; + + /* write a "nop" instruction */ + ipfk_addr[3] = 0; + + icache_inval(ipfk_addr, sizeof(ipfk_code)); + + *ipff_addr = 1; /* enable ipfilter_kernel */ + + MUTEX_EXIT(&ipfi_mutex); +#else + extern int ipfilterflag; + + ipfilterflag = 1; +#endif + nif_interfaces = 0; + nifattach(); + + return 0; +} + + +/* + * attach the packet filter to each non-loopback interface that is running + */ +static void +nifattach() +{ + nif_t *nif, *qf2; + struct ifnet *ifp; + struct frentry *f; + ipnat_t *np; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + + for (ifp = ifnet; ifp; ifp = ifp->if_next) { + if ((!(ifp->if_flags & IFF_RUNNING)) || + (ifp->if_flags & IFF_LOOPBACK)) + continue; + + /* + * Look for entry already setup for this device + */ + for (nif = nif_head; nif; nif = nif->nf_next) + if (nif->nf_ifp == ifp) + break; + if (nif) + continue; + + if (ifp->if_output == ipl_if_output) { + printf("IP Filter: ERROR INTF 0x%lx STILL ATTACHED\n", + ifp); + continue; + } +#if (IPFDEBUG >= 2) + printf("IP Filter: nifattach nif %x opt %x\n", + ifp, ifp->if_output); +#endif + KMALLOC(nif, nif_t *); + if (!nif) { + printf("IP Filter: malloc(%d) for nif_t failed\n", + sizeof(nif_t)); + continue; + } + + nif->nf_ifp = ifp; + (void) strncpy(nif->nf_name, ifp->if_name, + sizeof(nif->nf_name)); + nif->nf_name[sizeof(nif->nf_name) - 1] = '\0'; + nif->nf_unit = ifp->if_unit; + + nif->nf_next = nif_head; + nif_head = nif; + + /* + * Activate any rules directly associated with this interface + */ + WRITE_ENTER(&ipf_mutex); + for (f = ipf_rules[0][0]; f; f = f->fr_next) { + if ((f->fr_ifa == (struct ifnet *)-1)) { + if (f->fr_ifname[0] && + (GETIFP(f->fr_ifname, 4) == ifp)) + f->fr_ifa = ifp; + } + } + for (f = ipf_rules[1][0]; f; f = f->fr_next) { + if ((f->fr_ifa == (struct ifnet *)-1)) { + if (f->fr_ifname[0] && + (GETIFP(f->fr_ifname, 4) == ifp)) + f->fr_ifa = ifp; + } + } + RWLOCK_EXIT(&ipf_mutex); + WRITE_ENTER(&ipf_nat); + for (np = nat_list; np; np = np->in_next) { + if ((np->in_ifps[0] == (void *)-1)) { + if (np->in_ifnames[0][0] && + (GETIFP(np->in_ifnames[0], 4) == ifp)) + np->in_ifps[0] = (void *)ifp; + } + if ((np->in_ifps[1] == (void *)-1)) { + if (np->in_ifnames[1][0] && + (GETIFP(np->in_ifnames[1], 4) == ifp)) + np->in_ifps[1] = (void *)ifp; + } + } + RWLOCK_EXIT(&ipf_nat); + + nif->nf_output = ifp->if_output; + ifp->if_output = ipl_if_output; + +#if (IPFDEBUG >= 2) + printf("IP Filter: nifattach: ifp(%lx)->if_output FROM %lx TO %lx\n", + ifp, nif->nf_output, ifp->if_output); +#endif + + printf("IP Filter: attach to [%s,%d]\n", + nif->nf_name, ifp->if_unit); + } + if (!nif_head) + printf("IP Filter: not attached to any interfaces\n"); + + nif_interfaces = in_interfaces; + + MUTEX_EXIT(&ipfi_mutex); + + return; +} + + +/* + * unhook the IP filter from all defined interfaces with IP addresses + */ +static void +nifdetach() +{ + nif_t *nif, *qf2, **qp; + struct ifnet *ifp; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + /* + * Make two passes, first get rid of all the unknown devices, next + * unlink known devices. + */ + for (qp = &nif_head; (nif = *qp); ) { + for (ifp = ifnet; ifp; ifp = ifp->if_next) + if (nif->nf_ifp == ifp) + break; + if (ifp) { + qp = &nif->nf_next; + continue; + } + printf("IP Filter: removing [%s]\n", nif->nf_name); + *qp = nif->nf_next; + KFREE(nif); + } + + while ((nif = nif_head)) { + nif_head = nif->nf_next; + for (ifp = ifnet; ifp; ifp = ifp->if_next) + if (nif->nf_ifp == ifp) + break; + if (ifp) { + printf("IP Filter: detaching [%s,%d]\n", + nif->nf_name, ifp->if_unit); + +#if (IPFDEBUG >= 4) + printf("IP Filter: nifdetach: ifp(%lx)->if_output FROM %lx TO %lx\n", + ifp, ifp->if_output, nif->nf_output); +#endif + ifp->if_output = nif->nf_output; + } + KFREE(nif); + } + MUTEX_EXIT(&ipfi_mutex); + + return; +} + + +void +ipl_ipfilter_detach(void) +{ +#ifdef IPFILTER_LKM + nifdetach(); + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + + if (ipff_addr) { + *ipff_addr = 0; + + if (ipfk_addr) { + bcopy(ipfk_code, ipfk_addr, sizeof(ipfk_code)); + icache_inval(ipfk_addr - 16, sizeof(ipfk_code)+32); + } + + *ipff_addr = ipff_value; + } + + MUTEX_EXIT(&ipfi_mutex); +#else + extern int ipfilterflag; + + nifdetach(); + + ipfilterflag = 0; +#endif +} + + +/* this function is called from ipf_slowtimer at 500ms intervals to + keep our interface list in sync */ +void +ipl_ipfilter_intfsync(void) +{ + MUTEX_ENTER(&ipfi_mutex); + if (nif_interfaces != in_interfaces) { + /* if the number of interfaces has changed, resync */ + MUTEX_EXIT(&ipfi_mutex); + ipf_sync(&ipfmain, NULL); + } else + MUTEX_EXIT(&ipfi_mutex); +} + +#ifdef IPFILTER_LKM +/* this routine should be treated as an interrupt routine and should + not call any routines that would cause it to sleep, such as: biowait(), + sleep(), psema() or delay(). +*/ +int +iplunload(void) +{ + int error = 0; + + if (ipf_refcnt) + return EBUSY; + + WRITE_ENTER(&ipf_global); + error = ipl_detach(); + if (error != 0) { + RWLOCK_EXIT(&ipf_global); + return error; + } + ipf_running = -2; + +#if (IRIX < 60500) + LOCK_DEALLOC(ipl_mutex.l); + LOCK_DEALLOC(ipf_rw.l); + LOCK_DEALLOC(ipf_auth.l); + LOCK_DEALLOC(ipf_natfrag.l); + LOCK_DEALLOC(ipf_ipidfrag.l); + LOCK_DEALLOC(ipf_tokens.l); + LOCK_DEALLOC(ipf_stinsert.l); + LOCK_DEALLOC(ipf_nat_new.l); + LOCK_DEALLOC(ipf_natio.l); + LOCK_DEALLOC(ipf_nat.l); + LOCK_DEALLOC(ipf_state.l); + LOCK_DEALLOC(ipf_frag.l); + LOCK_DEALLOC(ipf_auth_mx.l); + LOCK_DEALLOC(ipf_mutex.l); + LOCK_DEALLOC(ipf_frcache.l); + LOCK_DEALLOC(ipfi_mutex.l); + RWLOCK_EXIT(&ipf_global); + LOCK_DEALLOC(ipf_global.l); +#else + MUTEX_DESTROY(&ipf_rw); + MUTEX_DESTROY(&ipfi_mutex); + MUTEX_DESTROY(&ipf_timeoutlock); + RW_DESTROY(&ipf_mutex); + RW_DESTROY(&ipf_frcache); + RW_DESTROY(&ipf_tokens); + RWLOCK_EXIT(&ipf_global); + delay(hz); + RW_DESTROY(&ipf_global); +#endif + + printf("%s unloaded\n", ipfilter_version); + + delay(hz); + + return 0; +} +#endif + +void +ipfilterinit(void) +{ +#ifdef IPFILTER_LKM + int error; +#endif + +#if (IRIX < 60500) + ipfi_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); +ipf_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); +ipf_frcache.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); +ipf_timeoutlock.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_global.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_frag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_state.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_nat.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_stinsert.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_natfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_ipidfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_tokens.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_auth.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_rw.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipl_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + + if (!ipfi_mutex.l || !ipf_mutex.l || !ipf_timeoutlock.l || + !ipf_frag.l || !ipf_state.l || !ipf_nat.l || !ipf_natfrag.l || + !ipf_auth.l || !ipf_rw.l || !ipf_ipidfrag.l || !ipl_mutex.l || + !ipf_stinsert.l || !ipf_auth_mx.l || !ipf_frcache.l || + !ipf_tokens.l) + panic("IP Filter: LOCK_ALLOC failed"); +#else + MUTEX_INIT(&ipf_rw, "ipf rw mutex"); + MUTEX_INIT(&ipf_timeoutlock, "ipf timeout mutex"); + RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); + RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); + RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock"); +#endif + +#ifdef IPFILTER_LKM + error = ipl_attach(); + if (error) { + iplunload(); + } else { + char *defpass; + + if (FR_ISPASS(ipf_pass)) + defpass = "pass"; + else if (FR_ISBLOCK(ipf_pass)) + defpass = "block"; + else + defpass = "no-match -> block"; + + printf("%s initialized. Default = %s all, Logging = %s%s\n", + ipfilter_version, defpass, +# ifdef IPFILTER_LOG + "enabled", +# else + "disabled", +# endif +# ifdef IPFILTER_COMPILED + " (COMPILED)" +# else + "" +# endif + ); + } +#endif + + return; +} |