mbuf.c revision 38544
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
39static struct memmap {
40  struct mbuf *queue;
41  int fragments, octets;
42} MemMap[MB_MAX + 2];
43
44static int totalalloced;
45
46int
47mbuf_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
56struct mbuf *
57mbuf_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
79struct mbuf *
80mbuf_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
95void
96mbuf_Free(struct mbuf * bp)
97{
98  while (bp)
99    bp = mbuf_FreeSeg(bp);
100}
101
102struct mbuf *
103mbuf_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
128void
129mbuf_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
146int
147mbuf_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
167void
168mbuf_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
179struct mbuf *
180mbuf_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
201void
202mbuf_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