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

📄 mirrorend.c

📁 Bridge PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* mirrorEnd.c - mirroring END device driver *//* * Copyright (c) 2000-2006 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. *//*modification history--------------------01s,04feb06,kch  Fixed apigen doc errors and warnings.01r,15apr05,svk  Update API descriptions01q,07feb05,svk  Remove unused/obsolete include01p,19jul04,myz  removed end_err_block_flag and moved muxTxRestart to bridge.01o,07aug03,myz  zero out drvCtrl at init, call mirrorEndStop and undo last fix		 in mirrorEndUnload01n,03jun03,myz  clear the snarfCount in mirrorEndUnload01m,22may03,svk  Add a missing cast, debug message changes01l,06may03,svk  Remove the costly netJobAdd in mirrorEndSend()01k,02may03,svk  Add multicast support, avoid a possible deadlock,                  address optimzation, re-format for coding convention01j,17apr03,svk  Update copyright date01i,22nov02,zhu  removed compiler warnings01h,22nov02,zhu  added polling mode support01g,18oct02,ep   removing gnu warning01f,15apr02,zhu  changed arg types to call mirrorEndReceive01e,15apr02,zhu  made changes to docs01d,10apr02,svk  Replace another netJobAdd with mirrorEndReceive01c,09apr02,svk  Replace a netJobAdd with mirrorEndReceive01b,27sep01,zhu  TSR#257133 flow control01a,10oct00,jhl  created*//*DESCRIPTIONThis library implements a mirroring END device driver.INCLUDE FILES: mirrorEnd.hSEE ALSO: endLib*//* includes */#include "vxWorks.h"#include "string.h"#include "iv.h"#include "taskLib.h"#include "memLib.h"#include "ioctl.h"#include "net/mbuf.h"#include "net/protosw.h"#include "socket.h"#include "errno.h"#include "errnoLib.h"#include "net/unixLib.h"#include "net/route.h"#include "net/if_subr.h"#include "cacheLib.h"#include "stdio.h"#include "intLib.h"#include "logLib.h"#include "netLib.h"#include "iosLib.h"#include "net/if.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "netinet/if_ether.h"#include "etherLib.h"#include "etherMultiLib.h"#include "end.h"#include "semLib.h"/* Uncomment the line below to enable debug messages *//*#define END_MIRROR_DEBUG */#ifdef END_MIRROR_DEBUGint endMirrorDebug = 1;#define LOG_MSG \        if (endMirrorDebug) \		logMsg		#else#define LOG_MSG(a0,a1,a2,a3,a4,a5,a6)#endif#undef END_MACROS#include "endLib.h"#include "lstLib.h"#include "netBufLib.h"#include "wrn/bridge/mirrorEnd.h"/* defines */#define     LENGTH_MIN_FBUF     9       /* min. size of the first buffer in a frame */#define     SPEED               10000000/* ethernet speed */#define     MAX_MIRROR_CHANNELS 2#define     CHANNEL_DOWN    	0#define     CHANNEL_UP      	1/* macros *//* A shortcut for getting the hardware address from the MIB II stuff. */#define     END_HADDR(pEnd)     ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define     END_HADDR_LEN(pEnd) ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)/* both pMac1 and pMac2 must point to a two byte boundary */#define     MAC_ADDR_EQ(pMac1,pMac2)	\                ( (pMac1[0] == pMac2[0]) && \                  (pMac1[1] == pMac2[1]) && \                  (pMac1[2] == pMac2[2]) ) /* pMacAddr must point to a two byte boundary */#define     IS_BROADCAST(pMacAddr) \                ( (pMacAddr[0] == bcastMacAddr[0]) && \                  (pMacAddr[1] == bcastMacAddr[1]) && \                  (pMacAddr[2] == bcastMacAddr[2]) )                  /* typedefs *//* END control structure */typedef struct end_ctrl     {    END_OBJ     endObject;      /* base class */    int         unit;           /* unit number */    BOOL        promiscuous;    /* promiscuous on or off */    BOOL        polling;        /* polling mode */    END_OBJ *   pPhyEnd;    UINT16      enetAddr[3];    /* ethernet address of this entry */    } END_CTRL;/* globals */int mirrorSendStatus = OK;/* locals */LOCAL UINT16 bcastMacAddr[3] = { 0xFFFF, 0xFFFF, 0xFFFF };LOCAL END_CTRL  drvCtrl[MAX_MIRROR_CHANNELS];   /* array of driver control */LOCAL int channelState[MAX_MIRROR_CHANNELS] = {CHANNEL_DOWN, CHANNEL_DOWN };/* prototypes */END_OBJ*        mirrorEndLoad(char* initString);LOCAL STATUS    mirrorEndStart(END_CTRL* pDrvCtrl);LOCAL STATUS    mirrorEndStop(END_CTRL* pDrvCtrl);LOCAL STATUS    mirrorEndUnload(END_CTRL* pDrvCtrl);LOCAL int       mirrorEndIoctl(END_CTRL* pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS    mirrorEndSend(END_CTRL* pDrvCtrl, M_BLK* pMblk);LOCAL void      mirrorEndReceive(END_CTRL* pDrvCtrl, M_BLK* pMblk);LOCAL STATUS    mirrorEndMCastAddrAdd(END_CTRL* pDrvCtrl, char* pAddress);LOCAL STATUS    mirrorEndMCastAddrDel(END_CTRL* pDrvCtrl, char* pAddress);LOCAL STATUS    mirrorEndMCastAddrGet(END_CTRL* pDrvCtrl, MULTI_TABLE* pTable);LOCAL STATUS    mirrorEndPollStart(END_CTRL* pDrvCtrl);LOCAL STATUS    mirrorEndPollStop(END_CTRL* pDrvCtrl);LOCAL STATUS    mirrorEndPollSend(END_CTRL* pDrvCtrl, M_BLK* pMblk);LOCAL STATUS    mirrorEndPollReceive(END_CTRL* pDrvCtrl, M_BLK* pMblk);LOCAL BOOL      isInMulticastList(END_CTRL* pDrvCtrl, UINT16* enetAddr);extern STATUS bridgeNextPhyDevEndGet(char *,int *);/* * Define the device function table.  This is static across all driver * instances. */LOCAL NET_FUNCS netFuncs =     {    (FUNCPTR)mirrorEndStart,            /* start func. */    (FUNCPTR)mirrorEndStop,             /* stop func. */    (FUNCPTR)mirrorEndUnload,           /* unload func. */    (FUNCPTR)mirrorEndIoctl,            /* ioctl func. */    (FUNCPTR)mirrorEndSend,             /* send func. */    (FUNCPTR)mirrorEndMCastAddrAdd,     /* multicast add func. */    (FUNCPTR)mirrorEndMCastAddrDel,     /* multicast delete func. */    (FUNCPTR)mirrorEndMCastAddrGet,     /* multicast get fun. */    (FUNCPTR)mirrorEndPollSend,         /* polling send func. */    (FUNCPTR)mirrorEndPollReceive,      /* polling receive func.  */    endEtherAddressForm,                /* Put address info into a packet.  */    endEtherPacketDataGet,              /* Get a pointer to packet data. */    endEtherPacketAddrGet               /* Get packet addresses. */    };/******************************************************************************** mirrorEndLoad - initialize the driver and device** This routine initializes the driver and the device. All of the * device-specific parameters are passed in the <initString> parameter. * <initstring> is of the following format, where <unit> is the device* driver unit number:** <unit>:** Mirror driver unit number can be 'MIRROR_STACK_UNIT_NUM' (0) or* 'MIRROR_BRIDGE_UNIT_NUM' (1). These are defined in:** target/h/wrn/bridge/mirrorEnd.h** Typically, unit 0 is attached to the network stack and unit 1 is attached to* the bridge.** RETURNS: An END object pointer on success, or NULL on error** ERRNO: N/A**/END_OBJ* mirrorEndLoad    (    char*   initString    )    {    END_CTRL*   pDrvCtrl;    if (initString == NULL)        return NULL;        if (initString[0] == 0)        {        bcopy((char *)MIRROR_DEV_NAME, initString, MIRROR_DEV_NAME_LEN);        return NULL;        }    /* Parse InitString */    switch (initString[0])        {        case '0':            pDrvCtrl = &drvCtrl[0];	    bzero((char *)pDrvCtrl,sizeof(END_CTRL));             pDrvCtrl->unit = 0;            SYS_ENET_ADDR_GET((char *) pDrvCtrl->enetAddr);            break;                case '1':            pDrvCtrl = &drvCtrl[1];	    bzero((char *)pDrvCtrl,sizeof(END_CTRL));             pDrvCtrl->unit = 1;                        /* if unit ever REALLY needs a MAC address, change this appropriately */            SYS_ENET_ADDR_GET((char *) pDrvCtrl->enetAddr);                          break;                default:            return NULL;        }    /* Check if we are already attached */    if (pDrvCtrl->endObject.attached == TRUE)        return &pDrvCtrl->endObject;    /* endObject initializations */    if (END_OBJ_INIT(&pDrvCtrl->endObject,                      (void*)pDrvCtrl,                      MIRROR_DEV_NAME,                     pDrvCtrl->unit,                      &netFuncs,                     MIRROR_END_OBJ_STRING) == ERROR)        {        return NULL;        }    /* Initialize MIB2 entries */    if (END_MIB_INIT(&pDrvCtrl->endObject,                      M2_ifType_ethernet_csmacd,                     (UCHAR *) pDrvCtrl->enetAddr,                      6,                      ETHERMTU,                     SPEED) == ERROR)        {        return NULL;        }    /* we need to import the memory pool from a real physical driver. At least     * the WDB end driver is using it     */    if (pDrvCtrl->unit == 0)        {        char devName[END_NAME_MAX];        int unit = 0;        bzero(devName,END_NAME_MAX);	if (bridgeNextPhyDevEndGet(devName,&unit) == ERROR)            {            logMsg("mirrorEndLoad: No physical device found\n",1,2,3,4,5,6);            }        else	    {	    END_OBJ * pEnd;	    pEnd = endFindByName(devName,unit);            if (pEnd != NULL)	        pDrvCtrl->endObject.pNetPool = pEnd->pNetPool;            pDrvCtrl->pPhyEnd = pEnd;	    }        }    /* Mark the device ready */    /* IFF_SCAT is not defined by default */    END_OBJ_READY(&pDrvCtrl->endObject,                  IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);    /* Successful return */    return &pDrvCtrl->endObject;    }/******************************************************************************** mirrorEndStart - start the device ** This routine marks the interface as up.** The complement of this routine is mirrorEndStop().  Once a unit is reset by* mirrorEndStop(), it may be re-initialized to a running state by this routine.* * RETURNS: OK if successful, otherwise ERROR** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndStart    (    END_CTRL*   pDrvCtrl    )    {    /* initialize flag(s) */    pDrvCtrl->polling     = FALSE;    pDrvCtrl->promiscuous = FALSE;    /* mark the channel state as "UP" */    channelState[pDrvCtrl->unit] = CHANNEL_UP;        /* raise the interface flags - mark the device as up */    END_FLAGS_SET (&pDrvCtrl->endObject, IFF_UP | IFF_RUNNING);    return OK;    }/******************************************************************************** mirrorEndStop - stop the device ** This routine marks the interface as down.** The complement of this routine is mirrorEndStart().  Once a unit is * stop in this routine, it may be re-initialized to a running state by * mirrorEndStart().** RETURNS: OK or ERROR** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndStop    (    END_CTRL*   pDrvCtrl    )    {    /* mark the channel state as "DOWN" */    channelState[pDrvCtrl->unit] = CHANNEL_DOWN;        /* mark the driver as down */    END_FLAGS_CLR (&pDrvCtrl->endObject, IFF_UP | IFF_RUNNING);    return OK;    }/******************************************************************************* mirrorEndUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK always** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndUnload    (    END_CTRL*   pDrvCtrl    )    {    mirrorEndStop(pDrvCtrl);    END_OBJECT_UNLOAD(&pDrvCtrl->endObject);    return OK;    }/******************************************************************************** mirrorEndIoctl - network interface control routine** This routine implements the network interface control functions.* It handles EIOCSIFADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS,* EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 and EIOCGFBUF ENDERRBLOCK commands.** RETURNS: OK if successful, otherwise EINVAL** ERRNO: N/A** NOMANUAL*/LOCAL int mirrorEndIoctl    (    END_CTRL*   pDrvCtrl,    int         cmd,    caddr_t     data    )    {    int         error = 0;    long        value;    END_OBJ*    pEndObj = &pDrvCtrl->endObject;    switch ((UINT)cmd)        {        case EIOCSADDR:            if (data == NULL)                {                error = EINVAL;                }            else                 {                bcopy((char*)data,                       (char*)END_HADDR(pEndObj),                       END_HADDR_LEN(pEndObj));                }            break;        case EIOCGADDR:            if (data == NULL)                {                error = EINVAL;                }            else                 {                bcopy((char*)END_HADDR(pEndObj),                       (char*)data,                      END_HADDR_LEN(pEndObj));                }            break;           case EIOCSFLAGS:            value = (long)data;            if (value < 0)                {                value = -value;                value--;                END_FLAGS_CLR(pEndObj, value);                }            else                 {                END_FLAGS_SET(pEndObj, value);                }	                if (END_FLAGS_GET(pEndObj) & IFF_PROMISC)                {                pDrvCtrl->promiscuous = TRUE;                }            else                 {                pDrvCtrl->promiscuous = FALSE;

⌨️ 快捷键说明

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