throughput.c revision 36819
131921Sbrian/*- 231921Sbrian * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 331921Sbrian * All rights reserved. 431921Sbrian * 531921Sbrian * Redistribution and use in source and binary forms, with or without 631921Sbrian * modification, are permitted provided that the following conditions 731921Sbrian * are met: 831921Sbrian * 1. Redistributions of source code must retain the above copyright 931921Sbrian * notice, this list of conditions and the following disclaimer. 1031921Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1131921Sbrian * notice, this list of conditions and the following disclaimer in the 1231921Sbrian * documentation and/or other materials provided with the distribution. 1331921Sbrian * 1431921Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1531921Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1631921Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1731921Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1831921Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1931921Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2031921Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2131921Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2231921Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2331921Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2431921Sbrian * SUCH DAMAGE. 2531921Sbrian * 2636819Sbrian * $Id: throughput.c,v 1.5 1998/05/21 21:48:41 brian Exp $ 2731272Sbrian */ 2831272Sbrian 2936285Sbrian#include <sys/types.h> 3031272Sbrian 3131272Sbrian#include <stdio.h> 3236285Sbrian#include <string.h> 3336285Sbrian#include <termios.h> 3431272Sbrian#include <time.h> 3531272Sbrian 3631343Sbrian#include "log.h" 3731272Sbrian#include "timer.h" 3831272Sbrian#include "throughput.h" 3936285Sbrian#include "descriptor.h" 4036285Sbrian#include "prompt.h" 4131272Sbrian 4231272Sbrianvoid 4331272Sbrianthroughput_init(struct pppThroughput *t) 4431272Sbrian{ 4531272Sbrian int f; 4631272Sbrian 4731272Sbrian t->OctetsIn = t->OctetsOut = 0; 4831272Sbrian for (f = 0; f < SAMPLE_PERIOD; f++) 4931272Sbrian t->SampleOctets[f] = 0; 5031272Sbrian t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0; 5136819Sbrian t->BestOctetsPerSecondTime = time(NULL); 5236285Sbrian memset(&t->Timer, '\0', sizeof t->Timer); 5336285Sbrian t->Timer.name = "throughput"; 5436285Sbrian t->uptime = 0; 5536285Sbrian t->rolling = 0; 5631272Sbrian throughput_stop(t); 5731272Sbrian} 5831272Sbrian 5931272Sbrianvoid 6036285Sbrianthroughput_disp(struct pppThroughput *t, struct prompt *prompt) 6131272Sbrian{ 6231272Sbrian int secs_up; 6331272Sbrian 6431418Sbrian secs_up = t->uptime ? time(NULL) - t->uptime : 0; 6536285Sbrian prompt_Printf(prompt, "Connect time: %d secs\n", secs_up); 6631272Sbrian if (secs_up == 0) 6731272Sbrian secs_up = 1; 6836285Sbrian prompt_Printf(prompt, "%ld octets in, %ld octets out\n", 6936285Sbrian t->OctetsIn, t->OctetsOut); 7036285Sbrian if (t->rolling) { 7136285Sbrian prompt_Printf(prompt, " overall %5ld bytes/sec\n", 7236285Sbrian (t->OctetsIn+t->OctetsOut)/secs_up); 7336285Sbrian prompt_Printf(prompt, " currently %5d bytes/sec\n", t->OctetsPerSecond); 7436819Sbrian prompt_Printf(prompt, " peak %5d bytes/sec on %s\n", 7536819Sbrian t->BestOctetsPerSecond, ctime(&t->BestOctetsPerSecondTime)); 7631272Sbrian } else 7736285Sbrian prompt_Printf(prompt, "Overall %ld bytes/sec\n", 7836285Sbrian (t->OctetsIn+t->OctetsOut)/secs_up); 7931272Sbrian} 8031272Sbrian 8131272Sbrian 8231272Sbrianvoid 8331272Sbrianthroughput_log(struct pppThroughput *t, int level, const char *title) 8431272Sbrian{ 8531272Sbrian if (t->uptime) { 8631272Sbrian int secs_up; 8731272Sbrian 8831418Sbrian secs_up = t->uptime ? time(NULL) - t->uptime : 0; 8931272Sbrian if (title) 9036285Sbrian log_Printf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets" 9131272Sbrian " out\n", title, secs_up, t->OctetsIn, t->OctetsOut); 9231272Sbrian else 9336285Sbrian log_Printf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n", 9431272Sbrian secs_up, t->OctetsIn, t->OctetsOut); 9531272Sbrian if (secs_up == 0) 9631272Sbrian secs_up = 1; 9736285Sbrian if (t->rolling) 9836819Sbrian log_Printf(level, " total %ld bytes/sec, peak %d bytes/sec on %s\n", 9936819Sbrian (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond, 10036819Sbrian ctime(&t->BestOctetsPerSecondTime)); 10131272Sbrian else 10236285Sbrian log_Printf(level, " total %ld bytes/sec\n", 10331272Sbrian (t->OctetsIn+t->OctetsOut)/secs_up); 10431272Sbrian } 10531272Sbrian} 10631272Sbrian 10731272Sbrianstatic void 10831343Sbrianthroughput_sampler(void *v) 10931272Sbrian{ 11031343Sbrian struct pppThroughput *t = (struct pppThroughput *)v; 11131272Sbrian u_long old; 11231272Sbrian 11336285Sbrian timer_Stop(&t->Timer); 11431272Sbrian 11531272Sbrian old = t->SampleOctets[t->nSample]; 11631272Sbrian t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut; 11731272Sbrian t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD; 11836819Sbrian if (t->BestOctetsPerSecond < t->OctetsPerSecond) { 11931272Sbrian t->BestOctetsPerSecond = t->OctetsPerSecond; 12036819Sbrian t->BestOctetsPerSecondTime = time(NULL); 12136819Sbrian } 12231272Sbrian if (++t->nSample == SAMPLE_PERIOD) 12331272Sbrian t->nSample = 0; 12431272Sbrian 12536285Sbrian timer_Start(&t->Timer); 12631272Sbrian} 12731272Sbrian 12831272Sbrianvoid 12936285Sbrianthroughput_start(struct pppThroughput *t, const char *name, int rolling) 13031272Sbrian{ 13136285Sbrian timer_Stop(&t->Timer); 13231272Sbrian throughput_init(t); 13336285Sbrian t->rolling = rolling ? 1 : 0; 13431272Sbrian time(&t->uptime); 13536285Sbrian if (t->rolling) { 13631272Sbrian t->Timer.load = SECTICKS; 13731272Sbrian t->Timer.func = throughput_sampler; 13836285Sbrian t->Timer.name = name; 13931272Sbrian t->Timer.arg = t; 14036285Sbrian timer_Start(&t->Timer); 14131272Sbrian } 14231272Sbrian} 14331272Sbrian 14431272Sbrianvoid 14531272Sbrianthroughput_stop(struct pppThroughput *t) 14631272Sbrian{ 14736285Sbrian timer_Stop(&t->Timer); 14831272Sbrian} 14931272Sbrian 15031272Sbrianvoid 15131272Sbrianthroughput_addin(struct pppThroughput *t, int n) 15231272Sbrian{ 15331272Sbrian t->OctetsIn += n; 15431272Sbrian} 15531272Sbrian 15631272Sbrianvoid 15731272Sbrianthroughput_addout(struct pppThroughput *t, int n) 15831272Sbrian{ 15931272Sbrian t->OctetsOut += n; 16031272Sbrian} 161