4 * Copyright (C) 1993-2001 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
10 #include <sys/param.h>
11 #include <sys/systm.h>
17 #include <sys/kernel.h>
18 #include <sys/vnode.h>
19 #include <sys/namei.h>
20 #include <sys/malloc.h>
21 #include <sys/mount.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/in.h>
27 #include <netinet/ip.h>
28 #include <net/route.h>
29 #include <netinet/ip_var.h>
30 #include <netinet/tcp.h>
31 #include <netinet/tcpip.h>
34 #include "ip_compat.h"
37 #define vn_lock(v,f) VOP_LOCK(v)
39 #if !defined(VOP_LEASE) && defined(LEASE_CHECK)
40 #define VOP_LEASE LEASE_CHECK
44 extern int lkmenodev
__P((void));
47 int if_ipl_lkmentry
__P((struct lkm_table
*, int, int));
49 int if_ipl
__P((struct lkm_table
*, int, int));
51 static int ipl_unload
__P((void));
52 static int ipl_load
__P((void));
53 static int ipl_remove
__P((void));
54 static int iplaction
__P((struct lkm_table
*, int));
55 static char *ipf_devfiles
[] = { IPL_NAME
, IPNAT_NAME
, IPSTATE_NAME
,
56 IPAUTH_NAME
, IPSYNC_NAME
, IPSCAN_NAME
,
57 IPLOOKUP_NAME
, NULL
};
60 struct cdevsw ipldevsw
=
67 (void *)nullop
, /* stop */
68 (void *)NULL
, /* tty */
69 (void *)nullop
, /* select */
70 (void *)nullop
, /* mmap */
76 MOD_DEV(IPL_VERSION
, LM_DT_CHAR
, -1, &ipldevsw
);
78 extern int vd_unuseddev
__P((void));
79 extern struct cdevsw cdevsw
[];
84 int if_ipl_lkmentry (lkmtp
, cmd
, ver
)
86 int if_ipl(lkmtp
, cmd
, ver
)
88 struct lkm_table
*lkmtp
;
91 DISPATCH(lkmtp
, cmd
, ver
, iplaction
, iplaction
, iplaction
);
94 int lkmexists
__P((struct lkm_table
*)); /* defined in /sys/kern/kern_lkm.c */
96 static int iplaction(lkmtp
, cmd
)
97 struct lkm_table
*lkmtp
;
101 struct lkm_dev
*args
= lkmtp
->private.lkm_dev
;
107 if (lkmexists(lkmtp
))
110 for (i
= 0; i
< nchrdev
; i
++)
111 if (cdevsw
[i
].d_open
== (dev_type_open((*)))lkmenodev
||
112 cdevsw
[i
].d_open
== iplopen
)
115 printf("IP Filter: No free cdevsw slots\n");
120 args
->lkm_offset
= i
; /* slot in cdevsw[] */
121 printf("IP Filter: loaded into slot %d\n", ipl_major
);
126 printf("IP Filter: unloaded from slot %d\n",
139 static int ipl_remove()
145 for (i
= 0; (name
= ipf_devfiles
[i
]); i
++) {
146 #if OpenBSD >= 200311
147 NDINIT(&nd
, DELETE
, LOCKPARENT
| LOCKLEAF
, UIO_SYSSPACE
,
150 NDINIT(&nd
, DELETE
, LOCKPARENT
, UIO_SYSSPACE
, name
, curproc
);
152 if ((error
= namei(&nd
)))
154 VOP_LEASE(nd
.ni_vp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
156 VOP_LOCK(nd
.ni_vp
, LK_EXCLUSIVE
| LK_RETRY
, curproc
);
157 VOP_LEASE(nd
.ni_dvp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
159 (void)uvm_vnp_uncache(nd
.ni_vp
);
161 VOP_LEASE(nd
.ni_dvp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
162 VOP_LEASE(nd
.ni_vp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
164 (void) VOP_REMOVE(nd
.ni_dvp
, nd
.ni_vp
, &nd
.ni_cnd
);
170 static int ipl_unload()
175 * Unloading - remove the filter rule check from the IP
176 * input/output stream.
180 else if (fr_running
>= 0)
185 error
= ipl_remove();
186 printf("%s unloaded\n", ipfilter_version
);
192 static int ipl_load()
196 int error
= 0, fmode
= S_IFCHR
|0600, i
;
200 * XXX Remove existing device nodes prior to creating new ones
201 * XXX using the assigned LKM device slot's major number. In a
202 * XXX perfect world we could use the ones specified by cdevsw[].
208 for (i
= 0; (error
== 0) && (name
= ipf_devfiles
[i
]); i
++) {
209 NDINIT(&nd
, CREATE
, LOCKPARENT
, UIO_SYSSPACE
, name
, curproc
);
210 if ((error
= namei(&nd
)))
212 if (nd
.ni_vp
!= NULL
) {
213 VOP_ABORTOP(nd
.ni_dvp
, &nd
.ni_cnd
);
214 if (nd
.ni_dvp
== nd
.ni_vp
)
223 vattr
.va_type
= VCHR
;
224 vattr
.va_mode
= (fmode
& 07777);
225 vattr
.va_rdev
= (ipl_major
<< 8) | i
;
226 VOP_LEASE(nd
.ni_dvp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
227 error
= VOP_MKNOD(nd
.ni_dvp
, &nd
.ni_vp
, &nd
.ni_cnd
, &vattr
);
233 if (FR_ISPASS(fr_pass
))
235 else if (FR_ISBLOCK(fr_pass
))
238 defpass
= "no-match -> block";
240 printf("%s initialized. Default = %s all, Logging = %s%s\n",
241 ipfilter_version
, defpass
,
247 #ifdef IPFILTER_COMPILED