~ubuntu-branches/ubuntu/vivid/basilisk2/vivid

« back to all changes in this revision

Viewing changes to src/slirp/mbuf.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-03-06 19:33:01 UTC
  • mfrom: (2.1.4 gutsy)
  • Revision ID: james.westby@ubuntu.com-20080306193301-cc2ofn705nfsq3y0
Tags: 0.9.20070407-4
* Update copyright-check cdbs snippet to parse licensecheck using perl:
  + No longer randomly drops newlines
  + More compact hint file (and ordered more like wiki-proposed new copyright
    syntax).
  + No longer ignore files without copyright.
* Update copyright_hints.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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