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

📄 muxtklib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
   if ((index = muxTkBibEntryGet (pEnd)) < 0)        {	if (muxTkDebug)	    logMsg ("muxTkBind: No more Bind entries", 1, 2, 3, 4, 5, 6);	return (NULL);        }    else	{        tkFlag = TK_DRV_CHECK(&muxBindBase[index]);	}    /* Allocate a new protocol structure and bind the protocol to the END. */    pNewProto = (NET_PROTOCOL *)KHEAP_ALLOC(sizeof (NET_PROTOCOL));    if (pNewProto == NULL)        {        /* free BIB entry */        bzero ((void *)&muxBindBase[index], sizeof(MUX_BIND_ENTRY));        logMsg ("muxBind cannot allocate protocol node", 0, 0, 0, 0, 0, 0);        errnoSet (S_muxLib_ALLOC_FAILED);        return (NULL);        }    bzero ( (char *)pNewProto, sizeof(NET_PROTOCOL));    /* bind the protocol to the END */    if (type != MUX_PROTO_OUTPUT)	{	/* populate all fields in the new protocol node */	pNewProto->stackShutdownRtn = stackShutdownRtn;	pNewProto->stackTxRestartRtn = stackTxRestartRtn;	pNewProto->stackErrorRtn = stackErrorRtn;        }    pNewProto->type = type;    /* Indicate that muxTkBind() was used. */    pNewProto->nptFlag = TRUE;    if (tkFlag != TRUE && type != MUX_PROTO_OUTPUT)        {        /* Use a wrapper receive routine when sending data with END devices. */        pNewProto->stackRcvRtn = muxEndRcvRtn;        }    else        {        pNewProto->stackRcvRtn = stackRcvRtn;        }    /*     * For all input protocols bound using muxTkBind,     * install the BIB entry pointer as the call back ID.     */    pNewProto->pSpare = &muxBindBase[index];    if (type != MUX_PROTO_OUTPUT)        {	/* copy the protocol name or generate one if not available */	if (pProtoName != NULL)	    {	    strncpy (pNewProto->name, pProtoName, 32);	    }	else	    {	    sprintf (pNewProto->name, "Protocol %d",		     lstCount (&pEnd->protocols));	    }        }    /* Insert the protocol in the END_OBJ protocol list */    switch (type)        {        case MUX_PROTO_OUTPUT:        case MUX_PROTO_PROMISC:            lstAdd (&pEnd->protocols, &pNewProto->node);            break;        default:            /* Add a standard or snarf protocol after any existing ones. */            lstInsert(&pEnd->protocols, pFinal, &pNewProto->node);            break;        }    if (type == MUX_PROTO_OUTPUT)	{	/* For an OUTPUT protocol place the filter in the END object itself. */        pEnd->outputFilter = pNewProto;        pEnd->pOutputFilterSpare = pNetCallbackId;	muxBindBase[index].pEnd->outputFilter->stackRcvRtn = muxEndRcvRtn;	pEnd->outputFilter->stackRcvRtn = stackRcvRtn;	}    muxBindBase[index].netStackRcvRtn = stackRcvRtn;    /* fill the rest of the BIB entry */    muxTkBibEntryFill (index, type, pNetCallbackId);    if (type == MUX_PROTO_SNARF)     /* Increase the count. */	(pEnd->snarfCount)++;    pNewProto->pNptCookie = &muxBindBase[index];    return (&muxBindBase[index]);    }/******************************************************************************* muxTkReceive - receive a packet from a NPT driver** This is the routine that the NPT driver calls to hand a packet to the MUX.* This routine forwards the received 'mBlk' chain to the network service* sublayer by calling its registered stackRcvRtn().** Typically, a driver includes an interrupt handling routine to process* received packets.  It should keep processing to a minimum during interrupt* context and then arrange for processing of the received packet within* task context.** Once the frame has been validated, the driver should pass it to the MUX* with the 'receiveRtn' member of its END_OBJ structure.  This routine has* the same prototype as (and typically is) muxTkReceive().** Depending on the protocol type (for example, MUX_PROTO_SNARF or* MUX_PROTO_PROMISC), this routine either forwards the received packet chain* unmodified or it changes the data pointer in the 'mBlk' to strip off the* frame header before forwarding the packet.** .IP <pCookie>* Expects the END_OBJ pointer returned by the driver's endLoad() or* nptLoad() function** .IP <pMblk>* Expects a pointer to the 'mBlk' structure containing the packet that has* been received** .IP <netSvcOffset>* Expects an offset into the frame to the point where the data field (the* network service layer header) begins** .IP <netSvcType>* Expects the network service type of the service for which the packet is* destined (typically this value can be found in the header of the received* frame)** .IP <uniPromiscuous>* Expects a boolean set to TRUE when driver is in promiscuous mode and* receives a unicast or a multicast packet not intended for this device.* When TRUE the packet is not handed over to network services other than* those registered as SNARF or PROMISCUOUS.** .IP <pSpareData>* Expects a pointer to any spare data the driver needs to pass up to the* network service layer, or NULL** RETURNS: OK or ERROR.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxTkReceive    (    void *    pCookie,		/* cookie passed in endLoad() call */    M_BLK_ID  pMblk,		/* a buffer passed to us. */    long      netSvcOffset,	/* offset to network datagram in the packet */    long      netSvcType,	/* network service type */    BOOL      uniPromiscuous,	/* TRUE when driver is in promiscuous mode */     void *    pSpareData	/* out of band data */    )    {    NET_PROTOCOL *      pProto;    END_OBJ *           pEnd;    long                type;    M_BLK_ID            pMblkOrig;    int 		count;    pEnd = (END_OBJ *)pCookie;    if (pEnd == NULL)        {        errnoSet (S_muxLib_NO_DEVICE);        if (pMblk)            netMblkClChainFree (pMblk);        return (ERROR);        }    /* Grab a new block and parse out the header information. */    count = lstCount (&pEnd->protocols);    if (count <= 0)        {        if (pMblk)            netMblkClChainFree (pMblk);        return (FALSE);        }    pProto = (NET_PROTOCOL *)lstFirst (&pEnd->protocols);    if (pProto == NULL)        {        if (pMblk)            netMblkClChainFree (pMblk);        return (ERROR);        }    /* Ignore incoming data if an output protocol is the only entry. */    if (count == 1 && pProto->type == MUX_PROTO_OUTPUT)        {        if (pMblk)            netMblkClChainFree (pMblk);        return (ERROR);        }    /*     * Loop through the protocol list.     * If a protocol's receive routine returns TRUE, that means it has     * consumed the packet.     * The protocol's receive routine should always return FALSE if other     * protocols have to see the packet.     * SNARF protocols have the priority over every other protocol.     * PROMISC protocols have the least priority.     */    type = netSvcType;    for (; pProto != NULL; pProto = (NET_PROTOCOL *)lstNext (&pProto->node))        {        MUX_ID muxId = (MUX_ID)(pProto->pSpare);	void * pNetCallbackId = NULL;        if (pProto->type == MUX_PROTO_OUTPUT)            continue;        if (muxId)            pNetCallbackId = muxId->pNetCallbackId;        if (pProto->type == MUX_PROTO_SNARF)            {            if ((pProto->stackRcvRtn) && (*pProto->stackRcvRtn) 		 (pNetCallbackId, type, pMblk, pSpareData) == TRUE)                return (OK);            }        else if (pProto->type == type && !uniPromiscuous)            {            /* Make sure the entire Link Hdr is in the first M_BLK */            pMblkOrig = pMblk;            if (pMblk->mBlkHdr.mLen < netSvcOffset &&                (pMblk = m_pullup (pMblk, netSvcOffset)) == NULL)                {                pMblk = pMblkOrig;                break;                }              /* remove the MAC header and set the packet length accordingly */             pMblk->mBlkHdr.mData += netSvcOffset;            pMblk->mBlkHdr.mLen  -= netSvcOffset;            pMblk->mBlkPktHdr.len  -= netSvcOffset;            if ((pProto->stackRcvRtn) &&                (((*pProto->stackRcvRtn) (pNetCallbackId, type, pMblk,                                          pSpareData)) == TRUE))                {                return (OK);                }            }        else if (pProto->type == MUX_PROTO_PROMISC)            {            if ((pProto->stackRcvRtn) &&                (((*pProto->stackRcvRtn) (pNetCallbackId, type, pMblk,                                          pSpareData)) == TRUE))                {                return (OK);                }            }        }    /* if the flow comes here then pMblk is not freed */    if (pMblk)        netMblkClChainFree (pMblk);    return (OK);    }/******************************************************************************* _muxTkSend - A private function common to both muxTkSend and muxTkPollSend** This routine does all of the processing required prior to a muxTkSend() or* muxTkPollSend() and calls the driver's send() or pollSend() routine; a* pointer to which is passed as the last argument. All other arguments are* the same as muxTkSend() or muxTkPollSend()** RETURNS: OK or ERROR** SEE ALSO: muxTkSend(), muxTkPollSend, muxSend(), muxPollSend** NOMANUAL */LOCAL STATUS _muxTkSend    (    MUX_ID    muxId,		/* cookie returned by muxTkBind */    M_BLK_ID  pNBuff,		/* data to be sent */    char *    dstMacAddr,	/* destination MAC address */    USHORT    netType,		/* network protocol that is calling us: redundant? */    void *    pSpareData,	/* spare data passed on each send */    FUNCPTR   sendRtn		/* the driver's send routine: poll or regular */    )    {    LL_HDR_INFO    llHdrInfo;     END_OBJ *      pEnd = muxId->pEnd;    NET_PROTOCOL * pOut = NULL;    /* we need these two M_BLKs for endAddressForm */    M_BLK srcAddr = {{NULL,NULL,NULL,0,MT_IFADDR,0,0}, {NULL,0}, NULL};    M_BLK dstAddr = {{NULL,NULL,NULL,0,MT_IFADDR,0,0}, {NULL,0}, NULL};    if (pEnd == NULL)        return (ERROR);    /* bump MIB2 statistic */    if (pNBuff != NULL &&           (pNBuff->mBlkHdr.mFlags & M_BCAST ||              pNBuff->mBlkHdr.mFlags & M_MCAST))        {        if (pEnd->flags & END_MIB_2233)            {            /*             * Do nothing as ifOutNUcastPkts is updated by the             * m2PktCountRtn function specified in the END objects             * M2_ID.             */            }        else /* (RFC1213 style counters supported) XXX */            {            ++(pEnd->mib2Tbl.ifOutNUcastPkts);            }        }    if (pEnd->outputFilter)        {        pOut = pEnd->outputFilter;        if (pOut->stackRcvRtn (pEnd->pOutputFilterSpare, netType, pNBuff,                                pSpareData) == TRUE)            {            return (OK);            }        }    if (!TK_DRV_CHECK(muxId))	{	M_BLK_ID  pSrcAddr = &srcAddr;	M_BLK_ID  pDstAddr = &dstAddr;	M_BLK_ID  pMacFrame = NULL;	char      srcMacAddr[64];        /* copy END MAC addr into a temporary buffer */        bzero (srcMacAddr, 64);        if (pEnd->flags & END_MIB_2233)            bcopy(END_ALT_HADDR(pEnd),srcMacAddr,END_ALT_HADDR_LEN(pEnd));        else            bcopy(END_HADDR(pEnd),srcMacAddr,END_HADDR_LEN(pEnd));	pDstAddr->mBlkHdr.mData = dstMacAddr;	pDstAddr->mBlkHdr.mLen = END_HADDR_LEN(pEnd);	pDstAddr->mBlkHdr.reserved = netType;	pSrcAddr->mBlkHdr.mData = srcMacAddr; 	pSrcAddr->mBlkHdr.mLen = END_HADDR_LEN(pEnd);	if (pEnd->pFuncTable->formAddress &&	    ((pMacFrame = pEnd->pFuncTable->formAddress (pNBuff, pSrcAddr,							 pDstAddr, FALSE))	      != NULL))	    {	    STATUS status;	    /*	     * if we get here, we send the fully formed MAC frame to 	     * the END driver	     */	    status = sendRtn (pEnd, pMacFrame);	    if (status != OK)		{		/*		 * resurrect the network layer packet		 */		if (pMacFrame == pNBuff)		    {		    if (pEnd->pFuncTable->packetDataGet (pNBuff, &llHdrInfo)			== ERROR)                        {                        if (pNBuff)                            netMblkClChainFree (pNBuff);                        return ERROR;                        }		    /* point to the network pkt header, and adjust the length */		    pNBuff->mBlkHdr.mData += llHdrInfo.dataOffset;		    pNBuff->mBlkHdr.mLen  -= llHdrInfo.dataOffset;		    if(pNBuff->mBlkHdr.mFlags & M_PKTHDR)			pNBuff->mBlkPktHdr.len -= llHdrInfo.dataOffset;		    #if 0		    logMsg("_muxTkSendError\n",1,2,3,4,5,6);		    #endif		    }                else		    {		    if(pMacFrame)			{			netMblkClFree(pMacFrame);			}                    pNBuff->mBlkHdr.mFlags |= M_PKTHDR;                    }		}	    return(status);	    }	else

⌨️ 快捷键说明

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