xref: /freebsd/usr.sbin/ppp/mbuf.c (revision a8445737e740901f5f2c8d24c12ef7fc8b00134e)
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.21 1998/08/21 18:10:15 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 
39 static struct memmap {
40   struct mbuf *queue;
41   int fragments, octets;
42 } MemMap[MB_MAX + 2];
43 
44 static int totalalloced;
45 
46 int
47 mbuf_Length(struct mbuf * bp)
48 {
49   int len;
50 
51   for (len = 0; bp; bp = bp->next)
52     len += bp->cnt;
53   return (len);
54 }
55 
56 struct mbuf *
57 mbuf_Alloc(int cnt, int type)
58 {
59   struct mbuf *bp;
60 
61   if (type > MB_MAX)
62     log_Printf(LogERROR, "Bad mbuf type %d\n", type);
63   bp = malloc(sizeof(struct mbuf) + cnt);
64   if (bp == NULL) {
65     log_Printf(LogALERT, "failed to allocate memory: %ld\n",
66                (long)sizeof(struct mbuf));
67     AbortProgram(EX_OSERR);
68   }
69   memset(bp, '\0', sizeof(struct mbuf));
70   MemMap[type].fragments++;
71   MemMap[type].octets += cnt;
72   totalalloced += cnt;
73   bp->size = bp->cnt = cnt;
74   bp->type = type;
75   bp->pnext = NULL;
76   return (bp);
77 }
78 
79 struct mbuf *
80 mbuf_FreeSeg(struct mbuf * bp)
81 {
82   struct mbuf *nbp;
83 
84   if (bp) {
85     nbp = bp->next;
86     MemMap[bp->type].fragments--;
87     MemMap[bp->type].octets -= bp->size;
88     totalalloced -= bp->size;
89     free(bp);
90     return (nbp);
91   }
92   return (bp);
93 }
94 
95 void
96 mbuf_Free(struct mbuf * bp)
97 {
98   while (bp)
99     bp = mbuf_FreeSeg(bp);
100 }
101 
102 struct mbuf *
103 mbuf_Read(struct mbuf * bp, u_char * ptr, int len)
104 {
105   int nb;
106 
107   while (bp && len > 0) {
108     if (len > bp->cnt)
109       nb = bp->cnt;
110     else
111       nb = len;
112     memcpy(ptr, MBUF_CTOP(bp), nb);
113     ptr += nb;
114     bp->cnt -= nb;
115     len -= nb;
116     bp->offset += nb;
117     if (bp->cnt == 0) {
118 #ifdef notdef
119       bp = bp->next;
120 #else
121       bp = mbuf_FreeSeg(bp);
122 #endif
123     }
124   }
125   return (bp);
126 }
127 
128 void
129 mbuf_Write(struct mbuf * bp, u_char * ptr, int cnt)
130 {
131   int plen;
132   int nb;
133 
134   plen = mbuf_Length(bp);
135   if (plen < cnt)
136     cnt = plen;
137 
138   while (cnt > 0) {
139     nb = (cnt < bp->cnt) ? cnt : bp->cnt;
140     memcpy(MBUF_CTOP(bp), ptr, nb);
141     cnt -= bp->cnt;
142     bp = bp->next;
143   }
144 }
145 
146 int
147 mbuf_Show(struct cmdargs const *arg)
148 {
149   int i;
150   static const char *mbuftype[] = {
151     "async", "fsm", "cbcp", "hdlcout", "ipin", "echo", "lqr", "link",
152     "vjcomp", "ipq", "mp" };
153 
154   prompt_Printf(arg->prompt, "Fragments (octets) in use:\n");
155   for (i = 1; i < MB_MAX; i += 2)
156     prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\t%10.10s: %04d (%06d)\n",
157 	    mbuftype[i-1], MemMap[i].fragments, MemMap[i].octets, mbuftype[i],
158             MemMap[i+1].fragments, MemMap[i+1].octets);
159 
160   if (i == MB_MAX)
161     prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\n",
162                   mbuftype[i-1], MemMap[i].fragments, MemMap[i].octets);
163 
164   return 0;
165 }
166 
167 void
168 mbuf_Log()
169 {
170   log_Printf(LogDEBUG, "mbuf_Log: mem alloced: %d\n", totalalloced);
171   log_Printf(LogDEBUG, "mbuf_Log:  1: %d  2: %d   3: %d   4: %d\n",
172 	MemMap[1].octets, MemMap[2].octets, MemMap[3].octets, MemMap[4].octets);
173   log_Printf(LogDEBUG, "mbuf_Log:  5: %d  6: %d   7: %d   8: %d\n",
174 	MemMap[5].octets, MemMap[6].octets, MemMap[7].octets, MemMap[8].octets);
175   log_Printf(LogDEBUG, "mbuf_Log:  9: %d 10: %d  11: %d\n",
176 	MemMap[9].octets, MemMap[10].octets, MemMap[11].octets);
177 }
178 
179 struct mbuf *
180 mbuf_Dequeue(struct mqueue *q)
181 {
182   struct mbuf *bp;
183 
184   log_Printf(LogDEBUG, "mbuf_Dequeue: queue len = %d\n", q->qlen);
185   bp = q->top;
186   if (bp) {
187     q->top = q->top->pnext;
188     q->qlen--;
189     if (q->top == NULL) {
190       q->last = q->top;
191       if (q->qlen)
192 	log_Printf(LogERROR, "mbuf_Dequeue: Not zero (%d)!!!\n", q->qlen);
193     }
194     bp->pnext = NULL;
195   }
196 
197   return bp;
198 }
199 
200 
201 void
202 mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp)
203 {
204   if (queue->last) {
205     queue->last->pnext = bp;
206     queue->last = bp;
207   } else
208     queue->last = queue->top = bp;
209   queue->qlen++;
210   log_Printf(LogDEBUG, "mbuf_Enqueue: len = %d\n", queue->qlen);
211 }
212