18c07a7b2SBrian Somers /*- 28c07a7b2SBrian Somers * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org> 38c07a7b2SBrian Somers * All rights reserved. 48c07a7b2SBrian Somers * 58c07a7b2SBrian Somers * Redistribution and use in source and binary forms, with or without 68c07a7b2SBrian Somers * modification, are permitted provided that the following conditions 78c07a7b2SBrian Somers * are met: 88c07a7b2SBrian Somers * 1. Redistributions of source code must retain the above copyright 98c07a7b2SBrian Somers * notice, this list of conditions and the following disclaimer. 108c07a7b2SBrian Somers * 2. Redistributions in binary form must reproduce the above copyright 118c07a7b2SBrian Somers * notice, this list of conditions and the following disclaimer in the 128c07a7b2SBrian Somers * documentation and/or other materials provided with the distribution. 138c07a7b2SBrian Somers * 148c07a7b2SBrian Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 158c07a7b2SBrian Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 168c07a7b2SBrian Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 178c07a7b2SBrian Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 188c07a7b2SBrian Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 198c07a7b2SBrian Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 208c07a7b2SBrian Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 218c07a7b2SBrian Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 228c07a7b2SBrian Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 238c07a7b2SBrian Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 248c07a7b2SBrian Somers * SUCH DAMAGE. 258c07a7b2SBrian Somers * 263b0f8d2eSBrian Somers * $Id: link.c,v 1.1.2.14 1998/03/20 19:48:08 brian Exp $ 278c07a7b2SBrian Somers * 288c07a7b2SBrian Somers */ 298c07a7b2SBrian Somers 308c07a7b2SBrian Somers #include <sys/param.h> 318c07a7b2SBrian Somers #include <netinet/in.h> 32eaa4df37SBrian Somers #include <netinet/in_systm.h> 33eaa4df37SBrian Somers #include <netinet/ip.h> 348c07a7b2SBrian Somers 358c07a7b2SBrian Somers #include <stdio.h> 3685b542cfSBrian Somers #include <termios.h> 378c07a7b2SBrian Somers 388c07a7b2SBrian Somers #include "command.h" 398c07a7b2SBrian Somers #include "mbuf.h" 408c07a7b2SBrian Somers #include "log.h" 418c07a7b2SBrian Somers #include "defs.h" 428c07a7b2SBrian Somers #include "timer.h" 43879ed6faSBrian Somers #include "lqr.h" 4463258dccSBrian Somers #include "hdlc.h" 458c07a7b2SBrian Somers #include "throughput.h" 468c07a7b2SBrian Somers #include "lcpproto.h" 478c07a7b2SBrian Somers #include "loadalias.h" 488c07a7b2SBrian Somers #include "vars.h" 496d666775SBrian Somers #include "fsm.h" 505828db6dSBrian Somers #include "iplist.h" 51eaa4df37SBrian Somers #include "slcompress.h" 525828db6dSBrian Somers #include "ipcp.h" 535ca5389aSBrian Somers #include "filter.h" 5485b542cfSBrian Somers #include "descriptor.h" 553b0f8d2eSBrian Somers #include "async.h" 563b0f8d2eSBrian Somers #include "lcp.h" 573b0f8d2eSBrian Somers #include "ccp.h" 583b0f8d2eSBrian Somers #include "link.h" 593b0f8d2eSBrian Somers #include "mp.h" 602f786681SBrian Somers #include "bundle.h" 6185b542cfSBrian Somers #include "prompt.h" 628c07a7b2SBrian Somers 638c07a7b2SBrian Somers void 648c07a7b2SBrian Somers link_AddInOctets(struct link *l, int n) 658c07a7b2SBrian Somers { 668c07a7b2SBrian Somers throughput_addin(&l->throughput, n); 678c07a7b2SBrian Somers } 688c07a7b2SBrian Somers 698c07a7b2SBrian Somers void 708c07a7b2SBrian Somers link_AddOutOctets(struct link *l, int n) 718c07a7b2SBrian Somers { 728c07a7b2SBrian Somers throughput_addout(&l->throughput, n); 738c07a7b2SBrian Somers } 748c07a7b2SBrian Somers 758c07a7b2SBrian Somers void 768c07a7b2SBrian Somers link_SequenceQueue(struct link *l) 778c07a7b2SBrian Somers { 788c07a7b2SBrian Somers LogPrintf(LogDEBUG, "link_SequenceQueue\n"); 798c07a7b2SBrian Somers while (l->Queue[PRI_NORMAL].qlen) 808c07a7b2SBrian Somers Enqueue(l->Queue + PRI_LINK, Dequeue(l->Queue + PRI_NORMAL)); 818c07a7b2SBrian Somers } 828c07a7b2SBrian Somers 838c07a7b2SBrian Somers int 848c07a7b2SBrian Somers link_QueueLen(struct link *l) 858c07a7b2SBrian Somers { 868c07a7b2SBrian Somers int i, len; 878c07a7b2SBrian Somers 888c07a7b2SBrian Somers for (i = 0, len = 0; i < LINK_QUEUES; i++) 898c07a7b2SBrian Somers len += l->Queue[i].qlen; 908c07a7b2SBrian Somers 918c07a7b2SBrian Somers return len; 928c07a7b2SBrian Somers } 938c07a7b2SBrian Somers 943b0f8d2eSBrian Somers int 953b0f8d2eSBrian Somers link_QueueBytes(struct link *l) 963b0f8d2eSBrian Somers { 973b0f8d2eSBrian Somers int i, len, bytes; 983b0f8d2eSBrian Somers struct mbuf *m; 993b0f8d2eSBrian Somers 1003b0f8d2eSBrian Somers bytes = 0; 1013b0f8d2eSBrian Somers for (i = 0, len = 0; i < LINK_QUEUES; i++) { 1023b0f8d2eSBrian Somers len = l->Queue[i].qlen; 1033b0f8d2eSBrian Somers m = l->Queue[i].top; 1043b0f8d2eSBrian Somers while (len--) { 1053b0f8d2eSBrian Somers bytes += plength(m); 1063b0f8d2eSBrian Somers m = m->pnext; 1073b0f8d2eSBrian Somers } 1083b0f8d2eSBrian Somers } 1093b0f8d2eSBrian Somers 1103b0f8d2eSBrian Somers return bytes; 1113b0f8d2eSBrian Somers } 1123b0f8d2eSBrian Somers 1138c07a7b2SBrian Somers struct mbuf * 1148c07a7b2SBrian Somers link_Dequeue(struct link *l) 1158c07a7b2SBrian Somers { 1168c07a7b2SBrian Somers int pri; 1178c07a7b2SBrian Somers struct mbuf *bp; 1188c07a7b2SBrian Somers 1198c07a7b2SBrian Somers for (bp = (struct mbuf *)0, pri = LINK_QUEUES - 1; pri >= 0; pri--) 1208c07a7b2SBrian Somers if (l->Queue[pri].qlen) { 1218c07a7b2SBrian Somers bp = Dequeue(l->Queue + pri); 1222289f246SBrian Somers LogPrintf(LogDEBUG, "link_Dequeue: Dequeued from queue %d," 1232289f246SBrian Somers " containing %d more packets\n", pri, l->Queue[pri].qlen); 1248c07a7b2SBrian Somers break; 1258c07a7b2SBrian Somers } 1268c07a7b2SBrian Somers 1278c07a7b2SBrian Somers return bp; 1288c07a7b2SBrian Somers } 1298c07a7b2SBrian Somers 1308c07a7b2SBrian Somers /* 1318c07a7b2SBrian Somers * Write to the link. Actualy, requested packets are queued, and go out 1328c07a7b2SBrian Somers * at some later time depending on the physical link implementation. 1338c07a7b2SBrian Somers */ 1348c07a7b2SBrian Somers void 1358c07a7b2SBrian Somers link_Write(struct link *l, int pri, const char *ptr, int count) 1368c07a7b2SBrian Somers { 1378c07a7b2SBrian Somers struct mbuf *bp; 1388c07a7b2SBrian Somers 1398c07a7b2SBrian Somers if(pri < 0 || pri >= LINK_QUEUES) 1408c07a7b2SBrian Somers pri = 0; 1418c07a7b2SBrian Somers 1428c07a7b2SBrian Somers bp = mballoc(count, MB_LINK); 1438c07a7b2SBrian Somers memcpy(MBUF_CTOP(bp), ptr, count); 1448c07a7b2SBrian Somers 1458c07a7b2SBrian Somers Enqueue(l->Queue + pri, bp); 1468c07a7b2SBrian Somers } 1478c07a7b2SBrian Somers 1488c07a7b2SBrian Somers void 1498c07a7b2SBrian Somers link_Output(struct link *l, int pri, struct mbuf *bp) 1508c07a7b2SBrian Somers { 1518c07a7b2SBrian Somers struct mbuf *wp; 1528c07a7b2SBrian Somers int len; 1538c07a7b2SBrian Somers 1548c07a7b2SBrian Somers if(pri < 0 || pri >= LINK_QUEUES) 1558c07a7b2SBrian Somers pri = 0; 1568c07a7b2SBrian Somers 1578c07a7b2SBrian Somers len = plength(bp); 1588c07a7b2SBrian Somers wp = mballoc(len, MB_LINK); 1598c07a7b2SBrian Somers mbread(bp, MBUF_CTOP(wp), len); 1608c07a7b2SBrian Somers Enqueue(l->Queue + pri, wp); 1618c07a7b2SBrian Somers } 1628c07a7b2SBrian Somers 1638c07a7b2SBrian Somers static struct protostatheader { 1648c07a7b2SBrian Somers u_short number; 1658c07a7b2SBrian Somers const char *name; 1668c07a7b2SBrian Somers } ProtocolStat[NPROTOSTAT] = { 1678c07a7b2SBrian Somers { PROTO_IP, "IP" }, 1688c07a7b2SBrian Somers { PROTO_VJUNCOMP, "VJ_UNCOMP" }, 1698c07a7b2SBrian Somers { PROTO_VJCOMP, "VJ_COMP" }, 1708c07a7b2SBrian Somers { PROTO_COMPD, "COMPD" }, 1718c07a7b2SBrian Somers { PROTO_LCP, "LCP" }, 1728c07a7b2SBrian Somers { PROTO_IPCP, "IPCP" }, 1738c07a7b2SBrian Somers { PROTO_CCP, "CCP" }, 1748c07a7b2SBrian Somers { PROTO_PAP, "PAP" }, 1758c07a7b2SBrian Somers { PROTO_LQR, "LQR" }, 1768c07a7b2SBrian Somers { PROTO_CHAP, "CHAP" }, 1773b0f8d2eSBrian Somers { PROTO_MP, "MULTILINK" }, 1788c07a7b2SBrian Somers { 0, "Others" } 1798c07a7b2SBrian Somers }; 1808c07a7b2SBrian Somers 1818c07a7b2SBrian Somers void 1828c07a7b2SBrian Somers link_ProtocolRecord(struct link *l, u_short proto, int type) 1838c07a7b2SBrian Somers { 1848c07a7b2SBrian Somers int i; 1858c07a7b2SBrian Somers 1868c07a7b2SBrian Somers for (i = 0; i < NPROTOSTAT; i++) 1878c07a7b2SBrian Somers if (ProtocolStat[i].number == proto) 1888c07a7b2SBrian Somers break; 1898c07a7b2SBrian Somers 1908c07a7b2SBrian Somers if (type == PROTO_IN) 1918c07a7b2SBrian Somers l->proto_in[i]++; 1928c07a7b2SBrian Somers else 1938c07a7b2SBrian Somers l->proto_out[i]++; 1948c07a7b2SBrian Somers } 1958c07a7b2SBrian Somers 1968c07a7b2SBrian Somers void 1978c07a7b2SBrian Somers link_ReportProtocolStatus(struct link *l) 1988c07a7b2SBrian Somers { 1998c07a7b2SBrian Somers int i; 2008c07a7b2SBrian Somers 20185b542cfSBrian Somers prompt_Printf(&prompt, " Protocol in out " 20285b542cfSBrian Somers "Protocol in out\n"); 2038c07a7b2SBrian Somers for (i = 0; i < NPROTOSTAT; i++) { 20485b542cfSBrian Somers prompt_Printf(&prompt, " %-9s: %8lu, %8lu", 2058c07a7b2SBrian Somers ProtocolStat[i].name, l->proto_in[i], l->proto_out[i]); 2068c07a7b2SBrian Somers if ((i % 2) == 0) 20785b542cfSBrian Somers prompt_Printf(&prompt, "\n"); 2088c07a7b2SBrian Somers } 2093b0f8d2eSBrian Somers if (!(i % 2)) 21085b542cfSBrian Somers prompt_Printf(&prompt, "\n"); 2118c07a7b2SBrian Somers } 212