/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * Copyright (c) 1995 Danny Gasparovski
 */

/*
 * mbuf's in SLiRP are much simpler than the real mbufs in
 * FreeBSD.  They are fixed size, determined by the MTU,
 * so that one whole packet can fit.  Mbuf's cannot be
 * chained together.  If there's more data than the mbuf
 * could hold, an external g_malloced buffer is pointed to
 * by m_ext (and the data pointers) and M_EXT is set in
 * the flags
 */

#include "slirp.h"

#define MBUF_THRESH 30

/*
 * Find a nice value for msize
 */
#define SLIRP_MSIZE(mtu) \
    (offsetof(struct mbuf, m_dat) + IF_MAXLINKHDR + TCPIPHDR_DELTA + (mtu))

void m_init(Slirp *slirp)
{
    slirp->m_freelist.qh_link = slirp->m_freelist.qh_rlink = &slirp->m_freelist;
    slirp->m_usedlist.qh_link = slirp->m_usedlist.qh_rlink = &slirp->m_usedlist;
}

void m_cleanup(Slirp *slirp)
{
    struct mbuf *m, *next;

    m = (struct mbuf *)slirp->m_usedlist.qh_link;
    while ((struct quehead *)m != &slirp->m_usedlist) {
        next = m->m_next;
        if (m->m_flags & M_EXT) {
            g_free(m->m_ext);
        }
        g_free(m);
        m = next;
    }
    m = (struct mbuf *)slirp->m_freelist.qh_link;
    while ((struct quehead *)m != &slirp->m_freelist) {
        next = m->m_next;
        g_free(m);
        m = next;
    }
}

/*
 * Get an mbuf from the free list, if there are none
 * allocate one
 *
 * Because fragmentation can occur if we alloc new mbufs and
 * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
 * which tells m_free to actually g_free() it
 */
struct mbuf *m_get(Slirp *slirp)
{
    register struct mbuf *m;
    int flags = 0;

    DEBUG_CALL("m_get");

    if (slirp->m_freelist.qh_link == &slirp->m_freelist) {
        m = g_malloc(SLIRP_MSIZE(slirp->if_mtu));
        slirp->mbuf_alloced++;
        if (slirp->mbuf_alloced > MBUF_THRESH)
            flags = M_DOFREE;
        m->slirp = slirp;
    } else {
        m = (struct mbuf *)slirp->m_freelist.qh_link;
        remque(m);
    }

    /* Insert it in the used list */
    insque(m, &slirp->m_usedlist);
    m->m_flags = (flags | M_USEDLIST);

    /* Initialise it */
    m->m_size = SLIRP_MSIZE(slirp->if_mtu) - offsetof(struct mbuf, m_dat);
    m->m_data = m->m_dat;
    m->m_len = 0;
    m->m_nextpkt = NULL;
    m->m_prevpkt = NULL;
    m->resolution_requested = false;
    m->expiration_date = (uint64_t)-1;
    DEBUG_ARG("m = %p", m);
    return m;
}

void m_free(struct mbuf *m)
{
    DEBUG_CALL("m_free");
    DEBUG_ARG("m = %p", m);

    if (m) {
        /* Remove from m_usedlist */
        if (m->m_flags & M_USEDLIST)
            remque(m);

        /* If it's M_EXT, free() it */
        if (m->m_flags & M_EXT) {
            g_free(m->m_ext);
        }
        /*
         * Either free() it or put it on the free list
         */
        if (m->m_flags & M_DOFREE) {
            m->slirp->mbuf_alloced--;
            g_free(m);
        } else if ((m->m_flags & M_FREELIST) == 0) {
            insque(m, &m->slirp->m_freelist);
            m->m_flags = M_FREELIST; /* Clobber other flags */
        }
    } /* if(m) */
}

/*
 * Copy data from one mbuf to the end of
 * the other.. if result is too big for one mbuf, allocate
 * an M_EXT data segment
 */
void m_cat(struct mbuf *m, struct mbuf *n)
{
    /*
     * If there's no room, realloc
     */
    if (M_FREEROOM(m) < n->m_len)
        m_inc(m, m->m_len + n->m_len);

    memcpy(m->m_data + m->m_len, n->m_data, n->m_len);
    m->m_len += n->m_len;

    m_free(n);
}


/* make m 'size' bytes large from m_data */
void m_inc(struct mbuf *m, int size)
{
    int gapsize;

    /* some compilers throw up on gotos.  This one we can fake. */
    if (M_ROOM(m) > size) {
        return;
    }

    if (m->m_flags & M_EXT) {
        gapsize = m->m_data - m->m_ext;
        m->m_ext = g_realloc(m->m_ext, size + gapsize);
    } else {
        gapsize = m->m_data - m->m_dat;
        m->m_ext = g_malloc(size + gapsize);
        memcpy(m->m_ext, m->m_dat, m->m_size);
        m->m_flags |= M_EXT;
    }

    m->m_data = m->m_ext + gapsize;
    m->m_size = size + gapsize;
}


void m_adj(struct mbuf *m, int len)
{
    if (m == NULL)
        return;
    if (len >= 0) {
        /* Trim from head */
        m->m_data += len;
        m->m_len -= len;
    } else {
        /* Trim from tail */
        len = -len;
        m->m_len -= len;
    }
}


/*
 * Copy len bytes from m, starting off bytes into n
 */
int m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
{
    if (len > M_FREEROOM(n))
        return -1;

    memcpy((n->m_data + n->m_len), (m->m_data + off), len);
    n->m_len += len;
    return 0;
}


/*
 * Given a pointer into an mbuf, return the mbuf
 * XXX This is a kludge, I should eliminate the need for it
 * Fortunately, it's not used often
 */
struct mbuf *dtom(Slirp *slirp, void *dat)
{
    struct mbuf *m;

    DEBUG_CALL("dtom");
    DEBUG_ARG("dat = %p", dat);

    /* bug corrected for M_EXT buffers */
    for (m = (struct mbuf *)slirp->m_usedlist.qh_link;
         (struct quehead *)m != &slirp->m_usedlist; m = m->m_next) {
        if (m->m_flags & M_EXT) {
            if ((char *)dat >= m->m_ext && (char *)dat < (m->m_ext + m->m_size))
                return m;
        } else {
            if ((char *)dat >= m->m_dat && (char *)dat < (m->m_dat + m->m_size))
                return m;
        }
    }

    DEBUG_ERROR("dtom failed");

    return (struct mbuf *)0;
}
