Synchronize the ipfilter contrib code with recent file descriptor cleanups.
[dragonfly.git] / contrib / ipfilter / mls_ipl.c
1 /*
2  * Copyright (C) 1993-2001 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  */
6 /*
7  * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate
8  * its own major char number! Way cool patch!
9  */
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <sys/time.h>
13 #include <sys/file.h>
14 #include <sys/socket.h>
15 #include <sys/conf.h>
16 #include <sys/syslog.h>
17 #include <sys/buf.h>
18 #include <sys/mbuf.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 #include <netinet/in.h>
30 #include <netinet/in_systm.h>
31 #include <netinet/ip.h>
32 #include <netinet/ip_var.h>
33 #include <netinet/tcp.h>
34 #include <netinet/tcpip.h>
35 #include <net/if.h>
36 #include "ipl.h"
37 #include "ip_compat.h"
38 #include "ip_fil.h"
39
40
41 #if !defined(lint)
42 static const char sccsid[] = "@(#)mls_ipl.c     2.6 10/15/95 (C) 1993-2000 Darren Reed";
43 static const char rcsid[] = "@(#)$Id: mls_ipl.c,v 2.2.2.2 2002/04/10 05:05:54 darrenr Exp $";
44 #endif
45
46 extern  int     ipldetach __P((void));
47 #ifndef IPFILTER_LOG
48 #define iplread nulldev
49 #endif
50 extern  int     nulldev __P((void));
51 extern  int     errno;
52 extern  int     iplidentify __P((char *));
53
54 extern int nodev __P((void));
55
56 static  int     unload __P((void));
57 static  int     ipl_attach __P((void));
58 int     xxxinit __P((u_int, struct vddrv *, caddr_t, struct vdstat *));
59 static  char    *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH,
60                                     NULL };
61
62
63 struct  cdevsw  ipldevsw = 
64 {
65         iplopen, iplclose, iplread, nulldev,
66         iplioctl, nulldev, nulldev, nulldev,
67         0, nulldev,
68 };
69
70
71 struct  dev_ops ipl_ops = 
72 {
73         1,
74         iplidentify,
75         iplattach,
76         iplopen,
77         iplclose,
78         iplread,
79         NULL,           /* write */
80         NULL,           /* strategy */
81         NULL,           /* dump */
82         0,              /* psize */
83         iplioctl,
84         NULL,           /* reset */
85         NULL            /* mmap */
86 };
87
88 int     ipl_major = 0;
89
90 #ifdef sun4m
91 struct  vdldrv  vd = 
92 {
93         VDMAGIC_PSEUDO,
94         IPL_VERSION,
95         &ipl_ops,
96         NULL,
97         &ipldevsw,
98         0,
99         0,
100         NULL,
101         NULL,
102         NULL,
103         0,
104         1,
105 };
106 #else /* sun4m */
107 struct vdldrv vd =
108 {
109         VDMAGIC_PSEUDO, /* magic */
110         IPL_VERSION,
111 #ifdef sun4c
112         &ipl_ops,       /* dev_ops */
113 #else
114         NULL,           /* struct mb_ctlr *mb_ctlr */
115         NULL,           /* struct mb_driver *mb_driver */
116         NULL,           /* struct mb_device *mb_device */
117         0,              /* num ctlrs */
118         1,              /* numdevs */
119 #endif /* sun4c */
120         NULL,           /* bdevsw */
121         &ipldevsw,      /* cdevsw */
122         0,              /* block major */
123         0,              /* char major */
124 };
125 #endif /* sun4m */
126
127 extern int vd_unuseddev __P((void));
128 extern struct cdevsw cdevsw[];
129 extern int nchrdev;
130
131 xxxinit(fc, vdp, data, vds)
132 u_int   fc;
133 struct  vddrv   *vdp;
134 caddr_t data;
135 struct  vdstat  *vds;
136 {
137         struct vdioctl_load *vdi = (struct vdioctl_load *)data;
138
139         switch (fc)
140         {
141         case VDLOAD:
142             {
143                 struct vdconf *vdc;
144                 if (vdi && vdi->vdi_userconf)
145                         for (vdc = vdi->vdi_userconf; vdc->vdc_type; vdc++)
146                                 if (vdc->vdc_type == VDCCHARMAJOR) {
147                                         ipl_major = vdc->vdc_data;
148                                         break;
149                                 }
150
151                 if (!ipl_major) {
152                         while (ipl_major < nchrdev &&
153                                cdevsw[ipl_major].d_open != vd_unuseddev)
154                                 ipl_major++;
155                         if (ipl_major == nchrdev)
156                                 return ENODEV;
157                 }
158                 vdp->vdd_vdtab = (struct vdlinkage *)&vd;
159                 vd.Drv_charmajor = ipl_major;
160                 return ipl_attach();
161             }
162         case VDUNLOAD:
163                 return unload();
164         case VDSTAT:
165                 return 0;
166         default:
167                 return EIO;
168         }
169 }
170
171
172 static  int     unload()
173 {
174         char *name;
175         int err, i;
176
177         err = ipldetach();
178         if (err)
179                 return err;
180         for (i = 0; (name = ipf_devfiles[i]); i++)
181                 (void) vn_remove(name, UIO_SYSSPACE, FILE);
182         return 0;
183 }
184
185
186 static  int     ipl_attach()
187 {
188         struct vnode *vp;
189         struct vattr vattr;
190         int error = 0, fmode = S_IFCHR|0600, i;
191         char *name;
192
193         error = iplattach();
194         if (error)
195                 return error;
196
197         for (i = 0; (name = ipf_devfiles[i]); i++) {
198                 (void) vn_remove(name, UIO_SYSSPACE, FILE);
199                 vattr_null(&vattr);
200                 vattr.va_type = MFTOVT(fmode);
201                 vattr.va_mode = (fmode & 07777);
202                 vattr.va_rdev = (ipl_major << 8) | i;
203
204                 error = vn_create(name, UIO_SYSSPACE, &vattr, EXCL, 0, &vp);
205                 if (error) {
206                         printf("IP Filter: vn_create(%s) = %d\n", name, error);
207                         break;
208                 } else {
209                         VN_RELE(vp);
210                 }
211         }
212         return error;
213 }