Path: blob/a-new-beginning/SharedDependencies/Sources/libslirp/include/mbuf.h
2 views
/* SPDX-License-Identifier: BSD-3-Clause */1/*2* Copyright (c) 1982, 1986, 1988, 19933* The Regents of the University of California. All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13* 3. Neither the name of the University nor the names of its contributors14* may be used to endorse or promote products derived from this software15* without specific prior written permission.16*17* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*29* @(#)mbuf.h 8.3 (Berkeley) 1/21/9430* mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp31*/3233#ifndef MBUF_H34#define MBUF_H3536/*37* Macros for type conversion38* mtod(m,t) - convert mbuf pointer to data pointer of correct type39*/40#define mtod(m, t) ((t)(m)->m_data)4142/* XXX About mbufs for slirp:43* Only one mbuf is ever used in a chain, for each "cell" of data.44* m_nextpkt points to the next packet, if fragmented.45* If the data is too large, the M_EXT is used, and a larger block46* is alloced. Therefore, m_free[m] must check for M_EXT and if set47* free the m_ext. This is inefficient memory-wise, but who cares.48*/4950/*51* mbufs allow to have a gap between the start of the allocated buffer (m_ext if52* M_EXT is set, m_dat otherwise) and the in-use data:53*54* |--gapsize----->|---m_len------->55* |----------m_size------------------------------>56* |----M_ROOM-------------------->57* |-M_FREEROOM-->58*59* ^ ^ ^60* m_dat/m_ext m_data end of buffer61*/6263/*64* How much room is in the mbuf, from m_data to the end of the mbuf65*/66#define M_ROOM(m) \67((m->m_flags & M_EXT) ? (((m)->m_ext + (m)->m_size) - (m)->m_data) : \68(((m)->m_dat + (m)->m_size) - (m)->m_data))6970/*71* How much free room there is72*/73#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len)7475/*76* How much free room there is before m_data77*/78#define M_ROOMBEFORE(m) \79(((m)->m_flags & M_EXT) ? (m)->m_data - (m)->m_ext \80: (m)->m_data - (m)->m_dat)8182struct mbuf {83/* XXX should union some of these! */84/* header at beginning of each mbuf: */85struct mbuf *m_next; /* Linked list of mbufs */86struct mbuf *m_prev;87struct mbuf *m_nextpkt; /* Next packet in queue/record */88struct mbuf *m_prevpkt; /* Flags aren't used in the output queue */89int m_flags; /* Misc flags */9091int m_size; /* Size of mbuf, from m_dat or m_ext */92struct socket *m_so;9394char *m_data; /* Current location of data */95int m_len; /* Amount of data in this mbuf, from m_data */9697Slirp *slirp;98bool resolution_requested;99uint64_t expiration_date;100char *m_ext;101/* start of dynamic buffer area, must be last element */102char m_dat[];103};104105static inline void ifs_remque(struct mbuf *ifm)106{107ifm->m_prevpkt->m_nextpkt = ifm->m_nextpkt;108ifm->m_nextpkt->m_prevpkt = ifm->m_prevpkt;109}110111#define M_EXT 0x01 /* m_ext points to more (malloced) data */112#define M_FREELIST 0x02 /* mbuf is on free list */113#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */114#define M_DOFREE \1150x08 /* when m_free is called on the mbuf, free() \116* it rather than putting it on the free list */117118/* Called by slirp_new */119void m_init(Slirp *);120121/* Called by slirp_cleanup */122void m_cleanup(Slirp *slirp);123124/* Allocate an mbuf */125struct mbuf *m_get(Slirp *);126127/* Release an mbuf (put possibly put it in allocation cache */128void m_free(struct mbuf *);129130/* Catenate the second buffer to the end of the first buffer, and release the second */131void m_cat(struct mbuf *, struct mbuf *);132133/* Grow the mbuf to the given size */134void m_inc(struct mbuf *, int);135136/* If len is positive, trim that amount from the head of the mbuf. If it is negative, trim it from the tail of the mbuf */137void m_adj(struct mbuf *, int len);138139/* Copy len bytes from the first buffer at the given offset, to the end of the second buffer */140int m_copy(struct mbuf *, struct mbuf *, int off, int len);141142/*143* Duplicate the mbuf144*145* copy_header specifies whether the bytes before m_data should also be copied.146* header_size specifies how many bytes are to be reserved before m_data.147*/148struct mbuf *m_dup(Slirp *slirp, struct mbuf *m, bool copy_header, size_t header_size);149150/*151* Given a pointer into an mbuf, return the mbuf152* XXX This is a kludge, I should eliminate the need for it153* Fortunately, it's not used often154*/155struct mbuf *dtom(Slirp *, void *);156157/* Check that the mbuf contains at least len bytes, and return the data */158void *mtod_check(struct mbuf *, size_t len);159160/* Return the end of the data of the mbuf */161void *m_end(struct mbuf *);162163/* Initialize the ifs queue of the mbuf */164static inline void ifs_init(struct mbuf *ifm)165{166ifm->m_nextpkt = ifm->m_prevpkt = ifm;167}168169#ifdef SLIRP_DEBUG170# define MBUF_DEBUG 1171#else172# ifdef HAVE_VALGRIND173# include <valgrind/valgrind.h>174# define MBUF_DEBUG RUNNING_ON_VALGRIND175# else176# define MBUF_DEBUG 0177# endif178#endif179180/*181* When a function is given an mbuf as well as the responsibility to free it, we182* want valgrind etc. to properly identify the new responsible for the183* free. Achieve this by making a new copy. For instance:184*185* f0(void) {186* struct mbuf *m = m_get(slirp);187* [...]188* switch (something) {189* case 1:190* f1(m);191* break;192* case 2:193* f2(m);194* break;195* [...]196* }197* }198*199* f1(struct mbuf *m) {200* M_DUP_DEBUG(m->slirp, m);201* [...]202* m_free(m); // but author of f1 might be forgetting this203* }204*205* f0 transfers the freeing responsibility to f1, f2, etc. Without the206* M_DUP_DEBUG call in f1, valgrind would tell us that it is f0 where the buffer207* was allocated, but it's difficult to know whether a leak is actually in f0,208* or in f1, or in f2, etc. Duplicating the mbuf in M_DUP_DEBUG each time the209* responsibility is transferred allows to immediately know where the leak210* actually is.211*/212#define M_DUP_DEBUG(slirp, m, copy_header, header_size) do { \213if (MBUF_DEBUG) { \214struct mbuf *__n; \215__n = m_dup((slirp), (m), (copy_header), (header_size)); \216m_free(m); \217(m) = __n; \218} else { \219(void) (slirp); (void) (copy_header); \220g_assert(M_ROOMBEFORE(m) >= (header_size)); \221} \222} while(0)223224#endif225226227