1145519Sdarrenr/* $FreeBSD$ */ 2145510Sdarrenr 331183Speter/* 4255332Scy * Copyright (C) 2012 by Darren Reed. 531183Speter * 680486Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 731183Speter */ 831183Speter/* 931183Speter * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate 1031183Speter * its own major char number! Way cool patch! 1131183Speter */ 1231183Speter 1331183Speter 1431183Speter#include <sys/param.h> 1531183Speter 16145510Sdarrenr#ifdef IPFILTER_LKM 17145510Sdarrenr# ifndef __FreeBSD_cc_version 18145510Sdarrenr# include <osreldate.h> 19145510Sdarrenr# else 20145510Sdarrenr# if __FreeBSD_cc_version < 430000 2198005Sdarrenr# include <osreldate.h> 22145510Sdarrenr# endif 23145510Sdarrenr# endif 24145510Sdarrenr# define ACTUALLY_LKM_NOT_KERNEL 25145510Sdarrenr#else 26145510Sdarrenr# ifndef __FreeBSD_cc_version 27145510Sdarrenr# include <sys/osreldate.h> 28145510Sdarrenr# else 29145510Sdarrenr# if __FreeBSD_cc_version < 430000 3098005Sdarrenr# include <sys/osreldate.h> 3198005Sdarrenr# endif 3295419Sdarrenr# endif 3331183Speter#endif 3431183Speter#include <sys/systm.h> 3531183Speter#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) 3653024Sguido# ifndef ACTUALLY_LKM_NOT_KERNEL 3753024Sguido# include "opt_devfs.h" 3853024Sguido# endif 3931183Speter# include <sys/conf.h> 4031183Speter# include <sys/kernel.h> 4131183Speter# ifdef DEVFS 4231183Speter# include <sys/devfsext.h> 4331183Speter# endif /*DEVFS*/ 4431183Speter#endif 4531183Speter#include <sys/conf.h> 4631183Speter#include <sys/file.h> 4753024Sguido#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 4853024Sguido# include <sys/lock.h> 4953024Sguido#endif 5031183Speter#include <sys/stat.h> 5131183Speter#include <sys/proc.h> 5231183Speter#include <sys/kernel.h> 5331183Speter#include <sys/vnode.h> 5431183Speter#include <sys/namei.h> 5531183Speter#include <sys/malloc.h> 5631183Speter#include <sys/mount.h> 5731183Speter#include <sys/exec.h> 5831183Speter#include <sys/mbuf.h> 5931183Speter#if BSD >= 199506 6031183Speter# include <sys/sysctl.h> 6131183Speter#endif 6253024Sguido#if (__FreeBSD_version >= 300000) 6353024Sguido# include <sys/socket.h> 6453024Sguido#endif 6531183Speter#include <net/if.h> 6631183Speter#include <netinet/in_systm.h> 6731183Speter#include <netinet/in.h> 6831183Speter#include <netinet/ip.h> 6931183Speter#include <net/route.h> 7031183Speter#include <netinet/ip_var.h> 7131183Speter#include <netinet/tcp.h> 7231183Speter#include <netinet/tcpip.h> 7380486Sdarrenr#include <sys/sysent.h> 7431183Speter#include <sys/lkm.h> 7531183Speter#include "netinet/ipl.h" 7631183Speter#include "netinet/ip_compat.h" 7731183Speter#include "netinet/ip_fil.h" 7831183Speter#include "netinet/ip_state.h" 7931183Speter#include "netinet/ip_nat.h" 8031183Speter#include "netinet/ip_auth.h" 8131183Speter#include "netinet/ip_frag.h" 8231183Speter 8331183Speter 8431183Speter#if !defined(VOP_LEASE) && defined(LEASE_CHECK) 8531183Speter#define VOP_LEASE LEASE_CHECK 8631183Speter#endif 8731183Speter 8831183Speterint xxxinit __P((struct lkm_table *, int, int)); 8931183Speter 90145510Sdarrenr#ifdef SYSCTL_OID 91145510Sdarrenrint sysctl_ipf_int SYSCTL_HANDLER_ARGS; 92145510Sdarrenr# define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ 93145510Sdarrenr SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ 94145510Sdarrenr ptr, val, sysctl_ipf_int, "I", descr); 95145510Sdarrenr# define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ 96145510Sdarrenr# define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) 9731183SpeterSYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); 98255332ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipf_flags, 0, ""); 99255332ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipf_pass, 0, ""); 100255332ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipf_active, 0, ""); 101255332ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipf_chksrc, 0, ""); 102255332ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipf_minttl, 0, ""); 103145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, 104255332Scy &ipf_tcpidletimeout, 0, ""); 105145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, 106255332Scy &ipf_tcphalfclosed, 0, ""); 107145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, 108255332Scy &ipf_tcpclosewait, 0, ""); 109145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, 110255332Scy &ipf_tcplastack, 0, ""); 111145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, 112255332Scy &ipf_tcptimeout, 0, ""); 113145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, 114255332Scy &ipf_tcpclosed, 0, ""); 115145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, 116255332Scy &ipf_udptimeout, 0, ""); 117145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, 118255332Scy &ipf_icmptimeout, 0, ""); 119145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, 120255332Scy &ipf_defnatage, 0, ""); 121145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, 122255332Scy &ipf_ipfrttl, 0, ""); 123255332ScySYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD, 124255332Scy &ipf_running, 0, ""); 125145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, 126255332Scy &ipf_statesize, 0, ""); 127145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, 128255332Scy &ipf_statemax, 0, ""); 129145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, 130255332Scy &ipf_authsize, 0, ""); 131145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, 132255332Scy &ipf_authused, 0, ""); 133145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, 134255332Scy &ipf_defaultauthage, 0, ""); 135145510SdarrenrSYSCTL_IPF(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW, 13660841Sdarrenr &ippr_ftp_pasvonly, 0, ""); 13731183Speter#endif 13831183Speter 13934739Speter#ifdef DEVFS 140145510Sdarrenrstatic void *ipf_devfs[IPL_LOGSIZE]; 14134739Speter#endif 14234739Speter 14331183Speter#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 144255332Scyint ipf_major = 0; 14531183Speter 146255332Scystatic struct cdevsw ipfdevsw = 14753024Sguido{ 148255332Scy ipfopen, /* open */ 149255332Scy ipfclose, /* close */ 150255332Scy ipfread, /* read */ 151145510Sdarrenr (void *)nullop, /* write */ 152255332Scy ipfioctl, /* ioctl */ 153145510Sdarrenr (void *)nullop, /* stop */ 154145510Sdarrenr (void *)nullop, /* reset */ 155145510Sdarrenr (void *)NULL, /* tty */ 156145510Sdarrenr (void *)nullop, /* select */ 157145510Sdarrenr (void *)nullop, /* mmap */ 158145510Sdarrenr NULL /* strategy */ 15953024Sguido}; 16053024Sguido 161255332ScyMOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipfdevsw); 16231183Speter 16331183Speterextern struct cdevsw cdevsw[]; 16431183Speterextern int vd_unuseddev __P((void)); 16531183Speterextern int nchrdev; 16631183Speter#else 16731183Speter 168255332Scystatic struct cdevsw ipf_cdevsw = { 169255332Scy ipfopen, ipfclose, ipfread, nowrite, /* 79 */ 170255332Scy ipfioctl, nostop, noreset, nodevtotty, 17153024Sguido#if (__FreeBSD_version >= 300000) 172255332Scy seltrue, nommap, nostrategy, "ipf", 17353024Sguido#else 174255332Scy noselect, nommap, nostrategy, "ipf", 17553024Sguido#endif 17631183Speter NULL, -1 17731183Speter}; 17831183Speter#endif 17931183Speter 180255332Scystatic void ipf_drvinit __P((void *)); 18131183Speter 18253024Sguido#ifdef ACTUALLY_LKM_NOT_KERNEL 183255332Scystatic int if_ipf_unload __P((struct lkm_table *, int)); 184255332Scystatic int if_ipf_load __P((struct lkm_table *, int)); 185255332Scystatic int if_ipf_remove __P((void)); 186255332Scystatic int ipf_major = CDEV_MAJOR; 18753024Sguido 188255332Scystatic int ipfaction __P((struct lkm_table *, int)); 189145510Sdarrenrstatic char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, 190145510Sdarrenr IPL_SCAN, IPL_SYNC, IPL_POOL, NULL }; 19131183Speter 19253024Sguidoextern int lkmenodev __P((void)); 19331183Speter 194255332Scystatic int ipfaction(lkmtp, cmd) 195255332Scy struct lkm_table *lkmtp; 196255332Scy int cmd; 19731183Speter{ 19831183Speter#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 199255332Scy int i = ipf_major; 20031183Speter struct lkm_dev *args = lkmtp->private.lkm_dev; 20131183Speter#endif 20231183Speter int err = 0; 20331183Speter 20431183Speter switch (cmd) 20531183Speter { 20631183Speter case LKM_E_LOAD : 20731183Speter if (lkmexists(lkmtp)) 20831183Speter return EEXIST; 20931183Speter 21031183Speter#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) 21131183Speter for (i = 0; i < nchrdev; i++) 21231183Speter if (cdevsw[i].d_open == lkmenodev || 213255332Scy cdevsw[i].d_open == ipfopen) 21431183Speter break; 21531183Speter if (i == nchrdev) { 21631183Speter printf("IP Filter: No free cdevsw slots\n"); 21731183Speter return ENODEV; 21831183Speter } 21931183Speter 220255332Scy ipf_major = i; 22131183Speter args->lkm_offset = i; /* slot in cdevsw[] */ 22231183Speter#endif 223255332Scy printf("IP Filter: loaded into slot %d\n", ipf_major); 224255332Scy err = if_ipf_load(lkmtp, cmd); 22534739Speter if (!err) 226255332Scy ipf_drvinit((void *)NULL); 22734739Speter return err; 22831183Speter break; 22931183Speter case LKM_E_UNLOAD : 230255332Scy err = if_ipf_unload(lkmtp, cmd); 23134739Speter if (!err) { 23231183Speter printf("IP Filter: unloaded from slot %d\n", 233255332Scy ipf_major); 23453024Sguido#ifdef DEVFS 23534739Speter if (ipf_devfs[IPL_LOGIPF]) 23634739Speter devfs_remove_dev(ipf_devfs[IPL_LOGIPF]); 23734739Speter if (ipf_devfs[IPL_LOGNAT]) 23834739Speter devfs_remove_dev(ipf_devfs[IPL_LOGNAT]); 23934739Speter if (ipf_devfs[IPL_LOGSTATE]) 24034739Speter devfs_remove_dev(ipf_devfs[IPL_LOGSTATE]); 24134739Speter if (ipf_devfs[IPL_LOGAUTH]) 24234739Speter devfs_remove_dev(ipf_devfs[IPL_LOGAUTH]); 243145510Sdarrenr if (ipf_devfs[IPL_LOGSCAN]) 244145510Sdarrenr devfs_remove_dev(ipf_devfs[IPL_LOGSCAN]); 245145510Sdarrenr if (ipf_devfs[IPL_LOGSYNC]) 246145510Sdarrenr devfs_remove_dev(ipf_devfs[IPL_LOGSYNC]); 247145510Sdarrenr if (ipf_devfs[IPL_LOGLOOKUP]) 248145510Sdarrenr devfs_remove_dev(ipf_devfs[IPL_LOGLOOKUP]); 24953024Sguido#endif 25034739Speter } 25131183Speter return err; 25231183Speter case LKM_E_STAT : 25331183Speter break; 25431183Speter default: 25531183Speter err = EIO; 25631183Speter break; 25731183Speter } 25831183Speter return 0; 25931183Speter} 26031183Speter 26131183Speter 262255332Scystatic int if_ipf_remove __P((void)) 26331183Speter{ 26431183Speter char *name; 26531183Speter struct nameidata nd; 26631183Speter int error, i; 26731183Speter 26831183Speter for (i = 0; (name = ipf_devfiles[i]); i++) { 26931183Speter NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); 27031183Speter if ((error = namei(&nd))) 27131183Speter return (error); 27231183Speter VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); 27353024Sguido#if (__FreeBSD_version >= 300000) 27453024Sguido VOP_LOCK(nd.ni_vp, LK_RETRY | LK_EXCLUSIVE, curproc); 27553024Sguido VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 27653024Sguido (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 27753024Sguido 27853024Sguido if (nd.ni_dvp == nd.ni_vp) 27953024Sguido vrele(nd.ni_dvp); 28053024Sguido else 28153024Sguido vput(nd.ni_dvp); 28253024Sguido if (nd.ni_vp != NULLVP) 28353024Sguido vput(nd.ni_vp); 28453024Sguido#else 28531183Speter VOP_LOCK(nd.ni_vp); 28631183Speter VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 28731183Speter (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 28853024Sguido#endif 28931183Speter } 29031183Speter 29131183Speter return 0; 29231183Speter} 29331183Speter 29431183Speter 295255332Scystatic int if_ipf_unload(lkmtp, cmd) 296255332Scy struct lkm_table *lkmtp; 297255332Scy int cmd; 29831183Speter{ 29931183Speter int error = 0; 30031183Speter 301255332Scy error = ipfdetach(); 30231183Speter if (!error) 303255332Scy error = if_ipf_remove(); 30431183Speter return error; 30531183Speter} 30631183Speter 30731183Speter 308255332Scystatic int if_ipf_load(lkmtp, cmd) 309255332Scy struct lkm_table *lkmtp; 310255332Scy int cmd; 31131183Speter{ 31231183Speter struct nameidata nd; 31331183Speter struct vattr vattr; 31431183Speter int error = 0, fmode = S_IFCHR|0600, i; 31531183Speter char *name; 31631183Speter 317255332Scy error = ipfattach(); 31831183Speter if (error) 31931183Speter return error; 320255332Scy (void) if_ipf_remove(); 32131183Speter 32231183Speter for (i = 0; (name = ipf_devfiles[i]); i++) { 32331183Speter NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); 32431183Speter if ((error = namei(&nd))) 32531183Speter return error; 32631183Speter if (nd.ni_vp != NULL) { 32731183Speter VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 32831183Speter if (nd.ni_dvp == nd.ni_vp) 32931183Speter vrele(nd.ni_dvp); 33031183Speter else 33131183Speter vput(nd.ni_dvp); 33231183Speter vrele(nd.ni_vp); 33331183Speter return (EEXIST); 33431183Speter } 33531183Speter VATTR_NULL(&vattr); 33631183Speter vattr.va_type = VCHR; 33731183Speter vattr.va_mode = (fmode & 07777); 338255332Scy vattr.va_rdev = (ipf_major << 8) | i; 33931183Speter VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); 34031183Speter error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 34153024Sguido#if (__FreeBSD_version >= 300000) 342145510Sdarrenr vput(nd.ni_dvp); 34353024Sguido#endif 34431183Speter if (error) 34531183Speter return error; 34631183Speter } 34731183Speter return 0; 34831183Speter} 34931183Speter 35053024Sguido#endif /* actually LKM */ 35131183Speter 35231183Speter#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) 35331183Speter/* 35431183Speter * strlen isn't present in 2.1.* kernels. 35531183Speter */ 35631183Spetersize_t strlen(string) 357255332Scy char *string; 35831183Speter{ 359145510Sdarrenr register char *s; 36031183Speter 361145510Sdarrenr for (s = string; *s; s++) 36231183Speter ; 363145510Sdarrenr return (size_t)(s - string); 36431183Speter} 36531183Speter 36631183Speter 36731183Speterint xxxinit(lkmtp, cmd, ver) 368255332Scy struct lkm_table *lkmtp; 369255332Scy int cmd, ver; 37031183Speter{ 371255332Scy DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); 37231183Speter} 37353024Sguido#else /* __FREEBSD_version >= 220000 */ 37431183Speter# ifdef IPFILTER_LKM 37531183Speter# include <sys/exec.h> 37631183Speter 37753024Sguido# if (__FreeBSD_version >= 300000) 378255332ScyMOD_DEV(if_ipf, LM_DT_CHAR, CDEV_MAJOR, &ipf_cdevsw); 37953024Sguido# else 380255332ScyMOD_DECL(if_ipf); 38131183Speter 38231183Speter 38331183Speterstatic struct lkm_dev _module = { 38431183Speter LM_DEV, 38531183Speter LKM_VERSION, 38631183Speter IPL_VERSION, 38731183Speter CDEV_MAJOR, 38831183Speter LM_DT_CHAR, 389255332Scy { (void *)&ipf_cdevsw } 39031183Speter}; 39153024Sguido# endif 39231183Speter 39331183Speter 394255332Scyint if_ipf __P((struct lkm_table *, int, int)); 39531183Speter 39631183Speter 397255332Scyint if_ipf(lkmtp, cmd, ver) 398255332Scy struct lkm_table *lkmtp; 399255332Scy int cmd, ver; 40031183Speter{ 40153024Sguido# if (__FreeBSD_version >= 300000) 402255332Scy MOD_DISPATCH(if_ipf, lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); 40353024Sguido# else 404255332Scy DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); 40553024Sguido# endif 40631183Speter} 40753024Sguido# endif /* IPFILTER_LKM */ 408255332Scystatic ipf_devsw_installed = 0; 40931183Speter 410255332Scystatic void ipf_drvinit __P((void *unused)) 41131183Speter{ 41231183Speter dev_t dev; 41334739Speter# ifdef DEVFS 41434739Speter void **tp = ipf_devfs; 41534739Speter# endif 41631183Speter 417255332Scy if (!ipf_devsw_installed ) { 41831183Speter dev = makedev(CDEV_MAJOR, 0); 419255332Scy cdevsw_add(&dev, &ipf_cdevsw, NULL); 420255332Scy ipf_devsw_installed = 1; 42131183Speter 42234739Speter# ifdef DEVFS 423255332Scy tp[IPL_LOGIPF] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGIPF, 42434739Speter DV_CHR, 0, 0, 0600, "ipf"); 425255332Scy tp[IPL_LOGNAT] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGNAT, 42634739Speter DV_CHR, 0, 0, 0600, "ipnat"); 427255332Scy tp[IPL_LOGSTATE] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGSTATE, 428145510Sdarrenr DV_CHR, 0, 0, 0600, 42934739Speter "ipstate"); 430255332Scy tp[IPL_LOGAUTH] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGAUTH, 431145510Sdarrenr DV_CHR, 0, 0, 0600, 43234739Speter "ipauth"); 43334739Speter# endif 43431183Speter } 43531183Speter} 43631183Speter 437145510Sdarrenr 438145510Sdarrenr#ifdef SYSCTL_IPF 439145510Sdarrenrint 440145510Sdarrenrsysctl_ipf_int SYSCTL_HANDLER_ARGS 441145510Sdarrenr{ 442145510Sdarrenr int error = 0; 443145510Sdarrenr 444145510Sdarrenr if (arg1) 445145510Sdarrenr error = SYSCTL_OUT(req, arg1, sizeof(int)); 446145510Sdarrenr else 447145510Sdarrenr error = SYSCTL_OUT(req, &arg2, sizeof(int)); 448145510Sdarrenr 449145510Sdarrenr if (error || !req->newptr) 450145510Sdarrenr return (error); 451145510Sdarrenr 452145510Sdarrenr if (!arg1) 453145510Sdarrenr error = EPERM; 454145510Sdarrenr else { 455255332Scy if ((oidp->oid_kind & CTLFLAG_OFF) && (ipf_running > 0)) 456145510Sdarrenr error = EBUSY; 457145510Sdarrenr else 458145510Sdarrenr error = SYSCTL_IN(req, arg1, sizeof(int)); 459145510Sdarrenr } 460145510Sdarrenr return (error); 461145510Sdarrenr} 462145510Sdarrenr#endif 463145510Sdarrenr 464145510Sdarrenr 46537074Speter# if defined(IPFILTER_LKM) || \ 46637074Speter defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) 467255332ScySYSINIT(ipfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipf_drvinit,NULL) 46831183Speter# endif /* IPFILTER_LKM */ 46931183Speter#endif /* _FreeBSD_version */ 470255332Scy 471255332Scy 472255332Scy/* 473255332Scy * routines below for saving IP headers to buffer 474255332Scy */ 475255332Scyint ipfopen(dev, flags 476255332Scy#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) 477255332Scy, devtype, p) 478255332Scy int devtype; 479255332Scy# if (__FreeBSD_version >= 500024) 480255332Scy struct thread *p; 481255332Scy# else 482255332Scy struct proc *p; 483255332Scy# endif /* __FreeBSD_version >= 500024 */ 484255332Scy#else 485255332Scy) 486255332Scy#endif 487255332Scy#if (__FreeBSD_version >= 502116) 488255332Scy struct cdev *dev; 489255332Scy#else 490255332Scy dev_t dev; 491255332Scy#endif 492255332Scy int flags; 493255332Scy{ 494255332Scy u_int unit = GET_MINOR(dev); 495255332Scy 496255332Scy if (IPL_LOGMAX < unit) 497255332Scy unit = ENXIO; 498255332Scy else 499255332Scy unit = 0; 500255332Scy return unit; 501255332Scy} 502255332Scy 503255332Scy 504255332Scyint ipfclose(dev, flags 505255332Scy#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) 506255332Scy, devtype, p) 507255332Scy int devtype; 508255332Scy# if (__FreeBSD_version >= 500024) 509255332Scy struct thread *p; 510255332Scy# else 511255332Scy struct proc *p; 512255332Scy# endif /* __FreeBSD_version >= 500024 */ 513255332Scy#else 514255332Scy) 515255332Scy#endif 516255332Scy#if (__FreeBSD_version >= 502116) 517255332Scy struct cdev *dev; 518255332Scy#else 519255332Scy dev_t dev; 520255332Scy#endif 521255332Scy int flags; 522255332Scy{ 523255332Scy u_int unit = GET_MINOR(dev); 524255332Scy 525255332Scy if (IPL_LOGMAX < unit) 526255332Scy unit = ENXIO; 527255332Scy else 528255332Scy unit = 0; 529255332Scy return unit; 530255332Scy} 531255332Scy 532255332Scy/* 533255332Scy * ipfread/ipflog 534255332Scy * both of these must operate with at least splnet() lest they be 535255332Scy * called during packet processing and cause an inconsistancy to appear in 536255332Scy * the filter lists. 537255332Scy */ 538255332Scy#if (BSD >= 199306) 539255332Scyint ipfread(dev, uio, ioflag) 540255332Scy int ioflag; 541255332Scy#else 542255332Scyint ipfread(dev, uio) 543255332Scy#endif 544255332Scy#if (__FreeBSD_version >= 502116) 545255332Scy struct cdev *dev; 546255332Scy#else 547255332Scy dev_t dev; 548255332Scy#endif 549255332Scy register struct uio *uio; 550255332Scy{ 551255332Scy u_int unit = GET_MINOR(dev); 552255332Scy 553255332Scy if (unit < 0) 554255332Scy return ENXIO; 555255332Scy 556255332Scy if (ipf_running < 1) 557255332Scy return EIO; 558255332Scy 559255332Scy if (unit == IPL_LOGSYNC) 560255332Scy return ipfsync_read(uio); 561255332Scy 562255332Scy#ifdef IPFILTER_LOG 563255332Scy return ipflog_read(unit, uio); 564255332Scy#else 565255332Scy return ENXIO; 566255332Scy#endif 567255332Scy} 568255332Scy 569255332Scy 570255332Scy/* 571255332Scy * ipfwrite 572255332Scy * both of these must operate with at least splnet() lest they be 573255332Scy * called during packet processing and cause an inconsistancy to appear in 574255332Scy * the filter lists. 575255332Scy */ 576255332Scy#if (BSD >= 199306) 577255332Scyint ipfwrite(dev, uio, ioflag) 578255332Scy int ioflag; 579255332Scy#else 580255332Scyint ipfwrite(dev, uio) 581255332Scy#endif 582255332Scy#if (__FreeBSD_version >= 502116) 583255332Scy struct cdev *dev; 584255332Scy#else 585255332Scy dev_t dev; 586255332Scy#endif 587255332Scy register struct uio *uio; 588255332Scy{ 589255332Scy 590255332Scy if (ipf_running < 1) 591255332Scy return EIO; 592255332Scy 593255332Scy if (GET_MINOR(dev) == IPL_LOGSYNC) 594255332Scy return ipfsync_write(uio); 595255332Scy return ENXIO; 596255332Scy} 597