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

📄 endlib.c

📁 3C90X驱动源码
💻 C
字号:
/* endLib.c - support library for END-based drivers *//* Copyright 1984 - 1999 Wind River Systems, Inc.  *//*modification history--------------------01r,16mar99,spm  recovered orphaned code from tor2_0_x branch (SPR #25770)01q,09dec98,n_s  fixed endEtherPacketDataGet to handle M_BLK chains. spr 2389501p,18nov98,n_s  fixed end8023AddressForm. spr 22976.01o,10dec97,gnn  made minor man page fixes01n,08dec97,gnn  END code review fixes.01m,17oct97,vin  changed prototypes, fixed endEtherPacketDataGet.01k,25sep97,gnn  SENS beta feedback fixes01j,27aug97,gnn  doc fixes and clean up.01i,25aug97,vin  added netMblkDup in endEtherPacketDataGet().01h,22aug97,gnn  cleaned up and improved endEtherAddrGet.01g,19aug97,gnn  changes due to new buffering scheme.                 added routine to get addresses from a packet.01f,12aug97,gnn  changes necessitated by MUX/END update.01e,jul3197,kbw  fixed man page problems found in beta review01d,26feb97,gnn  Set the type of a returned M_BLK_ID correctly.01c,05feb97,gnn  Added a check for NULL on allocation.01b,03feb97,gnn  Added default memory management routines.01a,26dec96,gnn	 written.*/ /*DESCRIPTIONThis library contains support routines for Enhanced Network Drivers.These routines are common to ALL ENDs.  Specialized routines should onlyappear in the drivers themselves.INCLUDE FILES:*//* includes */#include "vxWorks.h"#include "memLib.h"#include "netBufLib.h"#include "endLib.h"#include "end.h"#include "etherLib.h"#include "etherMultiLib.h"#include "bufLib.h"/* defints *//* typedefs *//* globals *//* locals *//* forward declarations */void endRcvRtnCall    (    END_OBJ* pEnd,    M_BLK_ID pData    )    {    if (pEnd->receiveRtn)         {         pEnd->receiveRtn ((pEnd), pData);         }    }void endTxSemTake    (    END_OBJ* pEnd,    int tmout    )     {    semTake(pEnd->txSem,tmout);    }void endTxSemGive    (    END_OBJ* pEnd    )    {    semGive (pEnd->txSem);    }void endFlagsClr    (    END_OBJ* pEnd,    int clrBits    )     {    pEnd->flags &= ~clrBits;    }void endFlagsSet    (    END_OBJ* pEnd,    int setBits    )    {    pEnd->flags |= (setBits);    }int endFlagsGet    (    END_OBJ* pEnd    )     {    return(pEnd->flags);    }int endMultiLstCnt    (    END_OBJ* pEnd    )    {    return (lstCount(&pEnd->multiList));    }ETHER_MULTI* endMultiLstFirst    (    END_OBJ *pEnd    )     {    return ((ETHER_MULTI *)(lstFirst(&pEnd->multiList)));    }ETHER_MULTI* endMultiLstNext    (    ETHER_MULTI* pCurrent    )     {    return ((ETHER_MULTI *)(lstNext(&pCurrent->node)));    }char* endDevName    (    END_OBJ* pEnd    )     {    return(pEnd->devObject.name);    }void endObjectUnload    (    END_OBJ* pEnd    )    {     lstFree (&pEnd->multiList);     lstFree (&pEnd->protocols);     }/******************************************************************************** mib2Init - initialize a MIB-II structure** Initialize a MIB-II structure.  Set all error counts to zero.  Assume* a 10Mbps Ethernet device.** RETURNS: OK or ERROR.*/STATUS mib2Init    (    M2_INTERFACETBL *pMib,	/* struct to be initialized */    long ifType,                /* ifType from m2Lib.h */    UCHAR * phyAddr,		/* MAC/PHY address */    int addrLength,             /* MAC/PHY address length */    int mtuSize,		/* MTU size */    int speed                   /* interface speed */    )    {    /* Clear out our statistics. */    bzero ((char *)pMib, sizeof (*pMib));    pMib->ifPhysAddress.addrLength = addrLength;        /* Obtain our Ethernet address and save it */    bcopy ((char *) phyAddr, (char *)pMib->ifPhysAddress.phyAddress,	    pMib->ifPhysAddress.addrLength);    /* Set static statistics. assume ethernet */    pMib->ifType = ifType;    pMib->ifMtu =  mtuSize;    pMib->ifSpeed = speed;    return OK;    }/******************************************************************************** mib2ErrorAdd - change a MIB-II error count** This function adds a specified value to one of the MIB-II error counters* in a MIB-II interface table.  The counter to be altered is specified* by the errCode argument.  Specifying a negative value reduces the error* count, a positive value increases the error count.** RETURNS: OK or ERROR.*/STATUS mib2ErrorAdd    (    M2_INTERFACETBL * pMib,    int errCode,    int value    )    {    switch (errCode)	{	default:	case MIB2_IN_ERRS:	    pMib->ifInErrors += value;	    break;	case MIB2_IN_UCAST:	    pMib->ifInUcastPkts += value;	    break;	case MIB2_OUT_ERRS:	    pMib->ifOutErrors += value;	    break;	case MIB2_OUT_UCAST:	    pMib->ifOutUcastPkts += value;	    break;	}        return OK;    }/********************************************************************************* endObjInit - initialize an END_OBJ structure** This routine initializes an END_OBJ structure and fills it with data from * the argument list.  It also creates and initializes semaphores and * protocol list.** RETURNS: OK or ERROR.*/STATUS endObjInit    (    END_OBJ *	pEndObj,	/* object to be initialized */    DEV_OBJ*	pDevice,	/* ptr to device struct */    char *	pBaseName,	/* device base name, for example, "ln" */    int		unit,		/* unit number */    NET_FUNCS * pFuncTable,	/* END device functions */    char*       pDescription    )    {    pEndObj->devObject.pDevice = pDevice;    /* Create the transmit semaphore. */    pEndObj->txSem = semMCreate ( SEM_Q_PRIORITY |                                  SEM_DELETE_SAFE |                                  SEM_INVERSION_SAFE);    if (pEndObj->txSem == NULL)        {        return (ERROR);        }    /* Install data and functions into the network node. */    pEndObj->flags = 0;    lstInit (&pEndObj->protocols); 	/* Head of protocol list, */					/* none yet. */    /* Check and control the length of the name string. */    if (strlen(pBaseName) > sizeof(pEndObj->devObject.name))        pBaseName[sizeof(pEndObj->devObject.name - 1)] = NULL;    strcpy (pEndObj->devObject.name, pBaseName);    /* Check and control the length of the description string. */    if (strlen(pDescription) > sizeof(pEndObj->devObject.description))        pDescription[sizeof(pEndObj->devObject.description - 1)] = NULL;    strcpy (pEndObj->devObject.description, pDescription);    pEndObj->devObject.unit = unit;        pEndObj->pFuncTable = pFuncTable;    /* Clear multicast info. */    lstInit (&pEndObj->multiList);    pEndObj->nMulti = 0;    pEndObj->snarfProto = FALSE;        return OK;    }/********************************************************************************* endObjFlagSet - set the `flags' member of an END_OBJ structure** As input, this routine expects a pointer to an END_OBJ structure * (the <pEnd> parameter) and a flags value (the <flags> parameter).* This routine sets the 'flags' member of the END_OBJ structure* to the value of the <flags> parameter. ** Because this routine assumes that the driver interface is now up,  * this routine also sets the 'attached' member of the referenced END_OBJ* structure to TRUE. ** RETURNS: OK*/STATUS endObjFlagSet    (    END_OBJ * pEnd,    UINT	flags    )    {    pEnd->attached = TRUE;    pEnd->flags = flags;    return OK;    }/******************************************************************************** end8023AddressForm - form an 802.3 address into a packet** This routine accepts the source and destination addressing information* through <pSrcAddr> and <pDstAddr> mBlks and returns an M_BLK_ID to the* assembled link level header.  This routine prepends the link level header* into <pMblk> if there is enough space available or it allocates a new* mBlk/clBlk/cluster and prepends the new mBlk to the mBlk chain passed in* <pMblk>.  This routine returns a pointer to an mBlk which contains the* link level header information.** RETURNS: M_BLK_ID or NULL.** NOMANUAL*/M_BLK_ID end8023AddressForm    (    M_BLK_ID pMblk,    M_BLK_ID pSrcAddr,    M_BLK_ID pDstAddr    )    {    short dataLen;     /* length of data including LLC */    short etherType;   /* Ethernet network type code */    struct llc * pLlc; /* link layer control header */    dataLen = pMblk->mBlkPktHdr.len + LLC_SNAP_FRAMELEN;    dataLen = htons (dataLen);     M_PREPEND(pMblk, ENET_HDR_REAL_SIZ + LLC_SNAP_FRAMELEN, M_DONTWAIT);    if (pMblk != NULL)        {        bcopy (pDstAddr->m_data, pMblk->m_data, pDstAddr->m_len);        bcopy (pSrcAddr->m_data, pMblk->m_data + pDstAddr->m_len,               pSrcAddr->m_len);	bcopy ((char *) &dataLen, pMblk->m_data + pDstAddr->m_len + 	       pSrcAddr->m_len, sizeof (short));	/* Fill in LLC using SNAP values */	pLlc = (struct llc *) (pMblk->m_data + pDstAddr->m_len + 			       pSrcAddr->m_len + sizeof (short));	pLlc->llc_dsap = LLC_SNAP_LSAP;	pLlc->llc_ssap = LLC_SNAP_LSAP; 	pLlc->llc_un.type_snap.control = LLC_UI;	bzero (pLlc->llc_un.type_snap.org_code, 	       sizeof (pLlc->llc_un.type_snap.org_code));	/* Enter ethernet network type code into the LLC snap field */	etherType = htons (pDstAddr->mBlkHdr.reserved);	bcopy ((char *) &etherType, 	       (char *) &(pLlc->llc_un.type_snap.ether_type), 	       sizeof (short));        }    return (pMblk);    }/******************************************************************************** endEtherAddressForm - form an Ethernet address into a packet** This routine accepts the source and destination addressing information * through <pSrcAddr> and <pDstAddr> and returns an 'M_BLK_ID' that points * to the assembled link-level header.  To do this, this routine prepends * the link-level header into the cluster associated with <pMblk> if there * is enough space available in the cluster.  It then returns a pointer to * the pointer referenced in <pMblk>.  However, if there is not enough space * in the cluster associated with <pMblk>, this routine reserves a * new 'mBlk'-'clBlk'-cluster construct for the header information. * It then prepends the new 'mBlk' to the 'mBlk' passed in <pMblk>.  As the * function value, this routine then returns a pointer to the new 'mBlk', * which the head of a chain of 'mBlk' structures.  The second element of this * chain is the 'mBlk' referenced in <pMblk>. ** RETURNS: M_BLK_ID or NULL.*/M_BLK_ID endEtherAddressForm    (    M_BLK_ID pMblk,     /* pointer to packet mBlk */    M_BLK_ID pSrcAddr,  /* pointer to source address */    M_BLK_ID pDstAddr   /* pointer to destination address */    )    {    M_PREPEND(pMblk, ENET_HDR_REAL_SIZ, M_DONTWAIT);    if (pMblk != NULL)        {        bcopy (pDstAddr->m_data, pMblk->m_data, 6);        bcopy (pSrcAddr->m_data, pMblk->m_data + 6, 6);        ((ENET_HDR *)pMblk->m_data)->type = pDstAddr->mBlkHdr.reserved;        }    return (pMblk);     }/******************************************************************************** endEtherPacketDataGet - return the beginning of the packet data** This routine fills the given <pLinkHdrInfo> with the appropriate offsets.** RETURNS: OK or ERROR.*/STATUS endEtherPacketDataGet    (    M_BLK_ID 		pMblk,    LL_HDR_INFO * 	pLinkHdrInfo    )    {    ENET_HDR * 		pEnetHdr;    ENET_HDR            enetHdr;    struct llc * 	pLLCHdr;    struct llc          llcHdr;    USHORT 		etherType;    pLinkHdrInfo->destAddrOffset	= 0;    pLinkHdrInfo->destSize 		= 6;    pLinkHdrInfo->srcAddrOffset		= 6;    pLinkHdrInfo->srcSize		= 6;    /* Try for RFC 894 first as it's the most common. */    /*      * make sure entire ether_header is in first M_BLK      * if not then copy the data to a temporary buffer      */    if (pMblk->mBlkHdr.mLen < ENET_HDR_REAL_SIZ) 	{	pEnetHdr = &enetHdr;	if (netMblkOffsetToBufCopy (pMblk, 0, (char *) pEnetHdr, 				    ENET_HDR_REAL_SIZ, (FUNCPTR) bcopy) 	    < ENET_HDR_REAL_SIZ)	    {	    return (ERROR);	    }	}    else	pEnetHdr = (ENET_HDR *)pMblk->mBlkHdr.mData;    etherType = ntohs(pEnetHdr->type);    /* Deal with 802.3 addressing. */    /* Here is the algorithm. */    /* If the etherType is less than the MTU then we know that */    /* this is an 802.x address from RFC 1700. */    if (etherType < ETHERMTU)	{	/* 	 * make sure entire ether_header + llc_hdr is in first M_BLK 	 * if not then copy the data to a temporary buffer 	 */		if (pMblk->mBlkHdr.mLen < ENET_HDR_REAL_SIZ + LLC_SNAP_FRAMELEN)	    {	    pLLCHdr = &llcHdr;	    if (netMblkOffsetToBufCopy (pMblk, ENET_HDR_REAL_SIZ, 					(char *) pLLCHdr, LLC_SNAP_FRAMELEN,					(FUNCPTR) bcopy)		< LLC_SNAP_FRAMELEN)		{		return (ERROR);		}	    }	else	    pLLCHdr = (struct llc *)((char *)pEnetHdr + ENET_HDR_REAL_SIZ);		/* Now it may be IP over 802.x so we check to see if the */	/* destination SAP is IP, if so we snag the ethertype from the */	/* proper place. */		/* Now if it's NOT IP over 802.x then we just used the DSAP as */	/* the etherType.  */		if (pLLCHdr->llc_dsap == LLC_SNAP_LSAP)            {	    etherType = ntohs(pLLCHdr->llc_un.type_snap.ether_type);            pLinkHdrInfo->dataOffset = ENET_HDR_REAL_SIZ + 8;            }	else            { /* no SNAP header */            pLinkHdrInfo->dataOffset = ENET_HDR_REAL_SIZ + 3;	    etherType = pLLCHdr->llc_dsap;            }	}    else        {        pLinkHdrInfo->dataOffset	= ENET_HDR_REAL_SIZ;        }    pLinkHdrInfo->pktType		= etherType;    return (OK);    }/******************************************************************************** endEtherPacketAddrGet - locate the addresses in a packet** This routine takes a 'M_BLK_ID', locates the address information, and * adjusts the M_BLK_ID structures referenced in <pSrc>, <pDst>, <pESrc>, * and <pEDst> so that their pData members point to the addressing * information in the packet.  The addressing information is not copied. * All 'mBlk' structures share the same cluster.** RETURNS: OK or ERROR.*/STATUS endEtherPacketAddrGet    (    M_BLK_ID pMblk, /* pointer to packet */    M_BLK_ID pSrc,  /* pointer to local source address */    M_BLK_ID pDst,  /* pointer to local destination address */    M_BLK_ID pESrc, /* pointer to remote source address (if any) */    M_BLK_ID pEDst  /* pointer to remote destination address (if any) */    )    {    if (pSrc != NULL)        {        pSrc = netMblkDup (pMblk, pSrc);        pSrc->mBlkHdr.mData += 6;        pSrc->mBlkHdr.mLen = 6;        }    if (pDst != NULL)        {        pDst = netMblkDup (pMblk, pDst);        pDst->mBlkHdr.mLen = 6;        }    if (pESrc != NULL)        {        pESrc = netMblkDup (pMblk, pESrc);        pESrc->mBlkHdr.mData += 6;        pESrc->mBlkHdr.mLen = 6;        }    if (pEDst != NULL)        {        pEDst = netMblkDup (pMblk, pEDst);        pEDst->mBlkHdr.mLen = 6;        }        return (OK);    }

⌨️ 快捷键说明

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