symbian-qemu-0.9.1-12/qemu-symbian-svp/slirp/mbuf.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * Copyright (c) 1995 Danny Gasparovski
       
     3  *
       
     4  * Please read the file COPYRIGHT for the
       
     5  * terms and conditions of the copyright.
       
     6  */
       
     7 
       
     8 /*
       
     9  * mbuf's in SLiRP are much simpler than the real mbufs in
       
    10  * FreeBSD.  They are fixed size, determined by the MTU,
       
    11  * so that one whole packet can fit.  Mbuf's cannot be
       
    12  * chained together.  If there's more data than the mbuf
       
    13  * could hold, an external malloced buffer is pointed to
       
    14  * by m_ext (and the data pointers) and M_EXT is set in
       
    15  * the flags
       
    16  */
       
    17 
       
    18 #include <slirp.h>
       
    19 
       
    20 int mbuf_alloced = 0;
       
    21 struct mbuf m_freelist, m_usedlist;
       
    22 #define MBUF_THRESH 30
       
    23 int mbuf_max = 0;
       
    24 
       
    25 /*
       
    26  * Find a nice value for msize
       
    27  * XXX if_maxlinkhdr already in mtu
       
    28  */
       
    29 #define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
       
    30 
       
    31 void
       
    32 m_init()
       
    33 {
       
    34 	m_freelist.m_next = m_freelist.m_prev = &m_freelist;
       
    35 	m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
       
    36 }
       
    37 
       
    38 /*
       
    39  * Get an mbuf from the free list, if there are none
       
    40  * malloc one
       
    41  *
       
    42  * Because fragmentation can occur if we alloc new mbufs and
       
    43  * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
       
    44  * which tells m_free to actually free() it
       
    45  */
       
    46 struct mbuf *
       
    47 m_get()
       
    48 {
       
    49 	register struct mbuf *m;
       
    50 	int flags = 0;
       
    51 
       
    52 	DEBUG_CALL("m_get");
       
    53 
       
    54 	if (m_freelist.m_next == &m_freelist) {
       
    55 		m = (struct mbuf *)malloc(SLIRP_MSIZE);
       
    56 		if (m == NULL) goto end_error;
       
    57 		mbuf_alloced++;
       
    58 		if (mbuf_alloced > MBUF_THRESH)
       
    59 			flags = M_DOFREE;
       
    60 		if (mbuf_alloced > mbuf_max)
       
    61 			mbuf_max = mbuf_alloced;
       
    62 	} else {
       
    63 		m = m_freelist.m_next;
       
    64 		remque(m);
       
    65 	}
       
    66 
       
    67 	/* Insert it in the used list */
       
    68 	insque(m,&m_usedlist);
       
    69 	m->m_flags = (flags | M_USEDLIST);
       
    70 
       
    71 	/* Initialise it */
       
    72 	m->m_size = SLIRP_MSIZE - sizeof(struct m_hdr);
       
    73 	m->m_data = m->m_dat;
       
    74 	m->m_len = 0;
       
    75 	m->m_nextpkt = 0;
       
    76 	m->m_prevpkt = 0;
       
    77 end_error:
       
    78 	DEBUG_ARG("m = %lx", (long )m);
       
    79 	return m;
       
    80 }
       
    81 
       
    82 void
       
    83 m_free(m)
       
    84 	struct mbuf *m;
       
    85 {
       
    86 
       
    87   DEBUG_CALL("m_free");
       
    88   DEBUG_ARG("m = %lx", (long )m);
       
    89 
       
    90   if(m) {
       
    91 	/* Remove from m_usedlist */
       
    92 	if (m->m_flags & M_USEDLIST)
       
    93 	   remque(m);
       
    94 
       
    95 	/* If it's M_EXT, free() it */
       
    96 	if (m->m_flags & M_EXT)
       
    97 	   free(m->m_ext);
       
    98 
       
    99 	/*
       
   100 	 * Either free() it or put it on the free list
       
   101 	 */
       
   102 	if (m->m_flags & M_DOFREE) {
       
   103 		free(m);
       
   104 		mbuf_alloced--;
       
   105 	} else if ((m->m_flags & M_FREELIST) == 0) {
       
   106 		insque(m,&m_freelist);
       
   107 		m->m_flags = M_FREELIST; /* Clobber other flags */
       
   108 	}
       
   109   } /* if(m) */
       
   110 }
       
   111 
       
   112 /*
       
   113  * Copy data from one mbuf to the end of
       
   114  * the other.. if result is too big for one mbuf, malloc()
       
   115  * an M_EXT data segment
       
   116  */
       
   117 void
       
   118 m_cat(m, n)
       
   119 	register struct mbuf *m, *n;
       
   120 {
       
   121 	/*
       
   122 	 * If there's no room, realloc
       
   123 	 */
       
   124 	if (M_FREEROOM(m) < n->m_len)
       
   125 		m_inc(m,m->m_size+MINCSIZE);
       
   126 
       
   127 	memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
       
   128 	m->m_len += n->m_len;
       
   129 
       
   130 	m_free(n);
       
   131 }
       
   132 
       
   133 
       
   134 /* make m size bytes large */
       
   135 void
       
   136 m_inc(m, size)
       
   137         struct mbuf *m;
       
   138         int size;
       
   139 {
       
   140 	int datasize;
       
   141 
       
   142 	/* some compiles throw up on gotos.  This one we can fake. */
       
   143         if(m->m_size>size) return;
       
   144 
       
   145         if (m->m_flags & M_EXT) {
       
   146 	  datasize = m->m_data - m->m_ext;
       
   147 	  m->m_ext = (char *)realloc(m->m_ext,size);
       
   148 /*		if (m->m_ext == NULL)
       
   149  *			return (struct mbuf *)NULL;
       
   150  */
       
   151 	  m->m_data = m->m_ext + datasize;
       
   152         } else {
       
   153 	  char *dat;
       
   154 	  datasize = m->m_data - m->m_dat;
       
   155 	  dat = (char *)malloc(size);
       
   156 /*		if (dat == NULL)
       
   157  *			return (struct mbuf *)NULL;
       
   158  */
       
   159 	  memcpy(dat, m->m_dat, m->m_size);
       
   160 
       
   161 	  m->m_ext = dat;
       
   162 	  m->m_data = m->m_ext + datasize;
       
   163 	  m->m_flags |= M_EXT;
       
   164         }
       
   165 
       
   166         m->m_size = size;
       
   167 
       
   168 }
       
   169 
       
   170 
       
   171 
       
   172 void
       
   173 m_adj(m, len)
       
   174 	struct mbuf *m;
       
   175 	int len;
       
   176 {
       
   177 	if (m == NULL)
       
   178 		return;
       
   179 	if (len >= 0) {
       
   180 		/* Trim from head */
       
   181 		m->m_data += len;
       
   182 		m->m_len -= len;
       
   183 	} else {
       
   184 		/* Trim from tail */
       
   185 		len = -len;
       
   186 		m->m_len -= len;
       
   187 	}
       
   188 }
       
   189 
       
   190 
       
   191 /*
       
   192  * Copy len bytes from m, starting off bytes into n
       
   193  */
       
   194 int
       
   195 m_copy(n, m, off, len)
       
   196 	struct mbuf *n, *m;
       
   197 	int off, len;
       
   198 {
       
   199 	if (len > M_FREEROOM(n))
       
   200 		return -1;
       
   201 
       
   202 	memcpy((n->m_data + n->m_len), (m->m_data + off), len);
       
   203 	n->m_len += len;
       
   204 	return 0;
       
   205 }
       
   206 
       
   207 
       
   208 /*
       
   209  * Given a pointer into an mbuf, return the mbuf
       
   210  * XXX This is a kludge, I should eliminate the need for it
       
   211  * Fortunately, it's not used often
       
   212  */
       
   213 struct mbuf *
       
   214 dtom(dat)
       
   215 	void *dat;
       
   216 {
       
   217 	struct mbuf *m;
       
   218 
       
   219 	DEBUG_CALL("dtom");
       
   220 	DEBUG_ARG("dat = %lx", (long )dat);
       
   221 
       
   222 	/* bug corrected for M_EXT buffers */
       
   223 	for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
       
   224 	  if (m->m_flags & M_EXT) {
       
   225 	    if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
       
   226 	      return m;
       
   227 	  } else {
       
   228 	    if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
       
   229 	      return m;
       
   230 	  }
       
   231 	}
       
   232 
       
   233 	DEBUG_ERROR((dfd, "dtom failed"));
       
   234 
       
   235 	return (struct mbuf *)0;
       
   236 }