VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/mbuf.c@ 1033

Last change on this file since 1033 was 1033, checked in by vboxsync, 18 years ago

Big change to make slirp fully instantiatable (replace all global
variables with local ones, passing a reference to the state/config
structure to all places which are interested). You can now have as many
cards in the guest configured for NAT networking as you want.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette