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