4 * Copyright (C) 2000 by Darren Reed.
7 * See the IPFILTER.LICENCE file for details on licencing.
11 #include <sys/param.h>
12 #include <sys/systm.h>
13 #include <sys/kernel.h>
14 #include <sys/module.h>
16 #include <sys/socket.h>
17 #include <sys/sysctl.h>
18 #include <sys/select.h>
19 #if __FreeBSD_version >= 500000
20 # include <sys/selinfo.h>
23 #include <netinet/in_systm.h>
24 #include <netinet/in.h>
27 #include <netinet/ipl.h>
28 #include <netinet/ip_compat.h>
29 #include <netinet/ip_fil.h>
30 #include <netinet/ip_state.h>
31 #include <netinet/ip_nat.h>
32 #include <netinet/ip_auth.h>
33 #include <netinet/ip_frag.h>
34 #include <netinet/ip_sync.h>
36 #if __FreeBSD_version >= 502116
37 static struct cdev *ipf_devs[IPL_LOGSIZE];
39 static dev_t ipf_devs[IPL_LOGSIZE];
42 static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS );
43 static int ipf_modload(void);
44 static int ipf_modunload(void);
46 SYSCTL_DECL(_net_inet);
47 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
48 SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
49 ptr, val, sysctl_ipf_int, "I", descr);
50 #define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */
51 #define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF)
52 SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
53 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
54 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
55 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
56 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
57 &fr_tcpidletimeout, 0, "");
58 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
59 &fr_tcphalfclosed, 0, "");
60 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
61 &fr_tcpclosewait, 0, "");
62 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
63 &fr_tcplastack, 0, "");
64 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
65 &fr_tcptimeout, 0, "");
66 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
67 &fr_tcpclosed, 0, "");
68 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
69 &fr_udptimeout, 0, "");
70 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
71 &fr_udpacktimeout, 0, "");
72 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
73 &fr_icmptimeout, 0, "");
74 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO,
75 &fr_defnatage, 0, "");
76 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
78 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
80 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO,
81 &fr_statesize, 0, "");
82 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO,
84 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO,
85 &ipf_nattable_sz, 0, "");
86 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO,
87 &ipf_natrules_sz, 0, "");
88 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO,
89 &ipf_rdrrules_sz, 0, "");
90 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO,
91 &ipf_hostmap_sz, 0, "");
92 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO,
94 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
96 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
97 &fr_defaultauthage, 0, "");
98 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, "");
99 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, "");
101 #define CDEV_MAJOR 79
102 #include <sys/poll.h>
103 #if __FreeBSD_version >= 500043
104 # include <sys/select.h>
105 static int iplpoll(struct cdev *dev, int events, struct thread *td);
107 static struct cdevsw ipl_cdevsw = {
108 # if __FreeBSD_version >= 502103
109 .d_version = D_VERSION,
110 .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */
118 # if __FreeBSD_version >= 500043
121 # if __FreeBSD_version < 600000
126 static int iplpoll(dev_t dev, int events, struct proc *p);
128 static struct cdevsw ipl_cdevsw = {
130 /* close */ iplclose,
132 /* write */ iplwrite,
133 /* ioctl */ iplioctl,
136 /* strategy */ nostrategy,
138 /* maj */ CDEV_MAJOR,
142 # if (__FreeBSD_version < 500043)
145 # if (__FreeBSD_version > 430000)
151 static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
152 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
156 ipfilter_modevent(module_t mod, int type, void *unused)
163 error = ipf_modload();
167 error = ipf_modunload();
180 char *defpass, *c, *str;
183 RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex");
184 RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock");
185 RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock");
189 RW_DESTROY(&ipf_global);
190 RW_DESTROY(&ipf_mutex);
191 RW_DESTROY(&ipf_frcache);
195 for (i = 0; i < IPL_LOGSIZE; i++)
198 for (i = 0; (str = ipf_devfiles[i]); i++) {
200 for(j = strlen(str); j > 0; j--)
207 ipf_devs[i] = make_dev(&ipl_cdevsw, i, 0, 0, 0600, c);
210 error = ipf_pfil_hook();
215 if (FR_ISPASS(fr_pass))
217 else if (FR_ISBLOCK(fr_pass))
220 defpass = "no-match -> block";
222 printf("%s initialized. Default = %s all, Logging = %s%s\n",
223 ipfilter_version, defpass,
229 #ifdef IPFILTER_COMPILED
247 if (fr_running >= 0) {
250 WRITE_ENTER(&ipf_global);
252 RWLOCK_EXIT(&ipf_global);
258 RW_DESTROY(&ipf_global);
259 RW_DESTROY(&ipf_mutex);
260 RW_DESTROY(&ipf_frcache);
264 for (i = 0; ipf_devfiles[i]; i++) {
265 if (ipf_devs[i] != NULL)
266 destroy_dev(ipf_devs[i]);
269 printf("%s unloaded\n", ipfilter_version);
275 static moduledata_t ipfiltermod = {
282 DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
283 #ifdef MODULE_VERSION
284 MODULE_VERSION(ipfilter, 1);
290 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
295 error = SYSCTL_OUT(req, arg1, sizeof(int));
297 error = SYSCTL_OUT(req, &arg2, sizeof(int));
299 if (error || !req->newptr)
305 if ((oidp->oid_kind & CTLFLAG_OFF) && (fr_running > 0))
308 error = SYSCTL_IN(req, arg1, sizeof(int));
316 #if __FreeBSD_version >= 500043
317 iplpoll(struct cdev *dev, int events, struct thread *td)
319 iplpoll(dev_t dev, int events, struct proc *td)
322 u_int xmin = GET_MINOR(dev);
325 if (xmin < 0 || xmin > IPL_LOGMAX)
336 if ((events & (POLLIN | POLLRDNORM)) && ipflog_canread(xmin))
337 revents |= events & (POLLIN | POLLRDNORM);
341 if ((events & (POLLIN | POLLRDNORM)) && fr_auth_waiting())
342 revents |= events & (POLLIN | POLLRDNORM);
346 if ((events & (POLLIN | POLLRDNORM)) && ipfsync_canread())
347 revents |= events & (POLLIN | POLLRDNORM);
348 if ((events & (POLLOUT | POLLWRNORM)) && ipfsync_canwrite())
349 revents |= events & (POLLOUT | POLLWRNORM);
358 if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
359 selrecord(td, &ipfselwait[xmin]);