uipc_mbuf.c revision 113480
1/*
2 * Copyright (c) 1982, 1986, 1988, 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)uipc_mbuf.c	8.2 (Berkeley) 1/4/94
34 * $FreeBSD: head/sys/kern/uipc_mbuf.c 113480 2003-04-14 16:04:10Z rwatson $
35 */
36
37#include "opt_mac.h"
38#include "opt_param.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/lock.h>
44#include <sys/mac.h>
45#include <sys/malloc.h>
46#include <sys/mbuf.h>
47#include <sys/sysctl.h>
48#include <sys/domain.h>
49#include <sys/protosw.h>
50
51int	max_linkhdr;
52int	max_protohdr;
53int	max_hdr;
54int	max_datalen;
55int	m_defragpackets;
56int	m_defragbytes;
57int	m_defraguseless;
58int	m_defragfailure;
59
60/*
61 * sysctl(8) exported objects
62 */
63SYSCTL_DECL(_kern_ipc);
64SYSCTL_INT(_kern_ipc, KIPC_MAX_LINKHDR, max_linkhdr, CTLFLAG_RW,
65	   &max_linkhdr, 0, "");
66SYSCTL_INT(_kern_ipc, KIPC_MAX_PROTOHDR, max_protohdr, CTLFLAG_RW,
67	   &max_protohdr, 0, "");
68SYSCTL_INT(_kern_ipc, KIPC_MAX_HDR, max_hdr, CTLFLAG_RW, &max_hdr, 0, "");
69SYSCTL_INT(_kern_ipc, KIPC_MAX_DATALEN, max_datalen, CTLFLAG_RW,
70	   &max_datalen, 0, "");
71SYSCTL_INT(_kern_ipc, OID_AUTO, m_defragpackets, CTLFLAG_RD,
72	   &m_defragpackets, 0, "");
73SYSCTL_INT(_kern_ipc, OID_AUTO, m_defragbytes, CTLFLAG_RD,
74	   &m_defragbytes, 0, "");
75SYSCTL_INT(_kern_ipc, OID_AUTO, m_defraguseless, CTLFLAG_RD,
76	   &m_defraguseless, 0, "");
77SYSCTL_INT(_kern_ipc, OID_AUTO, m_defragfailure, CTLFLAG_RD,
78	   &m_defragfailure, 0, "");
79
80/*
81 * "Move" mbuf pkthdr from "from" to "to".
82 * "from" must have M_PKTHDR set, and "to" must be empty.
83 */
84void
85m_move_pkthdr(struct mbuf *to, struct mbuf *from)
86{
87
88#if 0
89	/* see below for why these are not enabled */
90	M_ASSERTPKTHDR(to);
91	KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags),
92	    ("m_move_pkthdr: to has tags"));
93#endif
94	KASSERT((to->m_flags & M_EXT) == 0, ("m_move_pkthdr: to has cluster"));
95#ifdef MAC
96	if (to->m_flags & M_PKTHDR)
97		mac_destroy_mbuf(to);
98#endif
99	to->m_flags = from->m_flags & M_COPYFLAGS;
100	to->m_data = to->m_pktdat;
101	to->m_pkthdr = from->m_pkthdr;		/* especially tags */
102#ifdef MAC
103	mac_init_mbuf(to, 1);			/* XXXMAC no way to fail */
104	mac_create_mbuf_from_mbuf(from, to);
105#endif
106	SLIST_INIT(&from->m_pkthdr.tags);	/* purge tags from src */
107	from->m_flags &= ~M_PKTHDR;
108}
109
110/*
111 * Duplicate "from"'s mbuf pkthdr in "to".
112 * "from" must have M_PKTHDR set, and "to" must be empty.
113 * In particular, this does a deep copy of the packet tags.
114 */
115int
116m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
117{
118
119#if 0
120	/*
121	 * The mbuf allocator only initializes the pkthdr
122	 * when the mbuf is allocated with MGETHDR. Many users
123	 * (e.g. m_copy*, m_prepend) use MGET and then
124	 * smash the pkthdr as needed causing these
125	 * assertions to trip.  For now just disable them.
126	 */
127	M_ASSERTPKTHDR(to);
128	KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags), ("m_dup_pkthdr: to has tags"));
129#endif
130#ifdef MAC
131	if (to->m_flags & M_PKTHDR)
132		mac_destroy_mbuf(to);
133#endif
134	to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT);
135	if ((to->m_flags & M_EXT) == 0)
136		to->m_data = to->m_pktdat;
137	to->m_pkthdr = from->m_pkthdr;
138#ifdef MAC
139	mac_init_mbuf(to, 1);			/* XXXMAC no way to fail */
140	mac_create_mbuf_from_mbuf(from, to);
141#endif
142	SLIST_INIT(&to->m_pkthdr.tags);
143	return (m_tag_copy_chain(to, from, MBTOM(how)));
144}
145
146/*
147 * Lesser-used path for M_PREPEND:
148 * allocate new mbuf to prepend to chain,
149 * copy junk along.
150 */
151struct mbuf *
152m_prepend(struct mbuf *m, int len, int how)
153{
154	struct mbuf *mn;
155
156	MGET(mn, how, m->m_type);
157	if (mn == NULL) {
158		m_freem(m);
159		return (NULL);
160	}
161	if (m->m_flags & M_PKTHDR) {
162		M_MOVE_PKTHDR(mn, m);
163#ifdef MAC
164		mac_destroy_mbuf(m);
165#endif
166	}
167	mn->m_next = m;
168	m = mn;
169	if (len < MHLEN)
170		MH_ALIGN(m, len);
171	m->m_len = len;
172	return (m);
173}
174
175/*
176 * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
177 * continuing for "len" bytes.  If len is M_COPYALL, copy to end of mbuf.
178 * The wait parameter is a choice of M_TRYWAIT/M_DONTWAIT from caller.
179 * Note that the copy is read-only, because clusters are not copied,
180 * only their reference counts are incremented.
181 */
182struct mbuf *
183m_copym(struct mbuf *m, int off0, int len, int wait)
184{
185	struct mbuf *n, **np;
186	int off = off0;
187	struct mbuf *top;
188	int copyhdr = 0;
189
190	KASSERT(off >= 0, ("m_copym, negative off %d", off));
191	KASSERT(len >= 0, ("m_copym, negative len %d", len));
192	if (off == 0 && m->m_flags & M_PKTHDR)
193		copyhdr = 1;
194	while (off > 0) {
195		KASSERT(m != NULL, ("m_copym, offset > size of mbuf chain"));
196		if (off < m->m_len)
197			break;
198		off -= m->m_len;
199		m = m->m_next;
200	}
201	np = &top;
202	top = 0;
203	while (len > 0) {
204		if (m == NULL) {
205			KASSERT(len == M_COPYALL,
206			    ("m_copym, length > size of mbuf chain"));
207			break;
208		}
209		MGET(n, wait, m->m_type);
210		*np = n;
211		if (n == NULL)
212			goto nospace;
213		if (copyhdr) {
214			if (!m_dup_pkthdr(n, m, wait))
215				goto nospace;
216			if (len == M_COPYALL)
217				n->m_pkthdr.len -= off0;
218			else
219				n->m_pkthdr.len = len;
220			copyhdr = 0;
221		}
222		n->m_len = min(len, m->m_len - off);
223		if (m->m_flags & M_EXT) {
224			n->m_data = m->m_data + off;
225			n->m_ext = m->m_ext;
226			n->m_flags |= M_EXT;
227			MEXT_ADD_REF(m);
228		} else
229			bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
230			    (u_int)n->m_len);
231		if (len != M_COPYALL)
232			len -= n->m_len;
233		off = 0;
234		m = m->m_next;
235		np = &n->m_next;
236	}
237	if (top == NULL)
238		mbstat.m_mcfail++;	/* XXX: No consistency. */
239
240	return (top);
241nospace:
242	m_freem(top);
243	mbstat.m_mcfail++;	/* XXX: No consistency. */
244	return (NULL);
245}
246
247/*
248 * Copy an entire packet, including header (which must be present).
249 * An optimization of the common case `m_copym(m, 0, M_COPYALL, how)'.
250 * Note that the copy is read-only, because clusters are not copied,
251 * only their reference counts are incremented.
252 * Preserve alignment of the first mbuf so if the creator has left
253 * some room at the beginning (e.g. for inserting protocol headers)
254 * the copies still have the room available.
255 */
256struct mbuf *
257m_copypacket(struct mbuf *m, int how)
258{
259	struct mbuf *top, *n, *o;
260
261	MGET(n, how, m->m_type);
262	top = n;
263	if (n == NULL)
264		goto nospace;
265
266	if (!m_dup_pkthdr(n, m, how))
267		goto nospace;
268	n->m_len = m->m_len;
269	if (m->m_flags & M_EXT) {
270		n->m_data = m->m_data;
271		n->m_ext = m->m_ext;
272		n->m_flags |= M_EXT;
273		MEXT_ADD_REF(m);
274	} else {
275		n->m_data = n->m_pktdat + (m->m_data - m->m_pktdat );
276		bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
277	}
278
279	m = m->m_next;
280	while (m) {
281		MGET(o, how, m->m_type);
282		if (o == NULL)
283			goto nospace;
284
285		n->m_next = o;
286		n = n->m_next;
287
288		n->m_len = m->m_len;
289		if (m->m_flags & M_EXT) {
290			n->m_data = m->m_data;
291			n->m_ext = m->m_ext;
292			n->m_flags |= M_EXT;
293			MEXT_ADD_REF(m);
294		} else {
295			bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
296		}
297
298		m = m->m_next;
299	}
300	return top;
301nospace:
302	m_freem(top);
303	mbstat.m_mcfail++;	/* XXX: No consistency. */
304	return (NULL);
305}
306
307/*
308 * Copy data from an mbuf chain starting "off" bytes from the beginning,
309 * continuing for "len" bytes, into the indicated buffer.
310 */
311void
312m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
313{
314	u_int count;
315
316	KASSERT(off >= 0, ("m_copydata, negative off %d", off));
317	KASSERT(len >= 0, ("m_copydata, negative len %d", len));
318	while (off > 0) {
319		KASSERT(m != NULL, ("m_copydata, offset > size of mbuf chain"));
320		if (off < m->m_len)
321			break;
322		off -= m->m_len;
323		m = m->m_next;
324	}
325	while (len > 0) {
326		KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain"));
327		count = min(m->m_len - off, len);
328		bcopy(mtod(m, caddr_t) + off, cp, count);
329		len -= count;
330		cp += count;
331		off = 0;
332		m = m->m_next;
333	}
334}
335
336/*
337 * Copy a packet header mbuf chain into a completely new chain, including
338 * copying any mbuf clusters.  Use this instead of m_copypacket() when
339 * you need a writable copy of an mbuf chain.
340 */
341struct mbuf *
342m_dup(struct mbuf *m, int how)
343{
344	struct mbuf **p, *top = NULL;
345	int remain, moff, nsize;
346
347	/* Sanity check */
348	if (m == NULL)
349		return (NULL);
350	M_ASSERTPKTHDR(m);
351
352	/* While there's more data, get a new mbuf, tack it on, and fill it */
353	remain = m->m_pkthdr.len;
354	moff = 0;
355	p = &top;
356	while (remain > 0 || top == NULL) {	/* allow m->m_pkthdr.len == 0 */
357		struct mbuf *n;
358
359		/* Get the next new mbuf */
360		MGET(n, how, m->m_type);
361		if (n == NULL)
362			goto nospace;
363		if (top == NULL) {		/* first one, must be PKTHDR */
364			if (!m_dup_pkthdr(n, m, how))
365				goto nospace;
366			nsize = MHLEN;
367		} else				/* not the first one */
368			nsize = MLEN;
369		if (remain >= MINCLSIZE) {
370			MCLGET(n, how);
371			if ((n->m_flags & M_EXT) == 0) {
372				(void)m_free(n);
373				goto nospace;
374			}
375			nsize = MCLBYTES;
376		}
377		n->m_len = 0;
378
379		/* Link it into the new chain */
380		*p = n;
381		p = &n->m_next;
382
383		/* Copy data from original mbuf(s) into new mbuf */
384		while (n->m_len < nsize && m != NULL) {
385			int chunk = min(nsize - n->m_len, m->m_len - moff);
386
387			bcopy(m->m_data + moff, n->m_data + n->m_len, chunk);
388			moff += chunk;
389			n->m_len += chunk;
390			remain -= chunk;
391			if (moff == m->m_len) {
392				m = m->m_next;
393				moff = 0;
394			}
395		}
396
397		/* Check correct total mbuf length */
398		KASSERT((remain > 0 && m != NULL) || (remain == 0 && m == NULL),
399		    	("%s: bogus m_pkthdr.len", __func__));
400	}
401	return (top);
402
403nospace:
404	m_freem(top);
405	mbstat.m_mcfail++;	/* XXX: No consistency. */
406	return (NULL);
407}
408
409/*
410 * Concatenate mbuf chain n to m.
411 * Both chains must be of the same type (e.g. MT_DATA).
412 * Any m_pkthdr is not updated.
413 */
414void
415m_cat(struct mbuf *m, struct mbuf *n)
416{
417	while (m->m_next)
418		m = m->m_next;
419	while (n) {
420		if (m->m_flags & M_EXT ||
421		    m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
422			/* just join the two chains */
423			m->m_next = n;
424			return;
425		}
426		/* splat the data from one into the other */
427		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
428		    (u_int)n->m_len);
429		m->m_len += n->m_len;
430		n = m_free(n);
431	}
432}
433
434void
435m_adj(struct mbuf *mp, int req_len)
436{
437	int len = req_len;
438	struct mbuf *m;
439	int count;
440
441	if ((m = mp) == NULL)
442		return;
443	if (len >= 0) {
444		/*
445		 * Trim from head.
446		 */
447		while (m != NULL && len > 0) {
448			if (m->m_len <= len) {
449				len -= m->m_len;
450				m->m_len = 0;
451				m = m->m_next;
452			} else {
453				m->m_len -= len;
454				m->m_data += len;
455				len = 0;
456			}
457		}
458		m = mp;
459		if (mp->m_flags & M_PKTHDR)
460			m->m_pkthdr.len -= (req_len - len);
461	} else {
462		/*
463		 * Trim from tail.  Scan the mbuf chain,
464		 * calculating its length and finding the last mbuf.
465		 * If the adjustment only affects this mbuf, then just
466		 * adjust and return.  Otherwise, rescan and truncate
467		 * after the remaining size.
468		 */
469		len = -len;
470		count = 0;
471		for (;;) {
472			count += m->m_len;
473			if (m->m_next == (struct mbuf *)0)
474				break;
475			m = m->m_next;
476		}
477		if (m->m_len >= len) {
478			m->m_len -= len;
479			if (mp->m_flags & M_PKTHDR)
480				mp->m_pkthdr.len -= len;
481			return;
482		}
483		count -= len;
484		if (count < 0)
485			count = 0;
486		/*
487		 * Correct length for chain is "count".
488		 * Find the mbuf with last data, adjust its length,
489		 * and toss data from remaining mbufs on chain.
490		 */
491		m = mp;
492		if (m->m_flags & M_PKTHDR)
493			m->m_pkthdr.len = count;
494		for (; m; m = m->m_next) {
495			if (m->m_len >= count) {
496				m->m_len = count;
497				break;
498			}
499			count -= m->m_len;
500		}
501		while (m->m_next)
502			(m = m->m_next) ->m_len = 0;
503	}
504}
505
506/*
507 * Rearange an mbuf chain so that len bytes are contiguous
508 * and in the data area of an mbuf (so that mtod and dtom
509 * will work for a structure of size len).  Returns the resulting
510 * mbuf chain on success, frees it and returns null on failure.
511 * If there is room, it will add up to max_protohdr-len extra bytes to the
512 * contiguous region in an attempt to avoid being called next time.
513 */
514struct mbuf *
515m_pullup(struct mbuf *n, int len)
516{
517	struct mbuf *m;
518	int count;
519	int space;
520
521	/*
522	 * If first mbuf has no cluster, and has room for len bytes
523	 * without shifting current data, pullup into it,
524	 * otherwise allocate a new mbuf to prepend to the chain.
525	 */
526	if ((n->m_flags & M_EXT) == 0 &&
527	    n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
528		if (n->m_len >= len)
529			return (n);
530		m = n;
531		n = n->m_next;
532		len -= m->m_len;
533	} else {
534		if (len > MHLEN)
535			goto bad;
536		MGET(m, M_DONTWAIT, n->m_type);
537		if (m == NULL)
538			goto bad;
539		m->m_len = 0;
540		if (n->m_flags & M_PKTHDR)
541			M_MOVE_PKTHDR(m, n);
542	}
543	space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
544	do {
545		count = min(min(max(len, max_protohdr), space), n->m_len);
546		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
547		  (u_int)count);
548		len -= count;
549		m->m_len += count;
550		n->m_len -= count;
551		space -= count;
552		if (n->m_len)
553			n->m_data += count;
554		else
555			n = m_free(n);
556	} while (len > 0 && n);
557	if (len > 0) {
558		(void) m_free(m);
559		goto bad;
560	}
561	m->m_next = n;
562	return (m);
563bad:
564	m_freem(n);
565	mbstat.m_mpfail++;	/* XXX: No consistency. */
566	return (NULL);
567}
568
569/*
570 * Partition an mbuf chain in two pieces, returning the tail --
571 * all but the first len0 bytes.  In case of failure, it returns NULL and
572 * attempts to restore the chain to its original state.
573 *
574 * Note that the resulting mbufs might be read-only, because the new
575 * mbuf can end up sharing an mbuf cluster with the original mbuf if
576 * the "breaking point" happens to lie within a cluster mbuf. Use the
577 * M_WRITABLE() macro to check for this case.
578 */
579struct mbuf *
580m_split(struct mbuf *m0, int len0, int wait)
581{
582	struct mbuf *m, *n;
583	u_int len = len0, remain;
584
585	for (m = m0; m && len > m->m_len; m = m->m_next)
586		len -= m->m_len;
587	if (m == NULL)
588		return (NULL);
589	remain = m->m_len - len;
590	if (m0->m_flags & M_PKTHDR) {
591		MGETHDR(n, wait, m0->m_type);
592		if (n == NULL)
593			return (NULL);
594		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
595		n->m_pkthdr.len = m0->m_pkthdr.len - len0;
596		m0->m_pkthdr.len = len0;
597		if (m->m_flags & M_EXT)
598			goto extpacket;
599		if (remain > MHLEN) {
600			/* m can't be the lead packet */
601			MH_ALIGN(n, 0);
602			n->m_next = m_split(m, len, wait);
603			if (n->m_next == NULL) {
604				(void) m_free(n);
605				return (NULL);
606			} else {
607				n->m_len = 0;
608				return (n);
609			}
610		} else
611			MH_ALIGN(n, remain);
612	} else if (remain == 0) {
613		n = m->m_next;
614		m->m_next = NULL;
615		return (n);
616	} else {
617		MGET(n, wait, m->m_type);
618		if (n == NULL)
619			return (NULL);
620		M_ALIGN(n, remain);
621	}
622extpacket:
623	if (m->m_flags & M_EXT) {
624		n->m_flags |= M_EXT;
625		n->m_ext = m->m_ext;
626		MEXT_ADD_REF(m);
627		n->m_data = m->m_data + len;
628	} else {
629		bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
630	}
631	n->m_len = remain;
632	m->m_len = len;
633	n->m_next = m->m_next;
634	m->m_next = NULL;
635	return (n);
636}
637/*
638 * Routine to copy from device local memory into mbufs.
639 * Note that `off' argument is offset into first mbuf of target chain from
640 * which to begin copying the data to.
641 */
642struct mbuf *
643m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
644	 void (*copy)(char *from, caddr_t to, u_int len))
645{
646	struct mbuf *m;
647	struct mbuf *top = 0, **mp = &top;
648	int len;
649
650	if (off < 0 || off > MHLEN)
651		return (NULL);
652
653	MGETHDR(m, M_DONTWAIT, MT_DATA);
654	if (m == NULL)
655		return (NULL);
656	m->m_pkthdr.rcvif = ifp;
657	m->m_pkthdr.len = totlen;
658	len = MHLEN;
659
660	while (totlen > 0) {
661		if (top) {
662			MGET(m, M_DONTWAIT, MT_DATA);
663			if (m == NULL) {
664				m_freem(top);
665				return (NULL);
666			}
667			len = MLEN;
668		}
669		if (totlen + off >= MINCLSIZE) {
670			MCLGET(m, M_DONTWAIT);
671			if (m->m_flags & M_EXT)
672				len = MCLBYTES;
673		} else {
674			/*
675			 * Place initial small packet/header at end of mbuf.
676			 */
677			if (top == NULL && totlen + off + max_linkhdr <= len) {
678				m->m_data += max_linkhdr;
679				len -= max_linkhdr;
680			}
681		}
682		if (off) {
683			m->m_data += off;
684			len -= off;
685			off = 0;
686		}
687		m->m_len = len = min(totlen, len);
688		if (copy)
689			copy(buf, mtod(m, caddr_t), (u_int)len);
690		else
691			bcopy(buf, mtod(m, caddr_t), (u_int)len);
692		buf += len;
693		*mp = m;
694		mp = &m->m_next;
695		totlen -= len;
696	}
697	return (top);
698}
699
700/*
701 * Copy data from a buffer back into the indicated mbuf chain,
702 * starting "off" bytes from the beginning, extending the mbuf
703 * chain if necessary.
704 */
705void
706m_copyback(struct mbuf *m0, int off, int len, caddr_t cp)
707{
708	int mlen;
709	struct mbuf *m = m0, *n;
710	int totlen = 0;
711
712	if (m0 == NULL)
713		return;
714	while (off > (mlen = m->m_len)) {
715		off -= mlen;
716		totlen += mlen;
717		if (m->m_next == NULL) {
718			n = m_get_clrd(M_DONTWAIT, m->m_type);
719			if (n == NULL)
720				goto out;
721			n->m_len = min(MLEN, len + off);
722			m->m_next = n;
723		}
724		m = m->m_next;
725	}
726	while (len > 0) {
727		mlen = min (m->m_len - off, len);
728		bcopy(cp, off + mtod(m, caddr_t), (u_int)mlen);
729		cp += mlen;
730		len -= mlen;
731		mlen += off;
732		off = 0;
733		totlen += mlen;
734		if (len == 0)
735			break;
736		if (m->m_next == NULL) {
737			n = m_get(M_DONTWAIT, m->m_type);
738			if (n == NULL)
739				break;
740			n->m_len = min(MLEN, len);
741			m->m_next = n;
742		}
743		m = m->m_next;
744	}
745out:	if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
746		m->m_pkthdr.len = totlen;
747}
748
749void
750m_print(const struct mbuf *m)
751{
752	int len;
753	const struct mbuf *m2;
754
755	len = m->m_pkthdr.len;
756	m2 = m;
757	while (len) {
758		printf("%p %*D\n", m2, m2->m_len, (u_char *)m2->m_data, "-");
759		len -= m2->m_len;
760		m2 = m2->m_next;
761	}
762	return;
763}
764
765u_int
766m_fixhdr(struct mbuf *m0)
767{
768	u_int len;
769
770	len = m_length(m0, NULL);
771	m0->m_pkthdr.len = len;
772	return (len);
773}
774
775u_int
776m_length(struct mbuf *m0, struct mbuf **last)
777{
778	struct mbuf *m;
779	u_int len;
780
781	len = 0;
782	for (m = m0; m != NULL; m = m->m_next) {
783		len += m->m_len;
784		if (m->m_next == NULL)
785			break;
786	}
787	if (last != NULL)
788		*last = m;
789	return (len);
790}
791
792/*
793 * Defragment a mbuf chain, returning the shortest possible
794 * chain of mbufs and clusters.  If allocation fails and
795 * this cannot be completed, NULL will be returned, but
796 * the passed in chain will be unchanged.  Upon success,
797 * the original chain will be freed, and the new chain
798 * will be returned.
799 *
800 * If a non-packet header is passed in, the original
801 * mbuf (chain?) will be returned unharmed.
802 */
803struct mbuf *
804m_defrag(struct mbuf *m0, int how)
805{
806	struct mbuf	*m_new = NULL, *m_final = NULL;
807	int		progress = 0, length;
808
809	if (!(m0->m_flags & M_PKTHDR))
810		return (m0);
811
812
813	if (m0->m_pkthdr.len > MHLEN)
814		m_final = m_getcl(how, MT_DATA, M_PKTHDR);
815	else
816		m_final = m_gethdr(how, MT_DATA);
817
818	if (m_final == NULL)
819		goto nospace;
820
821	if (m_dup_pkthdr(m_final, m0, how) == NULL)
822		goto nospace;
823
824	m_new = m_final;
825
826	while (progress < m0->m_pkthdr.len) {
827		length = m0->m_pkthdr.len - progress;
828		if (length > MCLBYTES)
829			length = MCLBYTES;
830
831		if (m_new == NULL) {
832			if (length > MLEN)
833				m_new = m_getcl(how, MT_DATA, 0);
834			else
835				m_new = m_get(how, MT_DATA);
836			if (m_new == NULL)
837				goto nospace;
838		}
839
840		m_copydata(m0, progress, length, mtod(m_new, caddr_t));
841		progress += length;
842		m_new->m_len = length;
843		if (m_new != m_final)
844			m_cat(m_final, m_new);
845		m_new = NULL;
846	}
847	if (m0->m_next == NULL)
848		m_defraguseless++;
849	m_freem(m0);
850	m0 = m_final;
851	m_defragpackets++;
852	m_defragbytes += m0->m_pkthdr.len;
853	return (m0);
854nospace:
855	m_defragfailure++;
856	if (m_new)
857		m_free(m_new);
858	if (m_final)
859		m_freem(m_final);
860	return (NULL);
861}
862