📄 pfildrv.c
字号:
/* * Copyright (C) 2000, 2003 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */#include <sys/conf.h>#include <sys/debug.h>#include <sys/atomic.h>#include <sys/ethernet.h>#include <sys/stream.h>#include <sys/errno.h>#include <sys/socket.h>#include <sys/sockio.h>#include <sys/cred.h>#include <sys/modctl.h>#include <sys/devops.h>#include <sys/ddi.h>#include <sys/sunddi.h>#include <sys/stat.h>#include <sys/cmn_err.h>#include <sys/dlpi.h>#include <sys/kmem.h>#include <sys/strsun.h>#include <net/if.h>#include <net/if_dl.h>#include <inet/common.h>#include <inet/nd.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <netinet/udp.h>#include <netinet/ip_icmp.h>#if SOLARIS2 >= 8# include <netinet/ip6.h>#endif#undef IPOPT_EOL#undef IPOPT_NOP#undef IPOPT_RR#undef IPOPT_LSRR#undef IPOPT_SSRR#include <inet/ip.h>#include <inet/ip_if.h>#include "compat.h"#include "qif.h"#include "pfil.h"#undef USE_SERVICE_ROUTINE#define MINSDUSZ 1#define MAXSDUSZ INFPSZchar _depends_on[] = "drv/ip";static struct module_info pfil_minfo = { 0x534b, "pfil", MINSDUSZ, MAXSDUSZ, 0, 0};krwlock_t pfil_rw;int pfildebug = 0;/************************************************************************ * STREAMS device information (/dev/pfil) */static int pfildevopen(queue_t *, dev_t *, int, int, cred_t *);static int pfildevclose(queue_t *, int, cred_t *);static struct qinit pfil_rinit = { NULL, NULL, pfildevopen, pfildevclose, NULL, &pfil_minfo, NULL};static struct qinit pfil_winit = { (pfi_t)pfilwput, NULL, NULL, NULL, NULL, &pfil_minfo, NULL};struct streamtab pfil_dev_strtab = { &pfil_rinit, &pfil_winit};extern int nulldev();extern int nodev();void pfil_donotip(int, qif_t *, queue_t *, mblk_t *, mblk_t *, struct ip *, size_t);static int pfil_info(dev_info_t *, ddi_info_cmd_t , void *, void **);static int pfil_attach(dev_info_t *, ddi_attach_cmd_t);#if SOLARIS2 < 10static int pfil_identify(dev_info_t *);#endifstatic int pfil_detach(dev_info_t *, ddi_detach_cmd_t);#ifdef DDI_DEFINE_STREAM_OPSDDI_DEFINE_STREAM_OPS(pfil_devops, nulldev, nulldev, pfil_attach, pfil_detach, nulldev, pfil_info, D_MP, &pfil_dev_strtab);#elsestatic struct cb_ops pfil_ops = { nodev, /* cb_open */ nodev, /* cb_close */ nodev, /* cb_strategy */ nodev, /* cb_print */ nodev, /* cb_dump */ nodev, /* cb_read */ nodev, /* cb_write */ nodev, /* cb_ioctl */ nodev, /* cb_devmap */ nodev, /* cb_mmap */ nodev, /* cb_segmap */ nochpoll, /* cb_chpoll */ ddi_prop_op, /* cb_prop_op */ &pfilinfo, /* cb_stream */ D_MP /* cb_flag */};static struct dev_ops pfil_devops = { DEVO_REV, /* devo_rev */ 0, /* devo_refcnt */ pfil_info, /* devo_getinfo */#if SOLARIS2 >= 10 nulldev,#else pfil_identify, /* devo_identify */#endif nulldev, /* devo_probe */ pfil_attach, /* devo_attach */ pfil_detach, /* devo_detach */ nodev, /* devo_reset */ &pfil_ops, /* devo_cb_ops */ NULL /* devo_bus_ops */};#endifstatic struct modldrv modldrv = { &mod_driverops, "pfil Streams driver "/**/PFIL_RELEASE, &pfil_devops};/************************************************************************ * STREAMS module information */static int pfilmodopen(queue_t *, dev_t *, int, int, cred_t *);static int pfilmodclose(queue_t *, int, cred_t *);static struct qinit pfilmod_rinit = { (pfi_t)pfilmodrput, NULL, pfilmodopen, pfilmodclose, NULL, &pfil_minfo, NULL};static struct qinit pfilmod_winit = { (pfi_t)pfilmodwput, NULL, NULL, NULL, NULL, &pfil_minfo, NULL};struct streamtab pfil_mod_strtab = { &pfilmod_rinit, &pfilmod_winit};static struct fmodsw fsw = { "pfil", &pfil_mod_strtab, D_MP};static struct modlstrmod modlstrmod = { &mod_strmodops, "pfil Streams module "/**/PFIL_RELEASE, &fsw};/************************************************************************ * STREAMS externally visible information for _init() and _info () */static struct modlinkage modlinkage = { MODREV_1, { (void *)&modlstrmod, (void *)&modldrv, NULL }};/************************************************************************ * STREAMS device functions */static dev_info_t *pfil_dev_info;/* ------------------------------------------------------------------------ *//* Function: pfil_attach *//* Returns: int - DDI_SUCCESS for success, otherwise DDI_FAILURE *//* Parameters: devi(I) - pointer to packet information *//* cmd(I) - DDI command to process *//* *//* Called when the driver has been attached, just create the device file. *//* ------------------------------------------------------------------------ *//*ARGUSED*/static int pfil_attach(dev_info_t *devi, ddi_attach_cmd_t cmd){ /* LINTED: E_CONSTANT_CONDITION */ PRINT(3,(CE_CONT, "!pfil_attach(%p,%x)\n", (void *)devi, cmd)); if (cmd != DDI_ATTACH) return (DDI_FAILURE); pfil_dev_info = devi; return (ddi_create_minor_node(devi, "pfil", S_IFCHR, 0, NULL, 0));}/* ------------------------------------------------------------------------ *//* Function: pfil_detach *//* Returns: int - DDI_SUCCESS for success, otherwise DDI_FAILURE *//* Parameters: devi(I) - pointer to device information *//* cmd(I) - DDI command to process *//* *//* Nothing to do here(?) except return that everything is ok. *//* ------------------------------------------------------------------------ *//*ARGUSED*/static int pfil_detach(dev_info_t *devi, ddi_detach_cmd_t cmd){ /* LINTED: E_CONSTANT_CONDITION */ PRINT(3,(CE_CONT, "!pfil_detach(%p,%x)\n", (void *)devi, cmd)); if (cmd != DDI_DETACH) return (DDI_FAILURE); ASSERT(devi == pfil_dev_info); ddi_remove_minor_node(devi, NULL); return (DDI_SUCCESS);}/* ------------------------------------------------------------------------ *//* Function: pfil_info *//* Returns: int - DDI_SUCCESS (success), DDI_FAILURE (failure) *//* Parameters: dip(I) - pointer to device information *//* cmd(I) - DDI command to process *//* arg(I) - paramter to the command to be processed *//* res(O) - pointer to storage for returning results *//* *//* Handles information queries made by the kernel of the STREAMS device. *//* ------------------------------------------------------------------------ *//*ARGUSED*/static int pfil_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **res){ int result = DDI_FAILURE; /* LINTED: E_CONSTANT_CONDITION */ PRINT(3,(CE_CONT, "!pfil_info(%p,%x,%p,%p)\n", (void *)dip, infocmd, arg, (void *)res)); switch (infocmd) { case DDI_INFO_DEVT2DEVINFO: if (pfil_dev_info != NULL) { *res = (void *)pfil_dev_info; result = DDI_SUCCESS; } break; case DDI_INFO_DEVT2INSTANCE: *res = NULL; result = DDI_SUCCESS; break; default : break; } return result;}#if SOLARIS2 < 10/* ------------------------------------------------------------------------ *//* Function: pfil_identify *//* Returns: int - DDI_IDENTIFIED (success), DDI_NOT_IDENTIFIED (failure)*//* Parameters: devi(I) - pointer to a dev_info structure *//* *//* Check to see if this module is correctly associated with the device info *//* structure passed in. *//* ------------------------------------------------------------------------ */static int pfil_identify(dev_info_t *devi){ int result = DDI_NOT_IDENTIFIED; /*LINTED: E_CONSTANT_CONDITION*/ PRINT(3,(CE_CONT, "!pfil_identify(%p)\n", (void *)devi)); if (strcmp((char *)ddi_get_name(devi), "!pfil") == 0) result = DDI_IDENTIFIED; return result;}#endif/* ------------------------------------------------------------------------ *//* Function: pfildevopen *//* Returns: int - 0 == sucess, else failure *//* Parameters: q(I) - pointer to STREAMS queue *//* devp(I) - pointer to a device number *//* oflag(I) - file mode open flags (always 0 for module opens) *//* sflag(I) - flag indicating how the open is being made *//* crp(I) - pointer to message credentials from the user *//* *//* Perform any action required to open the STREAMS device, supporting it *//* being opened in a cloning fashion. *//* ------------------------------------------------------------------------ *//*ARGSUSED*/static int pfildevopen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp){ int result = 0; /* LINTED: E_CONSTANT_CONDITION */ PRINT(3,(CE_CONT, "!pfildevopen(%p,%p,%x,%x,%p) [%s]\n", (void *)q, (void *)devp, oflag, sflag, (void *)crp, QTONM(q))); /* * As per recommendation on man page open(9e) */ if ((sflag & MODOPEN) != 0) result = ENXIO; if (result == 0) qprocson(q); return result;}/* ------------------------------------------------------------------------ *//* Function: pfildevclose *//* Returns: int - always returns 0. *//* Parameters: q(I) - pointer to STREAMS queue *//* flag(I) - file status flag *//* crp(I) - pointer to message credentials from the user *//* *//* Perform any action required to close the STREAMS device. *//* ------------------------------------------------------------------------ *//*ARGSUSED*/static int pfildevclose(queue_t *q, int flag, cred_t *crp){ /* LINTED: E_CONSTANT_CONDITION */ PRINT(3,(CE_CONT, "!pfildevclose(%p,%x,%p) [%s]\n", (void *)q, flag, (void *)crp, QTONM(q))); qprocsoff(q);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -