ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/slirp/mbuf.c
Revision: 1.1
Committed: 2005-05-13T09:00:59Z (19 years, 6 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
CVS Tags: nigel-build-17
Log Message:
slirp user mode network emulation code from qemu

File Contents

# User Rev Content
1 gbeauche 1.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