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