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

📄 if_subr.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    int			width		/* width of the copy */    )    {    FAST char *		pBuf = (char *) (pIoBuf);    FAST struct mbuf * 	pMbufHead = pMbuf;    FAST char *		adjBuf;    FAST int 		adjLen;    FAST int 		odd = 0;    FAST int 		ix;    char 		temp [4];    if (width == NONE)        {        for (; pMbuf != NULL; pBuf += pMbuf->m_len, pMbuf = pMbuf->m_next)            bcopy (mtod (pMbuf, char *), pBuf, pMbuf->m_len);        }    else if (width == 1)        {	for (; pMbuf != NULL; pBuf += pMbuf->m_len, pMbuf = pMbuf->m_next)	    bcopyBytes (mtod (pMbuf, char *), pBuf, pMbuf->m_len);        }        else if (width == 2)        {	for (; pMbuf != NULL; pMbuf = pMbuf->m_next)	    {	    adjLen = pMbuf->m_len;	    adjBuf = mtod(pMbuf, char *);	    if (odd > 0)		{		--pBuf;		*((UINT16 *) temp) = *((UINT16 *) pBuf);		temp [1] = *adjBuf++;		--adjLen;		*((UINT16 *) pBuf) = *((UINT16 *) temp);		pBuf += 2;		}	    bcopyWords (adjBuf, pBuf, (adjLen + 1) >> 1);	    pBuf += adjLen;            odd = adjLen & 0x1;	    }        }    else if (width == 4)        {	for (; pMbuf != NULL; pMbuf = pMbuf->m_next)	    {	    adjLen = pMbuf->m_len;	    adjBuf = mtod(pMbuf, char *);	    if (odd > 0)		{		pBuf -= odd;		*((UINT32 *) temp) = *((UINT32 *) pBuf);		for (ix = odd; ix < 4; ix++, adjBuf++, --adjLen)		    temp [ix] = *adjBuf;		*((UINT32 *) pBuf) = *((UINT32 *) temp);		pBuf += 4;		}	    bcopyLongs (adjBuf, pBuf, (adjLen + 3) >> 2);	    pBuf += adjLen;            odd = adjLen & 0x3;	    }        }    else        {        panic ("copyFromMbufs");        }    m_freem (pMbufHead); 			/* free the mbuf chain */        return ((int) pBuf - (int) pIoBuf);		/* return length copied */    }/********************************************************************************* build_cluster - encapsulate a passed buffer into a cluster mbuf.** This routine is used to surround the passed buffer <buf0> with a* mbuf header and make it a pseudo cluster.  It is used primarily by the* network interface drivers to avoid copying large chunk of data incoming* from the network.  Network interface device drivers typically call this* routine with a pointer to the memory location where the IP data reside.* This buffer pointer is used as a cluster buffer pointer and inserted* into mbuf along with other relevant pieces information such as the* index into the reference count array, pointer to the reference count* array and the driver level free routine.** RETURNS: NULL if unsuccessful, pointer to <struct mbuf> if successful.** SEE ALSO: do_protocol_with_type(), uipc_mbuf.c** NOMANUAL*/struct mbuf *build_cluster (buf0, totlen, ifp, ctype, pRefCnt,			    freeRtn, arg1, arg2, arg3)    u_char 		*buf0;		/* the buffer containing data */    int			totlen;		/* len of the buffer */    struct ifnet	*ifp;		/* network interface device pointer */    u_char		ctype;		/* type of this cluster being built */    u_char		*pRefCnt;	/* type-specific ref count array */    FUNCPTR		freeRtn;	/* driver level free callback routine */    int			arg1;		/* first argument to freeRtn() */    int			arg2;		/* second argument to freeRtn() */    int			arg3;		/* third argument to freeRtn() */    {    FAST struct mbuf    *m;    CL_BLK_ID		pClBlk;    /* get an mbuf header, header will have ifp info in the packet header */    m = mBlkGet(_pNetDpool, M_DONTWAIT, MT_DATA);    if (m == NULL)			/* out of mbufs! */	return (NULL);    pClBlk = clBlkGet (_pNetDpool, M_DONTWAIT);         if (pClBlk == NULL)			/* out of cl Blks */        {        m_free (m); 	return (NULL);        }    /* intialize the header */    m->m_pkthdr.rcvif = ifp;    m->m_pkthdr.len = totlen;    m->m_data		= (caddr_t) buf0;     m->m_len		= m->m_pkthdr.len;    m->m_flags		= (M_EXT | M_PKTHDR) ;    m->pClBlk		= pClBlk;    m->m_extBuf		= (caddr_t) buf0;    m->m_extSize	= m->m_pkthdr.len;    m->m_extFreeRtn	= freeRtn;    m->m_extArg1	= arg1;    m->m_extArg2	= arg2;    m->m_extArg3	= arg3;    m->m_extRefCnt	= 1;    return (m);    }/********************************************************************************* do_protocol_with_type - demultiplex incoming packet to the protocol handlers** Demultiplexes the incoming packet to the associated protocol handler.  This* version supports IP, ARP, and a generic mechanism via an external lookup* table.** This routine differs from do_protocol() in that the link-level frame type* is passed directly, instead of passing a pointer to an Ethernet header,* respectively.** This routine must not be called interrupt level.** NOMANUAL*/void do_protocol_with_type    (    u_short        	type,		/* the frame type field */    struct mbuf *	pMbuf,		/* the frame data, in mbuf chain */    struct arpcom *	pArpcom,	/* the source interface information */    int			len		/* length of the mbuf data */    )    {    int s;    FAST struct ifqueue *	inq;    FUNCPTR 	pInputFunc; 	/* message handler */    switch (type)        {	case ETHERTYPE_IP:            ipintr(pMbuf);	    return;	case ETHERTYPE_ARP:            inq = &arpintrq;            pInputFunc = (FUNCPTR) arpintr;            break;        default:            {	    /* No protocol. Drop packet */	    	    ((struct ifnet *) pArpcom)->if_noproto++;	    m_freem (pMbuf);	/* free the mbuf chain */	    return;            }        }    s = splnet ();    if (IF_QFULL(inq))        {        IF_DROP (inq);        m_freem (pMbuf);		/* free the mbuf chain */	splx (s);	}    else        {        IF_ENQUEUE (inq, pMbuf);	/* put the mbuf chain in the packet queue */	splx (s);        /* Schedule a new job to finish the handling of the IP or ARP data. */#ifdef VIRTUAL_STACK        netJobAdd (pInputFunc, pArpcom->ac_if.vsNum, 0, 0, 0, 0);#else	arpintr();#endif /* VIRTUAL_STACK */        }    }/********************************************************************************* set_if_addr - handle SIOCSIFADDR ioctl** Sets a protocol address associated with this network interface.* This function is called by various ioctl handlers in each of the network* interface drivers.** RETURNS: 0 or appropriate errno** NOMANUAL*/int set_if_addr (ifp, data, enaddr)    struct ifnet 	*ifp;  	/* interface */    char 		*data;  /* usually "struct ifaddr *" */    u_char 		*enaddr;/* ethernet address */    {    int 		error = 0;    FAST struct ifaddr *ifa = (struct ifaddr *) data;    ifp->if_flags |= IFF_UP;    if ((error = (*ifp->if_init) (ifp->if_unit)) != 0)        return (error);    switch (ifa->ifa_addr->sa_family)        {#ifdef  INET        case AF_INET:            ((struct arpcom *) ifp)->ac_ipaddr = IA_SIN (ifa)->sin_addr;            arpwhohas ((struct arpcom *) ifp, &IA_SIN (ifa)->sin_addr);            break;#endif	/* INET */	default:	    logMsg ("eh: set_if_addr unknown family 0x%x\n",			ifa->ifa_addr->sa_family,0,0,0,0,0);	    break;        }    return (0);    }/********************************************************************************* ether_attach - attach a new network interface to the network layer.** Fill in the ifnet structure and pass it off to if_attach () routine* which will attach the network interface described in that structure* to the network layer software for future use in routing, packet reception,* and transmisison.** NOMANUAL*/STATUS ether_attach (ifp, unit, name, initRtn, ioctlRtn, outputRtn, resetRtn)    struct ifnet 	*ifp;		/* network interface data structure */    int 		unit;		/* unit number */    char 		*name;		/* name of the interface */    FUNCPTR 		initRtn;	/* initialization routine */    FUNCPTR 		ioctlRtn;	/* ioctl handler */    FUNCPTR 		outputRtn;	/* output routine */    FUNCPTR 		resetRtn;	/* reset routine */    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 14, 17,                     WV_NETEVENT_ETHERATTACH_START, ifp)#endif  /* INCLUDE_WVNET */#endif    bzero ((char *) ifp, sizeof (*ifp));    ifp->if_unit   = unit;    ifp->if_name   = name;    ifp->if_mtu    = ETHERMTU;    ifp->if_init   = initRtn;    ifp->if_ioctl  = ioctlRtn;    ifp->if_output = outputRtn;    ifp->if_reset  = resetRtn;    ifp->if_flags  = IFF_BROADCAST;    return (if_attach (ifp));    }/********************************************************************************* netTypeAdd - add a network type to list of network types.** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/STATUS netTypeAdd (etherType, inputRtn)    int             	etherType;	/* ethernet type */    FUNCPTR             inputRtn;	/* input routine */    {    NET_TYPE *          pType;    if ((pType = (NET_TYPE *) KHEAP_ALLOC(sizeof(NET_TYPE))) == NULL)        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */        WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_EMERGENCY, 7, 2,                         WV_NETEVENT_TYPEADD_FAIL, etherType)#endif  /* INCLUDE_WVNET */#endif        return (ERROR);        }    bzero((char *)pType, sizeof (NET_TYPE));    pType->etherType    = etherType;    pType->inputRtn     = inputRtn;    lstAdd (&netTypeList, &pType->node);    return (OK);    }/********************************************************************************* netTypeDelete - delete a network type from the list of network types.** RETURNS: OK if successful, otherwise ERROR.** NOMANUAL*/STATUS netTypeDelete (etherType)    int		etherType;		/* ethernet type */    {    NET_TYPE *	pType;    for (pType = (NET_TYPE *) lstFirst (&netTypeList);         pType != NULL; pType = (NET_TYPE *) lstNext (&pType->node))	{        if (etherType == pType->etherType)            {            lstDelete (&netTypeList, &pType->node);	    KHEAP_FREE((caddr_t)pType);            return (OK);            }	}    return (ERROR);    }/********************************************************************************* netTypeInit - initialize list of network types.** RETURNS: N/A** NOMANUAL*/void netTypeInit ()    {    lstInit (&netTypeList);    }

⌨️ 快捷键说明

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