1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include "slirp.h"
17
18#define MBUF_THRESH 30
19
20
21
22
23#define SLIRP_MSIZE\
24 (offsetof(struct mbuf, m_dat) + IF_MAXLINKHDR + TCPIPHDR_DELTA + IF_MTU)
25
26void
27m_init(Slirp *slirp)
28{
29 slirp->m_freelist.qh_link = slirp->m_freelist.qh_rlink = &slirp->m_freelist;
30 slirp->m_usedlist.qh_link = slirp->m_usedlist.qh_rlink = &slirp->m_usedlist;
31}
32
33void m_cleanup(Slirp *slirp)
34{
35 struct mbuf *m, *next;
36
37 m = (struct mbuf *) slirp->m_usedlist.qh_link;
38 while ((struct quehead *) m != &slirp->m_usedlist) {
39 next = m->m_next;
40 if (m->m_flags & M_EXT) {
41 g_free(m->m_ext);
42 }
43 g_free(m);
44 m = next;
45 }
46 m = (struct mbuf *) slirp->m_freelist.qh_link;
47 while ((struct quehead *) m != &slirp->m_freelist) {
48 next = m->m_next;
49 g_free(m);
50 m = next;
51 }
52}
53
54
55
56
57
58
59
60
61
62struct mbuf *
63m_get(Slirp *slirp)
64{
65 register struct mbuf *m;
66 int flags = 0;
67
68 DEBUG_CALL("m_get");
69
70 if (slirp->m_freelist.qh_link == &slirp->m_freelist) {
71 m = g_malloc(SLIRP_MSIZE);
72 slirp->mbuf_alloced++;
73 if (slirp->mbuf_alloced > MBUF_THRESH)
74 flags = M_DOFREE;
75 m->slirp = slirp;
76 } else {
77 m = (struct mbuf *) slirp->m_freelist.qh_link;
78 remque(m);
79 }
80
81
82 insque(m,&slirp->m_usedlist);
83 m->m_flags = (flags | M_USEDLIST);
84
85
86 m->m_size = SLIRP_MSIZE - offsetof(struct mbuf, m_dat);
87 m->m_data = m->m_dat;
88 m->m_len = 0;
89 m->m_nextpkt = NULL;
90 m->m_prevpkt = NULL;
91 m->resolution_requested = false;
92 m->expiration_date = (uint64_t)-1;
93 DEBUG_ARG("m = %p", m);
94 return m;
95}
96
97void
98m_free(struct mbuf *m)
99{
100
101 DEBUG_CALL("m_free");
102 DEBUG_ARG("m = %p", m);
103
104 if(m) {
105
106 if (m->m_flags & M_USEDLIST)
107 remque(m);
108
109
110 if (m->m_flags & M_EXT) {
111 g_free(m->m_ext);
112 }
113
114
115
116 if (m->m_flags & M_DOFREE) {
117 m->slirp->mbuf_alloced--;
118 g_free(m);
119 } else if ((m->m_flags & M_FREELIST) == 0) {
120 insque(m,&m->slirp->m_freelist);
121 m->m_flags = M_FREELIST;
122 }
123 }
124}
125
126
127
128
129
130
131void
132m_cat(struct mbuf *m, struct mbuf *n)
133{
134
135
136
137 if (M_FREEROOM(m) < n->m_len)
138 m_inc(m, m->m_len + n->m_len);
139
140 memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
141 m->m_len += n->m_len;
142
143 m_free(n);
144}
145
146
147
148void
149m_inc(struct mbuf *m, int size)
150{
151 int gapsize;
152
153
154 if (M_ROOM(m) > size) {
155 return;
156 }
157
158 if (m->m_flags & M_EXT) {
159 gapsize = m->m_data - m->m_ext;
160 m->m_ext = g_realloc(m->m_ext, size + gapsize);
161 } else {
162 gapsize = m->m_data - m->m_dat;
163 m->m_ext = g_malloc(size + gapsize);
164 memcpy(m->m_ext, m->m_dat, m->m_size);
165 m->m_flags |= M_EXT;
166 }
167
168 m->m_data = m->m_ext + gapsize;
169 m->m_size = size + gapsize;
170}
171
172
173
174void
175m_adj(struct mbuf *m, int len)
176{
177 if (m == NULL)
178 return;
179 if (len >= 0) {
180
181 m->m_data += len;
182 m->m_len -= len;
183 } else {
184
185 len = -len;
186 m->m_len -= len;
187 }
188}
189
190
191
192
193
194int
195m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
196{
197 if (len > M_FREEROOM(n))
198 return -1;
199
200 memcpy((n->m_data + n->m_len), (m->m_data + off), len);
201 n->m_len += len;
202 return 0;
203}
204
205
206
207
208
209
210
211struct mbuf *
212dtom(Slirp *slirp, void *dat)
213{
214 struct mbuf *m;
215
216 DEBUG_CALL("dtom");
217 DEBUG_ARG("dat = %p", dat);
218
219
220 for (m = (struct mbuf *) slirp->m_usedlist.qh_link;
221 (struct quehead *) m != &slirp->m_usedlist;
222 m = m->m_next) {
223 if (m->m_flags & M_EXT) {
224 if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
225 return m;
226 } else {
227 if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
228 return m;
229 }
230 }
231
232 DEBUG_ERROR("dtom failed");
233
234 return (struct mbuf *)0;
235}
236