4 * Copyright (C) 2012 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 extern ipf_main_softc_t ipfmain;
38 #if __FreeBSD_version >= 502116
39 static struct cdev *ipf_devs[IPL_LOGSIZE];
41 static dev_t ipf_devs[IPL_LOGSIZE];
44 static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS );
45 static int ipf_modload(void);
46 static int ipf_modunload(void);
48 #if (__FreeBSD_version >= 500024)
49 # if (__FreeBSD_version >= 502116)
50 static int ipfopen __P((struct cdev*, int, int, struct thread *));
51 static int ipfclose __P((struct cdev*, int, int, struct thread *));
53 static int ipfopen __P((dev_t, int, int, struct thread *));
54 static int ipfclose __P((dev_t, int, int, struct thread *));
55 # endif /* __FreeBSD_version >= 502116 */
57 static int ipfopen __P((dev_t, int, int, struct proc *));
58 static int ipfclose __P((dev_t, int, int, struct proc *));
60 #if (__FreeBSD_version >= 502116)
61 static int ipfread __P((struct cdev*, struct uio *, int));
62 static int ipfwrite __P((struct cdev*, struct uio *, int));
64 static int ipfread __P((dev_t, struct uio *, int));
65 static int ipfwrite __P((dev_t, struct uio *, int));
66 #endif /* __FreeBSD_version >= 502116 */
69 SYSCTL_DECL(_net_inet);
70 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
71 SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
72 ptr, val, sysctl_ipf_int, "I", descr);
73 #define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */
74 #define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF)
75 SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
76 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipfmain.ipf_flags, 0, "");
77 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipfmain.ipf_pass, 0, "");
78 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipfmain.ipf_active, 0, "");
79 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
80 &ipfmain.ipf_tcpidletimeout, 0, "");
81 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
82 &ipfmain.ipf_tcphalfclosed, 0, "");
83 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
84 &ipfmain.ipf_tcpclosewait, 0, "");
85 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
86 &ipfmain.ipf_tcplastack, 0, "");
87 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
88 &ipfmain.ipf_tcptimeout, 0, "");
89 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
90 &ipfmain.ipf_tcpclosed, 0, "");
91 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
92 &ipfmain.ipf_udptimeout, 0, "");
93 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
94 &ipfmain.ipf_udpacktimeout, 0, "");
95 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
96 &ipfmain.ipf_icmptimeout, 0, "");
98 /* this needs to be resolved at compile time */
99 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO,
100 &((ipf_nat_softc_t *)ipfmain.ipf_nat_soft)->ipf_nat_defage, 0, "");
101 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
102 &ipf_ipfrttl, 0, "");
104 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD,
105 &ipfmain.ipf_running, 0, "");
107 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO,
108 &ipfmain.ipf_state_soft)->ipf_state_size, 0, "");
109 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO,
110 &(ipfmain.ipf_state_soft)->ipf_state_max, 0, "");
111 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO,
112 &(ipfmain.ipf_nat_soft)->ipf_nat_table_sz, 0, "");
113 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO,
114 &(ipfmain.ipf_nat_soft)->ipf_nat_maprules_sz, 0, "");
115 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO,
116 &(ipfmain.ipf_nat_soft)->ipf_nat_rdrrules_sz, 0, "");
117 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO,
118 &(ipfmain.ipf_nat_soft)->ipf_nat_hostmap_sz, 0, "");
119 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO,
120 &ipf_auth_size, 0, "");
121 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
122 &ipf_auth_used, 0, "");
123 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
124 &ipf_auth_defaultage, 0, "");
126 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipfmain.ipf_chksrc, 0, "");
127 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipfmain.ipf_minttl, 0, "");
129 #define CDEV_MAJOR 79
130 #include <sys/poll.h>
131 #if __FreeBSD_version >= 500043
132 # include <sys/select.h>
133 static int ipfpoll(struct cdev *dev, int events, struct thread *td);
135 static struct cdevsw ipf_cdevsw = {
136 #if __FreeBSD_version >= 502103
137 .d_version = D_VERSION,
138 .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */
147 #if __FreeBSD_version < 600000
152 static int ipfpoll(dev_t dev, int events, struct proc *td);
154 static struct cdevsw ipf_cdevsw = {
156 /* close */ ipfclose,
158 /* write */ ipfwrite,
159 /* ioctl */ ipfioctl,
162 /* strategy */ nostrategy,
164 /* maj */ CDEV_MAJOR,
168 # if (__FreeBSD_version < 500043)
171 # if (__FreeBSD_version >= 430000)
177 static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
178 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
182 ipfilter_modevent(module_t mod, int type, void *unused)
189 error = ipf_modload();
193 error = ipf_modunload();
206 char *defpass, *c, *str;
209 if (ipf_load_all() != 0)
212 if (ipf_create_all(&ipfmain) == NULL)
215 error = ipfattach(&ipfmain);
219 for (i = 0; i < IPL_LOGSIZE; i++)
222 for (i = 0; (str = ipf_devfiles[i]); i++) {
224 for(j = strlen(str); j > 0; j--)
231 ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c);
234 error = ipf_pfil_hook();
239 if (FR_ISPASS(ipfmain.ipf_pass))
241 else if (FR_ISBLOCK(ipfmain.ipf_pass))
244 defpass = "no-match -> block";
246 printf("%s initialized. Default = %s all, Logging = %s%s\n",
247 ipfilter_version, defpass,
253 #ifdef IPFILTER_COMPILED
268 if (ipfmain.ipf_refcnt)
271 error = ipf_pfil_unhook();
275 if (ipfmain.ipf_running >= 0) {
276 error = ipfdetach(&ipfmain);
280 ipf_destroy_all(&ipfmain);
285 ipfmain.ipf_running = -2;
287 for (i = 0; ipf_devfiles[i]; i++) {
288 if (ipf_devs[i] != NULL)
289 destroy_dev(ipf_devs[i]);
292 printf("%s unloaded\n", ipfilter_version);
298 static moduledata_t ipfiltermod = {
305 DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
306 #ifdef MODULE_VERSION
307 MODULE_VERSION(ipfilter, 1);
313 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
318 error = SYSCTL_OUT(req, arg1, sizeof(int));
320 error = SYSCTL_OUT(req, &arg2, sizeof(int));
322 if (error || !req->newptr)
328 if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0))
331 error = SYSCTL_IN(req, arg1, sizeof(int));
339 #if __FreeBSD_version >= 500043
340 ipfpoll(struct cdev *dev, int events, struct thread *td)
342 ipfpoll(dev_t dev, int events, struct proc *td)
345 int unit = GET_MINOR(dev);
348 if (unit < 0 || unit > IPL_LOGMAX)
359 if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit))
360 revents |= events & (POLLIN | POLLRDNORM);
364 if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain))
365 revents |= events & (POLLIN | POLLRDNORM);
368 if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain))
369 revents |= events & (POLLIN | POLLRDNORM);
370 if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain))
371 revents |= events & (POLLOUT | POLLWRNORM);
379 if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
380 selrecord(td, &ipfmain.ipf_selwait[unit]);
387 * routines below for saving IP headers to buffer
389 static int ipfopen(dev, flags
390 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
393 # if (__FreeBSD_version >= 500024)
397 # endif /* __FreeBSD_version >= 500024 */
401 #if (__FreeBSD_version >= 502116)
408 int unit = GET_MINOR(dev);
411 if (IPL_LOGMAX < unit)
436 static int ipfclose(dev, flags
437 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
440 # if (__FreeBSD_version >= 500024)
444 # endif /* __FreeBSD_version >= 500024 */
448 #if (__FreeBSD_version >= 502116)
455 int unit = GET_MINOR(dev);
457 if (IPL_LOGMAX < unit)
466 * both of these must operate with at least splnet() lest they be
467 * called during packet processing and cause an inconsistancy to appear in
471 static int ipfread(dev, uio, ioflag)
474 static int ipfread(dev, uio)
476 #if (__FreeBSD_version >= 502116)
483 int unit = GET_MINOR(dev);
488 if (ipfmain.ipf_running < 1)
491 if (unit == IPL_LOGSYNC)
492 return ipf_sync_read(&ipfmain, uio);
495 return ipf_log_read(&ipfmain, unit, uio);
504 * both of these must operate with at least splnet() lest they be
505 * called during packet processing and cause an inconsistancy to appear in
509 static int ipfwrite(dev, uio, ioflag)
512 static int ipfwrite(dev, uio)
514 #if (__FreeBSD_version >= 502116)
522 if (ipfmain.ipf_running < 1)
525 if (GET_MINOR(dev) == IPL_LOGSYNC)
526 return ipf_sync_write(&ipfmain, uio);