diff options
Diffstat (limited to 'contrib/ipfilter/mls_ipl.c')
-rw-r--r-- | contrib/ipfilter/mls_ipl.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/contrib/ipfilter/mls_ipl.c b/contrib/ipfilter/mls_ipl.c new file mode 100644 index 0000000..4388b61 --- /dev/null +++ b/contrib/ipfilter/mls_ipl.c @@ -0,0 +1,351 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate + * its own major char number! Way cool patch! + */ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/file.h> +#include <sys/socket.h> +#include <sys/conf.h> +#include <sys/syslog.h> +#include <sys/buf.h> +#include <sys/mbuf.h> +#include <sys/param.h> +#include <sys/errno.h> +#include <sys/uio.h> +#include <sys/vnode.h> +#include <sundev/mbvar.h> +#include <sun/autoconf.h> +#include <sun/vddrv.h> +#if defined(sun4c) || defined(sun4m) +# include <sun/openprom.h> +#endif +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/ip_var.h> +#include <netinet/tcp.h> +#include <netinet/tcpip.h> +#include <net/if.h> +#include "ipl.h" +#include "ip_compat.h" +#include "ip_fil.h" + + +#if !defined(lint) +static const char sccsid[] = "@(#)mls_ipl.c 2.6 10/15/95 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)$Id$"; +#endif + +extern int ipfdetach __P((void)); +#ifndef IPFILTER_LOG +#define ipfread nulldev +#endif +extern int nulldev __P((void)); +extern int errno; + +extern int nodev __P((void)); + +static int unload __P((void)); +static int ipf_attach __P((void)); +int xxxinit __P((u_int, struct vddrv *, caddr_t, struct vdstat *)); +static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, + IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME, + IPLOOKUP_NAME, NULL }; +static int ipfopen __P((dev_t, int)); +static int ipfclose __P((dev_t, int)); +static int ipfread __P((dev_t, struct uio *)); +static int ipfwrite __P((dev_t, struct uio *)); + + +struct cdevsw ipfdevsw = +{ + ipfopen, ipfclose, ipfread, nulldev, + ipfioctl, nulldev, nulldev, nulldev, + 0, nulldev, +}; + + +struct dev_ops ipf_ops = +{ + 1, + ipfidentify, + ipfattach, + ipfopen, + ipfclose, + ipfread, + ipfwrite, + NULL, /* strategy */ + NULL, /* dump */ + 0, /* psize */ + ipfioctl, + NULL, /* reset */ + NULL /* mmap */ +}; + +int ipf_major = 0; + +#ifdef sun4m +struct vdldrv vd = +{ + VDMAGIC_PSEUDO, + IPL_VERSION, + &ipf_ops, + NULL, + &ipfdevsw, + 0, + 0, + NULL, + NULL, + NULL, + 0, + 1, +}; +#else /* sun4m */ +struct vdldrv vd = +{ + VDMAGIC_PSEUDO, /* magic */ + IPL_VERSION, +#ifdef sun4c + &ipf_ops, /* dev_ops */ +#else + NULL, /* struct mb_ctlr *mb_ctlr */ + NULL, /* struct mb_driver *mb_driver */ + NULL, /* struct mb_device *mb_device */ + 0, /* num ctlrs */ + 1, /* numdevs */ +#endif /* sun4c */ + NULL, /* bdevsw */ + &ipfdevsw, /* cdevsw */ + 0, /* block major */ + 0, /* char major */ +}; +#endif /* sun4m */ + +extern int vd_unuseddev __P((void)); +extern struct cdevsw cdevsw[]; +extern int nchrdev; + +xxxinit(fc, vdp, data, vds) + u_int fc; + struct vddrv *vdp; + caddr_t data; + struct vdstat *vds; +{ + struct vdioctl_load *vdi = (struct vdioctl_load *)data; + + switch (fc) + { + case VDLOAD: + { + struct vdconf *vdc; + if (vdi && vdi->vdi_userconf) + for (vdc = vdi->vdi_userconf; vdc->vdc_type; vdc++) + if (vdc->vdc_type == VDCCHARMAJOR) { + ipf_major = vdc->vdc_data; + break; + } + + if (!ipf_major) { + while (ipf_major < nchrdev && + cdevsw[ipf_major].d_open != vd_unuseddev) + ipf_major++; + if (ipf_major == nchrdev) + return ENODEV; + } + vdp->vdd_vdtab = (struct vdlinkage *)&vd; + vd.Drv_charmajor = ipf_major; + return ipf_attach(); + } + case VDUNLOAD: + return unload(); + case VDSTAT: + return 0; + default: + return EIO; + } +} + + +static int +unload() +{ + int err = 0, i; + char *name; + + if (ipf_refcnt != 0) + err = EBUSY; + else if (ipf_running >= 0) + err = ipfdetach(); + if (err) + return err; + + ipf_running = -2; + for (i = 0; (name = ipf_devfiles[i]); i++) + (void) vn_remove(name, UIO_SYSSPACE, FILE); + printf("%s unloaded\n", ipfilter_version); + return 0; +} + + +static int +ipf_attach() +{ + struct vnode *vp; + struct vattr vattr; + int error = 0, fmode = S_IFCHR|0600, i; + char *name; + + error = ipfattach(); + if (error) + return error; + + for (i = 0; (name = ipf_devfiles[i]); i++) { + (void) vn_remove(name, UIO_SYSSPACE, FILE); + vattr_null(&vattr); + vattr.va_type = MFTOVT(fmode); + vattr.va_mode = (fmode & 07777); + vattr.va_rdev = (ipf_major << 8) | i; + + error = vn_create(name, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); + if (error) { + printf("IP Filter: vn_create(%s) = %d\n", name, error); + break; + } else { + VN_RELE(vp); + } + } + + if (error == 0) { + 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 + ); + ipf_running = 1; + } + return error; +} + + +/* + * routines below for saving IP headers to buffer + */ +static int +ipfopen(dev, flags) + dev_t dev; + int flags; +{ + u_int unit = GET_MINOR(dev); + int error; + + if (IPL_LOGMAX < unit) { + error = ENXIO; + } else { + switch (unit) + { + case IPL_LOGIPF : + case IPL_LOGNAT : + case IPL_LOGSTATE : + case IPL_LOGAUTH : + case IPL_LOGLOOKUP : + case IPL_LOGSYNC : +#ifdef IPFILTER_SCAN + case IPL_LOGSCAN : +#endif + error = 0; + break; + default : + error = ENXIO; + break; + } + } + return error; +} + + +static int +ipfclose(dev, flags) + dev_t dev; + int flags; +{ + u_int unit = GET_MINOR(dev); + + if (IPL_LOGMAX < unit) + unit = ENXIO; + else + unit = 0; + return unit; +} + + +/* + * ipfread/ipflog + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +static int +ipfread(dev, uio) + dev_t dev; + register struct uio *uio; +{ + + if (ipf_running < 1) { + ipfmain.ipf_interror = 130006; + return EIO; + } + +#ifdef IPFILTER_LOG + return ipflog_read(GET_MINOR(dev), uio); +#else + ipfmain.ipf_interror = 130007; + return ENXIO; +#endif +} + + +/* + * ipfwrite + */ +static int +ipfwrite(dev, uio) + dev_t dev; + register struct uio *uio; +{ + + if (ipf_running < 1) { + ipfmain.ipf_interror = 130008; + return EIO; + } + + if (getminor(dev) == IPL_LOGSYNC) + return ipfsync_write(uio); + ipfmain.ipf_interror = 130009; + return ENXIO; +} |