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

📄 bridge.c

📁 Bridge PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* bridge.c - simple learning bridge without STP *//* * 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--------------------01z,04feb06,kch  Fixed apigen doc errors and warnings.01y,14jul05,myz  Fixed the broadcast failure when transmit buffers exhausted. 01y,20jun05,svk  Detach from IPv6 stack in bridgeShutdown()01x,15apr05,svk  Update API descriptions01w,07feb05,svk  Make bridge version string const01v,29oct04,svk  Add NOMANUAL to bridgeNextPhyDevEndGet()01u,20oct04,myz  use _pNetDpool pool instead of driver's pool.01t,19jul04,myz  improved END_ERR_BLOCK handling after field input.01s,05may04,svk  If END_ERR_BLOCK happens more than once, prepend the packet                 to driver sendq01r,29apr04,myz  fixed spr92002 and spr9670201q,20jun03,myz  removed the code for Patch muxTkBind override. This is not 		 needed for protocol type MUX_PROTO_SNARF01p,28may03,myz  added bridgeShutdown routine01o,07may03,svk  Add support for static mac addresses in bridge station cache01n,06may03,svk  Assume bridge port will not be removed when in use,		 reformat for coding convention01m,01may03,svk  Don't bridge EAPOL packet, handle tick wrap-around01l,17apr03,svk  Implement version number, update copyright01k,22nov02,zhu  added bridgeNextPhyDevEndGet function01j,28oct02,zhu  reduce compiler warnings01i,28oct02,zhu  fixed station cache aging timeout calculation01h,18oct02,zhu  added protocol check01g,19sep02,zhu  optimized bridge code01f,16jul02,zhu  turned debug flag BRIDGE_DEBUG off01e,06may02,zhu  fixing bugs in floodForwardPacket01d,15apr02,zhu  made changes for docs01c,04oct01,vks  MIPS alignment, station cache bugs 01b,27sep01,zhu  TSR#257133 flow control01a,28sep00,jhl  created*//*DESCRIPTIONThis library implements a simple learning bridge without STP (Spanning Tree Protocol).INCLUDE FILES: bridge.h mirrorEnd.hSEE ALSO: muxLib*/#include    "vxWorks.h"#include    "string.h"#include    "stdlib.h"#include    "stdio.h"#include    "memLib.h"#include    "lstLib.h"#include    "taskLib.h"#include    "semLib.h"#include    "sysLib.h"#include    "tickLib.h"#include    "muxLib.h"#include    "muxTkLib.h"#include    "end.h"#include    "netLib.h"#include    "net/if.h"#include    "private/muxLibP.h"#include    "ipProto.h"#ifdef INET6#include    "if6Lib.h"#endif  /* INET6 */#ifdef VIRTUAL_STACK#include <netinet/vsLib.h>#include <netinet/vsData.h>#include <netinet/vsNetCore.h>#endif /* VIRTUAL_STACK */#include    "wrn/bridge/bridge.h"#include    "wrn/bridge/mirrorEnd.h"/* Uncomment the line below to enable debug messages *//* #define     BRIDGE_DEBUG */  #ifdef BRIDGE_DEBUGint bridgeDebug = 1;#define DBG_PRINT(X) \    do { \    if (bridgeDebug) \        printf X; \    }while(0)#else#define DBG_PRINT(X)#endif/* constants */#define     STATION_CACHE_SIZE         1024        /* must be a power of 2 */#define     AGING_CHECK_DELAY_SECONDS  15#define     AGING_TIMEOUT_SECONDS      (5 * 60)#define     SNDERRQ_MAX_LEN            25/* typedefs *//* bridge port information */typedef struct     {    NODE        node;               /* must be first member in the structure */    char        name[END_NAME_MAX];     int         unitNum;    void*       pMuxBindCookie;    char        portType;    struct ifqueue errSndq;    } BRIDGE_PORT_INFO;/*defs for BRIDGE_PORT_INFO::portType */#define     BRIDGE_PORT_TYPE_END        0#define     BRIDGE_PORT_TYPE_NPT        1/* station cache entry */typedef struct     {    BOOL                inUse;          /* entry in use/available */    BRIDGE_PORT_INFO*   pPortInfo;      /* port info for port this entry                                            is attached to */    UINT32              tick;           /* sys tick this port was last heard                                           from */    UINT16              macAddr[3];     /* MAC address of this entry */    UINT32              flags;          /* static or dynamic */    } STATION_CACHE_ENTRY;/* macros */#define     STR_EQ(A,B)         ((strcmp((A), (B)) == 0) ? TRUE : FALSE)/* 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]))#define IS_4BYTE_ALIGNED(pAddr) \            (!((UINT32)(pAddr) & 0x3))#define IS_2BYTE_ALIGNED(pAddr) \            (!((UINT32)(pAddr) & 0x1))#if (_BYTE_ORDER == _BIG_ENDIAN)#define GETETHERTYPE(pMblk)  (*(UINT16*)(pMblk->mBlkHdr.mData + 12))#else   /* (_BYTE_ORDER == _BIG_ENDIAN) */#define GETETHERTYPE(pMblk)  (((*(UINT8*)(pMblk->mBlkHdr.mData + 12)) << 8) | \                               (*(UINT8*)(pMblk->mBlkHdr.mData + 13)))#endif  /* (_BYTE_ORDER == _BIG_ENDIAN) *//* station cache manipulation macros */#define     SC_ASSOCIATIVE_SET_SIZE     4/* externals */#ifndef VIRTUAL_STACKIMPORT NET_POOL_ID      _pNetDpool;#endif /* VIRTUAL_STACK */extern int mirrorSendStatus;/* Global data */const char * bridgeVersion = BRIDGE_VERSION;/* Local data */LOCAL UINT16  bcastMacAddr[3] = { 0xFFFF, 0xFFFF, 0xFFFF };LOCAL BOOL    bridgeInited = FALSE;LOCAL LIST    bridgePortList;LOCAL STATION_CACHE_ENTRY*  pStationCache;LOCAL SEM_ID    bridgePortListSemId;LOCAL SEM_ID    stationCacheSemId;LOCAL int       agingTaskId;LOCAL END_OBJ*  pMirrorStackEnd = NULL;LOCAL BRIDGE_PORT_INFO* pMirrorPortInfo = NULL;/* prototypes */LOCAL BOOL    bridgeRcvRtn(void* pNetCallBackId, long type, M_BLK* pMblk,                            void* pSpareData);LOCAL STATUS  bridgePortShutdownRtn(void* pNetCallBackId);LOCAL STATUS  bridgeRestartRtn(void* pNetCallBackId);LOCAL void    bridgeErrorRtn(void* pNetCallBackId, END_ERR* pError);                          LOCAL STATUS  packetForward(M_BLK* pMblk, BRIDGE_PORT_INFO* pDestPortInfo,                             BRIDGE_PORT_INFO* pSrcPortInfo);LOCAL STATUS  packetFloodForward(M_BLK* pMblk, BRIDGE_PORT_INFO* pSrcPortInfo);LOCAL void    bridgeAgingTask(void);LOCAL void    stationCacheEntryAdd(UINT16* pMacAddr, 				   BRIDGE_PORT_INFO* pPortInfo, UINT32 flags);LOCAL void    stationCacheEntryDelete(STATION_CACHE_ENTRY* pSCEntry);LOCAL STATION_CACHE_ENTRY* stationCacheEntryFind(UINT16* pMacAddr);LOCAL BRIDGE_PORT_INFO* portListEntryFind(char* pDevName, int unitNum);LOCAL STATUS bcastPktToStackSend (M_BLK_ID, BRIDGE_PORT_INFO*,                                   BRIDGE_PORT_INFO*);LOCAL STATUS  packetToPortSend (M_BLK*, BRIDGE_PORT_INFO*,BRIDGE_PORT_INFO*);void bridgePortListShow(void);void bridgeStationCacheShow(void);/******************************************************************************** bridgeInit - initialize the bridge** This routine initializes the bridge and station cache, and creates a bridge * port list and station cache access mutexes. This routine must be called * before you use any of the other bridge functionality.** RETURNS: OK, or ERROR if bridge initialization fails** ERRNO: N/A*/STATUS  bridgeInit(void)    {    int     index;        if (bridgeInited == TRUE)        return OK;       /***************************************************************************    * initialize the station cache    ***************************************************************************/    pStationCache = (STATION_CACHE_ENTRY*)calloc(STATION_CACHE_SIZE,                                                 sizeof(STATION_CACHE_ENTRY));    if (pStationCache == NULL)        {        DBG_PRINT(("bridgeInit: ERROR: Failure allocating station cache.\n"));        return ERROR;        }        for (index = 0; index < STATION_CACHE_SIZE; ++index)        pStationCache[index].inUse = FALSE;       /***************************************************************************    * initialize the bridge port information list    ***************************************************************************/    lstInit(&bridgePortList);   /***************************************************************************    * create bridge port list and station cache access mutexes    ***************************************************************************/    bridgePortListSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);        if (bridgePortListSemId == NULL)        {        DBG_PRINT(("bridgeInit: ERROR: Failure creating bridge list mutex.\n"));        free(pStationCache);        return ERROR;        }        stationCacheSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);        if (stationCacheSemId == NULL)        {        DBG_PRINT(("bridgeInit: ERROR: Failure creating bridge list mutex.\n"));        free(pStationCache);        semDelete(bridgePortListSemId);        return ERROR;        }       /***************************************************************************    * initialization complete     ***************************************************************************/    agingTaskId = taskSpawn("tBridgeAger", 250, 0, 4096,                         (FUNCPTR)bridgeAgingTask,                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0);        if (agingTaskId == ERROR)        {        DBG_PRINT(("bridgeInit: ERROR: Failure starting bridge aging task.\n"));        free(pStationCache);        semDelete(bridgePortListSemId);        semDelete(stationCacheSemId);        return ERROR;        }   pMirrorStackEnd = NULL;   pMirrorPortInfo = NULL;   /***************************************************************************    * initialization complete     ***************************************************************************/    bridgeInited = TRUE;        return OK;    }/******************************************************************************** bridgeShutdown - shut down the bridge** This routine performs the shutdown procedure of the bridge. It deletes the* bridge aging task, removes the bridge protocol interface from the MUX layer,* reverts the devices to non-promiscuous mode, unloads the mirror devices and* frees all the allocated resources. Once this routine is called, the bridge* can be restarted using its standard initialization routine.** Do not call this routine concurrently with the bridgePortRemove() and* bridgePortAdd() routines. No data packet should be sent to the bridge ports * by the local IP stack during the operation.** RETURNS: OK, or ERROR if fail to shut down** ERRNO: N/A*/STATUS bridgeShutdown(void)    {    BRIDGE_PORT_INFO* pPortInfo;    BRIDGE_PORT_INFO* pNextPortInfo;    END_OBJ *      pEnd;    /* validate the operation */    if (bridgeInited == FALSE)        return ERROR;    /* First set the device back to non promiscuous mode. This operation     * should stop most of bridge traffic     */    pPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList);    while (pPortInfo != NULL)        {        muxIoctl(pPortInfo->pMuxBindCookie,EIOCSFLAGS,(caddr_t)(~IFF_PROMISC));        pPortInfo = (BRIDGE_PORT_INFO *)lstNext((NODE*)pPortInfo);        }    /* delete tBridgeAger task */    taskDelete(agingTaskId);    /* Now remove the bridge ports  */    pPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList);    while (pPortInfo != NULL)        {	pNextPortInfo = (BRIDGE_PORT_INFO *)lstNext((NODE*)pPortInfo);	if (strcmp(MIRROR_DEV_NAME, pPortInfo->name) == 0)	    {	    /* must be mirror 1 bridge port */	    pEnd = endFindByName (pPortInfo->name,pPortInfo->unitNum);	    if (pEnd != NULL)		{		/* Need to set this field to some value different from pEnd		 * to prevent the muxDevUnload from freeing the drvCtrl                  * descriptor which is statically allocated in our case		 */		pEnd->devObject.pDevice = NULL;                muxDevUnload(pPortInfo->name,pPortInfo->unitNum);		}	    }        else	    {            bridgePortShutdownRtn((void*)pPortInfo);            }        pPortInfo = pNextPortInfo;        }    /* detach from IP stack for MIRROR_STACK_UNIT */    ipDetach(MIRROR_STACK_UNIT_NUM,MIRROR_DEV_NAME);#ifdef INET6     ip6Detach(MIRROR_STACK_UNIT_NUM,MIRROR_DEV_NAME);#endif  /* INET6 */     /* unload the mirror end drivers */    pEnd = endFindByName (MIRROR_DEV_NAME,MIRROR_STACK_UNIT_NUM);    if (pEnd != NULL)	{	pEnd->devObject.pDevice = NULL;        muxDevUnload(MIRROR_DEV_NAME,MIRROR_STACK_UNIT_NUM);        }     /* free the station cache */    free((void *)pStationCache);    /* delete bridgePortListSemId and stationCacheSemId */    semDelete(bridgePortListSemId);    semDelete(stationCacheSemId);    bridgeInited = FALSE;    return OK;    }    /******************************************************************************** bridgePortAdd -  add a device as a bridge port** This routine adds a device as a bridge port to the bridge port list.* bridgePortAdd() is called for the network interfaces that are attached to* the bridge as ports, including 'mirror1'. This routine binds the port's * device driver through the MUX as a network service with type * 'MUX_PROTO_SNARF'.** RETURNS: OK, or ERROR if port addition fails** ERRNO: N/A*/STATUS  bridgePortAdd    (    char*   pDevName,           /* device name */    int     unitNum             /* unit number */    )    {    void*               pMuxBindCookie;    BRIDGE_PORT_INFO*   pPortInfo;    END_OBJ*            pEnd;   /***************************************************************************    * if bridge hasn't been init'ed, initialize it    ***************************************************************************/    if (bridgeInited == FALSE)        bridgeInit();   /***************************************************************************    * verify that the port is already attached to the MUX    ***************************************************************************/    pEnd = endFindByName(pDevName, unitNum);        if (pEnd == NULL)

⌨️ 快捷键说明

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