1 /* $FreeBSD$ */
2 
3 /*
4  * Copyright (C) 2012 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  */
8 
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/kernel.h>
13 #include <sys/module.h>
14 #include <sys/conf.h>
15 #include <sys/socket.h>
16 #include <sys/sysctl.h>
17 #include <sys/select.h>
18 #if __FreeBSD_version >= 500000
19 # include <sys/selinfo.h>
20 #endif
21 #include <net/if.h>
22 #include <netinet/in_systm.h>
23 #include <netinet/in.h>
24 
25 
26 #include "netinet/ipl.h"
27 #include "netinet/ip_compat.h"
28 #include "netinet/ip_fil.h"
29 #include "netinet/ip_state.h"
30 #include "netinet/ip_nat.h"
31 #include "netinet/ip_auth.h"
32 #include "netinet/ip_frag.h"
33 #include "netinet/ip_sync.h"
34 
35 extern ipf_main_softc_t ipfmain;
36 
37 #if __FreeBSD_version >= 502116
38 static struct cdev *ipf_devs[IPL_LOGSIZE];
39 #else
40 static dev_t ipf_devs[IPL_LOGSIZE];
41 #endif
42 
43 #if 0
44 static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS );
45 #endif
46 static int ipf_modload(void);
47 static int ipf_modunload(void);
48 
49 #if (__FreeBSD_version >= 500024)
50 # if (__FreeBSD_version >= 502116)
51 static	int	ipfopen __P((struct cdev*, int, int, struct thread *));
52 static	int	ipfclose __P((struct cdev*, int, int, struct thread *));
53 # else
54 static	int	ipfopen __P((dev_t, int, int, struct thread *));
55 static	int	ipfclose __P((dev_t, int, int, struct thread *));
56 # endif /* __FreeBSD_version >= 502116 */
57 #else
58 static	int	ipfopen __P((dev_t, int, int, struct proc *));
59 static	int	ipfclose __P((dev_t, int, int, struct proc *));
60 #endif
61 #if (__FreeBSD_version >= 502116)
62 static	int	ipfread __P((struct cdev*, struct uio *, int));
63 static	int	ipfwrite __P((struct cdev*, struct uio *, int));
64 #else
65 static	int	ipfread __P((dev_t, struct uio *, int));
66 static	int	ipfwrite __P((dev_t, struct uio *, int));
67 #endif /* __FreeBSD_version >= 502116 */
68 
69 
70 
71 SYSCTL_DECL(_net_inet);
72 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
73 	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
74 		   ptr, val, sysctl_ipf_int, "I", descr);
75 #define	CTLFLAG_OFF	0x00800000	/* IPFilter must be disabled */
76 #define	CTLFLAG_RWO	(CTLFLAG_RW|CTLFLAG_OFF)
77 SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
78 #if 0
79 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipf_flags, 0, "");
80 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipf_pass, 0, "");
81 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipf_active, 0, "");
82 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
83 	   &ipf_tcpidletimeout, 0, "");
84 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
85 	   &ipf_tcphalfclosed, 0, "");
86 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
87 	   &ipf_tcpclosewait, 0, "");
88 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
89 	   &ipf_tcplastack, 0, "");
90 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
91 	   &ipf_tcptimeout, 0, "");
92 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
93 	   &ipf_tcpclosed, 0, "");
94 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
95 	   &ipf_udptimeout, 0, "");
96 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
97 	   &ipf_udpacktimeout, 0, "");
98 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
99 	   &ipf_icmptimeout, 0, "");
100 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO,
101 	   &ipf_nat_defage, 0, "");
102 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
103 	   &ipf_ipfrttl, 0, "");
104 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD,
105 	   &ipf_running, 0, "");
106 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO,
107 	   &ipf_state_size, 0, "");
108 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO,
109 	   &ipf_state_max, 0, "");
110 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO,
111 	   &ipf_nat_table_sz, 0, "");
112 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO,
113 	   &ipf_nat_maprules_sz, 0, "");
114 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO,
115 	   &ipf_nat_rdrrules_sz, 0, "");
116 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO,
117 	   &ipf_nat_hostmap_sz, 0, "");
118 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO,
119 	   &ipf_auth_size, 0, "");
120 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
121 	   &ipf_auth_used, 0, "");
122 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
123 	   &ipf_auth_defaultage, 0, "");
124 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipf_chksrc, 0, "");
125 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipf_minttl, 0, "");
126 #endif
127 
128 #define CDEV_MAJOR 79
129 #include <sys/poll.h>
130 #if __FreeBSD_version >= 500043
131 # include <sys/select.h>
132 static int ipfpoll(struct cdev *dev, int events, struct thread *td);
133 
134 static struct cdevsw ipf_cdevsw = {
135 #if __FreeBSD_version >= 502103
136 	.d_version =	D_VERSION,
137 	.d_flags =	0,	/* D_NEEDGIANT - Should be SMP safe */
138 #endif
139 	.d_open =	ipfopen,
140 	.d_close =	ipfclose,
141 	.d_read =	ipfread,
142 	.d_write =	ipfwrite,
143 	.d_ioctl =	ipfioctl,
144 	.d_poll =	ipfpoll,
145 	.d_name =	"ipf",
146 #if __FreeBSD_version < 600000
147 	.d_maj =	CDEV_MAJOR,
148 #endif
149 };
150 #else
151 static int ipfpoll(dev_t dev, int events, struct proc *td);
152 
153 static struct cdevsw ipf_cdevsw = {
154 	/* open */	ipfopen,
155 	/* close */	ipfclose,
156 	/* read */	ipfread,
157 	/* write */	ipfwrite,
158 	/* ioctl */	ipfioctl,
159 	/* poll */	ipfpoll,
160 	/* mmap */	nommap,
161 	/* strategy */	nostrategy,
162 	/* name */	"ipf",
163 	/* maj */	CDEV_MAJOR,
164 	/* dump */	nodump,
165 	/* psize */	nopsize,
166 	/* flags */	0,
167 # if (__FreeBSD_version < 500043)
168 	/* bmaj */	-1,
169 # endif
170 # if (__FreeBSD_version >= 430000)
171 	/* kqfilter */	NULL
172 # endif
173 };
174 #endif
175 
176 static char *ipf_devfiles[] = {	IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
177 				IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
178 
179 
180 static int
ipfilter_modevent(module_t mod,int type,void * unused)181 ipfilter_modevent(module_t mod, int type, void *unused)
182 {
183 	int error = 0;
184 
185 	switch (type)
186 	{
187 	case MOD_LOAD :
188 		error = ipf_modload();
189 		break;
190 
191 	case MOD_UNLOAD :
192 		error = ipf_modunload();
193 		break;
194 	default:
195 		error = EINVAL;
196 		break;
197 	}
198 	return error;
199 }
200 
201 
202 static int
ipf_modload()203 ipf_modload()
204 {
205 	char *defpass, *c, *str;
206 	int i, j, error;
207 
208 	if (ipf_load_all() != 0)
209 		return EIO;
210 
211 	if (ipf_create_all(&ipfmain) == NULL)
212 		return EIO;
213 
214 	error = ipfattach(&ipfmain);
215 	if (error)
216 		return error;
217 
218 	for (i = 0; i < IPL_LOGSIZE; i++)
219 		ipf_devs[i] = NULL;
220 
221 	for (i = 0; (str = ipf_devfiles[i]); i++) {
222 		c = NULL;
223 		for(j = strlen(str); j > 0; j--)
224 			if (str[j] == '/') {
225 				c = str + j + 1;
226 				break;
227 			}
228 		if (!c)
229 			c = str;
230 		ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, c);
231 	}
232 
233 	error = ipf_pfil_hook();
234 	if (error != 0)
235 		return error;
236 	ipf_event_reg();
237 
238 	if (FR_ISPASS(ipfmain.ipf_pass))
239 		defpass = "pass";
240 	else if (FR_ISBLOCK(ipfmain.ipf_pass))
241 		defpass = "block";
242 	else
243 		defpass = "no-match -> block";
244 
245 	printf("%s initialized.  Default = %s all, Logging = %s%s\n",
246 		ipfilter_version, defpass,
247 #ifdef IPFILTER_LOG
248 		"enabled",
249 #else
250 		"disabled",
251 #endif
252 #ifdef IPFILTER_COMPILED
253 		" (COMPILED)"
254 #else
255 		""
256 #endif
257 		);
258 	return 0;
259 }
260 
261 
262 static int
ipf_modunload()263 ipf_modunload()
264 {
265 	int error, i;
266 
267 	if (ipfmain.ipf_refcnt)
268 		return EBUSY;
269 
270 	error = ipf_pfil_unhook();
271 	if (error != 0)
272 		return error;
273 
274 	if (ipfmain.ipf_running >= 0) {
275 		error = ipfdetach(&ipfmain);
276 		if (error != 0)
277 			return error;
278 
279 		ipf_destroy_all(&ipfmain);
280 		ipf_unload_all();
281 	} else
282 		error = 0;
283 
284 	ipfmain.ipf_running = -2;
285 
286 	for (i = 0; ipf_devfiles[i]; i++) {
287 		if (ipf_devs[i] != NULL)
288 			destroy_dev(ipf_devs[i]);
289 	}
290 
291 	printf("%s unloaded\n", ipfilter_version);
292 
293 	return error;
294 }
295 
296 
297 static moduledata_t ipfiltermod = {
298 	"ipfilter",
299 	ipfilter_modevent,
300 	0
301 };
302 
303 
304 DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
305 #ifdef	MODULE_VERSION
306 MODULE_VERSION(ipfilter, 1);
307 #endif
308 
309 
310 #if 0
311 #ifdef SYSCTL_IPF
312 int
313 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
314 {
315 	int error = 0;
316 
317 	if (arg1)
318 		error = SYSCTL_OUT(req, arg1, sizeof(int));
319 	else
320 		error = SYSCTL_OUT(req, &arg2, sizeof(int));
321 
322 	if (error || !req->newptr)
323 		return (error);
324 
325 	if (!arg1)
326 		error = EPERM;
327 	else {
328 		if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0))
329 			error = EBUSY;
330 		else
331 			error = SYSCTL_IN(req, arg1, sizeof(int));
332 	}
333 	return (error);
334 }
335 #endif
336 #endif
337 
338 
339 static int
340 #if __FreeBSD_version >= 500043
ipfpoll(struct cdev * dev,int events,struct thread * td)341 ipfpoll(struct cdev *dev, int events, struct thread *td)
342 #else
343 ipfpoll(dev_t dev, int events, struct proc *td)
344 #endif
345 {
346 	u_int unit = GET_MINOR(dev);
347 	int revents;
348 
349 	if (unit < 0 || unit > IPL_LOGMAX)
350 		return 0;
351 
352 	revents = 0;
353 
354 	switch (unit)
355 	{
356 	case IPL_LOGIPF :
357 	case IPL_LOGNAT :
358 	case IPL_LOGSTATE :
359 #ifdef IPFILTER_LOG
360 		if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit))
361 			revents |= events & (POLLIN | POLLRDNORM);
362 #endif
363 		break;
364 	case IPL_LOGAUTH :
365 		if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain))
366 			revents |= events & (POLLIN | POLLRDNORM);
367 		break;
368 	case IPL_LOGSYNC :
369 		if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain))
370 			revents |= events & (POLLIN | POLLRDNORM);
371 		if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain))
372 			revents |= events & (POLLOUT | POLLWRNORM);
373 		break;
374 	case IPL_LOGSCAN :
375 	case IPL_LOGLOOKUP :
376 	default :
377 		break;
378 	}
379 
380 	if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
381 		selrecord(td, &ipfmain.ipf_selwait[unit]);
382 
383 	return revents;
384 }
385 
386 
387 /*
388  * routines below for saving IP headers to buffer
389  */
ipfopen(dev,flags,devtype,p)390 static int ipfopen(dev, flags
391 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
392 , devtype, p)
393 	int devtype;
394 # if (__FreeBSD_version >= 500024)
395 	struct thread *p;
396 # else
397 	struct proc *p;
398 # endif /* __FreeBSD_version >= 500024 */
399 #else
400 )
401 #endif
402 #if (__FreeBSD_version >= 502116)
403 	struct cdev *dev;
404 #else
405 	dev_t dev;
406 #endif
407 	int flags;
408 {
409 	u_int unit = GET_MINOR(dev);
410 	int error;
411 
412 	if (IPL_LOGMAX < unit)
413 		error = ENXIO;
414 	else {
415 		switch (unit)
416 		{
417 		case IPL_LOGIPF :
418 		case IPL_LOGNAT :
419 		case IPL_LOGSTATE :
420 		case IPL_LOGAUTH :
421 		case IPL_LOGLOOKUP :
422 		case IPL_LOGSYNC :
423 #ifdef IPFILTER_SCAN
424 		case IPL_LOGSCAN :
425 #endif
426 			error = 0;
427 			break;
428 		default :
429 			error = ENXIO;
430 			break;
431 		}
432 	}
433 	return error;
434 }
435 
436 
ipfclose(dev,flags,devtype,p)437 static int ipfclose(dev, flags
438 #if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
439 , devtype, p)
440 	int devtype;
441 # if (__FreeBSD_version >= 500024)
442 	struct thread *p;
443 # else
444 	struct proc *p;
445 # endif /* __FreeBSD_version >= 500024 */
446 #else
447 )
448 #endif
449 #if (__FreeBSD_version >= 502116)
450 	struct cdev *dev;
451 #else
452 	dev_t dev;
453 #endif
454 	int flags;
455 {
456 	u_int	unit = GET_MINOR(dev);
457 
458 	if (IPL_LOGMAX < unit)
459 		unit = ENXIO;
460 	else
461 		unit = 0;
462 	return unit;
463 }
464 
465 /*
466  * ipfread/ipflog
467  * both of these must operate with at least splnet() lest they be
468  * called during packet processing and cause an inconsistancy to appear in
469  * the filter lists.
470  */
471 #if (BSD >= 199306)
ipfread(dev,uio,ioflag)472 static int ipfread(dev, uio, ioflag)
473 	int ioflag;
474 #else
475 static int ipfread(dev, uio)
476 #endif
477 #if (__FreeBSD_version >= 502116)
478 	struct cdev *dev;
479 #else
480 	dev_t dev;
481 #endif
482 	struct uio *uio;
483 {
484 	u_int	unit = GET_MINOR(dev);
485 
486 	if (unit < 0)
487 		return ENXIO;
488 
489 	if (ipfmain.ipf_running < 1)
490 		return EIO;
491 
492 	if (unit == IPL_LOGSYNC)
493 		return ipf_sync_read(&ipfmain, uio);
494 
495 #ifdef IPFILTER_LOG
496 	return ipf_log_read(&ipfmain, unit, uio);
497 #else
498 	return ENXIO;
499 #endif
500 }
501 
502 
503 /*
504  * ipfwrite
505  * both of these must operate with at least splnet() lest they be
506  * called during packet processing and cause an inconsistancy to appear in
507  * the filter lists.
508  */
509 #if (BSD >= 199306)
ipfwrite(dev,uio,ioflag)510 static int ipfwrite(dev, uio, ioflag)
511 	int ioflag;
512 #else
513 static int ipfwrite(dev, uio)
514 #endif
515 #if (__FreeBSD_version >= 502116)
516 	struct cdev *dev;
517 #else
518 	dev_t dev;
519 #endif
520 	struct uio *uio;
521 {
522 
523 	if (ipfmain.ipf_running < 1)
524 		return EIO;
525 
526 	if (GET_MINOR(dev) == IPL_LOGSYNC)
527 		return ipf_sync_write(&ipfmain, uio);
528 	return ENXIO;
529 }
530