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

📄 uipc_mbuf.c

📁 完整的TCP/IP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	count = 0;	for (;;)	    {	    count += m->m_len;	    if (m->m_next == (struct mbuf *)0)		break;	    m = m->m_next;	    }	if (m->m_len >= len)	    {	    m->m_len -= len;	    if (mp->m_flags & M_PKTHDR)		mp->m_pkthdr.len -= len;	    return;	    }	count -= len;	if (count < 0)	    count = 0;	/*	 * Correct length for chain is "count".	 * Find the mbuf with last data, adjust its length,	 * and toss data from remaining mbufs on chain.	 */	m = mp;	if (m->m_flags & M_PKTHDR)	    m->m_pkthdr.len = count;	for (; m; m = m->m_next) 	    {	    if (m->m_len >= count) 		{		m->m_len = count;		break;		}	    count -= m->m_len;	    }	while ((m = m->m_next))	    m->m_len = 0;	}    }/********************************************************************************* m_pullup - ensure contiguous data area at the beginnig of an mbuf chain** Rearange an mbuf chain so that len bytes are contiguous* and in the data area of an mbuf (so that mtod and dtom* will work for a structure of size len).  Returns the resulting* mbuf chain on success, frees it and returns null on failure.*/struct mbuf *m_pullup(n, len)    register struct mbuf *n;    int len;    {    register struct mbuf *m;    register int count;    int space;    if (((n->m_data + len) < (n->m_extBuf + n->m_extSize)) && n->m_next)	{	if (n->m_len >= len)	    return (n); 	m = n;	n = n->m_next;	len -= m->m_len;	}    else 	{	m = mBufClGet(M_DONTWAIT, n->m_type, len, TRUE);	if (m == 0)	    goto bad;	m->m_len = 0;	if (n->m_flags & M_PKTHDR)	    {	    m->m_pkthdr = n->m_pkthdr;	    m->m_flags = n->m_flags; 	    n->m_flags &= ~M_PKTHDR;	    }	}    space = (m->m_extBuf + m->m_extSize) - (m->m_data + m->m_len);    do 	{	count = min(min(max(len, max_protohdr), space), n->m_len);	bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,	      (unsigned)count);	len -= count;	m->m_len += count;	n->m_len -= count;	space -= count;	if (n->m_len)	    n->m_data += count;	else	    n = m_free(n);	} while (len > 0 && n);    if (len > 0)	{	(void) m_free(m);	goto bad;	}    m->m_next = n;    return (m);    bad:    m_freem(n);    MPFail++;    return (0);    }/********************************************************************************* m_devget - Routine to copy from device local memory into mbufs.** Routine to copy from device local memory into mbufs.* This routine copies the device local memory into mbufs according to the* specified width. The interface pointer is initialized as a part of the* packet header in the mbuf chain. The first mbuf in the chain is always* a packet header and contains the interface pointer. This field is used* when it is necessary to retrieve the interface pointer from the mbuf chain.* If a copy function pointer is given, this function uses that function* pointer. This is given to enable the hardware specific copy routines to be* used instead of system routines.**/struct mbuf * m_devget(buf, totlen, width, ifp, copy)    char * buf;    int totlen;    int width;    struct ifnet *ifp;    void (*copy)();    {    register struct mbuf *m;    struct mbuf *top = NULL, **mp = &top;    register int len;    register char *cp;    cp = buf;    while (totlen > 0)	{        m = mBufClGet (M_DONTWAIT, MT_DATA, totlen, FALSE);        if (m == NULL)            {            if (top != NULL)                m_freem (top);            return (NULL);            }        	if (top == NULL)	    {            m->m_flags 		|= M_PKTHDR; 	    m->m_pkthdr.rcvif 	= ifp;	    m->m_pkthdr.len 	= totlen;	    len = min(totlen, m->m_extSize); 	/* length to copy */	    if (m->m_extSize > max_hdr) 		{		/* avoid costly m_prepends done in the context of tNetTask,		 * especially effective while forwarding packets.		 */		len = min (len, (m->m_extSize - max_linkhdr)); 		m->m_data += max_linkhdr;		}	    }	else            {	    len = min(totlen, m->m_extSize); 	/* length to copy */            }	m->m_len = len; 		/* initialize the length of mbuf */        	if (copy)	    (*copy)(cp, mtod(m, caddr_t), (unsigned)len);	else            {            switch (width)                {                case NONE:                    bcopy(cp, mtod(m, caddr_t), (unsigned)len);                    break;                case 1:                    bcopyBytes (cp, mtod(m, caddr_t), len);                    break;                case 2:                    bcopyWords (cp, mtod(m, caddr_t), (len + 1) >> 1);                    break;                case 4:                    bcopyLongs (cp, mtod(m, caddr_t), (len + 3) >> 2);                    break;                                        default:                    panic ("m_devget -- invalid mem copy width");                    break;                }            }	cp += len;		/* advance the pointer */	*mp = m;	mp = &m->m_next;	/* advance the mbuf */	totlen -= len;		/* decrment the total length */	}    return (top);		/* return the filled mbuf chain */    }#if 0 /* XXX *//* both m_copyback and m_copydata have to be reworked, these functions * are only used in rt_sock.c. They have been moved to rt_sock.c. * They have to be reworked and integrated into netBufLib.c *//* * Copy data from a buffer back into the indicated mbuf chain, * starting "off" bytes from the beginning, extending the mbuf * chain if necessary. */voidm_copyback(m0, off, len, cp)	struct	mbuf *m0;	register int off;	register int len;	caddr_t cp;{	register int mlen;	register struct mbuf *m = m0, *n;	int totlen = 0;	if (m0 == 0)		return;	while (off > (mlen = m->m_len)) {		off -= mlen;		totlen += mlen;		if (m->m_next == 0) {			n = m_getclr(M_DONTWAIT, m->m_type, CL_SIZE_128, TRUE);			if (n == 0)				goto out;			n->m_len = min(n->m_extSize, len + off);			m->m_next = n;		}		m = m->m_next;	}	while (len > 0) {		mlen = min (m->m_len - off, len);		bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);		cp += mlen;		len -= mlen;		mlen += off;		off = 0;		totlen += mlen;		if (len == 0)			break;		if (m->m_next == 0) {			n = mBufClGet(M_DONTWAIT, m->m_type, CL_SIZE_128, TRUE);			if (n == 0)				break;			n->m_len = min(n->m_extSize, len);			m->m_next = n;		}		m = m->m_next;	}out:	if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))		m->m_pkthdr.len = totlen;}/********************************************************************************* m_copydata - copy data from an mbuf chain into a buff* Copy data from an mbuf chain starting "off" bytes from the beginning,* continuing for "len" bytes, into the indicated buffer.*/void m_copydata(m, off, len, cp)    register struct mbuf *m;    register int off;    register int len;    caddr_t cp;    {    register unsigned count;    if (off < 0 || len < 0)	panic("m_copydata");    while (off > 0)	{	if (m == 0)	    panic("m_copydata");	if (off < m->m_len)	    break;	off -= m->m_len;	m = m->m_next;	}    while (len > 0)	{	if (m == 0)	    panic("m_copydata");	count = min(m->m_len - off, len);	bcopy(mtod(m, caddr_t) + off, cp, count);	len -= count;	cp += count;	off = 0;	m = m->m_next;	}    }/* XXX merged with netMblkChainDup in netBufLib.c */LOCAL int 	MCFail;	 	/* XXX temp variable pullup fails *//********************************************************************************* m_copym - make a copy of an mbuf chain.** Make a copy of an mbuf chain starting "off0" bytes from the beginning,* continuing for "len" bytes.  If len is M_COPYALL, copy to end of mbuf.* The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.*/struct mbuf * m_copym(m, off0, len, wait)    register struct mbuf *m;    int off0, wait;    register int len;    {    register struct mbuf *n, **np;    register int off = off0;    struct mbuf *top;    int copyhdr = 0;    if (off < 0 || len < 0)	panic("m_copym");    if (off == 0 && m->m_flags & M_PKTHDR)	copyhdr = 1;    while (off > 0)	{	if (m == 0)	    panic("m_copym");	if (off < m->m_len)	    break;	off -= m->m_len;	m = m->m_next;	}    np = &top;    top = 0;    while (len > 0)	{	if (m == 0)	    {	    if (len != M_COPYALL)		panic("m_copym");	    break;	    }	n = mBlkGet(_pNetDpool, wait, m->m_type);	if ((*np = n) == NULL)	    goto nospace;	if (copyhdr)	    {            n->m_pkthdr = m->m_pkthdr;	    if (len == M_COPYALL)		n->m_pkthdr.len -= off0;	    else		n->m_pkthdr.len = len;	    copyhdr = 0;	    }	n->m_flags = m->m_flags; 	n->m_len = min(len, m->m_len - off);	n->m_data = m->m_data + off;	n->m_ext = m->m_ext;	++(n->m_extRefCnt);	if (len != M_COPYALL)	    len -= n->m_len;	off = 0;	m = m->m_next;	np = &n->m_next;	}    if (top == 0)	MCFail++;    return (top);    nospace:    m_freem(top);    MCFail++;    return (0);    }/* * XXX merged with netMblkClFree & netMblkClChainFree in netBufLib.c * turned m_free and m_freem as macros in mbuf.h *//********************************************************************************* m_free - free the mBlk and cluster pair** This function frees the mBlk and also the cluster if the mBlk points to it.* This function returns a pointer to the next mBlk connected to the one that* is freed.** NOMANUAL* * RETURNS mBLK/NULL*/struct mbuf * m_free    (    FAST struct mbuf * 	pMblk		/* pointer to the mBlk to free */    )    {    FAST struct mbuf *	pMblkNext;	/* pointer to the next mBlk */    NET_POOL_ID		pNetPool;	/* pointer to net pool */        if (pMblk->m_type == MT_FREE)	panic("m_free");    pNetPool 	= MBLK_TO_NET_POOL(pMblk);     pMblkNext 	= pMblk->m_next;    /* free the cluster first if it is attached to the mBlk */        if (M_HASCL(pMblk))			        clBlkFree (pMblk->pClBlk->pNetPool, pMblk->pClBlk);    mBlkFree (pNetPool, pMblk); 		/* free the mBlk */    return (pMblkNext);    }/********************************************************************************* m_freem - free a list of mbufs linked via m_next** N.B.: If MFREE macro changes in mbuf.h m_freem should also change* 	accordingly.*/void m_freem(m)    FAST struct mbuf *m;    {    FAST struct mbuf *n;    if (m == NULL)	return;    do	{	n = m_free (m); 	}    while ((m = n));    }#endif /* XXX have to be reworked */

⌨️ 快捷键说明

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