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

📄 bridge.c

📁 vxworks下的bridge协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/* bridge.c - Simple learning bridge without STP uses NPT *//* Copyright 2000-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01q,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 uses NPT.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"#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)/**************************************************************************** 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;    } 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/**************************************************************************** Global data*/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;/**************************************************************************** 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);void bridgePortListShow(void);void bridgeStationCacheShow(void);/******************************************************************************** bridgeInit -  Initialize bridge** Initialize bridge and station cache. Create bridge port list and * station cache access mutexes.** RETURNS: OK, or ERROR if bridge initialization fails*/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;        }      /***************************************************************************    * initialization complete     ***************************************************************************/    bridgeInited = TRUE;        return OK;    }/******************************************************************************** bridgeShutdown -  Shut down the bridge component** This routine performs the shutdown procedure of the bridge component. It* deletes the bridge aging task, removes bridge protocol interface from* MUX layer, reverts back the devices to non-promiscuous mode, unloads the* mirror devices and finally frees all the allocated resources. Once this* routine is called, the bridge component can be restarted using its standard* initialization routine.** This routine should not be called concurrently with 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*/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);    /* 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** Add a device as a bridge port to the bridge port list.** RETURNS: OK, or ERROR if port addition fails*/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)        {        DBG_PRINT(("bridgePortAdd: ERROR: \"%s%d\" is not attached to MUX.\n",                   pDevName, unitNum));        return ERROR;        }       /***************************************************************************    * verify that this port is not already attached to the bridge    ***************************************************************************/    if (portListEntryFind(pDevName, unitNum) != NULL)        {        /* port is already in bridge port table */                DBG_PRINT(("bridgePortAdd: ERROR: \"%s%d\" is already attached\n",                   pDevName, unitNum));        return ERROR;        }       /***************************************************************************    * allocate space for bookkeeping info for the port    ***************************************************************************/    pPortInfo = (BRIDGE_PORT_INFO*)malloc(sizeof(BRIDGE_PORT_INFO));        if (pPortInfo == NULL)        {        DBG_PRINT(("bridgePortAdd: ERROR: out of memory, malloc failure.\n"));        return ERROR;        }       /***************************************************************************    * bind bridge to the port as a SNARFer    ***************************************************************************/    pMuxBindCookie = muxTkBind(pDevName,                               unitNum,                               bridgeRcvRtn,                               bridgePortShutdownRtn,                               bridgeRestartRtn,                               bridgeErrorRtn,                               MUX_PROTO_SNARF,                               "bridge",                               pPortInfo,   /* pNetCallBackId */                               NULL,        /* pNetSvcInfo */                               NULL);       /* pNetDrvInfo */    if (pMuxBindCookie == NULL)        {        DBG_PRINT(("bridgePortAdd: ERROR: muxTkBind() failed for \"%s%d\".\n",               pDevName, unitNum));        free(pPortInfo);        return ERROR;        }       /***************************************************************************    * save bookkeeping info for the port    ***************************************************************************/    bzero((char*)pPortInfo, sizeof(BRIDGE_PORT_INFO));        bcopy(pDevName, pPortInfo->name, END_NAME_MAX - 1);    pPortInfo->name[END_NAME_MAX - 1] = EOS;    pPortInfo->unitNum = unitNum;    pPortInfo->pMuxBindCookie = pMuxBindCookie;

⌨️ 快捷键说明

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