|
|
1.1 ! root 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 <stdlib.h> ! 19: #include <slirp.h> ! 20: ! 21: struct mbuf *mbutl; ! 22: char *mclrefcnt; ! 23: int mbuf_alloced = 0; ! 24: struct mbuf m_freelist, m_usedlist; ! 25: int mbuf_thresh = 30; ! 26: int mbuf_max = 0; ! 27: int msize; ! 28: ! 29: void ! 30: m_init() ! 31: { ! 32: m_freelist.m_next = m_freelist.m_prev = &m_freelist; ! 33: m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; ! 34: msize_init(); ! 35: } ! 36: ! 37: void ! 38: msize_init() ! 39: { ! 40: /* ! 41: * Find a nice value for msize ! 42: * XXX if_maxlinkhdr already in mtu ! 43: */ ! 44: msize = (if_mtu>if_mru?if_mtu:if_mru) + ! 45: if_maxlinkhdr + sizeof(struct m_hdr ) + 6; ! 46: } ! 47: ! 48: /* ! 49: * Get an mbuf from the free list, if there are none ! 50: * malloc one ! 51: * ! 52: * Because fragmentation can occur if we alloc new mbufs and ! 53: * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, ! 54: * which tells m_free to actually free() it ! 55: */ ! 56: struct mbuf * ! 57: m_get() ! 58: { ! 59: register struct mbuf *m; ! 60: int flags = 0; ! 61: ! 62: DEBUG_CALL("m_get"); ! 63: ! 64: if (m_freelist.m_next == &m_freelist) { ! 65: m = (struct mbuf *)malloc(msize); ! 66: if (m == NULL) goto end_error; ! 67: mbuf_alloced++; ! 68: if (mbuf_alloced > mbuf_thresh) ! 69: flags = M_DOFREE; ! 70: if (mbuf_alloced > mbuf_max) ! 71: mbuf_max = mbuf_alloced; ! 72: } else { ! 73: m = m_freelist.m_next; ! 74: remque(m); ! 75: } ! 76: ! 77: /* Insert it in the used list */ ! 78: insque(m,&m_usedlist); ! 79: m->m_flags = (flags | M_USEDLIST); ! 80: ! 81: /* Initialise it */ ! 82: m->m_size = msize - sizeof(struct m_hdr); ! 83: m->m_data = m->m_dat; ! 84: m->m_len = 0; ! 85: m->m_nextpkt = 0; ! 86: m->m_prevpkt = 0; ! 87: end_error: ! 88: DEBUG_ARG("m = %lx", (long )m); ! 89: return m; ! 90: } ! 91: ! 92: void ! 93: m_free(m) ! 94: struct mbuf *m; ! 95: { ! 96: ! 97: DEBUG_CALL("m_free"); ! 98: DEBUG_ARG("m = %lx", (long )m); ! 99: ! 100: if(m) { ! 101: /* Remove from m_usedlist */ ! 102: if (m->m_flags & M_USEDLIST) ! 103: remque(m); ! 104: ! 105: /* If it's M_EXT, free() it */ ! 106: if (m->m_flags & M_EXT) ! 107: free(m->m_ext); ! 108: ! 109: /* ! 110: * Either free() it or put it on the free list ! 111: */ ! 112: if (m->m_flags & M_DOFREE) { ! 113: free(m); ! 114: mbuf_alloced--; ! 115: } else if ((m->m_flags & M_FREELIST) == 0) { ! 116: insque(m,&m_freelist); ! 117: m->m_flags = M_FREELIST; /* Clobber other flags */ ! 118: } ! 119: } /* if(m) */ ! 120: } ! 121: ! 122: /* ! 123: * Copy data from one mbuf to the end of ! 124: * the other.. if result is too big for one mbuf, malloc() ! 125: * an M_EXT data segment ! 126: */ ! 127: void ! 128: m_cat(m, n) ! 129: register struct mbuf *m, *n; ! 130: { ! 131: /* ! 132: * If there's no room, realloc ! 133: */ ! 134: if (M_FREEROOM(m) < n->m_len) ! 135: m_inc(m,m->m_size+MINCSIZE); ! 136: ! 137: memcpy(m->m_data+m->m_len, n->m_data, n->m_len); ! 138: m->m_len += n->m_len; ! 139: ! 140: m_free(n); ! 141: } ! 142: ! 143: ! 144: /* make m size bytes large */ ! 145: void ! 146: m_inc(m, size) ! 147: struct mbuf *m; ! 148: int size; ! 149: { ! 150: int datasize; ! 151: ! 152: /* some compiles throw up on gotos. This one we can fake. */ ! 153: if(m->m_size>size) return; ! 154: ! 155: if (m->m_flags & M_EXT) { ! 156: datasize = m->m_data - m->m_ext; ! 157: m->m_ext = (char *)realloc(m->m_ext,size); ! 158: /* if (m->m_ext == NULL) ! 159: * return (struct mbuf *)NULL; ! 160: */ ! 161: m->m_data = m->m_ext + datasize; ! 162: } else { ! 163: char *dat; ! 164: datasize = m->m_data - m->m_dat; ! 165: dat = (char *)malloc(size); ! 166: /* if (dat == NULL) ! 167: * return (struct mbuf *)NULL; ! 168: */ ! 169: memcpy(dat, m->m_dat, m->m_size); ! 170: ! 171: m->m_ext = dat; ! 172: m->m_data = m->m_ext + datasize; ! 173: m->m_flags |= M_EXT; ! 174: } ! 175: ! 176: m->m_size = size; ! 177: ! 178: } ! 179: ! 180: ! 181: ! 182: void ! 183: m_adj(m, len) ! 184: struct mbuf *m; ! 185: int len; ! 186: { ! 187: if (m == NULL) ! 188: return; ! 189: if (len >= 0) { ! 190: /* Trim from head */ ! 191: m->m_data += len; ! 192: m->m_len -= len; ! 193: } else { ! 194: /* Trim from tail */ ! 195: len = -len; ! 196: m->m_len -= len; ! 197: } ! 198: } ! 199: ! 200: ! 201: /* ! 202: * Copy len bytes from m, starting off bytes into n ! 203: */ ! 204: int ! 205: m_copy(n, m, off, len) ! 206: struct mbuf *n, *m; ! 207: int off, len; ! 208: { ! 209: if (len > M_FREEROOM(n)) ! 210: return -1; ! 211: ! 212: memcpy((n->m_data + n->m_len), (m->m_data + off), len); ! 213: n->m_len += len; ! 214: return 0; ! 215: } ! 216: ! 217: ! 218: /* ! 219: * Given a pointer into an mbuf, return the mbuf ! 220: * XXX This is a kludge, I should eliminate the need for it ! 221: * Fortunately, it's not used often ! 222: */ ! 223: struct mbuf * ! 224: dtom(dat) ! 225: void *dat; ! 226: { ! 227: struct mbuf *m; ! 228: ! 229: DEBUG_CALL("dtom"); ! 230: DEBUG_ARG("dat = %lx", (long )dat); ! 231: ! 232: /* bug corrected for M_EXT buffers */ ! 233: for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) { ! 234: if (m->m_flags & M_EXT) { ! 235: if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) ! 236: return m; ! 237: } else { ! 238: if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) ! 239: return m; ! 240: } ! 241: } ! 242: ! 243: DEBUG_ERROR((dfd, "dtom failed")); ! 244: ! 245: return (struct mbuf *)0; ! 246: } ! 247:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.