diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 1999-12-05 07:30:32 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 1999-12-05 07:30:32 +0000 |
commit | 1062903d55add277b1db68215bddd50223953aa4 (patch) | |
tree | da04086a34e3b5151e96a3cfc47870453093d0c0 /sys/kern | |
parent | 798886eb3aa5b52d46215efe171dc51d79ad5a3d (diff) |
Add an m_inject()
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/uipc_mbuf.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 9022a20b284..f94d76ae370 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.17 1999/10/01 02:00:12 jason Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.18 1999/12/05 07:30:31 angelos Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -721,6 +721,67 @@ bad: } /* + * Inject a new mbuf chain of length siz in mbuf chain m0 at + * position len0. Returns a pointer to the first injected mbuf, or + * NULL on failure (m0 is left undisturbed). Note that if there is + * enough space for an object of size siz in the appropriate position, + * no memory will be allocated. Also, there will be no data movement in + * the first len0 bytes (pointers to that will remain valid). + * + * XXX It is assumed that siz is less than the size of an mbuf at the moment. + */ +struct mbuf * +m_inject(m0, len0, siz, wait) + register struct mbuf *m0; + int len0, siz, wait; +{ + register struct mbuf *m, *n, *n2 = NULL, *n3; + unsigned len = len0, remain; + + if ((siz >= MHLEN) || (len0 <= 0)) + return (NULL); + for (m = m0; m && len > m->m_len; m = m->m_next) + len -= m->m_len; + if (m == NULL) + return (NULL); + remain = m->m_len - len; + if (remain == 0) { + if ((m->m_next) && (M_LEADINGSPACE(m->m_next) >= siz)) { + m->m_next->m_len += siz; + m0->m_pkthdr.len += siz; + m->m_next->m_data -= siz; + return m->m_next; + } + } else { + n2 = m_copym2(m, len, remain, wait); + if (n2 == NULL) + return (NULL); + } + + MGET(n, wait, MT_DATA); + if (n == NULL) { + if (n2) + m_freem(n2); + return (NULL); + } + + n->m_len = siz; + m0->m_pkthdr.len += siz; + m->m_len -= remain; /* Trim */ + if (n2) { + for (n3 = n; n3->m_next != NULL; n3 = n3->m_next) + ; + n3->m_next = n2; + } else + n3 = n; + for (; n3->m_next != NULL; n3 = n3->m_next) + ; + n3->m_next = m->m_next; + m->m_next = n; + return n; +} + +/* * Partition an mbuf chain in two pieces, returning the tail -- * all but the first len0 bytes. In case of failure, it returns NULL and * attempts to restore the chain to its original state. |