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
);