1120386Ssam/* $FreeBSD$ */ 2120386Ssam/* $NetBSD: pfil.h,v 1.22 2003/06/23 12:57:08 martin Exp $ */ 360317Sdarrenr 4139823Simp/*- 560317Sdarrenr * Copyright (c) 1996 Matthew R. Green 660317Sdarrenr * All rights reserved. 760317Sdarrenr * 860317Sdarrenr * Redistribution and use in source and binary forms, with or without 960317Sdarrenr * modification, are permitted provided that the following conditions 1060317Sdarrenr * are met: 1160317Sdarrenr * 1. Redistributions of source code must retain the above copyright 1260317Sdarrenr * notice, this list of conditions and the following disclaimer. 1360317Sdarrenr * 2. Redistributions in binary form must reproduce the above copyright 1460317Sdarrenr * notice, this list of conditions and the following disclaimer in the 1560317Sdarrenr * documentation and/or other materials provided with the distribution. 1660317Sdarrenr * 3. The name of the author may not be used to endorse or promote products 1760317Sdarrenr * derived from this software without specific prior written permission. 1860317Sdarrenr * 1960317Sdarrenr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2060317Sdarrenr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2160317Sdarrenr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2260317Sdarrenr * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2360317Sdarrenr * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2460317Sdarrenr * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2560317Sdarrenr * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2660317Sdarrenr * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2760317Sdarrenr * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2860317Sdarrenr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2960317Sdarrenr * SUCH DAMAGE. 3060317Sdarrenr */ 3160317Sdarrenr 3260317Sdarrenr#ifndef _NET_PFIL_H_ 3360317Sdarrenr#define _NET_PFIL_H_ 3460317Sdarrenr 35120386Ssam#include <sys/systm.h> 36130731Sbde#include <sys/queue.h> 37120386Ssam#include <sys/_lock.h> 38120386Ssam#include <sys/_mutex.h> 39155226Scsjp#include <sys/lock.h> 40173904Smlaier#include <sys/rmlock.h> 4160317Sdarrenr 4260317Sdarrenrstruct mbuf; 4360317Sdarrenrstruct ifnet; 44135920Smlaierstruct inpcb; 4560317Sdarrenr 46254769Sandretypedef int (*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int, 47254769Sandre struct inpcb *); 48254769Sandre 4960317Sdarrenr/* 5060317Sdarrenr * The packet filter hooks are designed for anything to call them to 51254773Sandre * possibly intercept the packet. Multiple filter hooks are chained 52254773Sandre * together and after each other in the specified order. 5360317Sdarrenr */ 5460317Sdarrenrstruct packet_filter_hook { 55254777Sandre TAILQ_ENTRY(packet_filter_hook) pfil_chain; 56254777Sandre pfil_func_t pfil_func; 57254777Sandre void *pfil_arg; 5860317Sdarrenr}; 5960317Sdarrenr 6060317Sdarrenr#define PFIL_IN 0x00000001 6160317Sdarrenr#define PFIL_OUT 0x00000002 6260317Sdarrenr#define PFIL_WAITOK 0x00000004 6360317Sdarrenr#define PFIL_ALL (PFIL_IN|PFIL_OUT) 6460317Sdarrenr 65254773Sandretypedef TAILQ_HEAD(pfil_chain, packet_filter_hook) pfil_chain_t; 6660317Sdarrenr 67120386Ssam#define PFIL_TYPE_AF 1 /* key is AF_* type */ 68120386Ssam#define PFIL_TYPE_IFNET 2 /* key is ifnet pointer */ 69120386Ssam 70241888Smelifaro#define PFIL_FLAG_PRIVATE_LOCK 0x01 /* Personal lock instead of global */ 71241888Smelifaro 72254773Sandre/* 73254773Sandre * A pfil head is created by each protocol or packet intercept point. 74254773Sandre * For packet is then run through the hook chain for inspection. 75254773Sandre */ 7660317Sdarrenrstruct pfil_head { 77254777Sandre pfil_chain_t ph_in; 78254777Sandre pfil_chain_t ph_out; 79254777Sandre int ph_type; 80254777Sandre int ph_nhooks; 81210121Sluigi#if defined( __linux__ ) || defined( _WIN32 ) 82254777Sandre rwlock_t ph_mtx; 83210121Sluigi#else 84241888Smelifaro struct rmlock *ph_plock; /* Pointer to the used lock */ 85254777Sandre struct rmlock ph_lock; /* Private lock storage */ 86254777Sandre int flags; 87210121Sluigi#endif 88120386Ssam union { 89254777Sandre u_long phu_val; 90254777Sandre void *phu_ptr; 91120386Ssam } ph_un; 92254777Sandre#define ph_af ph_un.phu_val 93254777Sandre#define ph_ifnet ph_un.phu_ptr 94120386Ssam LIST_ENTRY(pfil_head) ph_list; 9585305Sru}; 9660317Sdarrenr 97254773Sandre/* Public functions for pfil hook management by packet filters. */ 98254773Sandrestruct pfil_head *pfil_head_get(int, u_long); 99254769Sandreint pfil_add_hook(pfil_func_t, void *, int, struct pfil_head *); 100254769Sandreint pfil_remove_hook(pfil_func_t, void *, int, struct pfil_head *); 101254777Sandre#define PFIL_HOOKED(p) ((p)->ph_nhooks > 0) 102254773Sandre 103254773Sandre/* Public functions to run the packet inspection by protocols. */ 104120386Ssamint pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *, 105135920Smlaier int, struct inpcb *inp); 10660317Sdarrenr 107254773Sandre/* Public functions for pfil head management by protocols. */ 108254773Sandreint pfil_head_register(struct pfil_head *); 109254773Sandreint pfil_head_unregister(struct pfil_head *); 110254773Sandre 111254777Sandre/* Public pfil locking functions for self managed locks by packet filters. */ 112241888Smelifarostruct rm_priotracker; /* Do not require including rmlock header */ 113254777Sandreint pfil_try_rlock(struct pfil_head *, struct rm_priotracker *); 114254777Sandrevoid pfil_rlock(struct pfil_head *, struct rm_priotracker *); 115254777Sandrevoid pfil_runlock(struct pfil_head *, struct rm_priotracker *); 116254777Sandrevoid pfil_wlock(struct pfil_head *); 117254777Sandrevoid pfil_wunlock(struct pfil_head *); 118254777Sandreint pfil_wowned(struct pfil_head *ph); 119241888Smelifaro 120254777Sandre/* Internal pfil locking functions. */ 121241888Smelifaro#define PFIL_LOCK_INIT_REAL(l, t) \ 122241888Smelifaro rm_init_flags(l, "PFil " t " rmlock", RM_RECURSE) 123241888Smelifaro#define PFIL_LOCK_DESTROY_REAL(l) \ 124241888Smelifaro rm_destroy(l) 125241888Smelifaro#define PFIL_LOCK_INIT(p) do { \ 126241888Smelifaro if ((p)->flags & PFIL_FLAG_PRIVATE_LOCK) { \ 127241888Smelifaro PFIL_LOCK_INIT_REAL(&(p)->ph_lock, "private"); \ 128241888Smelifaro (p)->ph_plock = &(p)->ph_lock; \ 129241888Smelifaro } else \ 130241888Smelifaro (p)->ph_plock = &V_pfil_lock; \ 131241888Smelifaro} while (0) 132241888Smelifaro#define PFIL_LOCK_DESTROY(p) do { \ 133241888Smelifaro if ((p)->flags & PFIL_FLAG_PRIVATE_LOCK) \ 134241888Smelifaro PFIL_LOCK_DESTROY_REAL((p)->ph_plock); \ 135241888Smelifaro} while (0) 136254777Sandre 137248490Sae#define PFIL_TRY_RLOCK(p, t) rm_try_rlock((p)->ph_plock, (t)) 138248490Sae#define PFIL_RLOCK(p, t) rm_rlock((p)->ph_plock, (t)) 139248490Sae#define PFIL_WLOCK(p) rm_wlock((p)->ph_plock) 140248490Sae#define PFIL_RUNLOCK(p, t) rm_runlock((p)->ph_plock, (t)) 141248490Sae#define PFIL_WUNLOCK(p) rm_wunlock((p)->ph_plock) 142248490Sae#define PFIL_WOWNED(p) rm_wowned((p)->ph_plock) 143155201Scsjp 144254774Sandre/* Internal locking macros for global/vnet pfil_head_list. */ 145254774Sandre#define PFIL_HEADLIST_LOCK() mtx_lock(&pfil_global_lock) 146254774Sandre#define PFIL_HEADLIST_UNLOCK() mtx_unlock(&pfil_global_lock) 147254774Sandre 14860317Sdarrenr#endif /* _NET_PFIL_H_ */ 149