1255332Scy/* $FreeBSD$ */ 2255332Scy 3255332Scy/* 4255332Scy * Copyright (C) 2012 by Darren Reed. 5255332Scy * 6255332Scy * See the IPFILTER.LICENCE file for details on licencing. 7255332Scy */ 8255332Scy/* 9255332Scy * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate 10255332Scy * its own major char number! Way cool patch! 11255332Scy */ 12255332Scy#include <sys/types.h> 13255332Scy#include <sys/stat.h> 14255332Scy#include <sys/time.h> 15255332Scy#include <sys/file.h> 16255332Scy#include <sys/conf.h> 17255332Scy#include <sys/syslog.h> 18255332Scy#include <sys/buf.h> 19255332Scy#include <sys/param.h> 20255332Scy#include <sys/errno.h> 21255332Scy#include <sys/uio.h> 22255332Scy#include <sys/vnode.h> 23255332Scy#include <sundev/mbvar.h> 24255332Scy#include <sun/autoconf.h> 25255332Scy#include <sun/vddrv.h> 26255332Scy#if defined(sun4c) || defined(sun4m) 27255332Scy#include <sun/openprom.h> 28255332Scy#endif 29255332Scy 30255332Scy#ifndef IPL_NAME 31255332Scy#define IPL_NAME "/dev/ipf" 32255332Scy#endif 33255332Scy 34255332Scyextern int ipfattach(), ipfopen(), ipfclose(), ipfioctl(), ipfread(); 35255332Scyextern int nulldev(), ipfidentify(), errno; 36255332Scy 37255332Scystruct cdevsw ipfdevsw = 38255332Scy{ 39255332Scy ipfopen, ipfclose, ipfread, nulldev, 40255332Scy ipfioctl, nulldev, nulldev, nulldev, 41255332Scy 0, nulldev, 42255332Scy}; 43255332Scy 44255332Scy 45255332Scystruct dev_ops ipf_ops = 46255332Scy{ 47255332Scy 1, 48255332Scy ipfidentify, 49255332Scy ipfattach, 50255332Scy ipfopen, 51255332Scy ipfclose, 52255332Scy ipfread, 53255332Scy NULL, /* write */ 54255332Scy NULL, /* strategy */ 55255332Scy NULL, /* dump */ 56255332Scy 0, /* psize */ 57255332Scy ipfioctl, 58255332Scy NULL, /* reset */ 59255332Scy NULL /* mmap */ 60255332Scy}; 61255332Scy 62255332Scyint ipf_major = 0; 63255332Scy 64255332Scy#ifdef sun4m 65255332Scystruct vdldrv vd = 66255332Scy{ 67255332Scy VDMAGIC_PSEUDO, 68255332Scy "ipf", 69255332Scy &ipf_ops, 70255332Scy NULL, 71255332Scy &ipfdevsw, 72255332Scy 0, 73255332Scy 0, 74255332Scy NULL, 75255332Scy NULL, 76255332Scy NULL, 77255332Scy 0, 78255332Scy 1, 79255332Scy}; 80255332Scy#else /* sun4m */ 81255332Scystruct vdldrv vd = 82255332Scy{ 83255332Scy VDMAGIC_PSEUDO, /* magic */ 84255332Scy "ipf", /* name */ 85255332Scy#ifdef sun4c 86255332Scy &ipf_ops, /* dev_ops */ 87255332Scy#else 88255332Scy NULL, /* struct mb_ctlr *mb_ctlr */ 89255332Scy NULL, /* struct mb_driver *mb_driver */ 90255332Scy NULL, /* struct mb_device *mb_device */ 91255332Scy 0, /* num ctlrs */ 92255332Scy 1, /* numdevs */ 93255332Scy#endif /* sun4c */ 94255332Scy NULL, /* bdevsw */ 95255332Scy &ipfdevsw, /* cdevsw */ 96255332Scy 0, /* block major */ 97255332Scy 0, /* char major */ 98255332Scy}; 99255332Scy#endif /* sun4m */ 100255332Scy 101255332Scyextern int vd_unuseddev(); 102255332Scyextern struct cdevsw cdevsw[]; 103255332Scyextern int nchrdev; 104255332Scy 105255332Scyxxxinit(fc, vdp, vdi, vds) 106255332Scy u_int fc; 107255332Scy struct vddrv *vdp; 108255332Scy caddr_t vdi; 109255332Scy struct vdstat *vds; 110255332Scy{ 111255332Scy struct vdlinkage *v; 112255332Scy int i; 113255332Scy 114255332Scy switch (fc) 115255332Scy { 116255332Scy case VDLOAD: 117255332Scy while (ipf_major < nchrdev && 118255332Scy cdevsw[ipf_major].d_open != vd_unuseddev) 119255332Scy ipf_major++; 120255332Scy if (ipf_major == nchrdev) 121255332Scy return ENODEV; 122255332Scy vd.Drv_charmajor = ipf_major; 123255332Scy vdp->vdd_vdtab = (struct vdlinkage *)&vd; 124255332Scy return ipf_attach(vdi); 125255332Scy case VDUNLOAD: 126255332Scy return unload(vdp, vdi); 127255332Scy 128255332Scy case VDSTAT: 129255332Scy return 0; 130255332Scy 131255332Scy default: 132255332Scy return EIO; 133255332Scy } 134255332Scy} 135255332Scy 136255332Scystatic unload(vdp, vdi) 137255332Scy struct vddrv *vdp; 138255332Scy struct vdioctl_unload *vdi; 139255332Scy{ 140255332Scy int i; 141255332Scy 142255332Scy (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); 143255332Scy return ipfdetach(); 144255332Scy} 145255332Scy 146255332Scy 147255332Scystatic int ipf_attach(vdi) 148255332Scystruct vdioctl_load *vdi; 149255332Scy{ 150255332Scy struct vnode *vp; 151255332Scy struct vattr vattr; 152255332Scy int error = 0, fmode = S_IFCHR|0600; 153255332Scy 154255332Scy (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); 155255332Scy vattr_null(&vattr); 156255332Scy vattr.va_type = MFTOVT(fmode); 157255332Scy vattr.va_mode = (fmode & 07777); 158255332Scy vattr.va_rdev = ipf_major<<8; 159255332Scy 160255332Scy error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); 161255332Scy if (error == 0) 162255332Scy VN_RELE(vp); 163255332Scy return ipfattach(0); 164255332Scy} 165