ml_ipl.c revision 259128
1/* $FreeBSD$ */ 2 3/* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8/* 9 * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate 10 * its own major char number! Way cool patch! 11 */ 12#include <sys/types.h> 13#include <sys/stat.h> 14#include <sys/time.h> 15#include <sys/file.h> 16#include <sys/conf.h> 17#include <sys/syslog.h> 18#include <sys/buf.h> 19#include <sys/param.h> 20#include <sys/errno.h> 21#include <sys/uio.h> 22#include <sys/vnode.h> 23#include <sundev/mbvar.h> 24#include <sun/autoconf.h> 25#include <sun/vddrv.h> 26#if defined(sun4c) || defined(sun4m) 27#include <sun/openprom.h> 28#endif 29 30#ifndef IPL_NAME 31#define IPL_NAME "/dev/ipf" 32#endif 33 34extern int ipfattach(), ipfopen(), ipfclose(), ipfioctl(), ipfread(); 35extern int nulldev(), ipfidentify(), errno; 36 37struct cdevsw ipfdevsw = 38{ 39 ipfopen, ipfclose, ipfread, nulldev, 40 ipfioctl, nulldev, nulldev, nulldev, 41 0, nulldev, 42}; 43 44 45struct dev_ops ipf_ops = 46{ 47 1, 48 ipfidentify, 49 ipfattach, 50 ipfopen, 51 ipfclose, 52 ipfread, 53 NULL, /* write */ 54 NULL, /* strategy */ 55 NULL, /* dump */ 56 0, /* psize */ 57 ipfioctl, 58 NULL, /* reset */ 59 NULL /* mmap */ 60}; 61 62int ipf_major = 0; 63 64#ifdef sun4m 65struct vdldrv vd = 66{ 67 VDMAGIC_PSEUDO, 68 "ipf", 69 &ipf_ops, 70 NULL, 71 &ipfdevsw, 72 0, 73 0, 74 NULL, 75 NULL, 76 NULL, 77 0, 78 1, 79}; 80#else /* sun4m */ 81struct vdldrv vd = 82{ 83 VDMAGIC_PSEUDO, /* magic */ 84 "ipf", /* name */ 85#ifdef sun4c 86 &ipf_ops, /* dev_ops */ 87#else 88 NULL, /* struct mb_ctlr *mb_ctlr */ 89 NULL, /* struct mb_driver *mb_driver */ 90 NULL, /* struct mb_device *mb_device */ 91 0, /* num ctlrs */ 92 1, /* numdevs */ 93#endif /* sun4c */ 94 NULL, /* bdevsw */ 95 &ipfdevsw, /* cdevsw */ 96 0, /* block major */ 97 0, /* char major */ 98}; 99#endif /* sun4m */ 100 101extern int vd_unuseddev(); 102extern struct cdevsw cdevsw[]; 103extern int nchrdev; 104 105xxxinit(fc, vdp, vdi, vds) 106 u_int fc; 107 struct vddrv *vdp; 108 caddr_t vdi; 109 struct vdstat *vds; 110{ 111 struct vdlinkage *v; 112 int i; 113 114 switch (fc) 115 { 116 case VDLOAD: 117 while (ipf_major < nchrdev && 118 cdevsw[ipf_major].d_open != vd_unuseddev) 119 ipf_major++; 120 if (ipf_major == nchrdev) 121 return ENODEV; 122 vd.Drv_charmajor = ipf_major; 123 vdp->vdd_vdtab = (struct vdlinkage *)&vd; 124 return ipf_attach(vdi); 125 case VDUNLOAD: 126 return unload(vdp, vdi); 127 128 case VDSTAT: 129 return 0; 130 131 default: 132 return EIO; 133 } 134} 135 136static unload(vdp, vdi) 137 struct vddrv *vdp; 138 struct vdioctl_unload *vdi; 139{ 140 int i; 141 142 (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); 143 return ipfdetach(); 144} 145 146 147static int ipf_attach(vdi) 148struct vdioctl_load *vdi; 149{ 150 struct vnode *vp; 151 struct vattr vattr; 152 int error = 0, fmode = S_IFCHR|0600; 153 154 (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); 155 vattr_null(&vattr); 156 vattr.va_type = MFTOVT(fmode); 157 vattr.va_mode = (fmode & 07777); 158 vattr.va_rdev = ipf_major<<8; 159 160 error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); 161 if (error == 0) 162 VN_RELE(vp); 163 return ipfattach(0); 164} 165