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

📄 muxlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
    }/******************************************************************************** muxBind - bind a protocol to the MUX given a driver name ** A protocol uses this routine to bind to a specific driver.* The driver is specified by the <pName> and <unit> arguments* (for example, ln and 0, ln and 1, ei and 0, ...).* The <stackRcvRtn> is called whenever the MUX has a packet of the specified * type.  If the type is MUX_PROTO_PROMISC, the protocol is considered * promiscuous and will get all of the packets that the MUX sees.* * .IP <pName> 20 * Expects a pointer to a character string that contains the name * of the device to which this protocol wants to use to send and * receive packets. * .IP <unit>* Expects a number which is the unit of the device of the type indicated* by <pName>.* .IP <stackRcvRtn> * Expects a pointer function that the MUX can call when it * wants to pass a packet up to the protocol.  For a description of * how you should write this routine, * see the description of a stackRcvRtn()* provided in * .I "Network Protocol Toolkit User's Guide."* .IP <stackShutdownRtn>  * Expects a pointer to the function that the MUX can call to * shutdown the protocol.  For a description of how to write such * a routine, see stackShutdownRtn() see the description of a stackRcvRtn()* provided in * .I "Network Protocol Toolkit User's Guide."* .IP <stackErrorRtn>* Expects a pointer to the function that the MUX can call to give errors* to the protocol.* .IP <type> * Expects a value that indicates the protocol type.  The MUX * uses this type to prioritize the protocol.  For example, a * protocol of type MUX_PROTO_SNARF has the highest priority * (see the description of protocol prioritizing provided in * .I "Network Protocol Toolkit User's Guide: Writing an NPT Protocol."* Aside from MUX_PROTO_SNARF and MUX_PROTO_PROMISC, valid protocol * types include any of the values specified in RFC1700. * If the type is MUX_PROTO_OUTPUT, this protocol is an output protocol and all* packets that are going to be output on this device are passed to the* stackRcvRtn() routine before actually being sent down to the device.  This* would be useful, for instance, for a network service that needs to send* packets directly to another network service, or for loop-back testing.* If the stackRcvRtn() returns OK, the packet is considered to have been* consumed and is no longer available.  An output protocol may return ERROR* from its stackRcvRtn() in order to look at the packet without consuming it.* .IP <pProtoName> * Expects a pointer to a character string for the name of this * protocol.  This string can be NULL, in which case a protocol name is* assigned internally.* .IP <pSpare>* Expects a pointer to a structure defined by the protocol.  This argument* is passed up to the protocol with each received packet.* * RETURNS: A cookie identifying the network driver to which the mux has*          bound the protocol.** ERRNO: S_muxLib_NO_DEVICE, S_muxLib_ALREADY_BOUND, S_muxLib_ALLOC_FAILED*/END_OBJ* muxBind    (    char * pName,		/* interface name, for example, ln, ei,... */    int unit,                   /* unit number */    BOOL (*stackRcvRtn) (void*, long, M_BLK_ID, LL_HDR_INFO *, void*),                                /* receive function to be called. */    STATUS (*stackShutdownRtn) (void*, void*),                                /* routine to call to shutdown the stack */    STATUS (*stackTxRestartRtn) (void*, void*),                                /* routine to tell the stack it can transmit */    void (*stackErrorRtn) (END_OBJ*, END_ERR*, void*),                                /* routine to call on an error. */    long type,			/* protocol type from RFC1700 and many */			        /* other sources (for example, 0x800 is IP) */    char* pProtoName,		/* string name for protocol  */    void* pSpare                /* per protocol spare pointer  */    )    {    NET_PROTOCOL* pNew;    NET_PROTOCOL* pNode;    END_OBJ* pEnd;     /* Check to see if we have a valid device. */    pEnd = endFindByName(pName, unit);    if (pEnd == NULL)        {        errnoSet(S_muxLib_NO_DEVICE);	return (pEnd);        }        /* if we already have a snarf protcol then return NULL. */    if (type == MUX_PROTO_SNARF && pEnd->snarfProto)        return (NULL);    /*      * Check to see if this is an OUTPUT protocol.     * If this is the case then that filter is placed into the     * device object itself.     */    if (type == MUX_PROTO_OUTPUT)        {        if (pEnd->outputFilter)            {            errnoSet(S_muxLib_ALREADY_BOUND);            return (NULL);            }        else            {            pEnd->outputFilter = stackRcvRtn;            pEnd->pOutputFilterSpare = pSpare;            return (pEnd);            }        }    /* Check to see if this protocol number is already taken. */    for (pNode = (NET_PROTOCOL *)lstFirst(&pEnd->protocols); pNode != NULL;          pNode = (NET_PROTOCOL *)lstNext(&pNode->node))        {        if (pNode->type == type)             {            errnoSet(S_muxLib_ALREADY_BOUND);            return (NULL);            }        }    /* Now we can allocate a new protocol structure. */    pNew = (NET_PROTOCOL *)malloc(sizeof(NET_PROTOCOL));    if (pNew == NULL)	{	logMsg ("muxBind cannot allocate protocol node", 1, 2, 3, 4,	    5, 6);        errnoSet (S_muxLib_ALLOC_FAILED);	return (NULL);	}    bzero((char *)pNew, sizeof(NET_PROTOCOL));    pNew->stackRcvRtn = stackRcvRtn;    pNew->stackShutdownRtn = stackShutdownRtn;    pNew->stackTxRestartRtn = stackTxRestartRtn;    pNew->stackErrorRtn = stackErrorRtn;    pNew->type = type;    pNew->flags = 0;    pNew->pSpare = pSpare;    if (pProtoName != NULL)	{	strncpy(pNew->name, pProtoName, 32);	}    else 	{	sprintf(pNew->name, "Protocol %d", lstCount(&pEnd->protocols));	}    switch (type)        {        case MUX_PROTO_PROMISC:            lstAdd(&pEnd->protocols, &pNew->node);            break;        case MUX_PROTO_SNARF:            lstInsert(&pEnd->protocols, NULL, &pNew->node);            pEnd->snarfProto = TRUE;            break;        default:            if (pEnd->snarfProto)                {                lstInsert(&pEnd->protocols, lstFirst(&pEnd->protocols),                          &pNew->node);                }            else                {                lstInsert(&pEnd->protocols, NULL, &pNew->node);                }            break;        }    return (pEnd);    }/****************************************************************************** * muxSend - send a packet out on a network interface** This routine uses the <pCookie> value returned during the bind to identify* the network interface through which the packet is to be transmitted.** .IP <pCookie>* Expects the pointer returned from muxBind().  This pointer * identifies the device to which the MUX has bound this protocol. * .IP <pNBuff>* Expects a pointer to the buffer that contains the packet you want * to transmit.  Before you call muxSend(), you need to put the * addressing information at the head of the buffer.  To do this, call * muxAddressForm(). ** Also, the buffer should probably be reserved from the MUX-* managed memory pool.  To reserve a buffer from this pool, the * protocol should call muxBufAlloc(). ** RETURNS: OK, ENETDOWN if <pCookie> does not represent a valid interface,*          or ERROR if the driver's endSend() routine fails.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxSend    (    void* pCookie,	/* cookie that identifies a network interface */                        /* (returned by muxBind() */    M_BLK_ID pNBuff	/* data to be sent */    )    {    int error;    END_OBJ* pEnd;    LL_HDR_INFO llHdrInfo;     long type;    pEnd = (END_OBJ *)pCookie;    if (pEnd == NULL)	{        errnoSet(S_muxLib_NO_DEVICE);	error = ENETDOWN;	}    else	{	if (pNBuff != NULL && 	    (pNBuff->mBlkHdr.mFlags & M_BCAST 	     || pNBuff->mBlkHdr.mFlags & M_MCAST))	    {	    ++(pEnd->mib2Tbl.ifOutNUcastPkts);	    }        if (pEnd->outputFilter)            {            if (muxPacketDataGet(pCookie, pNBuff, &llHdrInfo) == ERROR)                return (ERROR);            type = llHdrInfo.pktType;            if (pEnd->outputFilter(pEnd->devObject.pDevice, type,                                   pNBuff, &llHdrInfo,                                   pEnd->pOutputFilterSpare) == TRUE)		{		return (OK);		}            }	error = pEnd->pFuncTable->send(pEnd, pNBuff);	}    return (error);    }/****************************************************************************** * muxReceive - Receive a packet from a device driver.** This is the routine that the driver calls when it wishes to hand a* packet to the MUX.** RETURNS: OK or ERROR.** ERRNO: S_muxLib_NO_DEVICE** NOMANUAL*/STATUS muxReceive    (    void* pCookie,		/* Cookie passed in endLoad call */    M_BLK_ID pMblk		/* A buffer passed to us. */    )    {    NET_PROTOCOL * 	pProto;    END_OBJ * 		pEnd;    long 		type;    LL_HDR_INFO  	llHdrInfo;         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. */    if (lstCount (&pEnd->protocols) <= 0)        {        if (pMblk)            netMblkClChainFree (pMblk);        return (FALSE);        }    /*     * 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.     */    for (pProto = (NET_PROTOCOL *)lstFirst(&pEnd->protocols);          pProto != NULL; pProto = (NET_PROTOCOL *)lstNext(&pProto->node))	{        if (muxPacketDataGet(pCookie, pMblk, &llHdrInfo) == ERROR)            {            pEnd->mib2Tbl.ifInErrors++;            break;            }        type = llHdrInfo.pktType;        	if (pProto->type == MUX_PROTO_SNARF)            {            if ((*pProto->stackRcvRtn) (pCookie, type, pMblk, &llHdrInfo,                                        pProto->pSpare) == TRUE)                return (OK);            }        else if (pProto->type == type)            {            if ((*pProto->stackRcvRtn) (pCookie, type, pMblk, &llHdrInfo,                                        pProto->pSpare) == TRUE)                return (OK);            }        else if (pProto->type == MUX_PROTO_PROMISC)            {                   if ((*pProto->stackRcvRtn) (pCookie, type,                                        pMblk, NULL, pProto->pSpare) == TRUE)                return (OK);            }        }    /* if the flow comes here then pMblk is not freed */    pEnd->mib2Tbl.ifInUnknownProtos++;        if (pMblk)        netMblkClChainFree (pMblk);        return OK;    }/****************************************************************************** * muxPollSend - send a packet on a network interface** This routine takes a cookie which was returned by muxBind()* and uses it to determine which network interface driver* should be used in transmitting the data.  The routine takes the data* pointed to by <pNBuff> and sends it to the destination specified by calling* the functions in that driver.** .IP <pCookie>* Expects the cookie returned from muxBind(). This Cookie* identifies the device to which the MUX has bound the protocol calling* muxPollSend().** .IP <pNBuff>* Expects a pointer to the buffer('mBlk') chain that contains the packet to be* transmitted.** RETURNS: OK, ENETDOWN if <pCookie> doesn't represent a valid device,*          or ERROR if the device type is not recognized or if the*          endPollSend() routine for the driver fails.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxPollSend    (    void* pCookie,	/* cookie the protocol got from muxBind() */    M_BLK_ID pNBuff	/* data to be sent */    )    {    int error;    END_OBJ* pEnd;    LL_HDR_INFO llHdrInfo;     long type;    pEnd = (END_OBJ *)pCookie;    if (pEnd == NULL)	{        errnoSet (S_muxLib_NO_DEVICE);	error = ENETDOWN;	}    else	{        if (pEnd->outputFilter)            {            if (muxPacketDataGet(pCookie, pNBuff, &llHdrInfo) == ERROR)                return (ERROR);            type = llHdrInfo.pktType;            if (pEnd->outputFilter(pEnd->devObject.pDevice, type,                                   pNBuff, &llHdrInfo,                                   pEnd->pOutputFilterSpare) == OK)            return (OK);            }	error = pEnd->pFuncTable->pollSend(pEnd, pNBuff);	}    return (error);    }/****************************************************************************** * muxPollReceive - poll for a packet from a device driver** This is the routine that an upper layer can call to poll for a packet.** .IP <pCookie>* Expects the cookie that was returned from muxBind().* This "cookie" is an identifier for the driver.** .IP <pNBuff>* Expects a pointer to a buffer chain into which incoming data will be put.** RETURNS: OK, ENETDOWN if the pCookie*          does not represent a loaded driver, or an error value returned*          from the driver's registered endPollReceive() function.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxPollReceive    (    void* pCookie,		/* cookie passed in endLoad call */    M_BLK_ID pNBuff		/* a vector of buffers passed to us */    )    {    int error;    END_OBJ* pEnd;    pEnd = (END_OBJ *)pCookie;    if (pEnd == NULL)	{        errnoSet(S_muxLib_NO_DEVICE);	error = ENETDOWN;	}    else	{	error = pEnd->pFuncTable->pollRcv(pEnd, pNBuff);	}    return (error);    }/******************************************************************************** muxIoctl - send control information to the MUX or to a device** This routine gives the protocol access to the network driver's control * functions.  The MUX itself can implement some of the standard control* functions, so not all commands necessarily pass down to the device.  * Otherwise, both command and data pass down to the device unmolested.** This routine also lets the protocol change the routine that the MUX uses * to pass data up to the protocol as well as the routine that the MUX uses * to shutdown the protocol. ** .IP <pCookie>* Expects the pointer returned as the function value of muxBind().  The * pointer identifies the device to which this protocol is bound. * .IP <cmd>* Expects a value indicating the control command you want to execute. * For valid <cmd> values, see the description of the endIoctl() routine* provided in * .I "Network Protocol Toolkit User's Guide".* .IP <data>* Expects the data or a pointer to the data needed to * carry out the command specified in <cmd>. * * RETURNS: OK, ENETDOWN if pCookie does not represent a bound device,*          or ERROR if the command fails.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxIoctl    (    void* pCookie,	/* cookie identifying the device to access */    int cmd,		/* command to pass to ioctl */    caddr_t data	/* data need for command in cmd */    )

⌨️ 快捷键说明

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