xref: /freebsd/usr.sbin/ppp/throughput.c (revision 2764b86afdc99a30f4b1a4da2c04db8aa7aa785d)
11ae349f5Scvs2svn /*-
21ae349f5Scvs2svn  * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
31ae349f5Scvs2svn  * All rights reserved.
41ae349f5Scvs2svn  *
51ae349f5Scvs2svn  * Redistribution and use in source and binary forms, with or without
61ae349f5Scvs2svn  * modification, are permitted provided that the following conditions
71ae349f5Scvs2svn  * are met:
81ae349f5Scvs2svn  * 1. Redistributions of source code must retain the above copyright
91ae349f5Scvs2svn  *    notice, this list of conditions and the following disclaimer.
101ae349f5Scvs2svn  * 2. Redistributions in binary form must reproduce the above copyright
111ae349f5Scvs2svn  *    notice, this list of conditions and the following disclaimer in the
121ae349f5Scvs2svn  *    documentation and/or other materials provided with the distribution.
131ae349f5Scvs2svn  *
141ae349f5Scvs2svn  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
151ae349f5Scvs2svn  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
161ae349f5Scvs2svn  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
171ae349f5Scvs2svn  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
181ae349f5Scvs2svn  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
191ae349f5Scvs2svn  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
201ae349f5Scvs2svn  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
211ae349f5Scvs2svn  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
221ae349f5Scvs2svn  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
231ae349f5Scvs2svn  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
241ae349f5Scvs2svn  * SUCH DAMAGE.
251ae349f5Scvs2svn  *
262764b86aSBrian Somers  *	$Id: throughput.c,v 1.4.4.4 1998/04/06 09:12:37 brian Exp $
271ae349f5Scvs2svn  */
281ae349f5Scvs2svn 
292764b86aSBrian Somers #include <sys/types.h>
301ae349f5Scvs2svn 
311ae349f5Scvs2svn #include <stdio.h>
3285b542cfSBrian Somers #include <termios.h>
331ae349f5Scvs2svn #include <time.h>
341ae349f5Scvs2svn 
351ae349f5Scvs2svn #include "log.h"
361ae349f5Scvs2svn #include "timer.h"
371ae349f5Scvs2svn #include "throughput.h"
381ae349f5Scvs2svn #include "vars.h"
3985b542cfSBrian Somers #include "descriptor.h"
4085b542cfSBrian Somers #include "prompt.h"
411ae349f5Scvs2svn 
421ae349f5Scvs2svn void
431ae349f5Scvs2svn throughput_init(struct pppThroughput *t)
441ae349f5Scvs2svn {
451ae349f5Scvs2svn   int f;
461ae349f5Scvs2svn 
471ae349f5Scvs2svn   t->OctetsIn = t->OctetsOut = 0;
481ae349f5Scvs2svn   for (f = 0; f < SAMPLE_PERIOD; f++)
491ae349f5Scvs2svn     t->SampleOctets[f] = 0;
501ae349f5Scvs2svn   t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0;
513b0f8d2eSBrian Somers   t->Timer.name = "throughput";
521ae349f5Scvs2svn   throughput_stop(t);
531ae349f5Scvs2svn }
541ae349f5Scvs2svn 
551ae349f5Scvs2svn void
56b6217683SBrian Somers throughput_disp(struct pppThroughput *t, struct prompt *prompt)
571ae349f5Scvs2svn {
581ae349f5Scvs2svn   int secs_up;
591ae349f5Scvs2svn 
601ae349f5Scvs2svn   secs_up = t->uptime ? time(NULL) - t->uptime : 0;
61b6217683SBrian Somers   prompt_Printf(prompt, "Connect time: %d secs\n", secs_up);
621ae349f5Scvs2svn   if (secs_up == 0)
631ae349f5Scvs2svn     secs_up = 1;
64b6217683SBrian Somers   prompt_Printf(prompt, "%ld octets in, %ld octets out\n",
6585b542cfSBrian Somers                 t->OctetsIn, t->OctetsOut);
661ae349f5Scvs2svn   if (Enabled(ConfThroughput)) {
67b6217683SBrian Somers     prompt_Printf(prompt, "  overall   %5ld bytes/sec\n",
681ae349f5Scvs2svn                   (t->OctetsIn+t->OctetsOut)/secs_up);
69b6217683SBrian Somers     prompt_Printf(prompt, "  currently %5d bytes/sec\n", t->OctetsPerSecond);
70b6217683SBrian Somers     prompt_Printf(prompt, "  peak      %5d bytes/sec\n",
7185b542cfSBrian Somers                   t->BestOctetsPerSecond);
721ae349f5Scvs2svn   } else
73b6217683SBrian Somers     prompt_Printf(prompt, "Overall %ld bytes/sec\n",
7485b542cfSBrian Somers                   (t->OctetsIn+t->OctetsOut)/secs_up);
751ae349f5Scvs2svn }
761ae349f5Scvs2svn 
771ae349f5Scvs2svn 
781ae349f5Scvs2svn void
791ae349f5Scvs2svn throughput_log(struct pppThroughput *t, int level, const char *title)
801ae349f5Scvs2svn {
811ae349f5Scvs2svn   if (t->uptime) {
821ae349f5Scvs2svn     int secs_up;
831ae349f5Scvs2svn 
841ae349f5Scvs2svn     secs_up = t->uptime ? time(NULL) - t->uptime : 0;
851ae349f5Scvs2svn     if (title)
861ae349f5Scvs2svn       LogPrintf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
871ae349f5Scvs2svn                 " out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
881ae349f5Scvs2svn     else
891ae349f5Scvs2svn       LogPrintf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
901ae349f5Scvs2svn                 secs_up, t->OctetsIn, t->OctetsOut);
911ae349f5Scvs2svn     if (secs_up == 0)
921ae349f5Scvs2svn       secs_up = 1;
931ae349f5Scvs2svn     if (Enabled(ConfThroughput))
941ae349f5Scvs2svn       LogPrintf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
951ae349f5Scvs2svn                 (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond);
961ae349f5Scvs2svn     else
971ae349f5Scvs2svn       LogPrintf(level, " total %ld bytes/sec\n",
981ae349f5Scvs2svn                 (t->OctetsIn+t->OctetsOut)/secs_up);
991ae349f5Scvs2svn   }
1001ae349f5Scvs2svn }
1011ae349f5Scvs2svn 
1021ae349f5Scvs2svn static void
1031ae349f5Scvs2svn throughput_sampler(void *v)
1041ae349f5Scvs2svn {
1051ae349f5Scvs2svn   struct pppThroughput *t = (struct pppThroughput *)v;
1061ae349f5Scvs2svn   u_long old;
1071ae349f5Scvs2svn 
1081ae349f5Scvs2svn   StopTimer(&t->Timer);
1091ae349f5Scvs2svn   t->Timer.state = TIMER_STOPPED;
1101ae349f5Scvs2svn 
1111ae349f5Scvs2svn   old = t->SampleOctets[t->nSample];
1121ae349f5Scvs2svn   t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut;
1131ae349f5Scvs2svn   t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD;
1141ae349f5Scvs2svn   if (t->BestOctetsPerSecond < t->OctetsPerSecond)
1151ae349f5Scvs2svn     t->BestOctetsPerSecond = t->OctetsPerSecond;
1161ae349f5Scvs2svn   if (++t->nSample == SAMPLE_PERIOD)
1171ae349f5Scvs2svn     t->nSample = 0;
1181ae349f5Scvs2svn 
1191ae349f5Scvs2svn   StartTimer(&t->Timer);
1201ae349f5Scvs2svn }
1211ae349f5Scvs2svn 
1221ae349f5Scvs2svn void
1233b0f8d2eSBrian Somers throughput_start(struct pppThroughput *t, const char *name)
1241ae349f5Scvs2svn {
1251ae349f5Scvs2svn   throughput_init(t);
1261ae349f5Scvs2svn   time(&t->uptime);
1271ae349f5Scvs2svn   if (Enabled(ConfThroughput)) {
1281ae349f5Scvs2svn     t->Timer.state = TIMER_STOPPED;
1291ae349f5Scvs2svn     t->Timer.load = SECTICKS;
1301ae349f5Scvs2svn     t->Timer.func = throughput_sampler;
1313b0f8d2eSBrian Somers     t->Timer.name = name;
1321ae349f5Scvs2svn     t->Timer.arg = t;
1331ae349f5Scvs2svn     StartTimer(&t->Timer);
1341ae349f5Scvs2svn   }
1351ae349f5Scvs2svn }
1361ae349f5Scvs2svn 
1371ae349f5Scvs2svn void
1381ae349f5Scvs2svn throughput_stop(struct pppThroughput *t)
1391ae349f5Scvs2svn {
1401ae349f5Scvs2svn   if (Enabled(ConfThroughput))
1411ae349f5Scvs2svn     StopTimer(&t->Timer);
1421ae349f5Scvs2svn }
1431ae349f5Scvs2svn 
1441ae349f5Scvs2svn void
1451ae349f5Scvs2svn throughput_addin(struct pppThroughput *t, int n)
1461ae349f5Scvs2svn {
1471ae349f5Scvs2svn   t->OctetsIn += n;
1481ae349f5Scvs2svn }
1491ae349f5Scvs2svn 
1501ae349f5Scvs2svn void
1511ae349f5Scvs2svn throughput_addout(struct pppThroughput *t, int n)
1521ae349f5Scvs2svn {
1531ae349f5Scvs2svn   t->OctetsOut += n;
1541ae349f5Scvs2svn }
155