uipc_mbuf.c revision 108466
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 108466 2002-12-30 20:22:40Z sam $
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;
55
56/*
57 * sysctl(8) exported objects
58 */
59SYSCTL_DECL(_kern_ipc);
60SYSCTL_INT(_kern_ipc, KIPC_MAX_LINKHDR, max_linkhdr, CTLFLAG_RW,
61	   &max_linkhdr, 0, "");
62SYSCTL_INT(_kern_ipc, KIPC_MAX_PROTOHDR, max_protohdr, CTLFLAG_RW,
63	   &max_protohdr, 0, "");
64SYSCTL_INT(_kern_ipc, KIPC_MAX_HDR, max_hdr, CTLFLAG_RW, &max_hdr, 0, "");
65SYSCTL_INT(_kern_ipc, KIPC_MAX_DATALEN, max_datalen, CTLFLAG_RW,
66	   &max_datalen, 0, "");
67
68/*
69 * "Move" mbuf pkthdr from "from" to "to".
70 * "from" must have M_PKTHDR set, and "to" must be empty.
71 */
72void
73m_move_pkthdr(struct mbuf *to, struct mbuf *from)
74{
75
76#if 0
77	/* see below for why these are not enabled */
78	KASSERT(to->m_flags & M_PKTHDR,
79	    ("m_move_pkthdr: called on non-header"));
80	KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags),
81	    ("m_move_pkthdr: to has tags"));
82#endif
83	KASSERT((to->m_flags & M_EXT) == 0, ("m_move_pkthdr: to has cluster"));
84#ifdef MAC
85	if (to->m_flags & M_PKTHDR)
86		mac_destroy_mbuf(to);
87#endif
88	to->m_flags = from->m_flags & M_COPYFLAGS;
89	to->m_data = to->m_pktdat;
90	to->m_pkthdr = from->m_pkthdr;		/* especially tags */
91#ifdef MAC
92	mac_init_mbuf(to, 1);			/* XXXMAC no way to fail */
93	mac_create_mbuf_from_mbuf(from, to);
94#endif
95	SLIST_INIT(&from->m_pkthdr.tags);	/* purge tags from src */
96	from->m_flags &= ~M_PKTHDR;
97}
98
99/*
100 * Duplicate "from"'s mbuf pkthdr in "to".
101 * "from" must have M_PKTHDR set, and "to" must be empty.
102 * In particular, this does a deep copy of the packet tags.
103 */
104int
105m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
106{
107
108#if 0
109	/*
110	 * The mbuf allocator only initializes the pkthdr
111	 * when the mbuf is allocated with MGETHDR. Many users
112	 * (e.g. m_copy*, m_prepend) use MGET and then
113	 * smash the pkthdr as needed causing these
114	 * assertions to trip.  For now just disable them.
115	 */
116	KASSERT(to->m_flags & M_PKTHDR, ("m_dup_pkthdr: called on non-header"));
117	KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags), ("m_dup_pkthdr: to has tags"));
118#endif
119	KASSERT((to->m_flags & M_EXT) == 0, ("m_dup_pkthdr: to has cluster"));
120#ifdef MAC
121	if (to->m_flags & M_PKTHDR)
122		mac_destroy_mbuf(to);
123#endif
124	to->m_flags = from->m_flags & M_COPYFLAGS;
125	to->m_data = to->m_pktdat;
126	to->m_pkthdr = from->m_pkthdr;
127#ifdef MAC
128	mac_init_mbuf(to, 1);			/* XXXMAC no way to fail */
129	mac_create_mbuf_from_mbuf(from, to);
130#endif
131	SLIST_INIT(&to->m_pkthdr.tags);
132	return (m_tag_copy_chain(to, from, how));
133}
134
135/*
136 * Lesser-used path for M_PREPEND:
137 * allocate new mbuf to prepend to chain,
138 * copy junk along.
139 */
140struct mbuf *
141m_prepend(struct mbuf *m, int len, int how)
142{
143	struct mbuf *mn;
144
145	MGET(mn, how, m->m_type);
146	if (mn == NULL) {
147		m_freem(m);
148		return (NULL);
149	}
150	if (m->m_flags & M_PKTHDR) {
151		M_MOVE_PKTHDR(mn, m);
152#ifdef MAC
153		mac_destroy_mbuf(m);
154#endif
155	}
156	mn->m_next = m;
157	m = mn;
158	if (len < MHLEN)
159		MH_ALIGN(m, len);
160	m->m_len = len;
161	return (m);
162}
163
164/*
165 * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
166 * continuing for "len" bytes.  If len is M_COPYALL, copy to end of mbuf.
167 * The wait parameter is a choice of M_TRYWAIT/M_DONTWAIT from caller.
168 * Note that the copy is read-only, because clusters are not copied,
169 * only their reference counts are incremented.
170 */
171struct mbuf *
172m_copym(struct mbuf *m, int off0, int len, int wait)
173{
174	struct mbuf *n, **np;
175	int off = off0;
176	struct mbuf *top;
177	int copyhdr = 0;
178
179	KASSERT(off >= 0, ("m_copym, negative off %d", off));
180	KASSERT(len >= 0, ("m_copym, negative len %d", len));
181	if (off == 0 && m->m_flags & M_PKTHDR)
182		copyhdr = 1;
183	while (off > 0) {
184		KASSERT(m != NULL, ("m_copym, offset > size of mbuf chain"));
185		if (off < m->m_len)
186			break;
187		off -= m->m_len;
188		m = m->m_next;
189	}
190	np = &top;
191	top = 0;
192	while (len > 0) {
193		if (m == NULL) {
194			KASSERT(len == M_COPYALL,
195			    ("m_copym, length > size of mbuf chain"));
196			break;
197		}
198		MGET(n, wait, m->m_type);
199		*np = n;
200		if (n == NULL)
201			goto nospace;
202		if (copyhdr) {
203			if (!m_dup_pkthdr(n, m, wait))
204				goto nospace;
205			if (len == M_COPYALL)
206				n->m_pkthdr.len -= off0;
207			else
208				n->m_pkthdr.len = len;
209			copyhdr = 0;
210		}
211		n->m_len = min(len, m->m_len - off);
212		if (m->m_flags & M_EXT) {
213			n->m_data = m->m_data + off;
214			n->m_ext = m->m_ext;
215			n->m_flags |= M_EXT;
216			MEXT_ADD_REF(m);
217		} else
218			bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
219			    (u_int)n->m_len);
220		if (len != M_COPYALL)
221			len -= n->m_len;
222		off = 0;
223		m = m->m_next;
224		np = &n->m_next;
225	}
226	if (top == NULL)
227		mbstat.m_mcfail++;	/* XXX: No consistency. */
228
229	return (top);
230nospace:
231	m_freem(top);
232	mbstat.m_mcfail++;	/* XXX: No consistency. */
233	return (NULL);
234}
235
236/*
237 * Copy an entire packet, including header (which must be present).
238 * An optimization of the common case `m_copym(m, 0, M_COPYALL, how)'.
239 * Note that the copy is read-only, because clusters are not copied,
240 * only their reference counts are incremented.
241 * Preserve alignment of the first mbuf so if the creator has left
242 * some room at the beginning (e.g. for inserting protocol headers)
243 * the copies still have the room available.
244 */
245struct mbuf *
246m_copypacket(struct mbuf *m, int how)
247{
248	struct mbuf *top, *n, *o;
249
250	MGET(n, how, m->m_type);
251	top = n;
252	if (n == NULL)
253		goto nospace;
254
255	if (!m_dup_pkthdr(n, m, how))
256		goto nospace;
257	n->m_len = m->m_len;
258	if (m->m_flags & M_EXT) {
259		n->m_data = m->m_data;
260		n->m_ext = m->m_ext;
261		n->m_flags |= M_EXT;
262		MEXT_ADD_REF(m);
263	} else {
264		n->m_data = n->m_pktdat + (m->m_data - m->m_pktdat );
265		bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
266	}
267
268	m = m->m_next;
269	while (m) {
270		MGET(o, how, m->m_type);
271		if (o == NULL)
272			goto nospace;
273
274		n->m_next = o;
275		n = n->m_next;
276
277		n->m_len = m->m_len;
278		if (m->m_flags & M_EXT) {
279			n->m_data = m->m_data;
280			n->m_ext = m->m_ext;
281			n->m_flags |= M_EXT;
282			MEXT_ADD_REF(m);
283		} else {
284			bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
285		}
286
287		m = m->m_next;
288	}
289	return top;
290nospace:
291	m_freem(top);
292	mbstat.m_mcfail++;	/* XXX: No consistency. */
293	return (NULL);
294}
295
296/*
297 * Copy data from an mbuf chain starting "off" bytes from the beginning,
298 * continuing for "len" bytes, into the indicated buffer.
299 */
300void
301m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
302{
303	u_int count;
304
305	KASSERT(off >= 0, ("m_copydata, negative off %d", off));
306	KASSERT(len >= 0, ("m_copydata, negative len %d", len));
307	while (off > 0) {
308		KASSERT(m != NULL, ("m_copydata, offset > size of mbuf chain"));
309		if (off < m->m_len)
310			break;
311		off -= m->m_len;
312		m = m->m_next;
313	}
314	while (len > 0) {
315		KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain"));
316		count = min(m->m_len - off, len);
317		bcopy(mtod(m, caddr_t) + off, cp, count);
318		len -= count;
319		cp += count;
320		off = 0;
321		m = m->m_next;
322	}
323}
324
325/*
326 * Copy a packet header mbuf chain into a completely new chain, including
327 * copying any mbuf clusters.  Use this instead of m_copypacket() when
328 * you need a writable copy of an mbuf chain.
329 */
330struct mbuf *
331m_dup(struct mbuf *m, int how)
332{
333	struct mbuf **p, *top = NULL;
334	int remain, moff, nsize;
335
336	/* Sanity check */
337	if (m == NULL)
338		return (NULL);
339	KASSERT((m->m_flags & M_PKTHDR) != 0, ("%s: !PKTHDR", __func__));
340
341	/* While there's more data, get a new mbuf, tack it on, and fill it */
342	remain = m->m_pkthdr.len;
343	moff = 0;
344	p = &top;
345	while (remain > 0 || top == NULL) {	/* allow m->m_pkthdr.len == 0 */
346		struct mbuf *n;
347
348		/* Get the next new mbuf */
349		MGET(n, how, m->m_type);
350		if (n == NULL)
351			goto nospace;
352		if (top == NULL) {		/* first one, must be PKTHDR */
353			if (!m_dup_pkthdr(n, m, how))
354				goto nospace;
355			nsize = MHLEN;
356		} else				/* not the first one */
357			nsize = MLEN;
358		if (remain >= MINCLSIZE) {
359			MCLGET(n, how);
360			if ((n->m_flags & M_EXT) == 0) {
361				(void)m_free(n);
362				goto nospace;
363			}
364			nsize = MCLBYTES;
365		}
366		n->m_len = 0;
367
368		/* Link it into the new chain */
369		*p = n;
370		p = &n->m_next;
371
372		/* Copy data from original mbuf(s) into new mbuf */
373		while (n->m_len < nsize && m != NULL) {
374			int chunk = min(nsize - n->m_len, m->m_len - moff);
375
376			bcopy(m->m_data + moff, n->m_data + n->m_len, chunk);
377			moff += chunk;
378			n->m_len += chunk;
379			remain -= chunk;
380			if (moff == m->m_len) {
381				m = m->m_next;
382				moff = 0;
383			}
384		}
385
386		/* Check correct total mbuf length */
387		KASSERT((remain > 0 && m != NULL) || (remain == 0 && m == NULL),
388		    	("%s: bogus m_pkthdr.len", __func__));
389	}
390	return (top);
391
392nospace:
393	m_freem(top);
394	mbstat.m_mcfail++;	/* XXX: No consistency. */
395	return (NULL);
396}
397
398/*
399 * Concatenate mbuf chain n to m.
400 * Both chains must be of the same type (e.g. MT_DATA).
401 * Any m_pkthdr is not updated.
402 */
403void
404m_cat(struct mbuf *m, struct mbuf *n)
405{
406	while (m->m_next)
407		m = m->m_next;
408	while (n) {
409		if (m->m_flags & M_EXT ||
410		    m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
411			/* just join the two chains */
412			m->m_next = n;
413			return;
414		}
415		/* splat the data from one into the other */
416		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
417		    (u_int)n->m_len);
418		m->m_len += n->m_len;
419		n = m_free(n);
420	}
421}
422
423void
424m_adj(struct mbuf *mp, int req_len)
425{
426	int len = req_len;
427	struct mbuf *m;
428	int count;
429
430	if ((m = mp) == NULL)
431		return;
432	if (len >= 0) {
433		/*
434		 * Trim from head.
435		 */
436		while (m != NULL && len > 0) {
437			if (m->m_len <= len) {
438				len -= m->m_len;
439				m->m_len = 0;
440				m = m->m_next;
441			} else {
442				m->m_len -= len;
443				m->m_data += len;
444				len = 0;
445			}
446		}
447		m = mp;
448		if (mp->m_flags & M_PKTHDR)
449			m->m_pkthdr.len -= (req_len - len);
450	} else {
451		/*
452		 * Trim from tail.  Scan the mbuf chain,
453		 * calculating its length and finding the last mbuf.
454		 * If the adjustment only affects this mbuf, then just
455		 * adjust and return.  Otherwise, rescan and truncate
456		 * after the remaining size.
457		 */
458		len = -len;
459		count = 0;
460		for (;;) {
461			count += m->m_len;
462			if (m->m_next == (struct mbuf *)0)
463				break;
464			m = m->m_next;
465		}
466		if (m->m_len >= len) {
467			m->m_len -= len;
468			if (mp->m_flags & M_PKTHDR)
469				mp->m_pkthdr.len -= len;
470			return;
471		}
472		count -= len;
473		if (count < 0)
474			count = 0;
475		/*
476		 * Correct length for chain is "count".
477		 * Find the mbuf with last data, adjust its length,
478		 * and toss data from remaining mbufs on chain.
479		 */
480		m = mp;
481		if (m->m_flags & M_PKTHDR)
482			m->m_pkthdr.len = count;
483		for (; m; m = m->m_next) {
484			if (m->m_len >= count) {
485				m->m_len = count;
486				break;
487			}
488			count -= m->m_len;
489		}
490		while (m->m_next)
491			(m = m->m_next) ->m_len = 0;
492	}
493}
494
495/*
496 * Rearange an mbuf chain so that len bytes are contiguous
497 * and in the data area of an mbuf (so that mtod and dtom
498 * will work for a structure of size len).  Returns the resulting
499 * mbuf chain on success, frees it and returns null on failure.
500 * If there is room, it will add up to max_protohdr-len extra bytes to the
501 * contiguous region in an attempt to avoid being called next time.
502 */
503struct mbuf *
504m_pullup(struct mbuf *n, int len)
505{
506	struct mbuf *m;
507	int count;
508	int space;
509
510	/*
511	 * If first mbuf has no cluster, and has room for len bytes
512	 * without shifting current data, pullup into it,
513	 * otherwise allocate a new mbuf to prepend to the chain.
514	 */
515	if ((n->m_flags & M_EXT) == 0 &&
516	    n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
517		if (n->m_len >= len)
518			return (n);
519		m = n;
520		n = n->m_next;
521		len -= m->m_len;
522	} else {
523		if (len > MHLEN)
524			goto bad;
525		MGET(m, M_DONTWAIT, n->m_type);
526		if (m == NULL)
527			goto bad;
528		m->m_len = 0;
529		if (n->m_flags & M_PKTHDR)
530			M_MOVE_PKTHDR(m, n);
531	}
532	space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
533	do {
534		count = min(min(max(len, max_protohdr), space), n->m_len);
535		bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
536		  (u_int)count);
537		len -= count;
538		m->m_len += count;
539		n->m_len -= count;
540		space -= count;
541		if (n->m_len)
542			n->m_data += count;
543		else
544			n = m_free(n);
545	} while (len > 0 && n);
546	if (len > 0) {
547		(void) m_free(m);
548		goto bad;
549	}
550	m->m_next = n;
551	return (m);
552bad:
553	m_freem(n);
554	mbstat.m_mpfail++;	/* XXX: No consistency. */
555	return (NULL);
556}
557
558/*
559 * Partition an mbuf chain in two pieces, returning the tail --
560 * all but the first len0 bytes.  In case of failure, it returns NULL and
561 * attempts to restore the chain to its original state.
562 *
563 * Note that the resulting mbufs might be read-only, because the new
564 * mbuf can end up sharing an mbuf cluster with the original mbuf if
565 * the "breaking point" happens to lie within a cluster mbuf. Use the
566 * M_WRITABLE() macro to check for this case.
567 */
568struct mbuf *
569m_split(struct mbuf *m0, int len0, int wait)
570{
571	struct mbuf *m, *n;
572	u_int len = len0, remain;
573
574	for (m = m0; m && len > m->m_len; m = m->m_next)
575		len -= m->m_len;
576	if (m == NULL)
577		return (NULL);
578	remain = m->m_len - len;
579	if (m0->m_flags & M_PKTHDR) {
580		MGETHDR(n, wait, m0->m_type);
581		if (n == NULL)
582			return (NULL);
583		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
584		n->m_pkthdr.len = m0->m_pkthdr.len - len0;
585		m0->m_pkthdr.len = len0;
586		if (m->m_flags & M_EXT)
587			goto extpacket;
588		if (remain > MHLEN) {
589			/* m can't be the lead packet */
590			MH_ALIGN(n, 0);
591			n->m_next = m_split(m, len, wait);
592			if (n->m_next == NULL) {
593				(void) m_free(n);
594				return (NULL);
595			} else {
596				n->m_len = 0;
597				return (n);
598			}
599		} else
600			MH_ALIGN(n, remain);
601	} else if (remain == 0) {
602		n = m->m_next;
603		m->m_next = NULL;
604		return (n);
605	} else {
606		MGET(n, wait, m->m_type);
607		if (n == NULL)
608			return (NULL);
609		M_ALIGN(n, remain);
610	}
611extpacket:
612	if (m->m_flags & M_EXT) {
613		n->m_flags |= M_EXT;
614		n->m_ext = m->m_ext;
615		MEXT_ADD_REF(m);
616		n->m_data = m->m_data + len;
617	} else {
618		bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
619	}
620	n->m_len = remain;
621	m->m_len = len;
622	n->m_next = m->m_next;
623	m->m_next = NULL;
624	return (n);
625}
626/*
627 * Routine to copy from device local memory into mbufs.
628 * Note that `off' argument is offset into first mbuf of target chain from
629 * which to begin copying the data to.
630 */
631struct mbuf *
632m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
633	 void (*copy)(char *from, caddr_t to, u_int len))
634{
635	struct mbuf *m;
636	struct mbuf *top = 0, **mp = &top;
637	int len;
638
639	if (off < 0 || off > MHLEN)
640		return (NULL);
641
642	MGETHDR(m, M_DONTWAIT, MT_DATA);
643	if (m == NULL)
644		return (NULL);
645	m->m_pkthdr.rcvif = ifp;
646	m->m_pkthdr.len = totlen;
647	len = MHLEN;
648
649	while (totlen > 0) {
650		if (top) {
651			MGET(m, M_DONTWAIT, MT_DATA);
652			if (m == NULL) {
653				m_freem(top);
654				return (NULL);
655			}
656			len = MLEN;
657		}
658		if (totlen + off >= MINCLSIZE) {
659			MCLGET(m, M_DONTWAIT);
660			if (m->m_flags & M_EXT)
661				len = MCLBYTES;
662		} else {
663			/*
664			 * Place initial small packet/header at end of mbuf.
665			 */
666			if (top == NULL && totlen + off + max_linkhdr <= len) {
667				m->m_data += max_linkhdr;
668				len -= max_linkhdr;
669			}
670		}
671		if (off) {
672			m->m_data += off;
673			len -= off;
674			off = 0;
675		}
676		m->m_len = len = min(totlen, len);
677		if (copy)
678			copy(buf, mtod(m, caddr_t), (u_int)len);
679		else
680			bcopy(buf, mtod(m, caddr_t), (u_int)len);
681		buf += len;
682		*mp = m;
683		mp = &m->m_next;
684		totlen -= len;
685	}
686	return (top);
687}
688
689/*
690 * Copy data from a buffer back into the indicated mbuf chain,
691 * starting "off" bytes from the beginning, extending the mbuf
692 * chain if necessary.
693 */
694void
695m_copyback(struct mbuf *m0, int off, int len, caddr_t cp)
696{
697	int mlen;
698	struct mbuf *m = m0, *n;
699	int totlen = 0;
700
701	if (m0 == NULL)
702		return;
703	while (off > (mlen = m->m_len)) {
704		off -= mlen;
705		totlen += mlen;
706		if (m->m_next == NULL) {
707			n = m_get_clrd(M_DONTWAIT, m->m_type);
708			if (n == NULL)
709				goto out;
710			n->m_len = min(MLEN, len + off);
711			m->m_next = n;
712		}
713		m = m->m_next;
714	}
715	while (len > 0) {
716		mlen = min (m->m_len - off, len);
717		bcopy(cp, off + mtod(m, caddr_t), (u_int)mlen);
718		cp += mlen;
719		len -= mlen;
720		mlen += off;
721		off = 0;
722		totlen += mlen;
723		if (len == 0)
724			break;
725		if (m->m_next == NULL) {
726			n = m_get(M_DONTWAIT, m->m_type);
727			if (n == NULL)
728				break;
729			n->m_len = min(MLEN, len);
730			m->m_next = n;
731		}
732		m = m->m_next;
733	}
734out:	if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
735		m->m_pkthdr.len = totlen;
736}
737
738void
739m_print(const struct mbuf *m)
740{
741	int len;
742	const struct mbuf *m2;
743
744	len = m->m_pkthdr.len;
745	m2 = m;
746	while (len) {
747		printf("%p %*D\n", m2, m2->m_len, (u_char *)m2->m_data, "-");
748		len -= m2->m_len;
749		m2 = m2->m_next;
750	}
751	return;
752}
753
754u_int
755m_fixhdr(struct mbuf *m0)
756{
757	u_int len;
758
759	len = m_length(m0, NULL);
760	m0->m_pkthdr.len = len;
761	return (len);
762}
763
764u_int
765m_length(struct mbuf *m0, struct mbuf **last)
766{
767	struct mbuf *m;
768	u_int len;
769
770	len = 0;
771	for (m = m0; m != NULL; m = m->m_next) {
772		len += m->m_len;
773		if (m->m_next == NULL)
774			break;
775	}
776	if (last != NULL)
777		*last = m;
778	return (len);
779}
780