Deleted Added
full compact
mbuf.c (47695) mbuf.c (49582)
1/*
2 * PPP Memory handling module
3 *
4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5 *
6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the Internet Initiative Japan, Inc. The name of the
14 * IIJ may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 *
1/*
2 * PPP Memory handling module
3 *
4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5 *
6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the Internet Initiative Japan, Inc. The name of the
14 * IIJ may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * $Id: mbuf.c,v 1.26 1999/05/09 20:02:24 brian Exp $
20 * $Id: mbuf.c,v 1.27 1999/06/02 15:59:04 brian Exp $
21 *
22 */
23#include <sys/types.h>
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sysexits.h>
29#include <termios.h>
30
31#include "defs.h"
32#include "command.h"
33#include "mbuf.h"
34#include "log.h"
35#include "descriptor.h"
36#include "prompt.h"
37#include "main.h"
38
39static struct memmap {
40 struct mbuf *queue;
41 int fragments, octets;
42} MemMap[MB_MAX + 1];
43
44static int totalalloced;
45static unsigned long long mbuf_Mallocs, mbuf_Frees;
46
47int
48mbuf_Length(struct mbuf *bp)
49{
50 int len;
51
52 for (len = 0; bp; bp = bp->next)
53 len += bp->cnt;
54 return len;
55}
56
57struct mbuf *
58mbuf_Alloc(int cnt, int type)
59{
60 struct mbuf *bp;
61
62 if (type > MB_MAX) {
63 log_Printf(LogERROR, "Bad mbuf type %d\n", type);
64 type = MB_UNKNOWN;
65 }
66 bp = malloc(sizeof(struct mbuf) + cnt);
67 if (bp == NULL) {
68 log_Printf(LogALERT, "failed to allocate memory: %ld\n",
69 (long)sizeof(struct mbuf));
70 AbortProgram(EX_OSERR);
71 }
72 mbuf_Mallocs++;
73 memset(bp, '\0', sizeof(struct mbuf));
74 MemMap[type].fragments++;
75 MemMap[type].octets += cnt;
76 totalalloced += cnt;
77 bp->size = bp->cnt = cnt;
78 bp->type = type;
79 return bp;
80}
81
82struct mbuf *
83mbuf_FreeSeg(struct mbuf *bp)
84{
85 struct mbuf *nbp;
86
87 if (bp) {
88 nbp = bp->next;
89 MemMap[bp->type].fragments--;
90 MemMap[bp->type].octets -= bp->size;
91 totalalloced -= bp->size;
92 free(bp);
93 mbuf_Frees++;
94 bp = nbp;
95 }
96
97 return bp;
98}
99
100void
101mbuf_Free(struct mbuf *bp)
102{
103 while (bp)
104 bp = mbuf_FreeSeg(bp);
105}
106
107struct mbuf *
108mbuf_Read(struct mbuf *bp, void *v, size_t len)
109{
110 int nb;
111 u_char *ptr = v;
112
113 while (bp && len > 0) {
114 if (len > bp->cnt)
115 nb = bp->cnt;
116 else
117 nb = len;
118 if (nb) {
119 memcpy(ptr, MBUF_CTOP(bp), nb);
120 ptr += nb;
121 bp->cnt -= nb;
122 len -= nb;
123 bp->offset += nb;
124 }
125 if (bp->cnt == 0)
126 bp = mbuf_FreeSeg(bp);
127 }
128
129 while (bp && bp->cnt == 0)
130 bp = mbuf_FreeSeg(bp);
131
132 return bp;
133}
134
135size_t
136mbuf_View(struct mbuf *bp, void *v, size_t len)
137{
138 size_t nb, l = len;
139 u_char *ptr = v;
140
141 while (bp && l > 0) {
142 if (l > bp->cnt)
143 nb = bp->cnt;
144 else
145 nb = l;
146 memcpy(ptr, MBUF_CTOP(bp), nb);
147 ptr += nb;
148 l -= nb;
149 bp = bp->next;
150 }
151
152 return len - l;
153}
154
155struct mbuf *
156mbuf_Prepend(struct mbuf *bp, const void *ptr, size_t len, size_t extra)
157{
158 struct mbuf *head;
159
160 if (bp && bp->offset) {
161 if (bp->offset >= len) {
162 bp->offset -= len;
163 bp->cnt += len;
164 memcpy(MBUF_CTOP(bp), ptr, len);
165 return bp;
166 }
167 len -= bp->offset;
168 memcpy(bp + sizeof *bp, (const char *)ptr + len, bp->offset);
169 bp->cnt += bp->offset;
170 bp->offset = 0;
171 }
172
173 head = mbuf_Alloc(len + extra, bp ? bp->type : MB_UNKNOWN);
174 head->offset = extra;
175 head->cnt -= extra;
176 memcpy(MBUF_CTOP(head), ptr, len);
177 head->next = bp;
178
179 return head;
180}
181
182struct mbuf *
183mbuf_Truncate(struct mbuf *bp, size_t n)
184{
185 if (n == 0) {
186 mbuf_Free(bp);
187 return NULL;
188 }
189
190 for (; bp; bp = bp->next, n -= bp->cnt)
191 if (n < bp->cnt) {
192 bp->cnt = n;
193 mbuf_Free(bp->next);
194 bp->next = NULL;
195 break;
196 }
197
198 return bp;
199}
200
201void
202mbuf_Write(struct mbuf *bp, const void *ptr, size_t cnt)
203{
204 int plen;
205 int nb;
206
207 plen = mbuf_Length(bp);
208 if (plen < cnt)
209 cnt = plen;
210
211 while (cnt > 0) {
212 nb = (cnt < bp->cnt) ? cnt : bp->cnt;
213 memcpy(MBUF_CTOP(bp), ptr, nb);
214 cnt -= bp->cnt;
215 bp = bp->next;
216 }
217}
218
219int
220mbuf_Show(struct cmdargs const *arg)
221{
222 int i;
223 static const char *mbuftype[] = {
224 "ip in", "ip out", "alias in", "alias out", "mp in", "mp out",
225 "vj in", "vj out", "icompd in", "icompd out", "compd in", "compd out",
226 "lqr in", "lqr out", "echo in", "echo out", "proto in", "proto out",
227 "acf in", "acf out", "sync in", "sync out", "hdlc in", "hdlc out",
228 "async in", "async out", "cbcp in", "cbcp out", "chap in", "chap out",
229 "pap in", "pap out", "ccp in", "ccp out", "ipcp in", "ipcp out",
230 "lcp in", "lcp out", "unknown"
231 };
232
233 prompt_Printf(arg->prompt, "Fragments (octets) in use:\n");
234 for (i = 0; i < MB_MAX; i += 2)
235 prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\t%10.10s: %04d (%06d)\n",
236 mbuftype[i], MemMap[i].fragments, MemMap[i].octets,
237 mbuftype[i+1], MemMap[i+1].fragments, MemMap[i+1].octets);
238
239 if (i == MB_MAX)
240 prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\n",
241 mbuftype[i], MemMap[i].fragments, MemMap[i].octets);
242
21 *
22 */
23#include <sys/types.h>
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sysexits.h>
29#include <termios.h>
30
31#include "defs.h"
32#include "command.h"
33#include "mbuf.h"
34#include "log.h"
35#include "descriptor.h"
36#include "prompt.h"
37#include "main.h"
38
39static struct memmap {
40 struct mbuf *queue;
41 int fragments, octets;
42} MemMap[MB_MAX + 1];
43
44static int totalalloced;
45static unsigned long long mbuf_Mallocs, mbuf_Frees;
46
47int
48mbuf_Length(struct mbuf *bp)
49{
50 int len;
51
52 for (len = 0; bp; bp = bp->next)
53 len += bp->cnt;
54 return len;
55}
56
57struct mbuf *
58mbuf_Alloc(int cnt, int type)
59{
60 struct mbuf *bp;
61
62 if (type > MB_MAX) {
63 log_Printf(LogERROR, "Bad mbuf type %d\n", type);
64 type = MB_UNKNOWN;
65 }
66 bp = malloc(sizeof(struct mbuf) + cnt);
67 if (bp == NULL) {
68 log_Printf(LogALERT, "failed to allocate memory: %ld\n",
69 (long)sizeof(struct mbuf));
70 AbortProgram(EX_OSERR);
71 }
72 mbuf_Mallocs++;
73 memset(bp, '\0', sizeof(struct mbuf));
74 MemMap[type].fragments++;
75 MemMap[type].octets += cnt;
76 totalalloced += cnt;
77 bp->size = bp->cnt = cnt;
78 bp->type = type;
79 return bp;
80}
81
82struct mbuf *
83mbuf_FreeSeg(struct mbuf *bp)
84{
85 struct mbuf *nbp;
86
87 if (bp) {
88 nbp = bp->next;
89 MemMap[bp->type].fragments--;
90 MemMap[bp->type].octets -= bp->size;
91 totalalloced -= bp->size;
92 free(bp);
93 mbuf_Frees++;
94 bp = nbp;
95 }
96
97 return bp;
98}
99
100void
101mbuf_Free(struct mbuf *bp)
102{
103 while (bp)
104 bp = mbuf_FreeSeg(bp);
105}
106
107struct mbuf *
108mbuf_Read(struct mbuf *bp, void *v, size_t len)
109{
110 int nb;
111 u_char *ptr = v;
112
113 while (bp && len > 0) {
114 if (len > bp->cnt)
115 nb = bp->cnt;
116 else
117 nb = len;
118 if (nb) {
119 memcpy(ptr, MBUF_CTOP(bp), nb);
120 ptr += nb;
121 bp->cnt -= nb;
122 len -= nb;
123 bp->offset += nb;
124 }
125 if (bp->cnt == 0)
126 bp = mbuf_FreeSeg(bp);
127 }
128
129 while (bp && bp->cnt == 0)
130 bp = mbuf_FreeSeg(bp);
131
132 return bp;
133}
134
135size_t
136mbuf_View(struct mbuf *bp, void *v, size_t len)
137{
138 size_t nb, l = len;
139 u_char *ptr = v;
140
141 while (bp && l > 0) {
142 if (l > bp->cnt)
143 nb = bp->cnt;
144 else
145 nb = l;
146 memcpy(ptr, MBUF_CTOP(bp), nb);
147 ptr += nb;
148 l -= nb;
149 bp = bp->next;
150 }
151
152 return len - l;
153}
154
155struct mbuf *
156mbuf_Prepend(struct mbuf *bp, const void *ptr, size_t len, size_t extra)
157{
158 struct mbuf *head;
159
160 if (bp && bp->offset) {
161 if (bp->offset >= len) {
162 bp->offset -= len;
163 bp->cnt += len;
164 memcpy(MBUF_CTOP(bp), ptr, len);
165 return bp;
166 }
167 len -= bp->offset;
168 memcpy(bp + sizeof *bp, (const char *)ptr + len, bp->offset);
169 bp->cnt += bp->offset;
170 bp->offset = 0;
171 }
172
173 head = mbuf_Alloc(len + extra, bp ? bp->type : MB_UNKNOWN);
174 head->offset = extra;
175 head->cnt -= extra;
176 memcpy(MBUF_CTOP(head), ptr, len);
177 head->next = bp;
178
179 return head;
180}
181
182struct mbuf *
183mbuf_Truncate(struct mbuf *bp, size_t n)
184{
185 if (n == 0) {
186 mbuf_Free(bp);
187 return NULL;
188 }
189
190 for (; bp; bp = bp->next, n -= bp->cnt)
191 if (n < bp->cnt) {
192 bp->cnt = n;
193 mbuf_Free(bp->next);
194 bp->next = NULL;
195 break;
196 }
197
198 return bp;
199}
200
201void
202mbuf_Write(struct mbuf *bp, const void *ptr, size_t cnt)
203{
204 int plen;
205 int nb;
206
207 plen = mbuf_Length(bp);
208 if (plen < cnt)
209 cnt = plen;
210
211 while (cnt > 0) {
212 nb = (cnt < bp->cnt) ? cnt : bp->cnt;
213 memcpy(MBUF_CTOP(bp), ptr, nb);
214 cnt -= bp->cnt;
215 bp = bp->next;
216 }
217}
218
219int
220mbuf_Show(struct cmdargs const *arg)
221{
222 int i;
223 static const char *mbuftype[] = {
224 "ip in", "ip out", "alias in", "alias out", "mp in", "mp out",
225 "vj in", "vj out", "icompd in", "icompd out", "compd in", "compd out",
226 "lqr in", "lqr out", "echo in", "echo out", "proto in", "proto out",
227 "acf in", "acf out", "sync in", "sync out", "hdlc in", "hdlc out",
228 "async in", "async out", "cbcp in", "cbcp out", "chap in", "chap out",
229 "pap in", "pap out", "ccp in", "ccp out", "ipcp in", "ipcp out",
230 "lcp in", "lcp out", "unknown"
231 };
232
233 prompt_Printf(arg->prompt, "Fragments (octets) in use:\n");
234 for (i = 0; i < MB_MAX; i += 2)
235 prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\t%10.10s: %04d (%06d)\n",
236 mbuftype[i], MemMap[i].fragments, MemMap[i].octets,
237 mbuftype[i+1], MemMap[i+1].fragments, MemMap[i+1].octets);
238
239 if (i == MB_MAX)
240 prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\n",
241 mbuftype[i], MemMap[i].fragments, MemMap[i].octets);
242
243 prompt_Printf(arg->prompt, "Mallocs: %qu, Frees: %qu\n",
243 prompt_Printf(arg->prompt, "Mallocs: %llu, Frees: %llu\n",
244 mbuf_Mallocs, mbuf_Frees);
245
246 return 0;
247}
248
249struct mbuf *
250mbuf_Dequeue(struct mqueue *q)
251{
252 struct mbuf *bp;
253
254 log_Printf(LogDEBUG, "mbuf_Dequeue: queue len = %d\n", q->qlen);
255 bp = q->top;
256 if (bp) {
257 q->top = q->top->pnext;
258 q->qlen--;
259 if (q->top == NULL) {
260 q->last = q->top;
261 if (q->qlen)
262 log_Printf(LogERROR, "mbuf_Dequeue: Not zero (%d)!!!\n", q->qlen);
263 }
264 bp->pnext = NULL;
265 }
266
267 return bp;
268}
269
270void
271mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp)
272{
273 if (bp != NULL) {
274 if (queue->last) {
275 queue->last->pnext = bp;
276 queue->last = bp;
277 } else
278 queue->last = queue->top = bp;
279 queue->qlen++;
280 log_Printf(LogDEBUG, "mbuf_Enqueue: len = %d\n", queue->qlen);
281 }
282}
283
284struct mbuf *
285mbuf_Contiguous(struct mbuf *bp)
286{
287 /* Put it all in one contigous (aligned) mbuf */
288
289 if (bp != NULL) {
290 if (bp->next != NULL) {
291 struct mbuf *nbp;
292 u_char *cp;
293
294 nbp = mbuf_Alloc(mbuf_Length(bp), bp->type);
295
296 for (cp = MBUF_CTOP(nbp); bp; bp = mbuf_FreeSeg(bp)) {
297 memcpy(cp, MBUF_CTOP(bp), bp->cnt);
298 cp += bp->cnt;
299 }
300 bp = nbp;
301 }
302#ifndef __i386__ /* Do any other archs not care about alignment ? */
303 else if ((bp->offset & 0x03) != 0) {
304 bcopy(MBUF_CTOP(bp), bp + 1, bp->cnt);
305 bp->offset = 0;
306 }
307#endif
308 }
309
310 return bp;
311}
312
313void
314mbuf_SetType(struct mbuf *bp, int type)
315{
316 for (; bp; bp = bp->next)
317 if (type != bp->type) {
318 MemMap[bp->type].fragments--;
319 MemMap[bp->type].octets -= bp->size;
320 bp->type = type;
321 MemMap[type].fragments++;
322 MemMap[type].octets += bp->size;
323 }
324}
244 mbuf_Mallocs, mbuf_Frees);
245
246 return 0;
247}
248
249struct mbuf *
250mbuf_Dequeue(struct mqueue *q)
251{
252 struct mbuf *bp;
253
254 log_Printf(LogDEBUG, "mbuf_Dequeue: queue len = %d\n", q->qlen);
255 bp = q->top;
256 if (bp) {
257 q->top = q->top->pnext;
258 q->qlen--;
259 if (q->top == NULL) {
260 q->last = q->top;
261 if (q->qlen)
262 log_Printf(LogERROR, "mbuf_Dequeue: Not zero (%d)!!!\n", q->qlen);
263 }
264 bp->pnext = NULL;
265 }
266
267 return bp;
268}
269
270void
271mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp)
272{
273 if (bp != NULL) {
274 if (queue->last) {
275 queue->last->pnext = bp;
276 queue->last = bp;
277 } else
278 queue->last = queue->top = bp;
279 queue->qlen++;
280 log_Printf(LogDEBUG, "mbuf_Enqueue: len = %d\n", queue->qlen);
281 }
282}
283
284struct mbuf *
285mbuf_Contiguous(struct mbuf *bp)
286{
287 /* Put it all in one contigous (aligned) mbuf */
288
289 if (bp != NULL) {
290 if (bp->next != NULL) {
291 struct mbuf *nbp;
292 u_char *cp;
293
294 nbp = mbuf_Alloc(mbuf_Length(bp), bp->type);
295
296 for (cp = MBUF_CTOP(nbp); bp; bp = mbuf_FreeSeg(bp)) {
297 memcpy(cp, MBUF_CTOP(bp), bp->cnt);
298 cp += bp->cnt;
299 }
300 bp = nbp;
301 }
302#ifndef __i386__ /* Do any other archs not care about alignment ? */
303 else if ((bp->offset & 0x03) != 0) {
304 bcopy(MBUF_CTOP(bp), bp + 1, bp->cnt);
305 bp->offset = 0;
306 }
307#endif
308 }
309
310 return bp;
311}
312
313void
314mbuf_SetType(struct mbuf *bp, int type)
315{
316 for (; bp; bp = bp->next)
317 if (type != bp->type) {
318 MemMap[bp->type].fragments--;
319 MemMap[bp->type].octets -= bp->size;
320 bp->type = type;
321 MemMap[type].fragments++;
322 MemMap[type].octets += bp->size;
323 }
324}