throughput.c revision 36285
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 *
2636285Sbrian *	$Id: throughput.c,v 1.4.4.9 1998/05/01 19:26:04 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;
5136285Sbrian  memset(&t->Timer, '\0', sizeof t->Timer);
5236285Sbrian  t->Timer.name = "throughput";
5336285Sbrian  t->uptime = 0;
5436285Sbrian  t->rolling = 0;
5531272Sbrian  throughput_stop(t);
5631272Sbrian}
5731272Sbrian
5831272Sbrianvoid
5936285Sbrianthroughput_disp(struct pppThroughput *t, struct prompt *prompt)
6031272Sbrian{
6131272Sbrian  int secs_up;
6231272Sbrian
6331418Sbrian  secs_up = t->uptime ? time(NULL) - t->uptime : 0;
6436285Sbrian  prompt_Printf(prompt, "Connect time: %d secs\n", secs_up);
6531272Sbrian  if (secs_up == 0)
6631272Sbrian    secs_up = 1;
6736285Sbrian  prompt_Printf(prompt, "%ld octets in, %ld octets out\n",
6836285Sbrian                t->OctetsIn, t->OctetsOut);
6936285Sbrian  if (t->rolling) {
7036285Sbrian    prompt_Printf(prompt, "  overall   %5ld bytes/sec\n",
7136285Sbrian                  (t->OctetsIn+t->OctetsOut)/secs_up);
7236285Sbrian    prompt_Printf(prompt, "  currently %5d bytes/sec\n", t->OctetsPerSecond);
7336285Sbrian    prompt_Printf(prompt, "  peak      %5d bytes/sec\n",
7436285Sbrian                  t->BestOctetsPerSecond);
7531272Sbrian  } else
7636285Sbrian    prompt_Printf(prompt, "Overall %ld bytes/sec\n",
7736285Sbrian                  (t->OctetsIn+t->OctetsOut)/secs_up);
7831272Sbrian}
7931272Sbrian
8031272Sbrian
8131272Sbrianvoid
8231272Sbrianthroughput_log(struct pppThroughput *t, int level, const char *title)
8331272Sbrian{
8431272Sbrian  if (t->uptime) {
8531272Sbrian    int secs_up;
8631272Sbrian
8731418Sbrian    secs_up = t->uptime ? time(NULL) - t->uptime : 0;
8831272Sbrian    if (title)
8936285Sbrian      log_Printf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
9031272Sbrian                " out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
9131272Sbrian    else
9236285Sbrian      log_Printf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
9331272Sbrian                secs_up, t->OctetsIn, t->OctetsOut);
9431272Sbrian    if (secs_up == 0)
9531272Sbrian      secs_up = 1;
9636285Sbrian    if (t->rolling)
9736285Sbrian      log_Printf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
9831272Sbrian                (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond);
9931272Sbrian    else
10036285Sbrian      log_Printf(level, " total %ld bytes/sec\n",
10131272Sbrian                (t->OctetsIn+t->OctetsOut)/secs_up);
10231272Sbrian  }
10331272Sbrian}
10431272Sbrian
10531272Sbrianstatic void
10631343Sbrianthroughput_sampler(void *v)
10731272Sbrian{
10831343Sbrian  struct pppThroughput *t = (struct pppThroughput *)v;
10931272Sbrian  u_long old;
11031272Sbrian
11136285Sbrian  timer_Stop(&t->Timer);
11231272Sbrian
11331272Sbrian  old = t->SampleOctets[t->nSample];
11431272Sbrian  t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut;
11531272Sbrian  t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD;
11631272Sbrian  if (t->BestOctetsPerSecond < t->OctetsPerSecond)
11731272Sbrian    t->BestOctetsPerSecond = t->OctetsPerSecond;
11831272Sbrian  if (++t->nSample == SAMPLE_PERIOD)
11931272Sbrian    t->nSample = 0;
12031272Sbrian
12136285Sbrian  timer_Start(&t->Timer);
12231272Sbrian}
12331272Sbrian
12431272Sbrianvoid
12536285Sbrianthroughput_start(struct pppThroughput *t, const char *name, int rolling)
12631272Sbrian{
12736285Sbrian  timer_Stop(&t->Timer);
12831272Sbrian  throughput_init(t);
12936285Sbrian  t->rolling = rolling ? 1 : 0;
13031272Sbrian  time(&t->uptime);
13136285Sbrian  if (t->rolling) {
13231272Sbrian    t->Timer.load = SECTICKS;
13331272Sbrian    t->Timer.func = throughput_sampler;
13436285Sbrian    t->Timer.name = name;
13531272Sbrian    t->Timer.arg = t;
13636285Sbrian    timer_Start(&t->Timer);
13731272Sbrian  }
13831272Sbrian}
13931272Sbrian
14031272Sbrianvoid
14131272Sbrianthroughput_stop(struct pppThroughput *t)
14231272Sbrian{
14336285Sbrian  timer_Stop(&t->Timer);
14431272Sbrian}
14531272Sbrian
14631272Sbrianvoid
14731272Sbrianthroughput_addin(struct pppThroughput *t, int n)
14831272Sbrian{
14931272Sbrian  t->OctetsIn += n;
15031272Sbrian}
15131272Sbrian
15231272Sbrianvoid
15331272Sbrianthroughput_addout(struct pppThroughput *t, int n)
15431272Sbrian{
15531272Sbrian  t->OctetsOut += n;
15631272Sbrian}
157