|
|
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 <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: {
1.1.1.2 ! root 149: int datasize;
! 150:
1.1 root 151: /* some compiles throw up on gotos. This one we can fake. */
152: if(m->m_size>size) return;
153:
154: if (m->m_flags & M_EXT) {
1.1.1.2 ! root 155: datasize = m->m_data - m->m_ext;
1.1 root 156: m->m_ext = (char *)realloc(m->m_ext,size);
157: /* if (m->m_ext == NULL)
158: * return (struct mbuf *)NULL;
159: */
1.1.1.2 ! root 160: m->m_data = m->m_ext + datasize;
1.1 root 161: } else {
162: char *dat;
163: datasize = m->m_data - m->m_dat;
164: dat = (char *)malloc(size);
165: /* if (dat == NULL)
166: * return (struct mbuf *)NULL;
167: */
168: memcpy(dat, m->m_dat, m->m_size);
169:
170: m->m_ext = dat;
171: m->m_data = m->m_ext + datasize;
172: m->m_flags |= M_EXT;
173: }
174:
175: m->m_size = size;
176:
177: }
178:
179:
180:
181: void
182: m_adj(m, len)
183: struct mbuf *m;
184: int len;
185: {
186: if (m == NULL)
187: return;
188: if (len >= 0) {
189: /* Trim from head */
190: m->m_data += len;
191: m->m_len -= len;
192: } else {
193: /* Trim from tail */
194: len = -len;
195: m->m_len -= len;
196: }
197: }
198:
199:
200: /*
201: * Copy len bytes from m, starting off bytes into n
202: */
203: int
204: m_copy(n, m, off, len)
205: struct mbuf *n, *m;
206: int off, len;
207: {
208: if (len > M_FREEROOM(n))
209: return -1;
210:
211: memcpy((n->m_data + n->m_len), (m->m_data + off), len);
212: n->m_len += len;
213: return 0;
214: }
215:
216:
217: /*
218: * Given a pointer into an mbuf, return the mbuf
219: * XXX This is a kludge, I should eliminate the need for it
220: * Fortunately, it's not used often
221: */
222: struct mbuf *
223: dtom(dat)
224: void *dat;
225: {
226: struct mbuf *m;
227:
228: DEBUG_CALL("dtom");
229: DEBUG_ARG("dat = %lx", (long )dat);
230:
231: /* bug corrected for M_EXT buffers */
232: for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
233: if (m->m_flags & M_EXT) {
234: if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
235: return m;
236: } else {
237: if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
238: return m;
239: }
240: }
241:
242: DEBUG_ERROR((dfd, "dtom failed"));
243:
244: return (struct mbuf *)0;
245: }
246:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.