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
34 extern int ipfattach(), ipfopen(), ipfclose(), ipfioctl(), ipfread();
35 extern int nulldev(), ipfidentify(), errno;
36
37 struct cdevsw ipfdevsw =
38 {
39 ipfopen, ipfclose, ipfread, nulldev,
40 ipfioctl, nulldev, nulldev, nulldev,
41 0, nulldev,
42 };
43
44
45 struct 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
62 int ipf_major = 0;
63
64 #ifdef sun4m
65 struct 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 */
81 struct 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
101 extern int vd_unuseddev();
102 extern struct cdevsw cdevsw[];
103 extern int nchrdev;
104
xxxinit(fc,vdp,vdi,vds)105 xxxinit(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
136 static 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
ipf_attach(vdi)147 static int ipf_attach(vdi)
148 struct 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