Annotation of previous_trunk/src/slirp/mbuf.c, revision 1.1

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: size_t msize;
        !            28: 
        !            29: void 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 msize_init()
        !            37: {
        !            38:        /*
        !            39:         * Find a nice value for msize
        !            40:         * XXX if_maxlinkhdr already in mtu
        !            41:         */
        !            42:        msize = (if_mtu>if_mru?if_mtu:if_mru) + 
        !            43:                        if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
        !            44: }
        !            45: 
        !            46: /*
        !            47:  * Get an mbuf from the free list, if there are none
        !            48:  * malloc one
        !            49:  * 
        !            50:  * Because fragmentation can occur if we alloc new mbufs and
        !            51:  * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
        !            52:  * which tells m_free to actually free() it
        !            53:  */
        !            54: struct mbuf *m_get()
        !            55: {
        !            56:        register struct mbuf *m;
        !            57:        int flags = 0;
        !            58:        
        !            59:        DEBUG_CALL("m_get");
        !            60:        
        !            61:        if (m_freelist.m_next == &m_freelist) {
        !            62:                m = (struct mbuf *)malloc(msize);
        !            63:                if (m == NULL) goto end_error;
        !            64:                mbuf_alloced++;
        !            65:                if (mbuf_alloced > mbuf_thresh)
        !            66:                        flags = M_DOFREE;
        !            67:                if (mbuf_alloced > mbuf_max)
        !            68:                        mbuf_max = mbuf_alloced;
        !            69:        } else {
        !            70:                m = m_freelist.m_next;
        !            71:                remque(m);
        !            72:        }
        !            73:        
        !            74:        /* Insert it in the used list */
        !            75:        insque(m,&m_usedlist);
        !            76:        m->m_flags = (flags | M_USEDLIST);
        !            77:        
        !            78:        /* Initialise it */
        !            79:        m->m_size = msize - sizeof(struct m_hdr);
        !            80:        m->m_data = m->m_dat;
        !            81:        m->m_len = 0;
        !            82:        m->m_nextpkt = 0;
        !            83:        m->m_prevpkt = 0;
        !            84: end_error:
        !            85:        DEBUG_ARG("m = %lx", (long )m);
        !            86:        return m;
        !            87: }
        !            88: 
        !            89: void m_free(struct mbuf *m)
        !            90: {
        !            91:        
        !            92:   DEBUG_CALL("m_free");
        !            93:   DEBUG_ARG("m = %lx", (long )m);
        !            94:        
        !            95:   if(m) {
        !            96:        /* Remove from m_usedlist */
        !            97:        if (m->m_flags & M_USEDLIST)
        !            98:           remque(m);
        !            99:        
        !           100:        /* If it's M_EXT, free() it */
        !           101:        if (m->m_flags & M_EXT)
        !           102:           free(m->m_ext);
        !           103: 
        !           104:        /*
        !           105:         * Either free() it or put it on the free list
        !           106:         */
        !           107:        if (m->m_flags & M_DOFREE) {
        !           108:                free(m);
        !           109:                mbuf_alloced--;
        !           110:        } else if ((m->m_flags & M_FREELIST) == 0) {
        !           111:                insque(m,&m_freelist);
        !           112:                m->m_flags = M_FREELIST; /* Clobber other flags */
        !           113:        }
        !           114:   } /* if(m) */
        !           115: }
        !           116: 
        !           117: /*
        !           118:  * Copy data from one mbuf to the end of
        !           119:  * the other.. if result is too big for one mbuf, malloc()
        !           120:  * an M_EXT data segment
        !           121:  */
        !           122: void m_cat(register struct mbuf *m, register struct mbuf *n)
        !           123: {
        !           124:        /*
        !           125:         * If there's no room, realloc
        !           126:         */
        !           127:        if (M_FREEROOM(m) < n->m_len)
        !           128:                m_inc(m,m->m_size+MINCSIZE);
        !           129:        
        !           130:        memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
        !           131:        m->m_len += n->m_len;
        !           132: 
        !           133:        m_free(n);
        !           134: }
        !           135: 
        !           136: 
        !           137: /* make m size bytes large */
        !           138: void m_inc(struct mbuf *m, u_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 m_adj(struct mbuf *m, int len)
        !           173: {
        !           174:        if (m == NULL)
        !           175:                return;
        !           176:        if (len >= 0) {
        !           177:                /* Trim from head */
        !           178:                m->m_data += len;
        !           179:                m->m_len -= len;
        !           180:        } else {
        !           181:                /* Trim from tail */
        !           182:                len = -len;
        !           183:                m->m_len -= len;
        !           184:        }
        !           185: }
        !           186: 
        !           187: 
        !           188: /*
        !           189:  * Copy len bytes from m, starting off bytes into n
        !           190:  */
        !           191: int
        !           192: m_copy(struct mbuf *n, struct mbuf *m, u_int off, u_int len)
        !           193: {
        !           194:        if (len > M_FREEROOM(n))
        !           195:                return -1;
        !           196: 
        !           197:        memcpy((n->m_data + n->m_len), (m->m_data + off), len);
        !           198:        n->m_len += len;
        !           199:        return 0;
        !           200: }
        !           201: 
        !           202: 
        !           203: /*
        !           204:  * Given a pointer into an mbuf, return the mbuf
        !           205:  * XXX This is a kludge, I should eliminate the need for it
        !           206:  * Fortunately, it's not used often
        !           207:  */
        !           208: struct mbuf *dtom(void *dat)
        !           209: {
        !           210:        struct mbuf *m;
        !           211:        
        !           212:        DEBUG_CALL("dtom");
        !           213:        DEBUG_ARG("dat = %lx", (long )dat);
        !           214: 
        !           215:        /* bug corrected for M_EXT buffers */
        !           216:        for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
        !           217:          if (m->m_flags & M_EXT) {
        !           218:            if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
        !           219:              return m;
        !           220:          } else {
        !           221:            if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
        !           222:              return m;
        !           223:          }
        !           224:        }
        !           225:        
        !           226:        DEBUG_ERROR((dfd, "dtom failed"));
        !           227:        
        !           228:        return (struct mbuf *)0;
        !           229: }
        !           230: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.