1 /*- 2 * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id: link.c,v 1.5 1998/08/25 17:48:42 brian Exp $ 27 * 28 */ 29 30 #include <sys/types.h> 31 32 #include <stdio.h> 33 #include <string.h> 34 #include <termios.h> 35 36 #include "defs.h" 37 #include "mbuf.h" 38 #include "log.h" 39 #include "timer.h" 40 #include "lqr.h" 41 #include "hdlc.h" 42 #include "throughput.h" 43 #include "lcpproto.h" 44 #include "fsm.h" 45 #include "descriptor.h" 46 #include "lcp.h" 47 #include "ccp.h" 48 #include "link.h" 49 #include "prompt.h" 50 51 void 52 link_AddInOctets(struct link *l, int n) 53 { 54 throughput_addin(&l->throughput, n); 55 } 56 57 void 58 link_AddOutOctets(struct link *l, int n) 59 { 60 throughput_addout(&l->throughput, n); 61 } 62 63 void 64 link_SequenceQueue(struct link *l) 65 { 66 log_Printf(LogDEBUG, "link_SequenceQueue\n"); 67 while (l->Queue[PRI_NORMAL].qlen) 68 mbuf_Enqueue(l->Queue + PRI_LINK, mbuf_Dequeue(l->Queue + PRI_NORMAL)); 69 } 70 71 void 72 link_DeleteQueue(struct link *l) 73 { 74 struct mqueue *queue; 75 76 for (queue = l->Queue; queue < l->Queue + LINK_QUEUES; queue++) 77 while (queue->top) 78 mbuf_Free(mbuf_Dequeue(queue)); 79 } 80 81 int 82 link_QueueLen(struct link *l) 83 { 84 int i, len; 85 86 for (i = 0, len = 0; i < LINK_QUEUES; i++) 87 len += l->Queue[i].qlen; 88 89 return len; 90 } 91 92 int 93 link_QueueBytes(struct link *l) 94 { 95 int i, len, bytes; 96 struct mbuf *m; 97 98 bytes = 0; 99 for (i = 0, len = 0; i < LINK_QUEUES; i++) { 100 len = l->Queue[i].qlen; 101 m = l->Queue[i].top; 102 while (len--) { 103 bytes += mbuf_Length(m); 104 m = m->pnext; 105 } 106 } 107 108 return bytes; 109 } 110 111 struct mbuf * 112 link_Dequeue(struct link *l) 113 { 114 int pri; 115 struct mbuf *bp; 116 117 for (bp = (struct mbuf *)0, pri = LINK_QUEUES - 1; pri >= 0; pri--) 118 if (l->Queue[pri].qlen) { 119 bp = mbuf_Dequeue(l->Queue + pri); 120 log_Printf(LogDEBUG, "link_Dequeue: Dequeued from queue %d," 121 " containing %d more packets\n", pri, l->Queue[pri].qlen); 122 break; 123 } 124 125 return bp; 126 } 127 128 /* 129 * Write to the link. Actualy, requested packets are queued, and go out 130 * at some later time depending on the physical link implementation. 131 */ 132 void 133 link_Write(struct link *l, int pri, const char *ptr, int count) 134 { 135 struct mbuf *bp; 136 137 if(pri < 0 || pri >= LINK_QUEUES) 138 pri = 0; 139 140 bp = mbuf_Alloc(count, MB_LINK); 141 memcpy(MBUF_CTOP(bp), ptr, count); 142 143 mbuf_Enqueue(l->Queue + pri, bp); 144 } 145 146 void 147 link_Output(struct link *l, int pri, struct mbuf *bp) 148 { 149 struct mbuf *wp; 150 int len; 151 152 if(pri < 0 || pri >= LINK_QUEUES) 153 pri = 0; 154 155 len = mbuf_Length(bp); 156 wp = mbuf_Alloc(len, MB_LINK); 157 mbuf_Read(bp, MBUF_CTOP(wp), len); 158 mbuf_Enqueue(l->Queue + pri, wp); 159 } 160 161 static struct protostatheader { 162 u_short number; 163 const char *name; 164 } ProtocolStat[NPROTOSTAT] = { 165 { PROTO_IP, "IP" }, 166 { PROTO_VJUNCOMP, "VJ_UNCOMP" }, 167 { PROTO_VJCOMP, "VJ_COMP" }, 168 { PROTO_COMPD, "COMPD" }, 169 { PROTO_ICOMPD, "ICOMPD" }, 170 { PROTO_LCP, "LCP" }, 171 { PROTO_IPCP, "IPCP" }, 172 { PROTO_CCP, "CCP" }, 173 { PROTO_PAP, "PAP" }, 174 { PROTO_LQR, "LQR" }, 175 { PROTO_CHAP, "CHAP" }, 176 { PROTO_MP, "MULTILINK" }, 177 { 0, "Others" } 178 }; 179 180 void 181 link_ProtocolRecord(struct link *l, u_short proto, int type) 182 { 183 int i; 184 185 for (i = 0; i < NPROTOSTAT; i++) 186 if (ProtocolStat[i].number == proto) 187 break; 188 189 if (type == PROTO_IN) 190 l->proto_in[i]++; 191 else 192 l->proto_out[i]++; 193 } 194 195 void 196 link_ReportProtocolStatus(struct link *l, struct prompt *prompt) 197 { 198 int i; 199 200 prompt_Printf(prompt, " Protocol in out " 201 "Protocol in out\n"); 202 for (i = 0; i < NPROTOSTAT; i++) { 203 prompt_Printf(prompt, " %-9s: %8lu, %8lu", 204 ProtocolStat[i].name, l->proto_in[i], l->proto_out[i]); 205 if ((i % 2) == 0) 206 prompt_Printf(prompt, "\n"); 207 } 208 if (!(i % 2)) 209 prompt_Printf(prompt, "\n"); 210 } 211