4 * Copyright (C) 2000 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/kernel.h>
13 #include <sys/module.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>
22 #include <netinet/in_systm.h>
23 #include <netinet/in.h>
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>
35 #if __FreeBSD_version >= 502116
36 static struct cdev
*ipf_devs
[IPL_LOGSIZE
];
38 static dev_t ipf_devs
[IPL_LOGSIZE
];
41 static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS
);
42 static int ipf_modload(void);
43 static int ipf_modunload(void);
45 SYSCTL_DECL(_net_inet
);
46 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
47 SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \
48 ptr, val, sysctl_ipf_int, "I", descr);
49 #define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */
50 #define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF)
51 SYSCTL_NODE(_net_inet
, OID_AUTO
, ipf
, CTLFLAG_RW
, 0, "IPF");
52 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_flags
, CTLFLAG_RW
, &fr_flags
, 0, "");
53 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_pass
, CTLFLAG_RW
, &fr_pass
, 0, "");
54 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_active
, CTLFLAG_RD
, &fr_active
, 0, "");
55 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_tcpidletimeout
, CTLFLAG_RWO
,
56 &fr_tcpidletimeout
, 0, "");
57 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_tcphalfclosed
, CTLFLAG_RWO
,
58 &fr_tcphalfclosed
, 0, "");
59 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_tcpclosewait
, CTLFLAG_RWO
,
60 &fr_tcpclosewait
, 0, "");
61 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_tcplastack
, CTLFLAG_RWO
,
62 &fr_tcplastack
, 0, "");
63 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_tcptimeout
, CTLFLAG_RWO
,
64 &fr_tcptimeout
, 0, "");
65 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_tcpclosed
, CTLFLAG_RWO
,
66 &fr_tcpclosed
, 0, "");
67 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_udptimeout
, CTLFLAG_RWO
,
68 &fr_udptimeout
, 0, "");
69 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_udpacktimeout
, CTLFLAG_RWO
,
70 &fr_udpacktimeout
, 0, "");
71 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_icmptimeout
, CTLFLAG_RWO
,
72 &fr_icmptimeout
, 0, "");
73 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_defnatage
, CTLFLAG_RWO
,
74 &fr_defnatage
, 0, "");
75 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_ipfrttl
, CTLFLAG_RW
,
77 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_running
, CTLFLAG_RD
,
79 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_statesize
, CTLFLAG_RWO
,
80 &fr_statesize
, 0, "");
81 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_statemax
, CTLFLAG_RWO
,
83 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, ipf_nattable_sz
, CTLFLAG_RWO
,
84 &ipf_nattable_sz
, 0, "");
85 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, ipf_natrules_sz
, CTLFLAG_RWO
,
86 &ipf_natrules_sz
, 0, "");
87 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, ipf_rdrrules_sz
, CTLFLAG_RWO
,
88 &ipf_rdrrules_sz
, 0, "");
89 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, ipf_hostmap_sz
, CTLFLAG_RWO
,
90 &ipf_hostmap_sz
, 0, "");
91 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_authsize
, CTLFLAG_RWO
,
93 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_authused
, CTLFLAG_RD
,
95 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_defaultauthage
, CTLFLAG_RW
,
96 &fr_defaultauthage
, 0, "");
97 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_chksrc
, CTLFLAG_RW
, &fr_chksrc
, 0, "");
98 SYSCTL_IPF(_net_inet_ipf
, OID_AUTO
, fr_minttl
, CTLFLAG_RW
, &fr_minttl
, 0, "");
100 #define CDEV_MAJOR 79
101 #include <sys/poll.h>
102 #if __FreeBSD_version >= 500043
103 # include <sys/select.h>
104 static int iplpoll(struct cdev
*dev
, int events
, struct thread
*td
);
106 static struct cdevsw ipl_cdevsw
= {
107 # if __FreeBSD_version >= 502103
108 .d_version
= D_VERSION
,
109 .d_flags
= 0, /* D_NEEDGIANT - Should be SMP safe */
117 # if __FreeBSD_version >= 500043
120 # if __FreeBSD_version < 600000
125 static int iplpoll(dev_t dev
, int events
, struct proc
*p
);
127 static struct cdevsw ipl_cdevsw
= {
129 /* close */ iplclose
,
131 /* write */ iplwrite
,
132 /* ioctl */ iplioctl
,
135 /* strategy */ nostrategy
,
137 /* maj */ CDEV_MAJOR
,
141 # if (__FreeBSD_version < 500043)
144 # if (__FreeBSD_version > 430000)
150 static char *ipf_devfiles
[] = { IPL_NAME
, IPNAT_NAME
, IPSTATE_NAME
, IPAUTH_NAME
,
151 IPSYNC_NAME
, IPSCAN_NAME
, IPLOOKUP_NAME
, NULL
};
155 ipfilter_modevent(module_t mod
, int type
, void *unused
)
162 error
= ipf_modload();
166 error
= ipf_modunload();
179 char *defpass
, *c
, *str
;
182 RWLOCK_INIT(&ipf_global
, "ipf filter load/unload mutex");
183 RWLOCK_INIT(&ipf_mutex
, "ipf filter rwlock");
184 RWLOCK_INIT(&ipf_frcache
, "ipf cache rwlock");
188 RW_DESTROY(&ipf_global
);
189 RW_DESTROY(&ipf_mutex
);
190 RW_DESTROY(&ipf_frcache
);
194 for (i
= 0; i
< IPL_LOGSIZE
; i
++)
197 for (i
= 0; (str
= ipf_devfiles
[i
]); i
++) {
199 for(j
= strlen(str
); j
> 0; j
--)
206 ipf_devs
[i
] = make_dev(&ipl_cdevsw
, i
, 0, 0, 0600, c
);
209 error
= ipf_pfil_hook();
214 if (FR_ISPASS(fr_pass
))
216 else if (FR_ISBLOCK(fr_pass
))
219 defpass
= "no-match -> block";
221 printf("%s initialized. Default = %s all, Logging = %s%s\n",
222 ipfilter_version
, defpass
,
228 #ifdef IPFILTER_COMPILED
246 if (fr_running
>= 0) {
249 WRITE_ENTER(&ipf_global
);
251 RWLOCK_EXIT(&ipf_global
);
257 RW_DESTROY(&ipf_global
);
258 RW_DESTROY(&ipf_mutex
);
259 RW_DESTROY(&ipf_frcache
);
263 for (i
= 0; ipf_devfiles
[i
]; i
++) {
264 if (ipf_devs
[i
] != NULL
)
265 destroy_dev(ipf_devs
[i
]);
268 printf("%s unloaded\n", ipfilter_version
);
274 static moduledata_t ipfiltermod
= {
281 DECLARE_MODULE(ipfilter
, ipfiltermod
, SI_SUB_PROTO_DOMAIN
, SI_ORDER_ANY
);
282 #ifdef MODULE_VERSION
283 MODULE_VERSION(ipfilter
, 1);
289 sysctl_ipf_int ( SYSCTL_HANDLER_ARGS
)
294 error
= SYSCTL_OUT(req
, arg1
, sizeof(int));
296 error
= SYSCTL_OUT(req
, &arg2
, sizeof(int));
298 if (error
|| !req
->newptr
)
304 if ((oidp
->oid_kind
& CTLFLAG_OFF
) && (fr_running
> 0))
307 error
= SYSCTL_IN(req
, arg1
, sizeof(int));
315 #if __FreeBSD_version >= 500043
316 iplpoll(struct cdev
*dev
, int events
, struct thread
*td
)
318 iplpoll(dev_t dev
, int events
, struct proc
*td
)
321 u_int xmin
= GET_MINOR(dev
);
324 if (xmin
< 0 || xmin
> IPL_LOGMAX
)
335 if ((events
& (POLLIN
| POLLRDNORM
)) && ipflog_canread(xmin
))
336 revents
|= events
& (POLLIN
| POLLRDNORM
);
340 if ((events
& (POLLIN
| POLLRDNORM
)) && fr_auth_waiting())
341 revents
|= events
& (POLLIN
| POLLRDNORM
);
345 if ((events
& (POLLIN
| POLLRDNORM
)) && ipfsync_canread())
346 revents
|= events
& (POLLIN
| POLLRDNORM
);
347 if ((events
& (POLLOUT
| POLLWRNORM
)) && ipfsync_canwrite())
348 revents
|= events
& (POLLOUT
| POLLWRNORM
);
357 if ((revents
== 0) && ((events
& (POLLIN
|POLLRDNORM
)) != 0))
358 selrecord(td
, &ipfselwait
[xmin
]);