1/* 2 * Copyright (C) 1993-2001 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 */ 6/* 7 * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate 8 * its own major char number! Way cool patch! 9 */ 10 11 12#include <sys/param.h> 13 14#if defined(__FreeBSD__) 15# ifdef IPFILTER_LKM 16# ifndef __FreeBSD_cc_version 17# include <osreldate.h> 18# else 19# if __FreeBSD_cc_version < 430000 20# include <osreldate.h> 21# endif 22# endif 23# define ACTUALLY_LKM_NOT_KERNEL 24# else 25# ifndef __FreeBSD_cc_version 26# include <sys/osreldate.h> 27# else 28# if __FreeBSD_cc_version < 430000 29# include <sys/osreldate.h> 30# endif 31# endif 32# endif 33#endif 34#include <sys/systm.h> 35#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) 36# ifndef ACTUALLY_LKM_NOT_KERNEL 37# include "opt_devfs.h" 38# endif 39# include <sys/conf.h> 40# include <sys/kernel.h> 41# ifdef DEVFS 42# include <sys/devfsext.h> 43# endif /*DEVFS*/ 44#endif 45#include <sys/conf.h> 46#include <sys/file.h> 47#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 48# include <sys/lock.h> 49#endif 50#include <sys/stat.h> 51#include <sys/proc.h> 52#include <sys/uio.h> 53#include <sys/kernel.h> 54#include <sys/vnode.h> 55#include <sys/namei.h> 56#include <sys/malloc.h> 57#include <sys/mount.h> 58#include <sys/exec.h> 59#include <sys/mbuf.h> 60#if BSD >= 199506 61# include <sys/sysctl.h> 62#endif 63#if (__FreeBSD_version >= 300000) 64# include <sys/socket.h> 65#endif 66#include <net/if.h> 67#include <netinet/in_systm.h> 68#include <netinet/in.h> 69#include <netinet/ip.h> 70#include <net/route.h> 71#include <net/if.h> 72#include <netinet/ip_var.h> 73#include <netinet/tcp.h> 74#include <netinet/tcpip.h> 75#include <sys/sysent.h> 76#include <sys/lkm.h> 77#include "netinet/ipl.h" 78#include "netinet/ip_compat.h" 79#include "netinet/ip_fil.h" 80#include "netinet/ip_state.h" 81#include "netinet/ip_nat.h" 82#include "netinet/ip_auth.h" 83#include "netinet/ip_frag.h" 84#include "netinet/ip_proxy.h" 85 86 87#if !defined(VOP_LEASE) && defined(LEASE_CHECK) 88#define VOP_LEASE LEASE_CHECK 89#endif 90 91#ifndef MIN 92#define MIN(a,b) (((a)<(b))?(a):(b)) 93#endif 94 95int xxxinit __P((struct lkm_table *, int, int)); 96 97#ifdef SYSCTL_INT 98SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); 99SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); 100SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); 101SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); 102SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); 103SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); 104SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttllog, CTLFLAG_RW, 105 &fr_minttllog, 0, ""); 106SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW, 107 &fr_tcpidletimeout, 0, ""); 108SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW, 109 &fr_tcphalfclosed, 0, ""); 110SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW, 111 &fr_tcpclosewait, 0, ""); 112SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW, 113 &fr_tcplastack, 0, ""); 114SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW, 115 &fr_tcptimeout, 0, ""); 116SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW, 117 &fr_tcpclosed, 0, ""); 118SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW, 119 &fr_udptimeout, 0, "");
| 1/* 2 * Copyright (C) 1993-2001 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 */ 6/* 7 * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate 8 * its own major char number! Way cool patch! 9 */ 10 11 12#include <sys/param.h> 13 14#if defined(__FreeBSD__) 15# ifdef IPFILTER_LKM 16# ifndef __FreeBSD_cc_version 17# include <osreldate.h> 18# else 19# if __FreeBSD_cc_version < 430000 20# include <osreldate.h> 21# endif 22# endif 23# define ACTUALLY_LKM_NOT_KERNEL 24# else 25# ifndef __FreeBSD_cc_version 26# include <sys/osreldate.h> 27# else 28# if __FreeBSD_cc_version < 430000 29# include <sys/osreldate.h> 30# endif 31# endif 32# endif 33#endif 34#include <sys/systm.h> 35#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) 36# ifndef ACTUALLY_LKM_NOT_KERNEL 37# include "opt_devfs.h" 38# endif 39# include <sys/conf.h> 40# include <sys/kernel.h> 41# ifdef DEVFS 42# include <sys/devfsext.h> 43# endif /*DEVFS*/ 44#endif 45#include <sys/conf.h> 46#include <sys/file.h> 47#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 48# include <sys/lock.h> 49#endif 50#include <sys/stat.h> 51#include <sys/proc.h> 52#include <sys/uio.h> 53#include <sys/kernel.h> 54#include <sys/vnode.h> 55#include <sys/namei.h> 56#include <sys/malloc.h> 57#include <sys/mount.h> 58#include <sys/exec.h> 59#include <sys/mbuf.h> 60#if BSD >= 199506 61# include <sys/sysctl.h> 62#endif 63#if (__FreeBSD_version >= 300000) 64# include <sys/socket.h> 65#endif 66#include <net/if.h> 67#include <netinet/in_systm.h> 68#include <netinet/in.h> 69#include <netinet/ip.h> 70#include <net/route.h> 71#include <net/if.h> 72#include <netinet/ip_var.h> 73#include <netinet/tcp.h> 74#include <netinet/tcpip.h> 75#include <sys/sysent.h> 76#include <sys/lkm.h> 77#include "netinet/ipl.h" 78#include "netinet/ip_compat.h" 79#include "netinet/ip_fil.h" 80#include "netinet/ip_state.h" 81#include "netinet/ip_nat.h" 82#include "netinet/ip_auth.h" 83#include "netinet/ip_frag.h" 84#include "netinet/ip_proxy.h" 85 86 87#if !defined(VOP_LEASE) && defined(LEASE_CHECK) 88#define VOP_LEASE LEASE_CHECK 89#endif 90 91#ifndef MIN 92#define MIN(a,b) (((a)<(b))?(a):(b)) 93#endif 94 95int xxxinit __P((struct lkm_table *, int, int)); 96 97#ifdef SYSCTL_INT 98SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); 99SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); 100SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); 101SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); 102SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); 103SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); 104SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttllog, CTLFLAG_RW, 105 &fr_minttllog, 0, ""); 106SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW, 107 &fr_tcpidletimeout, 0, ""); 108SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW, 109 &fr_tcphalfclosed, 0, ""); 110SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW, 111 &fr_tcpclosewait, 0, ""); 112SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW, 113 &fr_tcplastack, 0, ""); 114SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW, 115 &fr_tcptimeout, 0, ""); 116SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW, 117 &fr_tcpclosed, 0, ""); 118SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW, 119 &fr_udptimeout, 0, "");
|
122SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW, 123 &fr_defnatage, 0, ""); 124SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, 125 &fr_ipfrttl, 0, ""); 126SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW, 127 &ipl_unreach, 0, ""); 128SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, 129 &fr_running, 0, ""); 130SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD, 131 &fr_authsize, 0, ""); 132SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, 133 &fr_authused, 0, ""); 134SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, 135 &fr_defaultauthage, 0, ""); 136SYSCTL_INT(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW, 137 &ippr_ftp_pasvonly, 0, ""); 138#endif 139 140#ifdef DEVFS 141static void *ipf_devfs[IPL_LOGMAX + 1]; 142#endif 143 144#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 145int ipl_major = 0; 146 147static struct cdevsw ipldevsw = 148{ 149 iplopen, /* open */ 150 iplclose, /* close */ 151 iplread, /* read */ 152 (void *)nullop, /* write */ 153 iplioctl, /* ioctl */ 154 (void *)nullop, /* stop */ 155 (void *)nullop, /* reset */ 156 (void *)NULL, /* tty */ 157 (void *)nullop, /* select */ 158 (void *)nullop, /* mmap */ 159 NULL /* strategy */ 160}; 161 162MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); 163 164extern struct cdevsw cdevsw[]; 165extern int vd_unuseddev __P((void)); 166extern int nchrdev; 167#else 168 169static struct cdevsw ipl_cdevsw = { 170 iplopen, iplclose, iplread, nowrite, /* 79 */ 171 iplioctl, nostop, noreset, nodevtotty, 172#if (__FreeBSD_version >= 300000) 173 seltrue, nommap, nostrategy, "ipl", 174#else 175 noselect, nommap, nostrategy, "ipl", 176#endif 177 NULL, -1 178}; 179#endif 180 181static void ipl_drvinit __P((void *)); 182 183#ifdef ACTUALLY_LKM_NOT_KERNEL 184static int if_ipl_unload __P((struct lkm_table *, int)); 185static int if_ipl_load __P((struct lkm_table *, int)); 186static int if_ipl_remove __P((void)); 187static int ipl_major = CDEV_MAJOR; 188 189static int iplaction __P((struct lkm_table *, int)); 190static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, NULL }; 191 192extern int lkmenodev __P((void)); 193 194static int iplaction(lkmtp, cmd) 195struct lkm_table *lkmtp; 196int cmd; 197{ 198#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 199 int i = ipl_major; 200 struct lkm_dev *args = lkmtp->private.lkm_dev; 201#endif 202 int err = 0; 203 204 switch (cmd) 205 { 206 case LKM_E_LOAD : 207 if (lkmexists(lkmtp)) 208 return EEXIST; 209 210#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 211 for (i = 0; i < nchrdev; i++) 212 if (cdevsw[i].d_open == lkmenodev || 213 cdevsw[i].d_open == iplopen) 214 break; 215 if (i == nchrdev) { 216 printf("IP Filter: No free cdevsw slots\n"); 217 return ENODEV; 218 } 219 220 ipl_major = i; 221 args->lkm_offset = i; /* slot in cdevsw[] */ 222#endif 223 printf("IP Filter: loaded into slot %d\n", ipl_major); 224 err = if_ipl_load(lkmtp, cmd); 225 if (!err) 226 ipl_drvinit((void *)NULL); 227 return err; 228 break; 229 case LKM_E_UNLOAD : 230 err = if_ipl_unload(lkmtp, cmd); 231 if (!err) { 232 printf("IP Filter: unloaded from slot %d\n", 233 ipl_major); 234#ifdef DEVFS 235 if (ipf_devfs[IPL_LOGIPF]) 236 devfs_remove_dev(ipf_devfs[IPL_LOGIPF]); 237 if (ipf_devfs[IPL_LOGNAT]) 238 devfs_remove_dev(ipf_devfs[IPL_LOGNAT]); 239 if (ipf_devfs[IPL_LOGSTATE]) 240 devfs_remove_dev(ipf_devfs[IPL_LOGSTATE]); 241 if (ipf_devfs[IPL_LOGAUTH]) 242 devfs_remove_dev(ipf_devfs[IPL_LOGAUTH]); 243#endif 244 } 245 return err; 246 case LKM_E_STAT : 247 break; 248 default: 249 err = EIO; 250 break; 251 } 252 return 0; 253} 254 255 256static int if_ipl_remove __P((void)) 257{ 258 char *name; 259 struct nameidata nd; 260 int error, i; 261 262 for (i = 0; (name = ipf_devfiles[i]); i++) { 263 NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); 264 if ((error = namei(&nd))) 265 return (error); 266 VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); 267#if (__FreeBSD_version >= 300000) 268 VOP_LOCK(nd.ni_vp, LK_RETRY | LK_EXCLUSIVE, curproc); 269 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 270 (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 271 272 if (nd.ni_dvp == nd.ni_vp) 273 vrele(nd.ni_dvp); 274 else 275 vput(nd.ni_dvp); 276 if (nd.ni_vp != NULLVP) 277 vput(nd.ni_vp); 278#else 279 VOP_LOCK(nd.ni_vp); 280 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 281 (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 282#endif 283 } 284 285 return 0; 286} 287 288 289static int if_ipl_unload(lkmtp, cmd) 290struct lkm_table *lkmtp; 291int cmd; 292{ 293 int error = 0; 294 295 error = ipldetach(); 296 if (!error) 297 error = if_ipl_remove(); 298 return error; 299} 300 301 302static int if_ipl_load(lkmtp, cmd) 303struct lkm_table *lkmtp; 304int cmd; 305{ 306 struct nameidata nd; 307 struct vattr vattr; 308 int error = 0, fmode = S_IFCHR|0600, i; 309 char *name; 310 311 error = iplattach(); 312 if (error) 313 return error; 314 (void) if_ipl_remove(); 315 316 for (i = 0; (name = ipf_devfiles[i]); i++) { 317 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); 318 if ((error = namei(&nd))) 319 return error; 320 if (nd.ni_vp != NULL) { 321 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 322 if (nd.ni_dvp == nd.ni_vp) 323 vrele(nd.ni_dvp); 324 else 325 vput(nd.ni_dvp); 326 vrele(nd.ni_vp); 327 return (EEXIST); 328 } 329 VATTR_NULL(&vattr); 330 vattr.va_type = VCHR; 331 vattr.va_mode = (fmode & 07777); 332 vattr.va_rdev = (ipl_major << 8) | i; 333 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 334 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 335#if (__FreeBSD_version >= 300000) 336 vput(nd.ni_dvp); 337#endif 338 if (error) 339 return error; 340 } 341 return 0; 342} 343 344#endif /* actually LKM */ 345 346#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) 347/* 348 * strlen isn't present in 2.1.* kernels. 349 */ 350size_t strlen(string) 351char *string; 352{ 353 register char *s; 354 355 for (s = string; *s; s++) 356 ; 357 return (size_t)(s - string); 358} 359 360 361int xxxinit(lkmtp, cmd, ver) 362struct lkm_table *lkmtp; 363int cmd, ver; 364{ 365 DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); 366} 367#else /* __FREEBSD_version >= 220000 */ 368# ifdef IPFILTER_LKM 369# include <sys/exec.h> 370 371# if (__FreeBSD_version >= 300000) 372MOD_DEV(if_ipl, LM_DT_CHAR, CDEV_MAJOR, &ipl_cdevsw); 373# else 374MOD_DECL(if_ipl); 375 376 377static struct lkm_dev _module = { 378 LM_DEV, 379 LKM_VERSION, 380 IPL_VERSION, 381 CDEV_MAJOR, 382 LM_DT_CHAR, 383 { (void *)&ipl_cdevsw } 384}; 385# endif 386 387 388int if_ipl __P((struct lkm_table *, int, int)); 389 390 391int if_ipl(lkmtp, cmd, ver) 392struct lkm_table *lkmtp; 393int cmd, ver; 394{ 395# if (__FreeBSD_version >= 300000) 396 MOD_DISPATCH(if_ipl, lkmtp, cmd, ver, iplaction, iplaction, iplaction); 397# else 398 DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); 399# endif 400} 401# endif /* IPFILTER_LKM */ 402static int ipl_devsw_installed = 0; 403 404static void ipl_drvinit __P((void *unused)) 405{ 406 dev_t dev; 407# ifdef DEVFS 408 void **tp = ipf_devfs; 409# endif 410 411 if (!ipl_devsw_installed ) { 412 dev = makedev(CDEV_MAJOR, 0); 413 cdevsw_add(&dev, &ipl_cdevsw, NULL); 414 ipl_devsw_installed = 1; 415 416# ifdef DEVFS 417 tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF, 418 DV_CHR, 0, 0, 0600, "ipf"); 419 tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT, 420 DV_CHR, 0, 0, 0600, "ipnat"); 421 tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE, 422 DV_CHR, 0, 0, 0600, 423 "ipstate"); 424 tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH, 425 DV_CHR, 0, 0, 0600, 426 "ipauth"); 427# endif 428 } 429} 430 431# if defined(IPFILTER_LKM) || \ 432 defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) 433SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL) 434# endif /* IPFILTER_LKM */ 435#endif /* _FreeBSD_version */
| 126SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW, 127 &fr_defnatage, 0, ""); 128SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, 129 &fr_ipfrttl, 0, ""); 130SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW, 131 &ipl_unreach, 0, ""); 132SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, 133 &fr_running, 0, ""); 134SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD, 135 &fr_authsize, 0, ""); 136SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, 137 &fr_authused, 0, ""); 138SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, 139 &fr_defaultauthage, 0, ""); 140SYSCTL_INT(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW, 141 &ippr_ftp_pasvonly, 0, ""); 142#endif 143 144#ifdef DEVFS 145static void *ipf_devfs[IPL_LOGMAX + 1]; 146#endif 147 148#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 149int ipl_major = 0; 150 151static struct cdevsw ipldevsw = 152{ 153 iplopen, /* open */ 154 iplclose, /* close */ 155 iplread, /* read */ 156 (void *)nullop, /* write */ 157 iplioctl, /* ioctl */ 158 (void *)nullop, /* stop */ 159 (void *)nullop, /* reset */ 160 (void *)NULL, /* tty */ 161 (void *)nullop, /* select */ 162 (void *)nullop, /* mmap */ 163 NULL /* strategy */ 164}; 165 166MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); 167 168extern struct cdevsw cdevsw[]; 169extern int vd_unuseddev __P((void)); 170extern int nchrdev; 171#else 172 173static struct cdevsw ipl_cdevsw = { 174 iplopen, iplclose, iplread, nowrite, /* 79 */ 175 iplioctl, nostop, noreset, nodevtotty, 176#if (__FreeBSD_version >= 300000) 177 seltrue, nommap, nostrategy, "ipl", 178#else 179 noselect, nommap, nostrategy, "ipl", 180#endif 181 NULL, -1 182}; 183#endif 184 185static void ipl_drvinit __P((void *)); 186 187#ifdef ACTUALLY_LKM_NOT_KERNEL 188static int if_ipl_unload __P((struct lkm_table *, int)); 189static int if_ipl_load __P((struct lkm_table *, int)); 190static int if_ipl_remove __P((void)); 191static int ipl_major = CDEV_MAJOR; 192 193static int iplaction __P((struct lkm_table *, int)); 194static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, NULL }; 195 196extern int lkmenodev __P((void)); 197 198static int iplaction(lkmtp, cmd) 199struct lkm_table *lkmtp; 200int cmd; 201{ 202#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 203 int i = ipl_major; 204 struct lkm_dev *args = lkmtp->private.lkm_dev; 205#endif 206 int err = 0; 207 208 switch (cmd) 209 { 210 case LKM_E_LOAD : 211 if (lkmexists(lkmtp)) 212 return EEXIST; 213 214#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 215 for (i = 0; i < nchrdev; i++) 216 if (cdevsw[i].d_open == lkmenodev || 217 cdevsw[i].d_open == iplopen) 218 break; 219 if (i == nchrdev) { 220 printf("IP Filter: No free cdevsw slots\n"); 221 return ENODEV; 222 } 223 224 ipl_major = i; 225 args->lkm_offset = i; /* slot in cdevsw[] */ 226#endif 227 printf("IP Filter: loaded into slot %d\n", ipl_major); 228 err = if_ipl_load(lkmtp, cmd); 229 if (!err) 230 ipl_drvinit((void *)NULL); 231 return err; 232 break; 233 case LKM_E_UNLOAD : 234 err = if_ipl_unload(lkmtp, cmd); 235 if (!err) { 236 printf("IP Filter: unloaded from slot %d\n", 237 ipl_major); 238#ifdef DEVFS 239 if (ipf_devfs[IPL_LOGIPF]) 240 devfs_remove_dev(ipf_devfs[IPL_LOGIPF]); 241 if (ipf_devfs[IPL_LOGNAT]) 242 devfs_remove_dev(ipf_devfs[IPL_LOGNAT]); 243 if (ipf_devfs[IPL_LOGSTATE]) 244 devfs_remove_dev(ipf_devfs[IPL_LOGSTATE]); 245 if (ipf_devfs[IPL_LOGAUTH]) 246 devfs_remove_dev(ipf_devfs[IPL_LOGAUTH]); 247#endif 248 } 249 return err; 250 case LKM_E_STAT : 251 break; 252 default: 253 err = EIO; 254 break; 255 } 256 return 0; 257} 258 259 260static int if_ipl_remove __P((void)) 261{ 262 char *name; 263 struct nameidata nd; 264 int error, i; 265 266 for (i = 0; (name = ipf_devfiles[i]); i++) { 267 NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); 268 if ((error = namei(&nd))) 269 return (error); 270 VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); 271#if (__FreeBSD_version >= 300000) 272 VOP_LOCK(nd.ni_vp, LK_RETRY | LK_EXCLUSIVE, curproc); 273 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 274 (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 275 276 if (nd.ni_dvp == nd.ni_vp) 277 vrele(nd.ni_dvp); 278 else 279 vput(nd.ni_dvp); 280 if (nd.ni_vp != NULLVP) 281 vput(nd.ni_vp); 282#else 283 VOP_LOCK(nd.ni_vp); 284 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 285 (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 286#endif 287 } 288 289 return 0; 290} 291 292 293static int if_ipl_unload(lkmtp, cmd) 294struct lkm_table *lkmtp; 295int cmd; 296{ 297 int error = 0; 298 299 error = ipldetach(); 300 if (!error) 301 error = if_ipl_remove(); 302 return error; 303} 304 305 306static int if_ipl_load(lkmtp, cmd) 307struct lkm_table *lkmtp; 308int cmd; 309{ 310 struct nameidata nd; 311 struct vattr vattr; 312 int error = 0, fmode = S_IFCHR|0600, i; 313 char *name; 314 315 error = iplattach(); 316 if (error) 317 return error; 318 (void) if_ipl_remove(); 319 320 for (i = 0; (name = ipf_devfiles[i]); i++) { 321 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); 322 if ((error = namei(&nd))) 323 return error; 324 if (nd.ni_vp != NULL) { 325 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 326 if (nd.ni_dvp == nd.ni_vp) 327 vrele(nd.ni_dvp); 328 else 329 vput(nd.ni_dvp); 330 vrele(nd.ni_vp); 331 return (EEXIST); 332 } 333 VATTR_NULL(&vattr); 334 vattr.va_type = VCHR; 335 vattr.va_mode = (fmode & 07777); 336 vattr.va_rdev = (ipl_major << 8) | i; 337 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 338 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 339#if (__FreeBSD_version >= 300000) 340 vput(nd.ni_dvp); 341#endif 342 if (error) 343 return error; 344 } 345 return 0; 346} 347 348#endif /* actually LKM */ 349 350#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) 351/* 352 * strlen isn't present in 2.1.* kernels. 353 */ 354size_t strlen(string) 355char *string; 356{ 357 register char *s; 358 359 for (s = string; *s; s++) 360 ; 361 return (size_t)(s - string); 362} 363 364 365int xxxinit(lkmtp, cmd, ver) 366struct lkm_table *lkmtp; 367int cmd, ver; 368{ 369 DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); 370} 371#else /* __FREEBSD_version >= 220000 */ 372# ifdef IPFILTER_LKM 373# include <sys/exec.h> 374 375# if (__FreeBSD_version >= 300000) 376MOD_DEV(if_ipl, LM_DT_CHAR, CDEV_MAJOR, &ipl_cdevsw); 377# else 378MOD_DECL(if_ipl); 379 380 381static struct lkm_dev _module = { 382 LM_DEV, 383 LKM_VERSION, 384 IPL_VERSION, 385 CDEV_MAJOR, 386 LM_DT_CHAR, 387 { (void *)&ipl_cdevsw } 388}; 389# endif 390 391 392int if_ipl __P((struct lkm_table *, int, int)); 393 394 395int if_ipl(lkmtp, cmd, ver) 396struct lkm_table *lkmtp; 397int cmd, ver; 398{ 399# if (__FreeBSD_version >= 300000) 400 MOD_DISPATCH(if_ipl, lkmtp, cmd, ver, iplaction, iplaction, iplaction); 401# else 402 DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); 403# endif 404} 405# endif /* IPFILTER_LKM */ 406static int ipl_devsw_installed = 0; 407 408static void ipl_drvinit __P((void *unused)) 409{ 410 dev_t dev; 411# ifdef DEVFS 412 void **tp = ipf_devfs; 413# endif 414 415 if (!ipl_devsw_installed ) { 416 dev = makedev(CDEV_MAJOR, 0); 417 cdevsw_add(&dev, &ipl_cdevsw, NULL); 418 ipl_devsw_installed = 1; 419 420# ifdef DEVFS 421 tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF, 422 DV_CHR, 0, 0, 0600, "ipf"); 423 tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT, 424 DV_CHR, 0, 0, 0600, "ipnat"); 425 tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE, 426 DV_CHR, 0, 0, 0600, 427 "ipstate"); 428 tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH, 429 DV_CHR, 0, 0, 0600, 430 "ipauth"); 431# endif 432 } 433} 434 435# if defined(IPFILTER_LKM) || \ 436 defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) 437SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL) 438# endif /* IPFILTER_LKM */ 439#endif /* _FreeBSD_version */
|