2 * Copyright (C) 1993-2001 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
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!
12 #include <sys/param.h>
15 * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
16 * on those hooks. We don't need any special mods with this!
18 #if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
19 (defined(NetBSD1_2) && NetBSD1_2 > 1)
23 #include <sys/systm.h>
29 #include <sys/kernel.h>
30 #include <sys/vnode.h>
31 #include <sys/namei.h>
32 #include <sys/malloc.h>
33 #include <sys/mount.h>
37 #include <netinet/in_systm.h>
38 #include <netinet/in.h>
39 #include <netinet/ip.h>
40 #include <net/route.h>
41 #include <netinet/ip_var.h>
42 #include <netinet/tcp.h>
43 #include <netinet/tcpip.h>
46 #include "ip_compat.h"
49 #if !defined(__NetBSD_Version__) || __NetBSD_Version__ < 103050000
50 #define vn_lock(v,f) VOP_LOCK(v)
53 #if !defined(VOP_LEASE) && defined(LEASE_CHECK)
54 #define VOP_LEASE LEASE_CHECK
58 #define MIN(a,b) (((a)<(b))?(a):(b))
62 extern int lkmenodev __P((void));
64 #if (NetBSD >= 199706) || (defined(OpenBSD) && (OpenBSD >= 200211))
65 int if_ipl_lkmentry __P((struct lkm_table *, int, int));
68 int if_ipl __P((struct lkm_table *, int, int));
70 int xxxinit __P((struct lkm_table *, int, int));
73 static int ipl_unload __P((void));
74 static int ipl_load __P((void));
75 static int ipl_remove __P((void));
76 static int iplaction __P((struct lkm_table *, int));
77 static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH,
81 #if (defined(NetBSD1_0) && (NetBSD1_0 > 1)) || \
82 (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199511))
83 # if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
84 extern const struct cdevsw ipl_cdevsw;
86 struct cdevsw ipldevsw =
101 struct cdevsw ipldevsw =
104 iplclose, /* close */
106 (void *)nullop, /* write */
107 iplioctl, /* ioctl */
108 (void *)nullop, /* stop */
110 (void *)nullop, /* reset */
112 (void *)NULL, /* tty */
113 (void *)nullop, /* select */
114 (void *)nullop, /* mmap */
120 #if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
121 MOD_DEV(IPL_VERSION, "ipl", NULL, -1, &ipl_cdevsw, -1);
123 MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw);
126 extern int vd_unuseddev __P((void));
127 extern struct cdevsw cdevsw[];
131 #if (NetBSD >= 199706) || (defined(OpenBSD) && (OpenBSD >= 200211))
132 int if_ipl_lkmentry(lkmtp, cmd, ver)
135 int if_ipl(lkmtp, cmd, ver)
137 int xxxinit(lkmtp, cmd, ver)
140 struct lkm_table *lkmtp;
143 DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
147 int lkmexists __P((struct lkm_table *)); /* defined in /sys/kern/kern_lkm.c */
150 static int iplaction(lkmtp, cmd)
151 struct lkm_table *lkmtp;
154 struct lkm_dev *args = lkmtp->private.lkm_dev;
156 #if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000)
163 if (lkmexists(lkmtp))
166 #if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000)
167 for (i = 0; i < nchrdev; i++)
168 if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev ||
169 cdevsw[i].d_open == iplopen)
172 printf("IP Filter: No free cdevsw slots\n");
177 args->lkm_offset = i; /* slot in cdevsw[] */
179 err = devsw_attach(args->lkm_devname,
180 args->lkm_bdev, &args->lkm_bdevmaj,
181 args->lkm_cdev, &args->lkm_cdevmaj);
184 ipl_major = args->lkm_cdevmaj;
186 printf("IP Filter: loaded into slot %d\n", ipl_major);
189 #if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
190 devsw_detach(args->lkm_bdev, args->lkm_cdev);
191 args->lkm_bdevmaj = -1;
192 args->lkm_cdevmaj = -1;
196 printf("IP Filter: unloaded from slot %d\n",
209 static int ipl_remove()
215 for (i = 0; (name = ipf_devfiles[i]); i++) {
216 NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
217 if ((error = namei(&nd)))
219 VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
221 VOP_LOCK(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, curproc);
223 # if !defined(__NetBSD_Version__) || (__NetBSD_Version__ < 106000000)
224 vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
227 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
228 (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
234 static int ipl_unload()
239 * Unloading - remove the filter rule check from the IP
240 * input/output stream.
242 #if defined(__NetBSD__)
243 error = ipl_disable();
249 error = ipl_remove();
254 static int ipl_load()
258 int error = 0, fmode = S_IFCHR|0600, i;
262 * XXX Remove existing device nodes prior to creating new ones
263 * XXX using the assigned LKM device slot's major number. In a
264 * XXX perfect world we could use the ones specified by cdevsw[].
268 error = ipl_enable();
272 for (i = 0; (name = ipf_devfiles[i]); i++) {
273 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
274 if ((error = namei(&nd)))
276 if (nd.ni_vp != NULL) {
277 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
278 if (nd.ni_dvp == nd.ni_vp)
286 vattr.va_type = VCHR;
287 vattr.va_mode = (fmode & 07777);
288 vattr.va_rdev = (ipl_major << 8) | i;
289 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
290 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);