xref: /freebsd/usr.sbin/ppp/throughput.c (revision c39934ea321903c1a19b1fe98bee9cabf046a59b)
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  *
26c39934eaSBrian Somers  *	$Id$
279a0b991fSBrian Somers  */
289a0b991fSBrian Somers 
299a0b991fSBrian Somers #include <sys/param.h>
309a0b991fSBrian Somers 
319a0b991fSBrian Somers #include <stdio.h>
329a0b991fSBrian Somers #include <time.h>
339a0b991fSBrian Somers #include <netinet/in.h>
349a0b991fSBrian Somers 
35b6e82f33SBrian Somers #include "command.h"
36b6e82f33SBrian Somers #include "mbuf.h"
37b6e82f33SBrian Somers #include "log.h"
389a0b991fSBrian Somers #include "timer.h"
399a0b991fSBrian Somers #include "throughput.h"
409a0b991fSBrian Somers #include "defs.h"
419a0b991fSBrian Somers #include "loadalias.h"
429a0b991fSBrian Somers #include "vars.h"
439a0b991fSBrian Somers 
449a0b991fSBrian Somers void
459a0b991fSBrian Somers throughput_init(struct pppThroughput *t)
469a0b991fSBrian Somers {
479a0b991fSBrian Somers   int f;
489a0b991fSBrian Somers 
499a0b991fSBrian Somers   t->OctetsIn = t->OctetsOut = 0;
509a0b991fSBrian Somers   for (f = 0; f < SAMPLE_PERIOD; f++)
519a0b991fSBrian Somers     t->SampleOctets[f] = 0;
529a0b991fSBrian Somers   t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0;
539a0b991fSBrian Somers   throughput_stop(t);
549a0b991fSBrian Somers }
559a0b991fSBrian Somers 
569a0b991fSBrian Somers void
579a0b991fSBrian Somers throughput_disp(struct pppThroughput *t, FILE *f)
589a0b991fSBrian Somers {
599a0b991fSBrian Somers   int secs_up;
609a0b991fSBrian Somers 
61fc85e494SBrian Somers   secs_up = t->uptime ? time(NULL) - t->uptime : 0;
629a0b991fSBrian Somers   fprintf(f, "Connect time: %d secs\n", secs_up);
639a0b991fSBrian Somers   if (secs_up == 0)
649a0b991fSBrian Somers     secs_up = 1;
659a0b991fSBrian Somers   fprintf(f, "%ld octets in, %ld octets out\n", t->OctetsIn, t->OctetsOut);
669a0b991fSBrian Somers   if (Enabled(ConfThroughput)) {
679a0b991fSBrian Somers     fprintf(f, "  overall   %5ld bytes/sec\n",
689a0b991fSBrian Somers             (t->OctetsIn+t->OctetsOut)/secs_up);
699a0b991fSBrian Somers     fprintf(f, "  currently %5d bytes/sec\n", t->OctetsPerSecond);
709a0b991fSBrian Somers     fprintf(f, "  peak      %5d bytes/sec\n", t->BestOctetsPerSecond);
719a0b991fSBrian Somers   } else
729a0b991fSBrian Somers     fprintf(f, "Overall %ld bytes/sec\n", (t->OctetsIn+t->OctetsOut)/secs_up);
739a0b991fSBrian Somers }
749a0b991fSBrian Somers 
759a0b991fSBrian Somers 
769a0b991fSBrian Somers void
779a0b991fSBrian Somers throughput_log(struct pppThroughput *t, int level, const char *title)
789a0b991fSBrian Somers {
799a0b991fSBrian Somers   if (t->uptime) {
809a0b991fSBrian Somers     int secs_up;
819a0b991fSBrian Somers 
82fc85e494SBrian Somers     secs_up = t->uptime ? time(NULL) - t->uptime : 0;
839a0b991fSBrian Somers     if (title)
849a0b991fSBrian Somers       LogPrintf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
859a0b991fSBrian Somers                 " out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
869a0b991fSBrian Somers     else
879a0b991fSBrian Somers       LogPrintf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
889a0b991fSBrian Somers                 secs_up, t->OctetsIn, t->OctetsOut);
899a0b991fSBrian Somers     if (secs_up == 0)
909a0b991fSBrian Somers       secs_up = 1;
919a0b991fSBrian Somers     if (Enabled(ConfThroughput))
929a0b991fSBrian Somers       LogPrintf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
939a0b991fSBrian Somers                 (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond);
949a0b991fSBrian Somers     else
959a0b991fSBrian Somers       LogPrintf(level, " total %ld bytes/sec\n",
969a0b991fSBrian Somers                 (t->OctetsIn+t->OctetsOut)/secs_up);
979a0b991fSBrian Somers   }
989a0b991fSBrian Somers }
999a0b991fSBrian Somers 
1009a0b991fSBrian Somers static void
101b6e82f33SBrian Somers throughput_sampler(void *v)
1029a0b991fSBrian Somers {
103b6e82f33SBrian Somers   struct pppThroughput *t = (struct pppThroughput *)v;
1049a0b991fSBrian Somers   u_long old;
1059a0b991fSBrian Somers 
1069a0b991fSBrian Somers   StopTimer(&t->Timer);
1079a0b991fSBrian Somers   t->Timer.state = TIMER_STOPPED;
1089a0b991fSBrian Somers 
1099a0b991fSBrian Somers   old = t->SampleOctets[t->nSample];
1109a0b991fSBrian Somers   t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut;
1119a0b991fSBrian Somers   t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD;
1129a0b991fSBrian Somers   if (t->BestOctetsPerSecond < t->OctetsPerSecond)
1139a0b991fSBrian Somers     t->BestOctetsPerSecond = t->OctetsPerSecond;
1149a0b991fSBrian Somers   if (++t->nSample == SAMPLE_PERIOD)
1159a0b991fSBrian Somers     t->nSample = 0;
1169a0b991fSBrian Somers 
1179a0b991fSBrian Somers   StartTimer(&t->Timer);
1189a0b991fSBrian Somers }
1199a0b991fSBrian Somers 
1209a0b991fSBrian Somers void
1219a0b991fSBrian Somers throughput_start(struct pppThroughput *t)
1229a0b991fSBrian Somers {
1239a0b991fSBrian Somers   throughput_init(t);
1249a0b991fSBrian Somers   time(&t->uptime);
1259a0b991fSBrian Somers   if (Enabled(ConfThroughput)) {
1269a0b991fSBrian Somers     t->Timer.state = TIMER_STOPPED;
1279a0b991fSBrian Somers     t->Timer.load = SECTICKS;
1289a0b991fSBrian Somers     t->Timer.func = throughput_sampler;
1299a0b991fSBrian Somers     t->Timer.arg = t;
1309a0b991fSBrian Somers     StartTimer(&t->Timer);
1319a0b991fSBrian Somers   }
1329a0b991fSBrian Somers }
1339a0b991fSBrian Somers 
1349a0b991fSBrian Somers void
1359a0b991fSBrian Somers throughput_stop(struct pppThroughput *t)
1369a0b991fSBrian Somers {
1379a0b991fSBrian Somers   if (Enabled(ConfThroughput))
1389a0b991fSBrian Somers     StopTimer(&t->Timer);
1399a0b991fSBrian Somers }
1409a0b991fSBrian Somers 
1419a0b991fSBrian Somers void
1429a0b991fSBrian Somers throughput_addin(struct pppThroughput *t, int n)
1439a0b991fSBrian Somers {
1449a0b991fSBrian Somers   t->OctetsIn += n;
1459a0b991fSBrian Somers }
1469a0b991fSBrian Somers 
1479a0b991fSBrian Somers void
1489a0b991fSBrian Somers throughput_addout(struct pppThroughput *t, int n)
1499a0b991fSBrian Somers {
1509a0b991fSBrian Somers   t->OctetsOut += n;
1519a0b991fSBrian Somers }
152