1 /*- 2 * Copyright (c) 1997 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$ 27 */ 28 29 #include <sys/param.h> 30 31 #include <stdio.h> 32 #include <time.h> 33 #include <netinet/in.h> 34 35 #include "command.h" 36 #include "mbuf.h" 37 #include "log.h" 38 #include "timer.h" 39 #include "throughput.h" 40 #include "defs.h" 41 #include "loadalias.h" 42 #include "vars.h" 43 44 void 45 throughput_init(struct pppThroughput *t) 46 { 47 int f; 48 49 t->OctetsIn = t->OctetsOut = 0; 50 for (f = 0; f < SAMPLE_PERIOD; f++) 51 t->SampleOctets[f] = 0; 52 t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0; 53 throughput_stop(t); 54 } 55 56 void 57 throughput_disp(struct pppThroughput *t, FILE *f) 58 { 59 int secs_up; 60 61 secs_up = t->uptime ? time(NULL) - t->uptime : 0; 62 fprintf(f, "Connect time: %d secs\n", secs_up); 63 if (secs_up == 0) 64 secs_up = 1; 65 fprintf(f, "%ld octets in, %ld octets out\n", t->OctetsIn, t->OctetsOut); 66 if (Enabled(ConfThroughput)) { 67 fprintf(f, " overall %5ld bytes/sec\n", 68 (t->OctetsIn+t->OctetsOut)/secs_up); 69 fprintf(f, " currently %5d bytes/sec\n", t->OctetsPerSecond); 70 fprintf(f, " peak %5d bytes/sec\n", t->BestOctetsPerSecond); 71 } else 72 fprintf(f, "Overall %ld bytes/sec\n", (t->OctetsIn+t->OctetsOut)/secs_up); 73 } 74 75 76 void 77 throughput_log(struct pppThroughput *t, int level, const char *title) 78 { 79 if (t->uptime) { 80 int secs_up; 81 82 secs_up = t->uptime ? time(NULL) - t->uptime : 0; 83 if (title) 84 LogPrintf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets" 85 " out\n", title, secs_up, t->OctetsIn, t->OctetsOut); 86 else 87 LogPrintf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n", 88 secs_up, t->OctetsIn, t->OctetsOut); 89 if (secs_up == 0) 90 secs_up = 1; 91 if (Enabled(ConfThroughput)) 92 LogPrintf(level, " total %ld bytes/sec, peak %d bytes/sec\n", 93 (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond); 94 else 95 LogPrintf(level, " total %ld bytes/sec\n", 96 (t->OctetsIn+t->OctetsOut)/secs_up); 97 } 98 } 99 100 static void 101 throughput_sampler(void *v) 102 { 103 struct pppThroughput *t = (struct pppThroughput *)v; 104 u_long old; 105 106 StopTimer(&t->Timer); 107 t->Timer.state = TIMER_STOPPED; 108 109 old = t->SampleOctets[t->nSample]; 110 t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut; 111 t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD; 112 if (t->BestOctetsPerSecond < t->OctetsPerSecond) 113 t->BestOctetsPerSecond = t->OctetsPerSecond; 114 if (++t->nSample == SAMPLE_PERIOD) 115 t->nSample = 0; 116 117 StartTimer(&t->Timer); 118 } 119 120 void 121 throughput_start(struct pppThroughput *t) 122 { 123 throughput_init(t); 124 time(&t->uptime); 125 if (Enabled(ConfThroughput)) { 126 t->Timer.state = TIMER_STOPPED; 127 t->Timer.load = SECTICKS; 128 t->Timer.func = throughput_sampler; 129 t->Timer.arg = t; 130 StartTimer(&t->Timer); 131 } 132 } 133 134 void 135 throughput_stop(struct pppThroughput *t) 136 { 137 if (Enabled(ConfThroughput)) 138 StopTimer(&t->Timer); 139 } 140 141 void 142 throughput_addin(struct pppThroughput *t, int n) 143 { 144 t->OctetsIn += n; 145 } 146 147 void 148 throughput_addout(struct pppThroughput *t, int n) 149 { 150 t->OctetsOut += n; 151 } 152