1c39934eaSBrian Somers /*- 2c39934eaSBrian Somers * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 3c39934eaSBrian Somers * All rights reserved. 4c39934eaSBrian Somers * 5c39934eaSBrian Somers * Redistribution and use in source and binary forms, with or without 6c39934eaSBrian Somers * modification, are permitted provided that the following conditions 7c39934eaSBrian Somers * are met: 8c39934eaSBrian Somers * 1. Redistributions of source code must retain the above copyright 9c39934eaSBrian Somers * notice, this list of conditions and the following disclaimer. 10c39934eaSBrian Somers * 2. Redistributions in binary form must reproduce the above copyright 11c39934eaSBrian Somers * notice, this list of conditions and the following disclaimer in the 12c39934eaSBrian Somers * documentation and/or other materials provided with the distribution. 13c39934eaSBrian Somers * 14c39934eaSBrian Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15c39934eaSBrian Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16c39934eaSBrian Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17c39934eaSBrian Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18c39934eaSBrian Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19c39934eaSBrian Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20c39934eaSBrian Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21c39934eaSBrian Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22c39934eaSBrian Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23c39934eaSBrian Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24c39934eaSBrian Somers * SUCH DAMAGE. 25c39934eaSBrian Somers * 26255aa9e3SBrian Somers * $Id: throughput.c,v 1.5 1998/05/21 21:48:41 brian Exp $ 279a0b991fSBrian Somers */ 289a0b991fSBrian Somers 292764b86aSBrian Somers #include <sys/types.h> 309a0b991fSBrian Somers 319a0b991fSBrian Somers #include <stdio.h> 32e3c70ce9SBrian Somers #include <string.h> 3385b542cfSBrian Somers #include <termios.h> 349a0b991fSBrian Somers #include <time.h> 359a0b991fSBrian Somers 36b6e82f33SBrian Somers #include "log.h" 379a0b991fSBrian Somers #include "timer.h" 389a0b991fSBrian Somers #include "throughput.h" 3985b542cfSBrian Somers #include "descriptor.h" 4085b542cfSBrian Somers #include "prompt.h" 419a0b991fSBrian Somers 429a0b991fSBrian Somers void 439a0b991fSBrian Somers throughput_init(struct pppThroughput *t) 449a0b991fSBrian Somers { 459a0b991fSBrian Somers int f; 469a0b991fSBrian Somers 479a0b991fSBrian Somers t->OctetsIn = t->OctetsOut = 0; 489a0b991fSBrian Somers for (f = 0; f < SAMPLE_PERIOD; f++) 499a0b991fSBrian Somers t->SampleOctets[f] = 0; 509a0b991fSBrian Somers t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0; 51255aa9e3SBrian Somers t->BestOctetsPerSecondTime = time(NULL); 52e3c70ce9SBrian Somers memset(&t->Timer, '\0', sizeof t->Timer); 533b0f8d2eSBrian Somers t->Timer.name = "throughput"; 54565e35e5SBrian Somers t->uptime = 0; 551342caedSBrian Somers t->rolling = 0; 569a0b991fSBrian Somers throughput_stop(t); 579a0b991fSBrian Somers } 589a0b991fSBrian Somers 599a0b991fSBrian Somers void 60b6217683SBrian Somers throughput_disp(struct pppThroughput *t, struct prompt *prompt) 619a0b991fSBrian Somers { 629a0b991fSBrian Somers int secs_up; 639a0b991fSBrian Somers 64fc85e494SBrian Somers secs_up = t->uptime ? time(NULL) - t->uptime : 0; 65b6217683SBrian Somers prompt_Printf(prompt, "Connect time: %d secs\n", secs_up); 669a0b991fSBrian Somers if (secs_up == 0) 679a0b991fSBrian Somers secs_up = 1; 68b6217683SBrian Somers prompt_Printf(prompt, "%ld octets in, %ld octets out\n", 6985b542cfSBrian Somers t->OctetsIn, t->OctetsOut); 701342caedSBrian Somers if (t->rolling) { 71b6217683SBrian Somers prompt_Printf(prompt, " overall %5ld bytes/sec\n", 729a0b991fSBrian Somers (t->OctetsIn+t->OctetsOut)/secs_up); 73b6217683SBrian Somers prompt_Printf(prompt, " currently %5d bytes/sec\n", t->OctetsPerSecond); 74255aa9e3SBrian Somers prompt_Printf(prompt, " peak %5d bytes/sec on %s\n", 75255aa9e3SBrian Somers t->BestOctetsPerSecond, ctime(&t->BestOctetsPerSecondTime)); 769a0b991fSBrian Somers } else 77b6217683SBrian Somers prompt_Printf(prompt, "Overall %ld bytes/sec\n", 7885b542cfSBrian Somers (t->OctetsIn+t->OctetsOut)/secs_up); 799a0b991fSBrian Somers } 809a0b991fSBrian Somers 819a0b991fSBrian Somers 829a0b991fSBrian Somers void 839a0b991fSBrian Somers throughput_log(struct pppThroughput *t, int level, const char *title) 849a0b991fSBrian Somers { 859a0b991fSBrian Somers if (t->uptime) { 869a0b991fSBrian Somers int secs_up; 879a0b991fSBrian Somers 88fc85e494SBrian Somers secs_up = t->uptime ? time(NULL) - t->uptime : 0; 899a0b991fSBrian Somers if (title) 90dd7e2610SBrian Somers log_Printf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets" 919a0b991fSBrian Somers " out\n", title, secs_up, t->OctetsIn, t->OctetsOut); 929a0b991fSBrian Somers else 93dd7e2610SBrian Somers log_Printf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n", 949a0b991fSBrian Somers secs_up, t->OctetsIn, t->OctetsOut); 959a0b991fSBrian Somers if (secs_up == 0) 969a0b991fSBrian Somers secs_up = 1; 971342caedSBrian Somers if (t->rolling) 98255aa9e3SBrian Somers log_Printf(level, " total %ld bytes/sec, peak %d bytes/sec on %s\n", 99255aa9e3SBrian Somers (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond, 100255aa9e3SBrian Somers ctime(&t->BestOctetsPerSecondTime)); 1019a0b991fSBrian Somers else 102dd7e2610SBrian Somers log_Printf(level, " total %ld bytes/sec\n", 1039a0b991fSBrian Somers (t->OctetsIn+t->OctetsOut)/secs_up); 1049a0b991fSBrian Somers } 1059a0b991fSBrian Somers } 1069a0b991fSBrian Somers 1079a0b991fSBrian Somers static void 108b6e82f33SBrian Somers throughput_sampler(void *v) 1099a0b991fSBrian Somers { 110b6e82f33SBrian Somers struct pppThroughput *t = (struct pppThroughput *)v; 1119a0b991fSBrian Somers u_long old; 1129a0b991fSBrian Somers 113dd7e2610SBrian Somers timer_Stop(&t->Timer); 1149a0b991fSBrian Somers 1159a0b991fSBrian Somers old = t->SampleOctets[t->nSample]; 1169a0b991fSBrian Somers t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut; 1179a0b991fSBrian Somers t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD; 118255aa9e3SBrian Somers if (t->BestOctetsPerSecond < t->OctetsPerSecond) { 1199a0b991fSBrian Somers t->BestOctetsPerSecond = t->OctetsPerSecond; 120255aa9e3SBrian Somers t->BestOctetsPerSecondTime = time(NULL); 121255aa9e3SBrian Somers } 1229a0b991fSBrian Somers if (++t->nSample == SAMPLE_PERIOD) 1239a0b991fSBrian Somers t->nSample = 0; 1249a0b991fSBrian Somers 125dd7e2610SBrian Somers timer_Start(&t->Timer); 1269a0b991fSBrian Somers } 1279a0b991fSBrian Somers 1289a0b991fSBrian Somers void 1291342caedSBrian Somers throughput_start(struct pppThroughput *t, const char *name, int rolling) 1309a0b991fSBrian Somers { 131dd7e2610SBrian Somers timer_Stop(&t->Timer); 1329a0b991fSBrian Somers throughput_init(t); 1331342caedSBrian Somers t->rolling = rolling ? 1 : 0; 1349a0b991fSBrian Somers time(&t->uptime); 1351342caedSBrian Somers if (t->rolling) { 1369a0b991fSBrian Somers t->Timer.load = SECTICKS; 1379a0b991fSBrian Somers t->Timer.func = throughput_sampler; 1383b0f8d2eSBrian Somers t->Timer.name = name; 1399a0b991fSBrian Somers t->Timer.arg = t; 140dd7e2610SBrian Somers timer_Start(&t->Timer); 1419a0b991fSBrian Somers } 1429a0b991fSBrian Somers } 1439a0b991fSBrian Somers 1449a0b991fSBrian Somers void 1459a0b991fSBrian Somers throughput_stop(struct pppThroughput *t) 1469a0b991fSBrian Somers { 147dd7e2610SBrian Somers timer_Stop(&t->Timer); 1489a0b991fSBrian Somers } 1499a0b991fSBrian Somers 1509a0b991fSBrian Somers void 1519a0b991fSBrian Somers throughput_addin(struct pppThroughput *t, int n) 1529a0b991fSBrian Somers { 1539a0b991fSBrian Somers t->OctetsIn += n; 1549a0b991fSBrian Somers } 1559a0b991fSBrian Somers 1569a0b991fSBrian Somers void 1579a0b991fSBrian Somers throughput_addout(struct pppThroughput *t, int n) 1589a0b991fSBrian Somers { 1599a0b991fSBrian Somers t->OctetsOut += n; 1609a0b991fSBrian Somers } 161