mbuf - Add m_apply and m_getptr
authorAlex Hornung <ahornung@gmail.com>
Mon, 28 Sep 2009 09:52:32 +0000 (10:52 +0100)
committerAlex Hornung <ahornung@gmail.com>
Fri, 2 Oct 2009 15:17:50 +0000 (16:17 +0100)
* Import m_apply and m_getptr from FreeBSD.

Obtained-from: FreeBSD

sys/kern/uipc_mbuf.c
sys/sys/mbuf.h

index 47beb41..17f3a8d 100644 (file)
@@ -1688,6 +1688,67 @@ out:     if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
                m->m_pkthdr.len = totlen;
 }
 
+/*
+ * Apply function f to the data in an mbuf chain starting "off" bytes from
+ * the beginning, continuing for "len" bytes.
+ */
+int
+m_apply(struct mbuf *m, int off, int len,
+    int (*f)(void *, void *, u_int), void *arg)
+{
+       u_int count;
+       int rval;
+
+       KASSERT(off >= 0, ("m_apply, negative off %d", off));
+       KASSERT(len >= 0, ("m_apply, negative len %d", len));
+       while (off > 0) {
+               KASSERT(m != NULL, ("m_apply, offset > size of mbuf chain"));
+               if (off < m->m_len)
+                       break;
+               off -= m->m_len;
+               m = m->m_next;
+       }
+       while (len > 0) {
+               KASSERT(m != NULL, ("m_apply, offset > size of mbuf chain"));
+               count = min(m->m_len - off, len);
+               rval = (*f)(arg, mtod(m, caddr_t) + off, count);
+               if (rval)
+                       return (rval);
+               len -= count;
+               off = 0;
+               m = m->m_next;
+       }
+       return (0);
+}
+
+/*
+ * Return a pointer to mbuf/offset of location in mbuf chain.
+ */
+struct mbuf *
+m_getptr(struct mbuf *m, int loc, int *off)
+{
+
+       while (loc >= 0) {
+               /* Normal end of search. */
+               if (m->m_len > loc) {
+                       *off = loc;
+                       return (m);
+               } else {
+                       loc -= m->m_len;
+                       if (m->m_next == NULL) {
+                               if (loc == 0) {
+                                       /* Point at the end of valid data. */
+                                       *off = m->m_len;
+                                       return (m);
+                               }
+                               return (NULL);
+                       }
+                       m = m->m_next;
+               }
+       }
+       return (NULL);
+}
+
 void
 m_print(const struct mbuf *m)
 {
index 6a66bdf..d3affa2 100644 (file)
@@ -444,6 +444,8 @@ extern      int              nmbufs;
 struct uio;
 
 void            m_adj(struct mbuf *, int);
+int             m_apply(struct mbuf *, int, int,
+                   int (*)(void *, void *, u_int), void *);
 void            m_cat(struct mbuf *, struct mbuf *);
 u_int           m_countm(struct mbuf *m, struct mbuf **lastm, u_int *mbcnt);
 void            m_copyback(struct mbuf *, int, int, caddr_t);
@@ -464,6 +466,7 @@ struct      mbuf    *m_getcl(int how, short type, int flags);
 struct mbuf    *m_getclr(int, int);
 struct mbuf    *m_gethdr(int, int);
 struct mbuf    *m_getm(struct mbuf *, int, int, int);
+struct mbuf    *m_getptr(struct mbuf *, int, int *);
 struct mbuf    *m_last(struct mbuf *m);
 u_int           m_lengthm(struct mbuf *m, struct mbuf **lastm);
 void            m_move_pkthdr(struct mbuf *, struct mbuf *);