| 1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/mlfk_ipl.c 145522 2005-04-25 18:43:14Z darrenr $ */ 2
|
1/*
| 3/*
|
2 * Copyright 1999 Guido van Rooij. All rights reserved. 3 *
| 4 * Copyright (C) 2000 by Darren Reed.
|
4 *
| 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.
|
27 */ 28 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/conf.h> 35#include <sys/socket.h> 36#include <sys/sysctl.h> 37#include <net/if.h> 38#include <netinet/in_systm.h> 39#include <netinet/in.h>
| 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
| |
47 48 49#include <netinet/ipl.h> 50#include <netinet/ip_compat.h> 51#include <netinet/ip_fil.h> 52#include <netinet/ip_state.h> 53#include <netinet/ip_nat.h> 54#include <netinet/ip_auth.h> 55#include <netinet/ip_frag.h>
| 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>
| |
57
| 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
|
59
| 36
|
| 37static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); 38static int ipf_modload(void); 39static int ipf_modunload(void); 40
|
60SYSCTL_DECL(_net_inet);
| 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)
|
61SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
| 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,
|
66 &fr_tcpidletimeout, 0, "");
| 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,
|
68 &fr_tcpclosewait, 0, "");
| 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,
|
70 &fr_tcplastack, 0, "");
| 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,
|
72 &fr_tcptimeout, 0, "");
| 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,
|
74 &fr_tcpclosed, 0, "");
| 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,
|
78 &fr_udptimeout, 0, "");
| 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,
|
80 &fr_udpacktimeout, 0, "");
| 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,
|
82 &fr_icmptimeout, 0, "");
| 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,
|
86 &fr_defnatage, 0, "");
| 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,
|
88 &fr_ipfrttl, 0, "");
| 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,
|
92 &fr_running, 0, "");
| 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,
|
94 &fr_authsize, 0, "");
| 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,
|
96 &fr_authused, 0, "");
| 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,
|
98 &fr_defaultauthage, 0, "");
| 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, "");
|
105
| 95
|
| 96#define CDEV_MAJOR 79 97#if __FreeBSD_version >= 501000
|
106static struct cdevsw ipl_cdevsw = {
| 98static struct cdevsw ipl_cdevsw = {
|
| 99# if __FreeBSD_version >= 502103
|
107 .d_version = D_VERSION,
| 100 .d_version = D_VERSION,
|
108 .d_flags = 0,
| 101 .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */ 102# endif
|
109 .d_open = iplopen, 110 .d_close = iplclose, 111 .d_read = iplread, 112 .d_ioctl = iplioctl, 113 .d_name = "ipl",
| 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
|
114};
| 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};
|
119#endif 120
| 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
|
121static int 122ipfilter_modevent(module_t mod, int type, void *unused) 123{
| 138static int 139ipfilter_modevent(module_t mod, int type, void *unused) 140{
|
124 char *c; 125 int i, error = 0;
| 141 int error = 0;
|
126
| 142
|
127 switch (type) {
| 143 switch (type) 144 {
|
128 case MOD_LOAD :
| 145 case MOD_LOAD :
|
| 146 error = ipf_modload(); 147 break;
|
129
| 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}
|
143
| 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);
| |
154
| 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
| 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;
|
176
| 169
|
| 170 for (i = 0; i < IPL_LOGSIZE; i++) 171 ipf_devs[i] = NULL; 172 173 for (i = 0; (str = ipf_devfiles[i]); i++) {
|
177 c = NULL;
| 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;
|
181 break; 182 } 183 if (!c)
| 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 }
|
187
| 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) {
|
194 error = ipldetach();
| 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]);
|
199 }
| 229 }
|
| 230 231 printf("%s unloaded\n", ipfilter_version); 232
|
200 return error; 201} 202
| 233 return error; 234} 235
|
| 236
|
203static moduledata_t ipfiltermod = {
| 237static moduledata_t ipfiltermod = {
|
204 IPL_VERSION,
| 238 "ipfilter",
|
205 ipfilter_modevent,
| 239 ipfilter_modevent,
|
206 0
| 240 0
|
207};
| 241};
|
| 242 243
|
208DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
| 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
|
| |