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>
14 #if defined(__FreeBSD__)
15 # ifndef __FreeBSD_version
17 # include <osreldate.h>
19 # include <sys/osreldate.h>
23 # define ACTUALLY_LKM_NOT_KERNEL
26 #include <sys/systm.h>
27 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
28 # ifndef ACTUALLY_LKM_NOT_KERNEL
29 # include "opt_devfs.h"
31 # include <sys/conf.h>
32 # include <sys/kernel.h>
34 # include <sys/devfsext.h>
39 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
40 # include <sys/lock.h>
45 #include <sys/kernel.h>
46 #include <sys/vnode.h>
47 #include <sys/namei.h>
48 #include <sys/malloc.h>
49 #include <sys/mount.h>
53 # include <sys/sysctl.h>
55 #if (__FreeBSD_version >= 300000)
56 # include <sys/socket.h>
59 #include <netinet/in_systm.h>
60 #include <netinet/in.h>
61 #include <netinet/ip.h>
62 #include <net/route.h>
64 #include <netinet/ip_var.h>
65 #include <netinet/tcp.h>
66 #include <netinet/tcpip.h>
67 #include <sys/sysent.h>
69 #include "netinet/ipl.h"
70 #include "netinet/ip_compat.h"
71 #include "netinet/ip_fil.h"
72 #include "netinet/ip_state.h"
73 #include "netinet/ip_nat.h"
74 #include "netinet/ip_auth.h"
75 #include "netinet/ip_frag.h"
76 #include "netinet/ip_proxy.h"
79 #if !defined(VOP_LEASE) && defined(LEASE_CHECK)
80 #define VOP_LEASE LEASE_CHECK
84 #define MIN(a,b) (((a)<(b))?(a):(b))
87 int xxxinit
__P((struct lkm_table
*, int, int));
90 SYSCTL_NODE(_net_inet
, OID_AUTO
, ipf
, CTLFLAG_RW
, 0, "IPF");
91 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_flags
, CTLFLAG_RW
, &fr_flags
, 0, "");
92 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_pass
, CTLFLAG_RW
, &fr_pass
, 0, "");
93 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_active
, CTLFLAG_RD
, &fr_active
, 0, "");
94 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_chksrc
, CTLFLAG_RW
, &fr_chksrc
, 0, "");
95 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_minttl
, CTLFLAG_RW
, &fr_minttl
, 0, "");
96 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_minttllog
, CTLFLAG_RW
,
97 &fr_minttllog
, 0, "");
98 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_tcpidletimeout
, CTLFLAG_RW
,
99 &fr_tcpidletimeout
, 0, "");
100 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_tcphalfclosed
, CTLFLAG_RW
,
101 &fr_tcphalfclosed
, 0, "");
102 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_tcpclosewait
, CTLFLAG_RW
,
103 &fr_tcpclosewait
, 0, "");
104 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_tcplastack
, CTLFLAG_RW
,
105 &fr_tcplastack
, 0, "");
106 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_tcptimeout
, CTLFLAG_RW
,
107 &fr_tcptimeout
, 0, "");
108 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_tcpclosed
, CTLFLAG_RW
,
109 &fr_tcpclosed
, 0, "");
110 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_udptimeout
, CTLFLAG_RW
,
111 &fr_udptimeout
, 0, "");
112 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_udpacktimeout
, CTLFLAG_RW
,
113 &fr_udpacktimeout
, 0, "");
114 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_icmptimeout
, CTLFLAG_RW
,
115 &fr_icmptimeout
, 0, "");
116 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_icmpacktimeout
, CTLFLAG_RW
,
117 &fr_icmpacktimeout
, 0, "");
118 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_defnatage
, CTLFLAG_RW
,
119 &fr_defnatage
, 0, "");
120 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_ipfrttl
, CTLFLAG_RW
,
122 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, ipl_unreach
, CTLFLAG_RW
,
123 &ipl_unreach
, 0, "");
124 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_running
, CTLFLAG_RD
,
126 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_authsize
, CTLFLAG_RD
,
127 &fr_authsize
, 0, "");
128 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_authused
, CTLFLAG_RD
,
129 &fr_authused
, 0, "");
130 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, fr_defaultauthage
, CTLFLAG_RW
,
131 &fr_defaultauthage
, 0, "");
132 SYSCTL_INT(_net_inet_ipf
, OID_AUTO
, ippr_ftp_pasvonly
, CTLFLAG_RW
,
133 &ippr_ftp_pasvonly
, 0, "");
137 static void *ipf_devfs
[IPL_LOGMAX
+ 1];
140 #if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
143 static struct cdevsw ipldevsw
=
146 iplclose
, /* close */
148 (void *)nullop
, /* write */
149 iplioctl
, /* ioctl */
150 (void *)nullop
, /* stop */
151 (void *)nullop
, /* reset */
152 (void *)NULL
, /* tty */
153 (void *)nullop
, /* select */
154 (void *)nullop
, /* mmap */
158 MOD_DEV(IPL_VERSION
, LM_DT_CHAR
, -1, &ipldevsw
);
160 extern struct cdevsw cdevsw
[];
161 extern int vd_unuseddev
__P((void));
165 static struct cdevsw ipl_cdevsw
= {
166 iplopen
, iplclose
, iplread
, nowrite
, /* 79 */
167 iplioctl
, nostop
, noreset
, nodevtotty
,
168 #if (__FreeBSD_version >= 300000)
169 seltrue
, nommap
, nostrategy
, "ipl",
171 noselect
, nommap
, nostrategy
, "ipl",
177 static void ipl_drvinit
__P((void *));
179 #ifdef ACTUALLY_LKM_NOT_KERNEL
180 static int if_ipl_unload
__P((struct lkm_table
*, int));
181 static int if_ipl_load
__P((struct lkm_table
*, int));
182 static int if_ipl_remove
__P((void));
183 static int ipl_major
= CDEV_MAJOR
;
185 static int iplaction
__P((struct lkm_table
*, int));
186 static char *ipf_devfiles
[] = { IPL_NAME
, IPL_NAT
, IPL_STATE
, IPL_AUTH
, NULL
};
188 extern int lkmenodev
__P((void));
190 static int iplaction(lkmtp
, cmd
)
191 struct lkm_table
*lkmtp
;
194 #if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
196 struct lkm_dev
*args
= lkmtp
->private.lkm_dev
;
203 if (lkmexists(lkmtp
))
206 #if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
207 for (i
= 0; i
< nchrdev
; i
++)
208 if (cdevsw
[i
].d_open
== lkmenodev
||
209 cdevsw
[i
].d_open
== iplopen
)
212 printf("IP Filter: No free cdevsw slots\n");
217 args
->lkm_offset
= i
; /* slot in cdevsw[] */
219 printf("IP Filter: loaded into slot %d\n", ipl_major
);
220 err
= if_ipl_load(lkmtp
, cmd
);
222 ipl_drvinit((void *)NULL
);
226 err
= if_ipl_unload(lkmtp
, cmd
);
228 printf("IP Filter: unloaded from slot %d\n",
231 if (ipf_devfs
[IPL_LOGIPF
])
232 devfs_remove_dev(ipf_devfs
[IPL_LOGIPF
]);
233 if (ipf_devfs
[IPL_LOGNAT
])
234 devfs_remove_dev(ipf_devfs
[IPL_LOGNAT
]);
235 if (ipf_devfs
[IPL_LOGSTATE
])
236 devfs_remove_dev(ipf_devfs
[IPL_LOGSTATE
]);
237 if (ipf_devfs
[IPL_LOGAUTH
])
238 devfs_remove_dev(ipf_devfs
[IPL_LOGAUTH
]);
252 static int if_ipl_remove
__P((void))
258 for (i
= 0; (name
= ipf_devfiles
[i
]); i
++) {
259 NDINIT(&nd
, DELETE
, LOCKPARENT
, UIO_SYSSPACE
, name
, curproc
);
260 if ((error
= namei(&nd
)))
262 VOP_LEASE(nd
.ni_vp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
263 #if (__FreeBSD_version >= 300000)
264 VOP_LOCK(nd
.ni_vp
, LK_RETRY
| LK_EXCLUSIVE
, curproc
);
265 VOP_LEASE(nd
.ni_dvp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
266 (void) VOP_REMOVE(nd
.ni_dvp
, nd
.ni_vp
, &nd
.ni_cnd
);
268 if (nd
.ni_dvp
== nd
.ni_vp
)
272 if (nd
.ni_vp
!= NULLVP
)
276 VOP_LEASE(nd
.ni_dvp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
277 (void) VOP_REMOVE(nd
.ni_dvp
, nd
.ni_vp
, &nd
.ni_cnd
);
285 static int if_ipl_unload(lkmtp
, cmd
)
286 struct lkm_table
*lkmtp
;
293 error
= if_ipl_remove();
298 static int if_ipl_load(lkmtp
, cmd
)
299 struct lkm_table
*lkmtp
;
304 int error
= 0, fmode
= S_IFCHR
|0600, i
;
310 (void) if_ipl_remove();
312 for (i
= 0; (name
= ipf_devfiles
[i
]); i
++) {
313 NDINIT(&nd
, CREATE
, LOCKPARENT
, UIO_SYSSPACE
, name
, curproc
);
314 if ((error
= namei(&nd
)))
316 if (nd
.ni_vp
!= NULL
) {
317 VOP_ABORTOP(nd
.ni_dvp
, &nd
.ni_cnd
);
318 if (nd
.ni_dvp
== nd
.ni_vp
)
326 vattr
.va_type
= VCHR
;
327 vattr
.va_mode
= (fmode
& 07777);
328 vattr
.va_rdev
= (ipl_major
<< 8) | i
;
329 VOP_LEASE(nd
.ni_dvp
, curproc
, curproc
->p_ucred
, LEASE_WRITE
);
330 error
= VOP_MKNOD(nd
.ni_dvp
, &nd
.ni_vp
, &nd
.ni_cnd
, &vattr
);
331 #if (__FreeBSD_version >= 300000)
340 #endif /* actually LKM */
342 #if defined(__FreeBSD_version) && (__FreeBSD_version < 220000)
344 * strlen isn't present in 2.1.* kernels.
346 size_t strlen(string
)
351 for (s
= string
; *s
; s
++)
353 return (size_t)(s
- string
);
357 int xxxinit(lkmtp
, cmd
, ver
)
358 struct lkm_table
*lkmtp
;
361 DISPATCH(lkmtp
, cmd
, ver
, iplaction
, iplaction
, iplaction
);
363 #else /* __FREEBSD_version >= 220000 */
365 # include <sys/exec.h>
367 # if (__FreeBSD_version >= 300000)
368 MOD_DEV(if_ipl
, LM_DT_CHAR
, CDEV_MAJOR
, &ipl_cdevsw
);
373 static struct lkm_dev _module
= {
379 { (void *)&ipl_cdevsw
}
384 int if_ipl
__P((struct lkm_table
*, int, int));
387 int if_ipl(lkmtp
, cmd
, ver
)
388 struct lkm_table
*lkmtp
;
391 # if (__FreeBSD_version >= 300000)
392 MOD_DISPATCH(if_ipl
, lkmtp
, cmd
, ver
, iplaction
, iplaction
, iplaction
);
394 DISPATCH(lkmtp
, cmd
, ver
, iplaction
, iplaction
, iplaction
);
397 # endif /* IPFILTER_LKM */
398 static int ipl_devsw_installed
= 0;
400 static void ipl_drvinit
__P((void *unused
))
404 void **tp
= ipf_devfs
;
407 if (!ipl_devsw_installed
) {
408 dev
= makedev(CDEV_MAJOR
, 0);
409 cdevsw_add(&dev
, &ipl_cdevsw
, NULL
);
410 ipl_devsw_installed
= 1;
413 tp
[IPL_LOGIPF
] = devfs_add_devswf(&ipl_cdevsw
, IPL_LOGIPF
,
414 DV_CHR
, 0, 0, 0600, "ipf");
415 tp
[IPL_LOGNAT
] = devfs_add_devswf(&ipl_cdevsw
, IPL_LOGNAT
,
416 DV_CHR
, 0, 0, 0600, "ipnat");
417 tp
[IPL_LOGSTATE
] = devfs_add_devswf(&ipl_cdevsw
, IPL_LOGSTATE
,
420 tp
[IPL_LOGAUTH
] = devfs_add_devswf(&ipl_cdevsw
, IPL_LOGAUTH
,
427 # if defined(IPFILTER_LKM) || \
428 defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
429 SYSINIT(ipldev
,SI_SUB_DRIVERS
,SI_ORDER_MIDDLE
+CDEV_MAJOR
,ipl_drvinit
,NULL
)
430 # endif /* IPFILTER_LKM */
431 #endif /* _FreeBSD_version */