⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bpfdrv.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* bpfDrv.c - Berkeley Packet Filter (BPF) I/O driver library *//* Copyright 1999 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 *	The Regents of the University of California.  All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)bpf.c	7.5 (Berkeley) 7/15/91 * * static char rcsid[] = * "$Header: bpf.c,v 1.67 96/09/26 22:00:52 leres Exp $"; *//*modification history--------------------01f,07may02,wap  Correctly initialize filter length (SPR #74358)01e,26mar02,wap  remember to call _bpfDevUnlock() when bpfIfSet() exits with                 error (SPR #74039)01d,17nov00,spm  added support for BSD Ethernet devices01c,24apr00,spm  updated to use NPT version of MUX cookie01b,05apr00,spm  added interfaces to suspend filtering and remove I/O device01a,24nov99,spm  created from BSD bpf.c,v 1.67 96/09/26 22:00:52*//*DESCRIPTIONThis library provides a driver which supports the customized retrieval ofincoming network data that meets the criteria imposed by a user-specifiedfilter.USER-CALLABLE ROUTINESThe bpfDrv() routine initializes the driver and the bpfDevCreate() routinecreates a packet filter device. Each BPF device allows direct access to theincoming data from one or more network interfaces.CREATING BPF DEVICESIn order to retrieve incoming network data, a BPF device must be created bycalling the bpfDevCreate() routine:.CS    STATUS bpfDevCreate        (        char *  pDevName,       /@ I/O system device name @/        int     numUnits,       /@ number of device units @/        int     bufSize         /@ block size for the BPF device @/        ).CEThe <numUnits> parameter specifies the maximum number of BPF units forthe device. Each unit is accessed through a separate file descriptorfor use with a unique filter and/or a different network interface. Forexample, the following call creates the "/bpf0" and "/bpf1" units:.CS    bpfDevCreate ("/bpf", 2, 4096);.CECONFIGURING BPF DEVICESAfter opening a device unit, the associated file descriptor must be bound toa specific network interface with the BIOCSETIF ioctl() option. The BIOCSETFioctl() option adds any filter instructions. Each file descriptor receivesa copy of any data which matches the filter. Different file descriptors mayshare the same interface. The underlying filters will receive an identicaldata stream.IOCTL FUNCTIONSThe BPF driver supports the following ioctl() functions:NOTEWhen reading data from BPF units, the supplied buffer must be able toaccept an entire block of data as defined by the <bufSize> parameter tothe bpfDevCreate() routine. That value is also available with the BIOCGBLENioctl() option described above.INCLUDE FILES: bpfDrv.hSEE ALSO: ioLib*//* includes */#include "vxWorks.h"#include "stdlib.h"#include "stdio.h"#include "string.h"#include "ctype.h" 	/* isdigit() declaration */#include "iosLib.h"#include "taskLib.h"#include "semLib.h"#include "tickLib.h"#include "errnoLib.h"#include "objLib.h"#include "sysLib.h"#include "net/if.h"#include "netLib.h"#include "net/bpf.h"#include "private/bpfLibP.h"#include "private/muxLibP.h"    /* PCOOKIE_TO_ENDOBJ conversion macro *//* defines */#define DEBUG#define ROTATE_BUFFERS(pBpfDev) \     (pBpfDev)->readHoldBuf = (pBpfDev)->recvStoreBuf; \     (pBpfDev)->readHoldLen = (pBpfDev)->recvStoreLen; \     (pBpfDev)->recvStoreBuf = (pBpfDev)->freeBuf;     \     (pBpfDev)->recvStoreLen = 0;                      \     (pBpfDev)->freeBuf = NULL;#define BPF_DEV_NAME "/dev/bpf"#ifdef DEBUG#undef LOCAL#define LOCAL#endif /* DEBUG */#define BPF_BUFSIZE 4096         /* default BPF buffer size */   /* globals *//* locals */LOCAL int 	bpfDrvNum = 0; 	 /* BPF driver number */LOCAL int 	bpfDrvCount = 0; /* Number of BPF driver users */LOCAL int bpfLockTaskId = 0;     /* ID of task holding global BPF lock */LOCAL SEM_ID bpfLockSemId;       /* Semaphore ID for global BPF lock */LOCAL int          numBpfDevs;   /* The number of allocated BPF devices */LOCAL BPF_DEV_CTRL * pBpfDevTbl; /* BPF device descriptor table */LOCAL UINT         bpfBufSize = BPF_BUFSIZE;   /* default BPF buffer size *//* forward declarations */LOCAL int bpfOpen (BPF_DEV_HDR * pBpfDevHdr, char * minorDevStr, int flags);LOCAL int bpfClose (BPF_DEV_CTRL * pBpfDev);LOCAL int bpfRead (BPF_DEV_CTRL * pBpfDev, char * pBuf, int nBytes);LOCAL int bpfWrite (BPF_DEV_CTRL * pBpfDev, char * pBuf, int nBytes);LOCAL STATUS bpfIoctl (BPF_DEV_CTRL * pBpfDev, int request, void * addr);LOCAL void bpfWakeup (BPF_DEV_CTRL * pBpfDev);LOCAL int bpfSleep (BPF_DEV_CTRL * pBpfDev, int numTicks);LOCAL void bpfTimeStamp (struct timeval * pTimeval);LOCAL STATUS bpfBufsAlloc (BPF_DEV_CTRL * pBpfDev);LOCAL void bpfDevReset (BPF_DEV_CTRL * pBpfDev);LOCAL STATUS bpfIfSet (BPF_DEV_CTRL * pBpfDev, struct ifreq * pIfReq,                        BOOL restartFlag);LOCAL void bpfSelectAdd (BPF_DEV_CTRL *, SEL_WAKEUP_NODE *);LOCAL void bpfSelectDelete (BPF_DEV_CTRL *, SEL_WAKEUP_NODE *);LOCAL int bpfSetFilter (BPF_DEV_CTRL * pBpfDev, struct bpf_program * pBpfProg);LOCAL void bpfDevReset (BPF_DEV_CTRL * pBpfDev);LOCAL void bpfDevFree (FAST BPF_DEV_CTRL * pBpfDev);LOCAL void bpfPacketCatch (FAST BPF_DEV_CTRL * pBpfDev, FAST M_BLK_ID pMBlk,                            FAST int snapLen, FAST int bpfHdrLen,                            struct timeval * pTimeVal, FAST int linkHdrLen);/********************************************************************************* bpfDrv - initialize the BPF driver* * This routine installs the Berkeley Packet Filter driver for access through* the I/O system. It is required before performing any I/O operations and is* executed automatically if INCLUDE_BPF is defined at the time the system* is built. Subsequent calls to the routine just count the number of users* with BPF access.** RETURNS: OK, or ERROR if initialization fails.** ERRNO: N/A*/STATUS bpfDrv (void)    {    /*     * For additional calls to this installation routine,     * just increase the number of users.     */    if (bpfDrvNum)        {        bpfDrvCount++;        return (OK);        }    bpfLockSemId = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE                                | SEM_INVERSION_SAFE);    if (bpfLockSemId == NULL)        {        return (ERROR);        }        bpfDrvNum = iosDrvInstall (NULL, NULL, bpfOpen, bpfClose,                               bpfRead, bpfWrite, bpfIoctl);    if (bpfDrvNum == ERROR)        {        bpfDrvNum = 0;        return (ERROR);        }    bpfDrvCount++;    return (OK);    }/********************************************************************************* bpfDrvRemove - remove BPF driver support* * This routine uninstalls the Berkeley Packet Filter driver, preventing* further access through the I/O system. It may only be called once to* reverse a particular installation with the bpfDrv initialization routine.* It has no effect if any other users retain BPF access through a separate* installation. The driver is also not removed if any BPF file descriptors* are currently open.** RETURNS: OK, or ERROR if removal fails.** ERRNO: S_ioLib_NO_DRIVER** NOMANUAL*/STATUS bpfDrvRemove (void)    {    STATUS result;    if (bpfDrvNum == 0)        {        errnoSet (S_ioLib_NO_DRIVER);        return (ERROR);        }    /* Decrease the number of users. Attempt removal if zero. */    bpfDrvCount--;    if (bpfDrvCount > 0)     /* Other users have access - do not remove. */        return (OK);    if (bpfDrvCount < 0)     /* Mismatched calls to remove routine. */        {        bpfDrvCount = 0;        return (ERROR);        }    /* Remove driver if no open files exist. */    result = iosDrvRemove (bpfDrvNum, FALSE);    if (result == ERROR) 	/* Error: open files found.*/        {        bpfDrvCount = 1;     /* Allows removal attempt after closing files. */        return (ERROR);        }    /* Driver removed from I/O system. Remove global lock and reset number. */    semDelete (bpfLockSemId);    bpfDrvNum = 0;    return (OK);    }/********************************************************************************* bpfDevCreate - create Berkeley Packet Filter device** This routine creates a Berkeley Packet Filter device. Each of the* <numUnits> units corresponds to a single available file descriptor for* monitoring a network device. The <pDevName> parameter provides the name* of the BPF device to the I/O system. The default name of "/bpf" (assigned* if <pDevName> is NULL) produces units named "/bpf0", "/bpf1", etc., up to* the <numUnits> limit.** RETURNS: OK, or ERROR if device creation failed.** ERRNO: S_ioLib_NO_DRIVER*/STATUS bpfDevCreate    (    char * 	pDevName, 	/* I/O system device name */    int 	numUnits,       /* number of device units */    int 	bufSize 	/* BPF device block size (0 for default) */    )    {    BPF_DEV_HDR * pBpfDevHdr;   /* I/O system device header for BPF units */    if (bpfDrvNum == 0)        {        errnoSet (S_ioLib_NO_DRIVER);        return (ERROR);        }    if (numUnits <= 0)        {        return (ERROR);        }    pBpfDevHdr = (BPF_DEV_HDR *)malloc (sizeof (BPF_DEV_HDR));    if (pBpfDevHdr == NULL)        {        return (ERROR);        }    pBpfDevHdr->lockSem = semBCreate (SEM_Q_FIFO, SEM_FULL);    if (pBpfDevHdr->lockSem == NULL)        {        free (pBpfDevHdr);        return (ERROR);        }    pBpfDevHdr->pBpfDevTbl = calloc (numUnits, sizeof (BPF_DEV_CTRL));    if (pBpfDevHdr->pBpfDevTbl == NULL)        {        free (pBpfDevHdr);        semDelete (pBpfDevHdr->lockSem);        return (ERROR);        }    pBpfDevHdr->pBpfNetIfTbl = calloc (numUnits, sizeof (BPF_PROTO_CTRL));    if (pBpfDevHdr->pBpfDevTbl == NULL)        {        free (pBpfDevHdr->pBpfDevTbl);         free (pBpfDevHdr);        semDelete (pBpfDevHdr->lockSem);        return (ERROR);        }    if (pDevName == NULL)        pDevName = BPF_DEV_NAME;    if (iosDevAdd ( (DEV_HDR *) pBpfDevHdr, pDevName, bpfDrvNum) != OK)        {        free (pBpfDevHdr->pBpfNetIfTbl);        free (pBpfDevHdr->pBpfDevTbl);        free (pBpfDevHdr);        semDelete (pBpfDevHdr->lockSem);        return (ERROR);        }    pBpfDevHdr->numDevs = numUnits;    pBpfDevHdr->bufSize = (bufSize <= 0) ? bpfBufSize : bufSize;    /* Initialize attachment to network interfaces. */    _bpfProtoInit ();    return (OK);    }/********************************************************************************* bpfDevDelete - destroy Berkeley Packet Filter device** This routine removes a Berkeley Packet Filter device and releases all* allocated memory. It will close any open files using the device.** RETURNS: OK, or ERROR if device not found** ERRNO: S_ioLib_NO_DRIVER** INTERNAL* This routine reverses the bpfDevCreate() routine operations.*/STATUS bpfDevDelete    (    char * 	pDevName 	/* name of BPF device to remove */    )    {    char * 	pTail = NULL; 	/* Pointer to tail of device name. */    BPF_DEV_HDR * pBpfDev; 	/* I/O system device header for BPF units */    if (bpfDrvNum == 0)        {        errnoSet (S_ioLib_NO_DRIVER);        return (ERROR);        }    pBpfDev = (BPF_DEV_HDR *)iosDevFind (pDevName, &pTail);    if (pBpfDev == NULL || pTail == pDevName) 	/* Device not found? */        return (ERROR);    /* Close any open files and remove the BPF device. */    iosDevDelete ( (DEV_HDR *)pBpfDev);    /*     * The I/O system device header is the first element in the overall     * BPF device header. Remove all other data structures for the device.     */    free (pBpfDev->pBpfNetIfTbl);    free (pBpfDev->pBpfDevTbl);    semDelete (pBpfDev->lockSem);    free (pBpfDev);    return (OK);    }/********************************************************************************* _bpfLock - provides mutual exclusion for the BPF driver** This routine protects critical sections of the BPF code by obtaining* a global lock which prevents additional BPF operations by any BPF units* through their associated file descriptors.** RETURNS:* BPF_LOCK_KEY  - if the BPF lock is newly acquired* BPF_DUMMY_KEY - if the calling task already owns the BPF_LOCK_KEY** NOMANUAL*/int _bpfLock (void)    {    int taskIdCurrent = taskIdSelf ();  /* ID of current task */        /* If the task already owns the lock return a dummy key */    if (bpfLockTaskId == taskIdCurrent)	{	return (BPF_DUMMY_KEY);	}    if (semTake (bpfLockSemId, WAIT_FOREVER) != OK)	{	panic ("bpfLock error");	}        bpfLockTaskId = taskIdCurrent;    return (BPF_LOCK_KEY);    }/********************************************************************************* _bpfUnlock - release the mutual exclusion for the BPF driver** This routine permits parallel BPF operations by any BPF units through* their associated file descriptors. It releases the lock previously acquired* by _bpfLock.  The routine has no effect if <lockKey> equals BPF_DUMMY_KEY* because of redundant lock attempts. If <lockKey> equals BPF_LOCK_KEY then* the lock will be released if the calling task currently owns the BPF lock.** RETURNS:* OK or ERROR if the calling task does not own the BPF lock** NOMANUAL*/ STATUS _bpfUnlock    (    int lockKey         /* BPF_LOCK_KEY or BPF_DUMMY_KEY */    )    {    int taskIdCurrent;  /* ID of current task */    if (lockKey == BPF_DUMMY_KEY)	{	return (OK);	}    taskIdCurrent = taskIdSelf ();    /* Calling task must own the BPF lock in order to release it */    if (taskIdCurrent != bpfLockTaskId)	{	return (ERROR);	}    bpfLockTaskId = 0;    semGive (bpfLockSemId);    return (OK);    }/********************************************************************************* _bpfDevLock - provides mutual exclusion for a BPF device** This routine protects shared data structures in the BPF code by obtaining* a lock which prevents BPF operations by any BPF units associated* with the same I/O device. This lock primarily supports stable "snapshots"* of the list of BPF units from a device attached to a particular network* interface. It also guarantees that a particular BPF unit will only be

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -