1145522Sdarrenr/*	$FreeBSD: releng/10.3/sys/contrib/ipfilter/netinet/mlfk_ipl.c 266829 2014-05-29 02:55:07Z cy $	*/
2145522Sdarrenr
354221Sguido/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
554221Sguido *
654221Sguido * $FreeBSD: releng/10.3/sys/contrib/ipfilter/netinet/mlfk_ipl.c 266829 2014-05-29 02:55:07Z cy $
7145522Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
854221Sguido */
954221Sguido
1060857Sdarrenr
1154221Sguido#include <sys/param.h>
1254221Sguido#include <sys/systm.h>
1354221Sguido#include <sys/kernel.h>
1454221Sguido#include <sys/module.h>
1554221Sguido#include <sys/conf.h>
1654221Sguido#include <sys/socket.h>
1754221Sguido#include <sys/sysctl.h>
18161356Sguido#include <sys/select.h>
19161356Sguido#if __FreeBSD_version >= 500000
20161356Sguido# include <sys/selinfo.h>
21255332Scy#endif
2254221Sguido#include <net/if.h>
2354221Sguido#include <netinet/in_systm.h>
2454221Sguido#include <netinet/in.h>
2554221Sguido
2654221Sguido
27255332Scy#include "netinet/ipl.h"
28255332Scy#include "netinet/ip_compat.h"
29255332Scy#include "netinet/ip_fil.h"
30255332Scy#include "netinet/ip_state.h"
31255332Scy#include "netinet/ip_nat.h"
32255332Scy#include "netinet/ip_auth.h"
33255332Scy#include "netinet/ip_frag.h"
34255332Scy#include "netinet/ip_sync.h"
3554221Sguido
36255332Scyextern ipf_main_softc_t ipfmain;
37255332Scy
38145522Sdarrenr#if __FreeBSD_version >= 502116
39145522Sdarrenrstatic struct cdev *ipf_devs[IPL_LOGSIZE];
40145522Sdarrenr#else
41145522Sdarrenrstatic dev_t ipf_devs[IPL_LOGSIZE];
42145522Sdarrenr#endif
4354221Sguido
44145522Sdarrenrstatic int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS );
45145522Sdarrenrstatic int ipf_modload(void);
46145522Sdarrenrstatic int ipf_modunload(void);
47266829Scystatic int ipf_fbsd_sysctl_create(ipf_main_softc_t*);
48266829Scystatic int ipf_fbsd_sysctl_destroy(ipf_main_softc_t*);
49145522Sdarrenr
50255332Scy#if (__FreeBSD_version >= 500024)
51255332Scy# if (__FreeBSD_version >= 502116)
52255332Scystatic	int	ipfopen __P((struct cdev*, int, int, struct thread *));
53255332Scystatic	int	ipfclose __P((struct cdev*, int, int, struct thread *));
54255332Scy# else
55255332Scystatic	int	ipfopen __P((dev_t, int, int, struct thread *));
56255332Scystatic	int	ipfclose __P((dev_t, int, int, struct thread *));
57255332Scy# endif /* __FreeBSD_version >= 502116 */
58255332Scy#else
59255332Scystatic	int	ipfopen __P((dev_t, int, int, struct proc *));
60255332Scystatic	int	ipfclose __P((dev_t, int, int, struct proc *));
61255332Scy#endif
62255332Scy#if (__FreeBSD_version >= 502116)
63255332Scystatic	int	ipfread __P((struct cdev*, struct uio *, int));
64255332Scystatic	int	ipfwrite __P((struct cdev*, struct uio *, int));
65255332Scy#else
66255332Scystatic	int	ipfread __P((dev_t, struct uio *, int));
67255332Scystatic	int	ipfwrite __P((dev_t, struct uio *, int));
68255332Scy#endif /* __FreeBSD_version >= 502116 */
69255332Scy
70255332Scy
7154221SguidoSYSCTL_DECL(_net_inet);
72145522Sdarrenr#define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
73145522Sdarrenr	SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
74145522Sdarrenr		   ptr, val, sysctl_ipf_int, "I", descr);
75266829Scy#define SYSCTL_DYN_IPF(parent, nbr, name, access,ptr, val, descr) \
76266829Scy	SYSCTL_ADD_OID(&ipf_clist, SYSCTL_STATIC_CHILDREN(parent), nbr, name, \
77266829Scy	CTLFLAG_DYN|CTLTYPE_INT|access, ptr, val, sysctl_ipf_int, "I", descr)
78266829Scystatic struct sysctl_ctx_list ipf_clist;
79145522Sdarrenr#define	CTLFLAG_OFF	0x00800000	/* IPFilter must be disabled */
80145522Sdarrenr#define	CTLFLAG_RWO	(CTLFLAG_RW|CTLFLAG_OFF)
8154221SguidoSYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
82266829ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipfmain.ipf_flags, 0, "IPF flags");
83266829ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipfmain.ipf_pass, 0, "default pass/block");
84266829ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipfmain.ipf_active, 0, "IPF is active");
85145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO,
86266829Scy	   &ipfmain.ipf_tcpidletimeout, 0, "TCP idle timeout in seconds");
87145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO,
88266829Scy	   &ipfmain.ipf_tcphalfclosed, 0, "timeout for half closed TCP sessions");
89145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO,
90266829Scy	   &ipfmain.ipf_tcpclosewait, 0, "timeout for TCP sessions in closewait status");
91145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO,
92266829Scy	   &ipfmain.ipf_tcplastack, 0, "timeout for TCP sessions in last ack status");
93145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO,
94255756Scy	   &ipfmain.ipf_tcptimeout, 0, "");
95145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO,
96255756Scy	   &ipfmain.ipf_tcpclosed, 0, "");
97145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO,
98266829Scy	   &ipfmain.ipf_udptimeout, 0, "UDP timeout");
99145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO,
100255756Scy	   &ipfmain.ipf_udpacktimeout, 0, "");
101145522SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO,
102266829Scy	   &ipfmain.ipf_icmptimeout, 0, "ICMP timeout");
103266829ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
104266829Scy	   &ipfmain.ipf_running, 0, "IPF is running");
105255756ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipfmain.ipf_chksrc, 0, "");
106255756ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipfmain.ipf_minttl, 0, "");
10754221Sguido
108145522Sdarrenr#define CDEV_MAJOR 79
109170268Sdarrenr#include <sys/poll.h>
110170268Sdarrenr#if __FreeBSD_version >= 500043
111161356Sguido# include <sys/select.h>
112255332Scystatic int ipfpoll(struct cdev *dev, int events, struct thread *td);
113161356Sguido
114255332Scystatic struct cdevsw ipf_cdevsw = {
115255332Scy#if __FreeBSD_version >= 502103
116126080Sphk	.d_version =	D_VERSION,
117145522Sdarrenr	.d_flags =	0,	/* D_NEEDGIANT - Should be SMP safe */
118255332Scy#endif
119255332Scy	.d_open =	ipfopen,
120255332Scy	.d_close =	ipfclose,
121255332Scy	.d_read =	ipfread,
122255332Scy	.d_write =	ipfwrite,
123255332Scy	.d_ioctl =	ipfioctl,
124255332Scy	.d_poll =	ipfpoll,
125255332Scy	.d_name =	"ipf",
126255332Scy#if __FreeBSD_version < 600000
127145522Sdarrenr	.d_maj =	CDEV_MAJOR,
128255332Scy#endif
12954221Sguido};
130145522Sdarrenr#else
131255332Scystatic int ipfpoll(dev_t dev, int events, struct proc *td);
132170268Sdarrenr
133255332Scystatic struct cdevsw ipf_cdevsw = {
134255332Scy	/* open */	ipfopen,
135255332Scy	/* close */	ipfclose,
136255332Scy	/* read */	ipfread,
137255332Scy	/* write */	ipfwrite,
138255332Scy	/* ioctl */	ipfioctl,
139255332Scy	/* poll */	ipfpoll,
140145522Sdarrenr	/* mmap */	nommap,
141145522Sdarrenr	/* strategy */	nostrategy,
142255332Scy	/* name */	"ipf",
143145522Sdarrenr	/* maj */	CDEV_MAJOR,
144145522Sdarrenr	/* dump */	nodump,
145145522Sdarrenr	/* psize */	nopsize,
146145522Sdarrenr	/* flags */	0,
147145522Sdarrenr# if (__FreeBSD_version < 500043)
148145522Sdarrenr	/* bmaj */	-1,
149145522Sdarrenr# endif
150255332Scy# if (__FreeBSD_version >= 430000)
151145522Sdarrenr	/* kqfilter */	NULL
152170268Sdarrenr# endif
153145522Sdarrenr};
154139255Sdarrenr#endif
155139255Sdarrenr
156145522Sdarrenrstatic char *ipf_devfiles[] = {	IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME,
157145522Sdarrenr				IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL };
158145522Sdarrenr
15954221Sguidostatic int
16054221Sguidoipfilter_modevent(module_t mod, int type, void *unused)
16154221Sguido{
162145522Sdarrenr	int error = 0;
16354221Sguido
164145522Sdarrenr	switch (type)
165145522Sdarrenr	{
16654221Sguido	case MOD_LOAD :
167145522Sdarrenr		error = ipf_modload();
168145522Sdarrenr		break;
16960857Sdarrenr
170145522Sdarrenr	case MOD_UNLOAD :
171145522Sdarrenr		error = ipf_modunload();
172145522Sdarrenr		break;
173145522Sdarrenr	default:
174145522Sdarrenr		error = EINVAL;
175145522Sdarrenr		break;
176145522Sdarrenr	}
177145522Sdarrenr	return error;
178145522Sdarrenr}
17954221Sguido
18054221Sguido
181145522Sdarrenrstatic int
182145522Sdarrenripf_modload()
183145522Sdarrenr{
184145522Sdarrenr	char *defpass, *c, *str;
185145522Sdarrenr	int i, j, error;
18654221Sguido
187255332Scy	if (ipf_load_all() != 0)
188255332Scy		return EIO;
189170268Sdarrenr
190255332Scy	if (ipf_create_all(&ipfmain) == NULL)
191255332Scy		return EIO;
192255332Scy
193266829Scy	if (ipf_fbsd_sysctl_create(&ipfmain) != 0)
194266829Scy		return EIO;
195266829Scy
196255332Scy	error = ipfattach(&ipfmain);
197255332Scy	if (error)
198145522Sdarrenr		return error;
19954221Sguido
200145522Sdarrenr	for (i = 0; i < IPL_LOGSIZE; i++)
201145522Sdarrenr		ipf_devs[i] = NULL;
202145522Sdarrenr
203145522Sdarrenr	for (i = 0; (str = ipf_devfiles[i]); i++) {
20454221Sguido		c = NULL;
205145522Sdarrenr		for(j = strlen(str); j > 0; j--)
206145522Sdarrenr			if (str[j] == '/') {
207145522Sdarrenr				c = str + j + 1;
20854221Sguido				break;
20954221Sguido			}
21054221Sguido		if (!c)
211145522Sdarrenr			c = str;
212255332Scy		ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c);
213145522Sdarrenr	}
21454221Sguido
215172776Sdarrenr	error = ipf_pfil_hook();
216172776Sdarrenr	if (error != 0)
217172776Sdarrenr		return error;
218172776Sdarrenr	ipf_event_reg();
219172776Sdarrenr
220255332Scy	if (FR_ISPASS(ipfmain.ipf_pass))
221145522Sdarrenr		defpass = "pass";
222255332Scy	else if (FR_ISBLOCK(ipfmain.ipf_pass))
223145522Sdarrenr		defpass = "block";
224255332Scy	else
225145522Sdarrenr		defpass = "no-match -> block";
226145522Sdarrenr
227145522Sdarrenr	printf("%s initialized.  Default = %s all, Logging = %s%s\n",
228255332Scy		ipfilter_version, defpass,
229145522Sdarrenr#ifdef IPFILTER_LOG
230145522Sdarrenr		"enabled",
231145522Sdarrenr#else
232145522Sdarrenr		"disabled",
233145522Sdarrenr#endif
234145522Sdarrenr#ifdef IPFILTER_COMPILED
235145522Sdarrenr		" (COMPILED)"
236145522Sdarrenr#else
237145522Sdarrenr		""
238145522Sdarrenr#endif
239255332Scy		);
240145522Sdarrenr	return 0;
241145522Sdarrenr}
242145522Sdarrenr
243145522Sdarrenr
244145522Sdarrenrstatic int
245145522Sdarrenripf_modunload()
246145522Sdarrenr{
247145522Sdarrenr	int error, i;
248145522Sdarrenr
249255332Scy	if (ipfmain.ipf_refcnt)
250145522Sdarrenr		return EBUSY;
251145522Sdarrenr
252266829Scy	if (ipf_fbsd_sysctl_destroy(&ipfmain) != 0)
253266829Scy		return EIO;
254266829Scy
255255332Scy	error = ipf_pfil_unhook();
256255332Scy	if (error != 0)
257255332Scy		return error;
258255332Scy
259255332Scy	if (ipfmain.ipf_running >= 0) {
260255332Scy		error = ipfdetach(&ipfmain);
261145522Sdarrenr		if (error != 0)
262145522Sdarrenr			return error;
263255332Scy
264266829Scy		ipf_fbsd_sysctl_destroy(&ipfmain);
265255332Scy		ipf_destroy_all(&ipfmain);
266255332Scy		ipf_unload_all();
267145522Sdarrenr	} else
268145522Sdarrenr		error = 0;
269145522Sdarrenr
270255332Scy	ipfmain.ipf_running = -2;
271170268Sdarrenr
272145522Sdarrenr	for (i = 0; ipf_devfiles[i]; i++) {
273145522Sdarrenr		if (ipf_devs[i] != NULL)
274145522Sdarrenr			destroy_dev(ipf_devs[i]);
27554221Sguido	}
276145522Sdarrenr
277145522Sdarrenr	printf("%s unloaded\n", ipfilter_version);
278145522Sdarrenr
27954221Sguido	return error;
28054221Sguido}
28154221Sguido
282145522Sdarrenr
28354221Sguidostatic moduledata_t ipfiltermod = {
284145522Sdarrenr	"ipfilter",
28554221Sguido	ipfilter_modevent,
286241394Skevlo	0
28754221Sguido};
288145522Sdarrenr
289145522Sdarrenr
29054221SguidoDECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
291145522Sdarrenr#ifdef	MODULE_VERSION
292145522SdarrenrMODULE_VERSION(ipfilter, 1);
293145522Sdarrenr#endif
294145522Sdarrenr
295145522Sdarrenr
296145522Sdarrenr#ifdef SYSCTL_IPF
297145522Sdarrenrint
298145522Sdarrenrsysctl_ipf_int ( SYSCTL_HANDLER_ARGS )
299145522Sdarrenr{
300145522Sdarrenr	int error = 0;
301145522Sdarrenr
302145522Sdarrenr	if (arg1)
303145522Sdarrenr		error = SYSCTL_OUT(req, arg1, sizeof(int));
304145522Sdarrenr	else
305145522Sdarrenr		error = SYSCTL_OUT(req, &arg2, sizeof(int));
306145522Sdarrenr
307145522Sdarrenr	if (error || !req->newptr)
308145522Sdarrenr		return (error);
309145522Sdarrenr
310145522Sdarrenr	if (!arg1)
311145522Sdarrenr		error = EPERM;
312145522Sdarrenr	else {
313255332Scy		if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0))
314145522Sdarrenr			error = EBUSY;
315145522Sdarrenr		else
316145522Sdarrenr			error = SYSCTL_IN(req, arg1, sizeof(int));
317145522Sdarrenr	}
318145522Sdarrenr	return (error);
319145522Sdarrenr}
320145522Sdarrenr#endif
321161356Sguido
322161356Sguido
323161356Sguidostatic int
324170268Sdarrenr#if __FreeBSD_version >= 500043
325255332Scyipfpoll(struct cdev *dev, int events, struct thread *td)
326170268Sdarrenr#else
327255332Scyipfpoll(dev_t dev, int events, struct proc *td)
328170268Sdarrenr#endif
329161356Sguido{
330255332Scy	int unit = GET_MINOR(dev);
331161356Sguido	int revents;
332161356Sguido
333255332Scy	if (unit < 0 || unit > IPL_LOGMAX)
334161356Sguido		return 0;
335161356Sguido
336161356Sguido	revents = 0;
337161356Sguido
338255332Scy	switch (unit)
339161356Sguido	{
340161356Sguido	case IPL_LOGIPF :
341161356Sguido	case IPL_LOGNAT :
342161356Sguido	case IPL_LOGSTATE :
343161356Sguido#ifdef IPFILTER_LOG
344255332Scy		if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit))
345161356Sguido			revents |= events & (POLLIN | POLLRDNORM);
346255332Scy#endif
347161356Sguido		break;
348161356Sguido	case IPL_LOGAUTH :
349255332Scy		if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain))
350161356Sguido			revents |= events & (POLLIN | POLLRDNORM);
351255332Scy		break;
352161356Sguido	case IPL_LOGSYNC :
353255332Scy		if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain))
354161356Sguido			revents |= events & (POLLIN | POLLRDNORM);
355255332Scy		if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain))
356161356Sguido			revents |= events & (POLLOUT | POLLWRNORM);
357161356Sguido		break;
358161356Sguido	case IPL_LOGSCAN :
359161356Sguido	case IPL_LOGLOOKUP :
360161356Sguido	default :
361161356Sguido		break;
362161356Sguido	}
363161356Sguido
364161356Sguido	if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0))
365255332Scy		selrecord(td, &ipfmain.ipf_selwait[unit]);
366161356Sguido
367161356Sguido	return revents;
368161356Sguido}
369255332Scy
370255332Scy
371255332Scy/*
372255332Scy * routines below for saving IP headers to buffer
373255332Scy */
374255332Scystatic int ipfopen(dev, flags
375255332Scy#if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
376255332Scy, devtype, p)
377255332Scy	int devtype;
378255332Scy# if (__FreeBSD_version >= 500024)
379255332Scy	struct thread *p;
380255332Scy# else
381255332Scy	struct proc *p;
382255332Scy# endif /* __FreeBSD_version >= 500024 */
383255332Scy#else
384255332Scy)
385255332Scy#endif
386255332Scy#if (__FreeBSD_version >= 502116)
387255332Scy	struct cdev *dev;
388255332Scy#else
389255332Scy	dev_t dev;
390255332Scy#endif
391255332Scy	int flags;
392255332Scy{
393255332Scy	int unit = GET_MINOR(dev);
394255332Scy	int error;
395255332Scy
396255332Scy	if (IPL_LOGMAX < unit)
397255332Scy		error = ENXIO;
398255332Scy	else {
399255332Scy		switch (unit)
400255332Scy		{
401255332Scy		case IPL_LOGIPF :
402255332Scy		case IPL_LOGNAT :
403255332Scy		case IPL_LOGSTATE :
404255332Scy		case IPL_LOGAUTH :
405255332Scy		case IPL_LOGLOOKUP :
406255332Scy		case IPL_LOGSYNC :
407255332Scy#ifdef IPFILTER_SCAN
408255332Scy		case IPL_LOGSCAN :
409255332Scy#endif
410255332Scy			error = 0;
411255332Scy			break;
412255332Scy		default :
413255332Scy			error = ENXIO;
414255332Scy			break;
415255332Scy		}
416255332Scy	}
417255332Scy	return error;
418255332Scy}
419255332Scy
420255332Scy
421255332Scystatic int ipfclose(dev, flags
422255332Scy#if ((BSD >= 199506) || (__FreeBSD_version >= 220000))
423255332Scy, devtype, p)
424255332Scy	int devtype;
425255332Scy# if (__FreeBSD_version >= 500024)
426255332Scy	struct thread *p;
427255332Scy# else
428255332Scy	struct proc *p;
429255332Scy# endif /* __FreeBSD_version >= 500024 */
430255332Scy#else
431255332Scy)
432255332Scy#endif
433255332Scy#if (__FreeBSD_version >= 502116)
434255332Scy	struct cdev *dev;
435255332Scy#else
436255332Scy	dev_t dev;
437255332Scy#endif
438255332Scy	int flags;
439255332Scy{
440255332Scy	int	unit = GET_MINOR(dev);
441255332Scy
442255332Scy	if (IPL_LOGMAX < unit)
443255332Scy		unit = ENXIO;
444255332Scy	else
445255332Scy		unit = 0;
446255332Scy	return unit;
447255332Scy}
448255332Scy
449255332Scy/*
450255332Scy * ipfread/ipflog
451255332Scy * both of these must operate with at least splnet() lest they be
452255332Scy * called during packet processing and cause an inconsistancy to appear in
453255332Scy * the filter lists.
454255332Scy */
455255332Scy#if (BSD >= 199306)
456255332Scystatic int ipfread(dev, uio, ioflag)
457255332Scy	int ioflag;
458255332Scy#else
459255332Scystatic int ipfread(dev, uio)
460255332Scy#endif
461255332Scy#if (__FreeBSD_version >= 502116)
462255332Scy	struct cdev *dev;
463255332Scy#else
464255332Scy	dev_t dev;
465255332Scy#endif
466255332Scy	struct uio *uio;
467255332Scy{
468255332Scy	int	unit = GET_MINOR(dev);
469255332Scy
470255332Scy	if (unit < 0)
471255332Scy		return ENXIO;
472255332Scy
473255332Scy	if (ipfmain.ipf_running < 1)
474255332Scy		return EIO;
475255332Scy
476255332Scy	if (unit == IPL_LOGSYNC)
477255332Scy		return ipf_sync_read(&ipfmain, uio);
478255332Scy
479255332Scy#ifdef IPFILTER_LOG
480255332Scy	return ipf_log_read(&ipfmain, unit, uio);
481255332Scy#else
482255332Scy	return ENXIO;
483255332Scy#endif
484255332Scy}
485255332Scy
486255332Scy
487255332Scy/*
488255332Scy * ipfwrite
489255332Scy * both of these must operate with at least splnet() lest they be
490255332Scy * called during packet processing and cause an inconsistancy to appear in
491255332Scy * the filter lists.
492255332Scy */
493255332Scy#if (BSD >= 199306)
494255332Scystatic int ipfwrite(dev, uio, ioflag)
495255332Scy	int ioflag;
496255332Scy#else
497255332Scystatic int ipfwrite(dev, uio)
498255332Scy#endif
499255332Scy#if (__FreeBSD_version >= 502116)
500255332Scy	struct cdev *dev;
501255332Scy#else
502255332Scy	dev_t dev;
503255332Scy#endif
504255332Scy	struct uio *uio;
505255332Scy{
506255332Scy
507255332Scy	if (ipfmain.ipf_running < 1)
508255332Scy		return EIO;
509255332Scy
510255332Scy	if (GET_MINOR(dev) == IPL_LOGSYNC)
511255332Scy		return ipf_sync_write(&ipfmain, uio);
512255332Scy	return ENXIO;
513255332Scy}
514266829Scy
515266829Scystatic int
516266829Scyipf_fbsd_sysctl_create(main_softc)
517266829Scy	ipf_main_softc_t *main_softc;
518266829Scy{
519266829Scy	ipf_nat_softc_t	*nat_softc;
520266829Scy	ipf_state_softc_t *state_softc;
521266829Scy	ipf_auth_softc_t *auth_softc;
522266829Scy	ipf_frag_softc_t *frag_softc;
523266829Scy
524266829Scy	nat_softc = main_softc->ipf_nat_soft;
525266829Scy	state_softc = main_softc->ipf_state_soft;
526266829Scy	auth_softc = main_softc->ipf_auth_soft;
527266829Scy	frag_softc = main_softc->ipf_frag_soft;
528266829Scy
529266829Scy	sysctl_ctx_init(&ipf_clist);
530266829Scy
531266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_defnatage", CTLFLAG_RWO,
532266829Scy	    &nat_softc->ipf_nat_defage, 0, "");
533266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_statesize", CTLFLAG_RWO,
534266829Scy	    &state_softc->ipf_state_size, 0, "");
535266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_statemax", CTLFLAG_RWO,
536266829Scy	    &state_softc->ipf_state_max, 0, "");
537266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "ipf_nattable_max", CTLFLAG_RWO,
538266829Scy	    &nat_softc->ipf_nat_table_max, 0, "");
539266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "ipf_nattable_sz", CTLFLAG_RWO,
540266829Scy	    &nat_softc->ipf_nat_table_sz, 0, "");
541266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "ipf_natrules_sz", CTLFLAG_RWO,
542266829Scy	    &nat_softc->ipf_nat_maprules_sz, 0, "");
543266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "ipf_rdrrules_sz", CTLFLAG_RWO,
544266829Scy	    &nat_softc->ipf_nat_rdrrules_sz, 0, "");
545266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "ipf_hostmap_sz", CTLFLAG_RWO,
546266829Scy	    &nat_softc->ipf_nat_hostmap_sz, 0, "");
547266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_authsize", CTLFLAG_RWO,
548266829Scy	   &auth_softc->ipf_auth_size, 0, "");
549266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_authused", CTLFLAG_RD,
550266829Scy	   &auth_softc->ipf_auth_used, 0, "");
551266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_defaultauthage", CTLFLAG_RW,
552266829Scy	   &auth_softc->ipf_auth_defaultage, 0, "");
553266829Scy	SYSCTL_DYN_IPF(_net_inet_ipf, OID_AUTO, "fr_ipfrttl", CTLFLAG_RW,
554266829Scy	   &frag_softc->ipfr_ttl, 0, "");
555266829Scy	return 0;
556266829Scy}
557266829Scy
558266829Scystatic int
559266829Scyipf_fbsd_sysctl_destroy(main_softc)
560266829Scy	ipf_main_softc_t *main_softc;
561266829Scy{
562266829Scy	if (sysctl_ctx_free(&ipf_clist)) {
563266829Scy		printf("sysctl_ctx_free failed");
564266829Scy		return(ENOTEMPTY);
565266829Scy	}
566266829Scy	return 0;
567266829Scy}
568266829Scy
569