📄 pfil.c
字号:
/* * Copyright (C) 2000, 2003 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * ident "@(#)$Id: pfil.c,v 1.27 2003/11/30 09:45:57 darrenr Exp $" * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */#ifndef __hpux#pragma ident "@(#)$Id: pfil.c,v 1.27 2003/11/30 09:45:57 darrenr Exp $"#elsestruct uio;#endif#include <sys/systm.h>#include <sys/types.h>#include <sys/param.h>#include <sys/errno.h>#include <sys/uio.h>#include <sys/buf.h>#include <sys/conf.h>#include <sys/cmn_err.h>#include <sys/stat.h>#include <sys/stream.h>#include <sys/poll.h>#include <sys/byteorder.h>#include <sys/socket.h>#ifdef sun# include <sys/kmem.h>#endif#include <sys/dlpi.h>#include <sys/lock.h>#include <sys/stropts.h>#include <net/if.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#ifdef sun# include <inet/common.h># if SOLARIS2 >= 8# include <netinet/ip6.h># endif# undef IPOPT_EOL# undef IPOPT_NOP# undef IPOPT_LSRR# undef IPOPT_SSRR# undef IPOPT_RR# include <inet/ip.h>#endif#include "compat.h"#include "qif.h"#include "pfil.h"int pfil_delayed_copy = 1;int pfilinterface = PFIL_INTERFACE;/*** HPUX Port** Align these structs to 16 bytes** so that the embedded locks (first member)** are 16 byte aligned*/#ifdef __hpux#pragma align 16struct pfil_head pfh_inet4 = { 0, NULL, NULL, 0 };#pragma align 16struct pfil_head pfh_inet6 = { 0, NULL, NULL, 0 };#pragma align 16struct pfil_head pfh_sync = { 0, NULL, NULL, 0 };#elsestruct pfil_head pfh_inet4;struct pfil_head pfh_inet6;struct pfil_head pfh_sync;#endifstatic int pfil_list_add(pfil_list_t *, int (*) __P((struct ip *, int, void *, int, void *, mblk_t **)), int);static int pfil_list_remove(pfil_list_t *, int (*) __P((struct ip *, int, void *, int, void *, mblk_t **)));/* ------------------------------------------------------------------------ *//* Function: pfil_report *//* Returns: int - always returns 0 *//* Parameters: q(I) - pointer to queue *//* mp(I) - pointer to mblk *//* arg(I) - pointer to value to retrieve *//* cred(I) - pointer to credential information *//* *//* Returns a list of the registered callbacks for processing packets going *//* in and out on a particular filtering head structure *//* ------------------------------------------------------------------------ */#if !defined(sun) || (SOLARIS2 <= 8)/*ARGSUSED*/int pfil_report(queue_t *q, mblk_t *mp, caddr_t arg)#else/*ARGSUSED*/int pfil_report(queue_t *q, mblk_t *mp, caddr_t arg, cred_t *cred)#endif{ packet_filter_hook_t *p; pfil_head_t *ph; ph = (pfil_head_t *)arg; READ_ENTER(&ph->ph_lock); (void) mi_mpprintf(mp, "in"); (void) mi_mpprintf(mp, "function\tflags"); for (p = ph->ph_in.pfl_top; p; p = p->pfil_next) (void) mi_mpprintf(mp,"%p\t%x", (void *)p->pfil_func, p->pfil_flags); (void) mi_mpprintf(mp, "out"); (void) mi_mpprintf(mp, "function\tflags"); for (p = ph->ph_out.pfl_top; p; p = p->pfil_next) (void) mi_mpprintf(mp,"%p\t%x", (void *)p->pfil_func, p->pfil_flags); RW_EXIT(&ph->ph_lock); return 0;}/* ------------------------------------------------------------------------ *//* Function: pfil_init *//* Returns: void *//* Parameters: ph(I) - pointer to pfil head structure *//* *//* Initialise a pfil_head structure. *//* ------------------------------------------------------------------------ */voidpfil_init(ph) struct pfil_head *ph;{#ifdef sun rw_init(&ph->ph_lock, "pfil head", RW_DRIVER, NULL);#endif#ifdef __hpux initlock(&ph->ph_lock, PFIL_SMAJ, 1020, "pfil head");#endif ph->ph_in.pfl_top = NULL; ph->ph_in.pfl_tail = &ph->ph_in.pfl_top; ph->ph_out.pfl_top = NULL; ph->ph_out.pfl_tail = &ph->ph_out.pfl_top; ph->ph_init = 1;}/* ------------------------------------------------------------------------ *//* Function: pfil_add_hook *//* Returns: int - 0 == success, else error. *//* Parameters: func(I) - function pointer to add *//* flags(I) - flags describing for which events to call the *//* passed function *//* ph(I) - pointer to callback head structure *//* *//* This function is the public interface for adding a callback function to *//* a list of callbacks for a particular protocol head (ph). *//* *//* pfil_add_hook() adds a function to the packet filter hook. the *//* flags are: *//* PFIL_IN call me on incoming packets *//* PFIL_OUT call me on outgoing packets *//* PFIL_WAITOK OK to call malloc and wait whilst adding this hook *//* ------------------------------------------------------------------------ */intpfil_add_hook(func, flags, ph) int (*func) __P((struct ip *, int, void *, int, void *, mblk_t **)); int flags; struct pfil_head *ph;{ int err = 0; ASSERT((flags & ~(PFIL_IN|PFIL_OUT|PFIL_WAITOK)) == 0); if (ph->ph_init == 0) pfil_init(ph); WRITE_ENTER(&ph->ph_lock); if (flags & PFIL_IN) err = pfil_list_add(&ph->ph_in, func, flags); if ((err == 0) && (flags & PFIL_OUT)) err = pfil_list_add(&ph->ph_out, func, flags); RW_EXIT(&ph->ph_lock); return err;}/* ------------------------------------------------------------------------ *//* Function: pfil_list_add *//* Returns: int - 0 == success, else error. *//* Parameters: list(I) - pfil list pointer *//* func(I) - function pointer to add *//* flags(I) - flags describing for which events to call the *//* passed function *//* Write Locks: list's owner *//* *//* Adds the function (func) to the end of the list of functions. *//* ------------------------------------------------------------------------ */static intpfil_list_add(list, func, flags) pfil_list_t *list; int (*func) __P((struct ip *, int, void *, int, void *, mblk_t **)); int flags;{ struct packet_filter_hook *pfh; int wait; wait = flags & PFIL_WAITOK ? KM_SLEEP : KM_NOSLEEP; KMALLOC(pfh, struct packet_filter_hook *, sizeof(*pfh), wait); if (pfh == NULL) return ENOMEM; pfh->pfil_func = func; pfh->pfil_flags = flags; /* * insert the input list in reverse order of the output list * so that the hooks are called in the reverse order for each * direction. So if it was A,B,C for input, it is C,B,A for output. */ if (flags & PFIL_OUT) { pfh->pfil_pnext = list->pfl_tail; *list->pfl_tail = pfh; list->pfl_tail = &pfh->pfil_next; } else if (flags & PFIL_IN) { pfh->pfil_pnext = &list->pfl_top; pfh->pfil_next = list->pfl_top; list->pfl_top = pfh; if (pfh->pfil_next == NULL) list->pfl_tail = &pfh->pfil_next; } return 0;}/* ------------------------------------------------------------------------ *//* Function: pfil_remove_hook *//* Returns: int - 0 == success, else error. *//* Parameters: func(I) - function pointer to remove *//* flags(I) - flags describing for which events to call the *//* passed function *//* ph(I) - pointer to callback head structure *//* *//* pfil_remove_hook removes a specific function from a particular *//* pfil_head's list of callbacks as given by which flags have been passed. *//* ------------------------------------------------------------------------ */intpfil_remove_hook(func, flags, ph) int (*func) __P((struct ip *, int, void *, int, void *, mblk_t **)); int flags; struct pfil_head *ph;{ int err = 0; ASSERT((flags & ~(PFIL_IN|PFIL_OUT)) == 0); if (ph->ph_init == 0) pfil_init(ph); WRITE_ENTER(&ph->ph_lock); if (flags & PFIL_IN) err = pfil_list_remove(&ph->ph_in, func); if ((err == 0) && (flags & PFIL_OUT)) err = pfil_list_remove(&ph->ph_out, func); RW_EXIT(&ph->ph_lock); return err;}/* ------------------------------------------------------------------------ *//* Function: pfil_list_remove *//* Returns: int - 0 == success, else error. *//* Parameters: list(I) - pfil list pointer *//* func(I) - function pointer to remove *//* Write Locks: list's owner *//* *//* pfil_list_remove is an internal function that takes a function off the *//* specified pfil list, providing that a match for func is found. *//* ------------------------------------------------------------------------ */static intpfil_list_remove(list, func) pfil_list_t *list; int (*func) __P((struct ip *, int, void *, int, void *, mblk_t **));{ struct packet_filter_hook *pfh; for (pfh = list->pfl_top; pfh; pfh = pfh->pfil_next) if (pfh->pfil_func == func) { *pfh->pfil_pnext = pfh->pfil_next; if (list->pfl_tail == &pfh->pfil_next) list->pfl_tail = pfh->pfil_pnext; KMFREE(pfh, sizeof(*pfh)); return 0; } return ESRCH;}/* ------------------------------------------------------------------------ *//* Function: pfil_hook_get *//* Returns: struct packet_filter_hook * - pointer to first member in *//* list of callbacks or NULL if *//* if there are none. *//* Parameters: flags(I) - indicates which callback list to return */ /* ph(I) - pointer to callback head structure *//* Locks: READ(ph->ph_lock) *//* *//* Returns the first pointer of the list associated with "flags" or NULL if *//* flags is not a recognised value. *//* ------------------------------------------------------------------------ */struct packet_filter_hook *pfil_hook_get(flag, ph) int flag; struct pfil_head *ph;{ /* ASSERT(rw_read_locked(&ph->ph_lock) != 0); */ if (ph->ph_init != 0) { switch (flag) { case PFIL_IN: return ph->ph_in.pfl_top; case PFIL_OUT: return ph->ph_out.pfl_top; } } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -