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

📄 mirrorend.c

📁 Bridge PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 2 页
字号:
                }            break;        case EIOCGFLAGS:            if (data == NULL)                {                error = EINVAL;                }            else                 {                *(int*)data = END_FLAGS_GET(pEndObj);                }            break;        case EIOCPOLLSTART:            error = mirrorEndPollStart(pDrvCtrl);            break;        case EIOCPOLLSTOP:            error = mirrorEndPollStop(pDrvCtrl);            break;        case EIOCGMIB2:            if (data == NULL)                {                error = EINVAL;                }            else                 {                bcopy((char*)&pDrvCtrl->endObject.mib2Tbl,                       (char*)data,                      sizeof(pDrvCtrl->endObject.mib2Tbl));                }            break;        case EIOCGFBUF:            if (data == NULL)                {                error =  EINVAL;                }            else                 {                *(int*)data = LENGTH_MIN_FBUF;                }            break;        default:            error = EINVAL;            break;        }    return error;    }/******************************************************************************** mirrorEndSend - output packet to network interface device** This routine() takes a M_BLK* and sends off the data in the M_BLK*.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer.** muxSend() calls this routine each time it wants to send a packet.** RETURNS: OK , ERROR or END_ERR_BLOCK** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndSend    (    END_CTRL*   pDrvCtrl,    M_BLK*      pMblk    )    {    int         otherHalfOfMirror;    int status = OK;    LOG_MSG("mirrorEndSend: unit: %d, pollMode: %d, ",            (int)pDrvCtrl->unit,             (int)pDrvCtrl->polling,             4, 5, 6, 7);    LOG_MSG("dst:%02X:%02X:%02X:%02X:%02X:%02X, ",            *(UCHAR *)(pMblk->mBlkHdr.mData),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 1),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 2),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 3),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 4),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 5));    LOG_MSG("src:%02X:%02X:%02X:%02X:%02X:%02X\n",            *((UCHAR *)(pMblk->mBlkHdr.mData) + 6),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 7),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 8),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 9),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 10),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 11));    if (pDrvCtrl->polling == TRUE)        {        netMblkClChainFree (pMblk); /* free the given mBlk chain */        return ERROR;        }    otherHalfOfMirror = pDrvCtrl->unit ^ 1;     /* 0->1, 1->0 */    if (channelState[otherHalfOfMirror] == CHANNEL_UP)        {        /* other half of mirror is up, send packet there */       	if (pDrvCtrl->unit == MIRROR_STACK_UNIT_NUM)            mirrorSendStatus = OK;        /*         * In the previous version of the Bridge, calling mirrorEndReceive         * directly caused deadlock when bridge tries to flood multicasts         * outgoing from local stack. One way to avoid the deadlock is to         * call mirrorEndReceive from tNetTask by using netJobAdd. But this         * causes performance hit, and also overloads the netJob ring buffer.         *         * The better solution is to call mirrorEndReceive directly, and         * avoid deadlock by not taking the bridge port list semaphore when         * flooding packets to all bridge ports. Taking this semaphore was         * previously thought necessary to guard against removal of a bridge         * port when the bridge is flooding packets to that port. The          * possibility of this occurring is very small, and can be avoided         * if the user makes sure the bridge port is free of incoming and         * outgoing traffic before removing the bridge port.         */        mirrorEndReceive(&drvCtrl[otherHalfOfMirror], pMblk);        if (pDrvCtrl->unit == MIRROR_STACK_UNIT_NUM)            status = mirrorSendStatus;        }    else         {        /* other half of mirror is not up, toss the packet */        netMblkClChainFree(pMblk);        }    /* Bump the statistic counter. */    END_ERR_ADD(&pDrvCtrl->endObject, MIB2_OUT_UCAST, +1);    return status;    }/******************************************************************************** isInMulticastList - is the address is a multicast address for this device?** This routine checks whether the given address matches a multicast address* from the current list of multicast addresses. ** RETURNS: TRUE or FALSE** ERRNO: N/A** NOMANUAL*/LOCAL BOOL isInMulticastList    (    END_CTRL*	pDrvCtrl,     /* pointer to END_CTRL structure */    UINT16*	enetAddr      /* address to check */    )    {    ETHER_MULTI* pCurr;    pCurr = (ETHER_MULTI *)lstFirst(&pDrvCtrl->endObject.multiList);    while (pCurr != (ETHER_MULTI *)NULL)        {        if (((UINT32)(pCurr->addr) & 0x01) == 0)             {            /* address is aligned on a 2 or 4 byte boundary */             if (MAC_ADDR_EQ(((UINT16 *)(pCurr->addr)), enetAddr) == TRUE)                return TRUE;            }        else            {            /* address is aligned on a byte-boundary */            if (bcmp(pCurr->addr, (char *)enetAddr, 6) == 0)                return TRUE;            }        pCurr = (ETHER_MULTI *)lstNext(&pCurr->node);        }            return FALSE;    }/******************************************************************************** mirrorEndReceive - process an input frame** This routine processes an input frame, then passes it up to the higher * level in a form it expects.  Buffer loaning, promiscuous mode are all * supported.  Trailer protocols is not supported.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/LOCAL void mirrorEndReceive    (    END_CTRL*   pDrvCtrl,       /* pointer to END_CTRL structure */    M_BLK*      pMblk    )    {     UINT16 * pTmp;    UINT16   enetAddr[3];    LOG_MSG("mirrorEndReceive: unit: %d, ", 	    (int)pDrvCtrl->unit, 	    2, 3, 4, 5, 6);    LOG_MSG("dst:%02X:%02X:%02X:%02X:%02X:%02X, ",            *(UCHAR *)(pMblk->mBlkHdr.mData),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 1),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 2),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 3),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 4),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 5));    LOG_MSG("src:%02X:%02X:%02X:%02X:%02X:%02X\n",            *((UCHAR *)(pMblk->mBlkHdr.mData) + 6),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 7),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 8),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 9),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 10),            *((UCHAR *)(pMblk->mBlkHdr.mData) + 11));           /* don't allow the packet through if in polling mode */   if (pDrvCtrl->polling == TRUE)       {       netMblkClChainFree(pMblk);       return;       }   /* if unit is not in promiscuous mode, filter packets to receive only    * packets for our MAC address or broadcasts.    */    if (pDrvCtrl->promiscuous == FALSE)        {        pTmp = (UINT16 *)(pMblk->mBlkHdr.mData);        if (((UINT32)(pTmp) & 0x01) == 0)            {            /* address is aligned on a 2 or 4 byte boundary */            enetAddr[0] = pTmp[0];            enetAddr[1] = pTmp[1];            enetAddr[2] = pTmp[2];            }        else            {            /* address is aligned on a byte-boundary */            bcopy((char *)pTmp, (char *)enetAddr, 6);            }                    if ((MAC_ADDR_EQ(enetAddr, pDrvCtrl->enetAddr) == 0) &&            (IS_BROADCAST(enetAddr) == 0) &&            (isInMulticastList(pDrvCtrl, enetAddr) == FALSE))            {            LOG_MSG("Dest addr not my addr/broadcast/multicast - dropping!\n",                    1, 2, 3, 4, 5, 6);            netMblkClChainFree(pMblk);            return;            }        }       LOG_MSG("Sending up the packet to my network stack\n",            1, 2, 3, 4, 5, 6);    /* send up to protocol */    END_RCV_RTN_CALL(&pDrvCtrl->endObject, pMblk);    /* bump input packet counter */    END_ERR_ADD(&pDrvCtrl->endObject, MIB2_IN_UCAST, +1);        }/******************************************************************************** mirrorEndMCastAddrAdd - add a multicast address for the device** Multicast makes no sense in this driver.  Keep the table for "get" calls.** RETURNS : OK or ERROR** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndMCastAddrAdd    (    END_CTRL*   pDrvCtrl,    char*       pAddr    )    {    STATUS error;    error = etherMultiAdd(&pDrvCtrl->endObject.multiList, pAddr);    if (error == ENETRESET)        {        pDrvCtrl->endObject.nMulti++;        error = OK;        }    return (error == OK) ? OK : ERROR;    }/******************************************************************************** mirrorEndMCastAddrDel - delete a multicast address for the device** This routine deletes a multicast address from the current list of* multicast addresses.** RETURNS : OK or ERROR** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndMCastAddrDel    (    END_CTRL *  pDrvCtrl,       /* pointer to END_CTRL structure */    char *      pAddr           /* Address to delete from the table. */    )    {    STATUS error;    error = etherMultiDel(&pDrvCtrl->endObject.multiList, pAddr);    if (error == ENETRESET)        {        pDrvCtrl->endObject.nMulti--;        error = OK;        }    return (error == OK) ? OK : ERROR;    }/******************************************************************************** mirrorEndMCastAddrGet - get the current multicast address list** This routine returns the current multicast address list in <pTable>** RETURNS: Multicast address list or NULL** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndMCastAddrGet    (    END_CTRL*       pDrvCtrl,    MULTI_TABLE*    pTable    )    {    return etherMultiGet(&pDrvCtrl->endObject.multiList, pTable);    }/******************************************************************************** mirrorEndPollStart - start polling mode** Using polled mode for the mirror driver makes no sense.  Do not use it.** RETURNS: OK** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndPollStart    (    END_CTRL*   pDrvCtrl    )    {    /* Set the polling flag */    pDrvCtrl->polling = TRUE;    /* need to set the real device, we either put all devices associated with     * this vritual mirror device into poll mode, or simply put one     * currently only put one.     */    (*pDrvCtrl->pPhyEnd->pFuncTable->ioctl)(pDrvCtrl->pPhyEnd,EIOCPOLLSTART,0);    return OK;    }/******************************************************************************** mirrorEndPollStop - stop polling mode** This routine stops the mirrorEnd from the polling mode.** RETURNS: OK always** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndPollStop    (    END_CTRL*   pDrvCtrl    )    {    /* reset the polling flag */    pDrvCtrl->polling = FALSE;    (*pDrvCtrl->pPhyEnd->pFuncTable->ioctl)(pDrvCtrl->pPhyEnd,EIOCPOLLSTOP,0);    return OK;    }/******************************************************************************* mirrorEndPollSend - transmit a packet in polled mode** This routine is called by a user to try and send a packet on the* device. It sends a packet directly on the network from the caller without* going through the normal processes of queuing a packet on an output queue* and the waiting for the device to decide to transmit it.** If it detects a transmission error, the restart command is issued.** These routine should not call any kernel functions.** RETURNS: OK or EAGAIN** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndPollSend    (    END_CTRL*   pDrvCtrl,    M_BLK*      pMblk    )    {    STATUS status;    /* mirror 1 should not call this function */    if (pDrvCtrl->unit != 0)	return ERROR;    /* call the poll routine in the real device */    status = pDrvCtrl->pPhyEnd->pFuncTable->pollSend(pDrvCtrl->pPhyEnd, 	                                             pMblk);    /* Bump the statistic counter. */    END_ERR_ADD(&pDrvCtrl->endObject, MIB2_OUT_UCAST, +1);    return OK;    }/******************************************************************************** mirrorEndPollReceive - receive a packet in polled mode** This routine receives a packet in polled mode** RETURNS: OK or ERROR** ERRNO: N/A** NOMANUAL*/LOCAL STATUS mirrorEndPollReceive    (    END_CTRL*   pDrvCtrl,    M_BLK*      pMblk    )    {    return pDrvCtrl->pPhyEnd->pFuncTable->pollRcv(pDrvCtrl->pPhyEnd, 	                                          pMblk);    }

⌨️ 快捷键说明

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