The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/mlf_ipl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 5fdaf480ce0b2eb6420eb7ce4727a6c6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.