1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/mlfk_ipl.c 145522 2005-04-25 18:43:14Z darrenr $ */ 2 |
3/*
|
2 * Copyright 1999 Guido van Rooij. All rights reserved.
3 *
|
4 * Copyright (C) 2000 by Darren Reed. |
5 *
|
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL THE HOLDER OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/contrib/ipfilter/netinet/mlfk_ipl.c 142720 2005-02-27 22:19:35Z phk $
|
6 * $FreeBSD: head/sys/contrib/ipfilter/netinet/mlfk_ipl.c 145522 2005-04-25 18:43:14Z darrenr $ 7 * See the IPFILTER.LICENCE file for details on licencing. |
8 */ 9 10 11#include <sys/param.h> 12#include <sys/systm.h> 13#include <sys/kernel.h> 14#include <sys/module.h> 15#include <sys/conf.h> 16#include <sys/socket.h> 17#include <sys/sysctl.h> 18#include <net/if.h> 19#include <netinet/in_systm.h> 20#include <netinet/in.h>
|
40#include <netinet/ip.h>
41#if (__FreeBSD_version >= 199511)
42# include <net/route.h>
43# include <netinet/ip_var.h>
44# include <netinet/tcp.h>
45# include <netinet/tcpip.h>
46#endif
|
21 22 23#include <netinet/ipl.h> 24#include <netinet/ip_compat.h> 25#include <netinet/ip_fil.h> 26#include <netinet/ip_state.h> 27#include <netinet/ip_nat.h> 28#include <netinet/ip_auth.h> 29#include <netinet/ip_frag.h>
|
56#include <netinet/ip_proxy.h>
|
30
|
58static struct cdev *ipf_devs[IPL_LOGMAX + 1];
|
31#if __FreeBSD_version >= 502116 32static struct cdev *ipf_devs[IPL_LOGSIZE]; 33#else 34static dev_t ipf_devs[IPL_LOGSIZE]; 35#endif |
36
|
37static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); 38static int ipf_modload(void); 39static int ipf_modunload(void); 40 |
41SYSCTL_DECL(_net_inet);
|
42#define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ 43 SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ 44 ptr, val, sysctl_ipf_int, "I", descr); 45#define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ 46#define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) |
47SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
|
62SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
63SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
64SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
65SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW,
|
48SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); 49SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); 50SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); 51SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, |
52 &fr_tcpidletimeout, 0, "");
|
67SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW,
|
53SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, 54 &fr_tcphalfclosed, 0, ""); 55SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, |
56 &fr_tcpclosewait, 0, "");
|
69SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW,
|
57SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, |
58 &fr_tcplastack, 0, "");
|
71SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW,
|
59SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, |
60 &fr_tcptimeout, 0, "");
|
73SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW,
|
61SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, |
62 &fr_tcpclosed, 0, "");
|
75SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW,
76 &fr_tcphalfclosed, 0, "");
77SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
|
63SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, |
64 &fr_udptimeout, 0, "");
|
79SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RW,
|
65SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO, |
66 &fr_udpacktimeout, 0, "");
|
81SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
|
67SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, |
68 &fr_icmptimeout, 0, "");
|
83SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmpacktimeout, CTLFLAG_RW,
84 &fr_icmpacktimeout, 0, "");
85SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
|
69SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, |
70 &fr_defnatage, 0, "");
|
87SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
|
71SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, |
72 &fr_ipfrttl, 0, "");
|
89SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW,
90 &ipl_unreach, 0, "");
91SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
|
73SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, |
74 &fr_running, 0, "");
|
93SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD,
|
75SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, 76 &fr_statesize, 0, ""); 77SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, 78 &fr_statemax, 0, ""); 79SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO, 80 &ipf_nattable_sz, 0, ""); 81SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO, 82 &ipf_natrules_sz, 0, ""); 83SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO, 84 &ipf_rdrrules_sz, 0, ""); 85SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO, 86 &ipf_hostmap_sz, 0, ""); 87SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, |
88 &fr_authsize, 0, "");
|
95SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
|
89SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, |
90 &fr_authused, 0, "");
|
97SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
|
91SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, |
92 &fr_defaultauthage, 0, "");
|
99SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, "");
100SYSCTL_INT(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW,
101 &ippr_ftp_pasvonly, 0, "");
102SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, "");
103SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttllog, CTLFLAG_RW,
104 &fr_minttllog, 0, "");
|
93SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); 94SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); |
95
|
96#define CDEV_MAJOR 79 97#if __FreeBSD_version >= 501000 |
98static struct cdevsw ipl_cdevsw = {
|
99# if __FreeBSD_version >= 502103 |
100 .d_version = D_VERSION,
|
108 .d_flags = 0,
|
101 .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */ 102# endif |
103 .d_open = iplopen, 104 .d_close = iplclose, 105 .d_read = iplread, 106 .d_ioctl = iplioctl, 107 .d_name = "ipl",
|
108# if __FreeBSD_version < 600000 109 .d_maj = CDEV_MAJOR, 110# endif |
111};
|
115
116#if (__FreeBSD_version >= 500000)
117kmutex_t ipl_mutex, ipf_rw;
118KRWLOCK_T ipf_mutex, ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
|
112#else 113static struct cdevsw ipl_cdevsw = { 114 /* open */ iplopen, 115 /* close */ iplclose, 116 /* read */ iplread, 117 /* write */ iplwrite, 118 /* ioctl */ iplioctl, 119 /* poll */ nopoll, 120 /* mmap */ nommap, 121 /* strategy */ nostrategy, 122 /* name */ "ipl", 123 /* maj */ CDEV_MAJOR, 124 /* dump */ nodump, 125 /* psize */ nopsize, 126 /* flags */ 0, 127# if (__FreeBSD_version < 500043) 128 /* bmaj */ -1, 129# endif 130 /* kqfilter */ NULL 131}; |
132#endif 133
|
134static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME, 135 IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL }; 136 137 |
138static int 139ipfilter_modevent(module_t mod, int type, void *unused) 140{
|
124 char *c;
125 int i, error = 0;
|
141 int error = 0; |
142
|
127 switch (type) {
|
143 switch (type) 144 { |
145 case MOD_LOAD :
|
146 error = ipf_modload(); 147 break; |
148
|
130 error = iplattach();
131 if (error)
132 break;
133#if (__FreeBSD_version >= 500000)
134 MUTEX_INIT(&ipl_mutex, "ipf log mutex", NULL);
135 MUTEX_INIT(&ipf_rw, "ipf rw mutex", NULL);
136 RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock", NULL);
137 RWLOCK_INIT(&ipf_frag, "ipf fragment rwlock", NULL);
138 RWLOCK_INIT(&ipf_state, "ipf IP state rwlock", NULL);
139 RWLOCK_INIT(&ipf_nat, "ipf IP NAT rwlock", NULL);
140 RWLOCK_INIT(&ipf_natfrag, "ipf IP NAT-Frag rwlock", NULL);
141 RWLOCK_INIT(&ipf_auth, "ipf User-Auth rwlock", NULL);
142#endif
|
149 case MOD_UNLOAD : 150 error = ipf_modunload(); 151 break; 152 default: 153 error = EINVAL; 154 break; 155 } 156 return error; 157} |
158
|
144 c = NULL;
145 for(i = strlen(IPL_NAME); i > 0; i--)
146 if (IPL_NAME[i] == '/') {
147 c = &IPL_NAME[i + 1];
148 break;
149 }
150 if (!c)
151 c = IPL_NAME;
152 ipf_devs[IPL_LOGIPF] =
153 make_dev(&ipl_cdevsw, IPL_LOGIPF, 0, 0, 0600, c);
|
159
|
155 c = NULL;
156 for(i = strlen(IPL_NAT); i > 0; i--)
157 if (IPL_NAT[i] == '/') {
158 c = &IPL_NAT[i + 1];
159 break;
160 }
161 if (!c)
162 c = IPL_NAT;
163 ipf_devs[IPL_LOGNAT] =
164 make_dev(&ipl_cdevsw, IPL_LOGNAT, 0, 0, 0600, c);
|
160static int 161ipf_modload() 162{ 163 char *defpass, *c, *str; 164 int i, j, error; |
165
|
166 c = NULL;
167 for(i = strlen(IPL_STATE); i > 0; i--)
168 if (IPL_STATE[i] == '/') {
169 c = &IPL_STATE[i + 1];
170 break;
171 }
172 if (!c)
173 c = IPL_STATE;
174 ipf_devs[IPL_LOGSTATE] =
175 make_dev(&ipl_cdevsw, IPL_LOGSTATE, 0, 0, 0600, c);
|
166 error = iplattach(); 167 if (error) 168 return error; |
169
|
170 for (i = 0; i < IPL_LOGSIZE; i++) 171 ipf_devs[i] = NULL; 172 173 for (i = 0; (str = ipf_devfiles[i]); i++) { |
174 c = NULL;
|
178 for(i = strlen(IPL_AUTH); i > 0; i--)
179 if (IPL_AUTH[i] == '/') {
180 c = &IPL_AUTH[i + 1];
|
175 for(j = strlen(str); j > 0; j--) 176 if (str[j] == '/') { 177 c = str + j + 1; |
178 break; 179 } 180 if (!c)
|
184 c = IPL_AUTH;
185 ipf_devs[IPL_LOGAUTH] =
186 make_dev(&ipl_cdevsw, IPL_LOGAUTH, 0, 0, 0600, c);
|
181 c = str; 182 ipf_devs[i] = make_dev(&ipl_cdevsw, i, 0, 0, 0600, c); 183 } |
184
|
188 break;
189 case MOD_UNLOAD :
190 destroy_dev(ipf_devs[IPL_LOGIPF]);
191 destroy_dev(ipf_devs[IPL_LOGNAT]);
192 destroy_dev(ipf_devs[IPL_LOGSTATE]);
193 destroy_dev(ipf_devs[IPL_LOGAUTH]);
|
185 if (FR_ISPASS(fr_pass)) 186 defpass = "pass"; 187 else if (FR_ISBLOCK(fr_pass)) 188 defpass = "block"; 189 else 190 defpass = "no-match -> block"; 191 192 printf("%s initialized. Default = %s all, Logging = %s%s\n", 193 ipfilter_version, defpass, 194#ifdef IPFILTER_LOG 195 "enabled", 196#else 197 "disabled", 198#endif 199#ifdef IPFILTER_COMPILED 200 " (COMPILED)" 201#else 202 "" 203#endif 204 ); 205 return 0; 206} 207 208 209static int 210ipf_modunload() 211{ 212 int error, i; 213 214 if (fr_refcnt) 215 return EBUSY; 216 217 if (fr_running >= 0) { |
218 error = ipldetach();
|
195 break;
196 default:
197 error = EINVAL;
198 break;
|
219 if (error != 0) 220 return error; 221 } else 222 error = 0; 223 224 fr_running = -2; 225 226 for (i = 0; ipf_devfiles[i]; i++) { 227 if (ipf_devs[i] != NULL) 228 destroy_dev(ipf_devs[i]); |
229 }
|
230 231 printf("%s unloaded\n", ipfilter_version); 232 |
233 return error; 234} 235
|
236 |
237static moduledata_t ipfiltermod = {
|
204 IPL_VERSION,
|
238 "ipfilter", |
239 ipfilter_modevent,
|
206 0
|
240 0 |
241};
|
242 243 |
244DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
|
245#ifdef MODULE_VERSION 246MODULE_VERSION(ipfilter, 1); 247#endif 248 249 250#ifdef SYSCTL_IPF 251int 252sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) 253{ 254 int error = 0; 255 256 if (arg1) 257 error = SYSCTL_OUT(req, arg1, sizeof(int)); 258 else 259 error = SYSCTL_OUT(req, &arg2, sizeof(int)); 260 261 if (error || !req->newptr) 262 return (error); 263 264 if (!arg1) 265 error = EPERM; 266 else { 267 if ((oidp->oid_kind & CTLFLAG_OFF) && (fr_running > 0)) 268 error = EBUSY; 269 else 270 error = SYSCTL_IN(req, arg1, sizeof(int)); 271 } 272 return (error); 273} 274#endif |
|