|
|
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: int mbuf_alloced = 0;
21: struct mbuf m_freelist, m_usedlist;
1.1.1.3 root 22: #define MBUF_THRESH 30
1.1 root 23: int mbuf_max = 0;
1.1.1.3 root 24:
25: /*
26: * Find a nice value for msize
27: * XXX if_maxlinkhdr already in mtu
28: */
1.1.1.4 ! root 29: #define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
1.1 root 30:
31: void
32: m_init()
33: {
34: m_freelist.m_next = m_freelist.m_prev = &m_freelist;
35: m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
36: }
37:
38: /*
39: * Get an mbuf from the free list, if there are none
40: * malloc one
1.1.1.3 root 41: *
1.1 root 42: * Because fragmentation can occur if we alloc new mbufs and
43: * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
44: * which tells m_free to actually free() it
45: */
46: struct mbuf *
47: m_get()
48: {
49: register struct mbuf *m;
50: int flags = 0;
1.1.1.3 root 51:
1.1 root 52: DEBUG_CALL("m_get");
1.1.1.3 root 53:
1.1 root 54: if (m_freelist.m_next == &m_freelist) {
1.1.1.4 ! root 55: m = (struct mbuf *)malloc(SLIRP_MSIZE);
1.1 root 56: if (m == NULL) goto end_error;
57: mbuf_alloced++;
1.1.1.3 root 58: if (mbuf_alloced > MBUF_THRESH)
1.1 root 59: flags = M_DOFREE;
60: if (mbuf_alloced > mbuf_max)
61: mbuf_max = mbuf_alloced;
62: } else {
63: m = m_freelist.m_next;
64: remque(m);
65: }
1.1.1.3 root 66:
1.1 root 67: /* Insert it in the used list */
68: insque(m,&m_usedlist);
69: m->m_flags = (flags | M_USEDLIST);
1.1.1.3 root 70:
1.1 root 71: /* Initialise it */
1.1.1.4 ! root 72: m->m_size = SLIRP_MSIZE - sizeof(struct m_hdr);
1.1 root 73: m->m_data = m->m_dat;
74: m->m_len = 0;
75: m->m_nextpkt = 0;
76: m->m_prevpkt = 0;
77: end_error:
78: DEBUG_ARG("m = %lx", (long )m);
79: return m;
80: }
81:
82: void
83: m_free(m)
84: struct mbuf *m;
85: {
1.1.1.3 root 86:
1.1 root 87: DEBUG_CALL("m_free");
88: DEBUG_ARG("m = %lx", (long )m);
1.1.1.3 root 89:
1.1 root 90: if(m) {
91: /* Remove from m_usedlist */
92: if (m->m_flags & M_USEDLIST)
93: remque(m);
1.1.1.3 root 94:
1.1 root 95: /* If it's M_EXT, free() it */
96: if (m->m_flags & M_EXT)
97: free(m->m_ext);
98:
99: /*
100: * Either free() it or put it on the free list
101: */
102: if (m->m_flags & M_DOFREE) {
103: free(m);
104: mbuf_alloced--;
105: } else if ((m->m_flags & M_FREELIST) == 0) {
106: insque(m,&m_freelist);
107: m->m_flags = M_FREELIST; /* Clobber other flags */
108: }
109: } /* if(m) */
110: }
111:
112: /*
113: * Copy data from one mbuf to the end of
114: * the other.. if result is too big for one mbuf, malloc()
115: * an M_EXT data segment
116: */
117: void
118: m_cat(m, n)
119: register struct mbuf *m, *n;
120: {
121: /*
122: * If there's no room, realloc
123: */
124: if (M_FREEROOM(m) < n->m_len)
125: m_inc(m,m->m_size+MINCSIZE);
1.1.1.3 root 126:
1.1 root 127: memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
128: m->m_len += n->m_len;
129:
130: m_free(n);
131: }
132:
133:
134: /* make m size bytes large */
135: void
136: m_inc(m, size)
137: struct mbuf *m;
138: int size;
139: {
1.1.1.2 root 140: int datasize;
141:
1.1 root 142: /* some compiles throw up on gotos. This one we can fake. */
143: if(m->m_size>size) return;
144:
145: if (m->m_flags & M_EXT) {
1.1.1.2 root 146: datasize = m->m_data - m->m_ext;
1.1 root 147: m->m_ext = (char *)realloc(m->m_ext,size);
148: /* if (m->m_ext == NULL)
149: * return (struct mbuf *)NULL;
1.1.1.3 root 150: */
1.1.1.2 root 151: m->m_data = m->m_ext + datasize;
1.1 root 152: } else {
153: char *dat;
154: datasize = m->m_data - m->m_dat;
155: dat = (char *)malloc(size);
156: /* if (dat == NULL)
157: * return (struct mbuf *)NULL;
158: */
159: memcpy(dat, m->m_dat, m->m_size);
1.1.1.3 root 160:
1.1 root 161: m->m_ext = dat;
162: m->m_data = m->m_ext + datasize;
163: m->m_flags |= M_EXT;
164: }
1.1.1.3 root 165:
1.1 root 166: m->m_size = size;
167:
168: }
169:
170:
171:
172: void
173: m_adj(m, len)
174: struct mbuf *m;
175: int len;
176: {
177: if (m == NULL)
178: return;
179: if (len >= 0) {
180: /* Trim from head */
181: m->m_data += len;
182: m->m_len -= len;
183: } else {
184: /* Trim from tail */
185: len = -len;
186: m->m_len -= len;
187: }
188: }
189:
190:
191: /*
192: * Copy len bytes from m, starting off bytes into n
193: */
194: int
195: m_copy(n, m, off, len)
196: struct mbuf *n, *m;
197: int off, len;
198: {
199: if (len > M_FREEROOM(n))
200: return -1;
201:
202: memcpy((n->m_data + n->m_len), (m->m_data + off), len);
203: n->m_len += len;
204: return 0;
205: }
206:
207:
208: /*
209: * Given a pointer into an mbuf, return the mbuf
210: * XXX This is a kludge, I should eliminate the need for it
211: * Fortunately, it's not used often
212: */
213: struct mbuf *
214: dtom(dat)
215: void *dat;
216: {
217: struct mbuf *m;
1.1.1.3 root 218:
1.1 root 219: DEBUG_CALL("dtom");
220: DEBUG_ARG("dat = %lx", (long )dat);
221:
222: /* bug corrected for M_EXT buffers */
223: for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
224: if (m->m_flags & M_EXT) {
225: if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
226: return m;
227: } else {
228: if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
229: return m;
230: }
231: }
1.1.1.3 root 232:
1.1 root 233: DEBUG_ERROR((dfd, "dtom failed"));
1.1.1.3 root 234:
1.1 root 235: return (struct mbuf *)0;
236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.