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

📄 bpfproto.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        {        /*         * At least one BPF device is already attached to the interface.         * Find the attached parent device for this BPF unit, if any.         */        pFirst = pNetIfCtrl;        pBpfUnit = (BPF_DEV_CTRL *)lstFirst ( &(pNetIfCtrl->bpfUnitList));        if (pBpfUnit == NULL)            return (ENOBUFS);        if (pBpfDev->bpfDevId != pBpfUnit->bpfDevId)            {            /*             * This BPF unit is not from the first attached device.             * Search for a matching shared device.             */            pNetIfCtrl = (BPF_PROTO_CTRL *)lstFirst (& (pFirst->bpfDevList));            while (pNetIfCtrl != NULL)                {            pBpfUnit = (BPF_DEV_CTRL *)lstFirst ( &(pNetIfCtrl->bpfUnitList));            if (pBpfUnit == NULL)                return (ENOBUFS);                if (pBpfDev->bpfDevId == pBpfUnit->bpfDevId)                    break;                pLast = pNetIfCtrl;                pNetIfCtrl = (BPF_PROTO_CTRL *)lstNext ((NODE *) pNetIfCtrl);                }            }        if (pNetIfCtrl != NULL)            {            /*             * Parent device found. Save the network interface attachment in             * the BPF unit entry, which will be appended to the existing list.             */            pBpfDev->pNetDev = pNetIfCtrl;            return (OK);            }        /*         * No other BPF unit from this device is attached to the         * given network interface. Add the unit's entry to the         * (private) list of BPF devices which share a network interface.         */        if (pBpfDev->pNetIfCtrl == NULL)            return (ENOBUFS);        /* Append the new attachment data to the private list. */        lstInsert (& (pFirst->bpfDevList), (NODE *)pLast,                   (NODE *)pBpfDev->pNetIfCtrl);        pLast = pBpfDev->pNetIfCtrl;        }    /*     * Attach the BPF MUX protocols and initialize the attachment data     * for a network interface attached to the global or a private list.     * Alternatively, use the existing Ethernet input hook attachment     * or add the input hook if no other BPF devices are using any BSD     * network interface.     */    /* Delete the data in this node, but don't clobber list pointers. */    tmpNode.next = pLast->bpfProtoLstNode.next;    tmpNode.previous = pLast->bpfProtoLstNode.previous;    bzero ( (char *)pLast, sizeof (BPF_PROTO_CTRL));    pLast->bpfProtoLstNode.next = tmpNode.next;    pLast->bpfProtoLstNode.previous = tmpNode.previous;    if (pIf)        {        /* Attaching a BPF device to a BSD network interface. */        bpfBsdDevCount++;        pLast->bsdFlag = TRUE;        pLast->pCookie = pIf;        }    else        {        /* Attach to MUX to receive incoming packets */        int deviceType = muxTkDrvCheck (pDevName);        if (deviceType == ERROR)            goto bpfProtoAttachErr;/*logMsg("BPF PROTO ATTACH: %d\n", deviceType, 0, 0, 0, 0, 0);*/        pLast->bsdFlag = FALSE;        if (deviceType == 0)            pLast->pCookie = muxBind (pDevName, devUnit, bpfProtoInput,                                       bpfProtoShutdown, NULL, NULL,                                       MUX_PROTO_SNARF, BPF_PROTO_NAME,                                       pLast);        else            pLast->pCookie = muxTkBind (pDevName, devUnit, bpfTkProtoInput,                                         bpfTkProtoShutdown, NULL, NULL,                                         MUX_PROTO_SNARF, BPF_PROTO_NAME, pLast,                                        NULL, NULL);        if (pLast->pCookie == NULL)            {            goto bpfProtoAttachErr;            }        }    /* Initialize list of attached BPF units and store interface name. */    lstInit (& (pLast->bpfUnitList));    strncpy (pLast->devName, pDevName, END_NAME_MAX);    pLast->devUnit = devUnit;    /* Reset the private attachment list for possible later use. */    lstInit (& (pLast->bpfDevList));    /* Copy remaining interface settings if possible. */    if (pFirst != pLast)        {        /*         * More than one BPF device is sharing the same network interface.         * Copy the common values from the first attachment.         */        pLast->mtuSize = pFirst->mtuSize;        pLast->dataLinkType = pFirst->dataLinkType;        }    else        {        /*         * The BPF unit is the first attachment to the network interface.         * Retrieve and save the interface information.         * Add the Ethernet input hook if no other BSD device is in use.         */        if (pLast->bsdFlag)            {            if (bpfBsdDevCount == 1)                {                if (etherInputHookAdd (bpfBsdProtoInput, NULL, 0) == ERROR)                    goto bpfProtoAttachErr;                }            pLast->mtuSize = ETHERMTU;            pLast->dataLinkType = DLT_EN10MB;            }        else            {            if (muxIoctl (pLast->pCookie, EIOCGMIB2, (char *)&m2Tbl) != OK)                {                goto bpfProtoAttachErr;                }            pLast->mtuSize = m2Tbl.ifMtu;            if (m2Tbl.ifType < 0 || m2Tbl.ifType >= bpfDltTblSize)                {                pLast->dataLinkType = DLT_NULL;                }            else                {                pLast->dataLinkType = bpfDltTbl [m2Tbl.ifType];                }            }        }    /* Save the new network interface attachment in the BPF unit entry. */    pBpfDev->pNetDev = pLast;    return (OK);    /*     * Remove any linked BPF MUX protocols if an error occurred     * while attaching to the network interface.     */bpfProtoAttachErr:    if ( (pLast->bsdFlag == FALSE) && pLast->pCookie != NULL)        {        int deviceType = muxTkDrvCheck (pLast->devName);        if (deviceType != ERROR)            {            if (deviceType == 0)                muxUnbind (pLast->pCookie, MUX_PROTO_SNARF,                       (FUNCPTR) bpfProtoInput);            else                muxUnbind (pLast->pCookie, MUX_PROTO_SNARF,                       (FUNCPTR) bpfTkProtoInput);            }        }    return (EINVAL);    }/* INTERNAL: Each device contains a table for binding BPF file * descriptors to network interfaces. Each BPF unit adds an element * to that table so that the associated file descriptor can use any * network interface. That element is unused if the file descriptor * uses the same network interface as another BPF unit of the same * device, but this approach allows users to create BPF devices without * limiting the number of unique network interfaces allowed. * This routine allows every BPF device access to a list of the network * interfaces which are currently in use so that the MUX bindings are * appropriately established and maintained. */void _bpfProtoInit (void)    {    if (!bpfProtoInitDone)        {        lstInit (&lstProtoInUse);        bpfProtoInitDone = TRUE;        }    return;    }STATUS _bpfProtoPromisc    (    BPF_PROTO_CTRL * pBpfProto,    BOOL           on    )    {    ULONG endFlags;    int error = OK;    BPF_PROTO_CTRL * pFirst;    /* First attachment to network interface. */#ifdef INCLUDE_IP    char devName [IFNAMSIZ];#endif  /* INCLUDE_IP */    if (pBpfProto->bsdFlag)        return (EINVAL);    if (on)        {        error = muxIoctl (pBpfProto->pCookie, EIOCGFLAGS, (char *) &endFlags);        if (error != OK)            {            return (EINVAL);            }        /* Enable promiscuous mode if not already enabled */         if ( (endFlags & IFF_PROMISC) == 0)            {            endFlags = IFF_PROMISC;            error = muxIoctl (pBpfProto->pCookie, EIOCSFLAGS,                               (char *) endFlags);            if (error != OK)                {                return (EINVAL);                }#ifdef INCLUDE_IP            sprintf (devName, "%s%d", pBpfProto->devName,                      pBpfProto->devUnit);             ifFlagChange (devName, IFF_PROMISC, TRUE);#endif  /* INCLUDE_IP */            }         pBpfProto->bpfPromiscEnabled = TRUE;        pBpfProto->numPromisc ++;        return (OK);        }    pBpfProto->numPromisc --;    /*     * Disable the network interface's promiscuous mode if no other BPF     * units from any BPF devices are using it.     */    if (pBpfProto->numPromisc == 0)        {        /* This BPF device no longer uses promiscuous mode. */        pBpfProto->bpfPromiscEnabled = FALSE;        /* Find the start of the attachment list for this network interface. */        for (pFirst = (BPF_PROTO_CTRL *)lstFirst (&lstProtoInUse);             pFirst != NULL;             pFirst = (BPF_PROTO_CTRL *)lstNext ((NODE *)pFirst))            {            if (pFirst->bsdFlag == TRUE)    /* Ignore BSD network devices. */                continue;            if (PCOOKIE_TO_ENDOBJ(pFirst->pCookie) ==                PCOOKIE_TO_ENDOBJ(pBpfProto->pCookie))                break;             }        if (pFirst == NULL)    /* No device attached? (Can't really occur). */            return (OK);        if (pFirst->numPromisc)            {            /*             * The first BPF device attached to the network             * interface is using the promiscuous mode setting.             */            return (OK);            }        else            {            /*             * Check the promiscuous mode setting for any             * BPF devices sharing a network interface.             */            pFirst = (BPF_PROTO_CTRL *)lstFirst (& (pFirst->bpfDevList));            while (pFirst != NULL)                {                if (pFirst->numPromisc)                    break;                pFirst = (BPF_PROTO_CTRL *)lstNext ( (NODE *)pFirst);                }            /* Leave interface setting unchanged if promiscuous mode found. */            if (pFirst != NULL)                return (OK);            }        endFlags = IFF_PROMISC;        /* Set mask which causes muxIoctl() routine to disable flags. */        endFlags = - endFlags - 1;        error = muxIoctl (pBpfProto->pCookie, EIOCSFLAGS,                           (char *) endFlags);        if (error != OK)            error = EINVAL;#ifdef INCLUDE_IP        sprintf (devName, "%s%d", pBpfProto->devName,                 pBpfProto->devUnit);         ifFlagChange (devName, IFF_PROMISC, FALSE);#endif  /* INCLUDE_IP */        }    return (error);    }STATUS _bpfProtoSend    (    BPF_PROTO_CTRL * pBpfProto,    char * pBuf,    int nBytes,    BOOL nonBlocking    )    {    M_BLK_ID pMBlk;    END_OBJ * pEnd;    if (pBpfProto->bsdFlag)        return (ERROR);    pEnd = PCOOKIE_TO_ENDOBJ(pBpfProto->pCookie);        pMBlk = netTupleGet (pEnd->pNetPool, nBytes,                         (nonBlocking ? M_DONTWAIT : M_WAIT), MT_DATA, TRUE);    if (pMBlk == NULL)	{	netErrnoSet (ENOBUFS);	return (ERROR);	}    return (muxSend (pBpfProto->pCookie, pMBlk));    }/****************************************************************************** * bpfTkProtoInput - Check incoming frame against every BPF unit** This routine checks incoming frame against every BPF unit attached to a* NPT device using the muxTk/END interface. The BPF device containing the* attachment data must still exist or the MUX would not call this* routine. Always return FALSE to allow normal stack processing after* applying any filters.** RETURNS: FALSE*/LOCAL BOOL bpfTkProtoInput     (    void *      pProtoCtrl,    long        type,    M_BLK_ID    pMBlk,    void *      pSpare    )    {    BPF_PROTO_CTRL * pBpfProto;    ulong_t          dataOffset;    if (pProtoCtrl == NULL)        return (FALSE);    /* Access a BPF unit's attachment to the network interface. */    pBpfProto = (BPF_PROTO_CTRL *) pProtoCtrl;    dataOffset = 0;    if (muxIoctl (pBpfProto->pCookie, EIOCGHDRLEN,                  (caddr_t)&dataOffset) != OK)        return (FALSE);    /* Apply the current filters and save matching frames. */    _bpfPacketTap (&(pBpfProto->bpfUnitList), type, pMBlk, dataOffset);    return (FALSE);    }/****************************************************************************** * bpfTkProtoShutdown - shutdown routine** This is the shut down routine passed to muxTkBind call** RETURNS: OK or ERROR*/LOCAL STATUS bpfTkProtoShutdown     (    void * pProtoCtrl    )    {    if (pProtoCtrl != NULL)        {        return (bpfProtoShutdown (NULL, pProtoCtrl));        }    return (OK);    }

⌨️ 快捷键说明

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