xref: /freebsd/usr.sbin/ppp/throughput.c (revision 1342caed9c9c94c4524363408e77113333963bd5)
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  *
261342caedSBrian Somers  *	$Id: throughput.c,v 1.4.4.6 1998/04/10 13:19:23 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"
3885b542cfSBrian Somers #include "descriptor.h"
3985b542cfSBrian Somers #include "prompt.h"
401ae349f5Scvs2svn 
411ae349f5Scvs2svn void
421ae349f5Scvs2svn throughput_init(struct pppThroughput *t)
431ae349f5Scvs2svn {
441ae349f5Scvs2svn   int f;
451ae349f5Scvs2svn 
461ae349f5Scvs2svn   t->OctetsIn = t->OctetsOut = 0;
471ae349f5Scvs2svn   for (f = 0; f < SAMPLE_PERIOD; f++)
481ae349f5Scvs2svn     t->SampleOctets[f] = 0;
491ae349f5Scvs2svn   t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0;
503b0f8d2eSBrian Somers   t->Timer.name = "throughput";
51565e35e5SBrian Somers   t->uptime = 0;
521342caedSBrian Somers   t->rolling = 0;
531ae349f5Scvs2svn   throughput_stop(t);
541ae349f5Scvs2svn }
551ae349f5Scvs2svn 
561ae349f5Scvs2svn void
57b6217683SBrian Somers throughput_disp(struct pppThroughput *t, struct prompt *prompt)
581ae349f5Scvs2svn {
591ae349f5Scvs2svn   int secs_up;
601ae349f5Scvs2svn 
611ae349f5Scvs2svn   secs_up = t->uptime ? time(NULL) - t->uptime : 0;
62b6217683SBrian Somers   prompt_Printf(prompt, "Connect time: %d secs\n", secs_up);
631ae349f5Scvs2svn   if (secs_up == 0)
641ae349f5Scvs2svn     secs_up = 1;
65b6217683SBrian Somers   prompt_Printf(prompt, "%ld octets in, %ld octets out\n",
6685b542cfSBrian Somers                 t->OctetsIn, t->OctetsOut);
671342caedSBrian Somers   if (t->rolling) {
68b6217683SBrian Somers     prompt_Printf(prompt, "  overall   %5ld bytes/sec\n",
691ae349f5Scvs2svn                   (t->OctetsIn+t->OctetsOut)/secs_up);
70b6217683SBrian Somers     prompt_Printf(prompt, "  currently %5d bytes/sec\n", t->OctetsPerSecond);
71b6217683SBrian Somers     prompt_Printf(prompt, "  peak      %5d bytes/sec\n",
7285b542cfSBrian Somers                   t->BestOctetsPerSecond);
731ae349f5Scvs2svn   } else
74b6217683SBrian Somers     prompt_Printf(prompt, "Overall %ld bytes/sec\n",
7585b542cfSBrian Somers                   (t->OctetsIn+t->OctetsOut)/secs_up);
761ae349f5Scvs2svn }
771ae349f5Scvs2svn 
781ae349f5Scvs2svn 
791ae349f5Scvs2svn void
801ae349f5Scvs2svn throughput_log(struct pppThroughput *t, int level, const char *title)
811ae349f5Scvs2svn {
821ae349f5Scvs2svn   if (t->uptime) {
831ae349f5Scvs2svn     int secs_up;
841ae349f5Scvs2svn 
851ae349f5Scvs2svn     secs_up = t->uptime ? time(NULL) - t->uptime : 0;
861ae349f5Scvs2svn     if (title)
871ae349f5Scvs2svn       LogPrintf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
881ae349f5Scvs2svn                 " out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
891ae349f5Scvs2svn     else
901ae349f5Scvs2svn       LogPrintf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
911ae349f5Scvs2svn                 secs_up, t->OctetsIn, t->OctetsOut);
921ae349f5Scvs2svn     if (secs_up == 0)
931ae349f5Scvs2svn       secs_up = 1;
941342caedSBrian Somers     if (t->rolling)
951ae349f5Scvs2svn       LogPrintf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
961ae349f5Scvs2svn                 (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond);
971ae349f5Scvs2svn     else
981ae349f5Scvs2svn       LogPrintf(level, " total %ld bytes/sec\n",
991ae349f5Scvs2svn                 (t->OctetsIn+t->OctetsOut)/secs_up);
1001ae349f5Scvs2svn   }
1011ae349f5Scvs2svn }
1021ae349f5Scvs2svn 
1031ae349f5Scvs2svn static void
1041ae349f5Scvs2svn throughput_sampler(void *v)
1051ae349f5Scvs2svn {
1061ae349f5Scvs2svn   struct pppThroughput *t = (struct pppThroughput *)v;
1071ae349f5Scvs2svn   u_long old;
1081ae349f5Scvs2svn 
1091ae349f5Scvs2svn   StopTimer(&t->Timer);
1101ae349f5Scvs2svn   t->Timer.state = TIMER_STOPPED;
1111ae349f5Scvs2svn 
1121ae349f5Scvs2svn   old = t->SampleOctets[t->nSample];
1131ae349f5Scvs2svn   t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut;
1141ae349f5Scvs2svn   t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD;
1151ae349f5Scvs2svn   if (t->BestOctetsPerSecond < t->OctetsPerSecond)
1161ae349f5Scvs2svn     t->BestOctetsPerSecond = t->OctetsPerSecond;
1171ae349f5Scvs2svn   if (++t->nSample == SAMPLE_PERIOD)
1181ae349f5Scvs2svn     t->nSample = 0;
1191ae349f5Scvs2svn 
1201ae349f5Scvs2svn   StartTimer(&t->Timer);
1211ae349f5Scvs2svn }
1221ae349f5Scvs2svn 
1231ae349f5Scvs2svn void
1241342caedSBrian Somers throughput_start(struct pppThroughput *t, const char *name, int rolling)
1251ae349f5Scvs2svn {
1261ae349f5Scvs2svn   throughput_init(t);
1271342caedSBrian Somers   t->rolling = rolling ? 1 : 0;
1281ae349f5Scvs2svn   time(&t->uptime);
1291342caedSBrian Somers   if (t->rolling) {
1301ae349f5Scvs2svn     t->Timer.state = TIMER_STOPPED;
1311ae349f5Scvs2svn     t->Timer.load = SECTICKS;
1321ae349f5Scvs2svn     t->Timer.func = throughput_sampler;
1333b0f8d2eSBrian Somers     t->Timer.name = name;
1341ae349f5Scvs2svn     t->Timer.arg = t;
1351ae349f5Scvs2svn     StartTimer(&t->Timer);
1361ae349f5Scvs2svn   }
1371ae349f5Scvs2svn }
1381ae349f5Scvs2svn 
1391ae349f5Scvs2svn void
1401ae349f5Scvs2svn throughput_stop(struct pppThroughput *t)
1411ae349f5Scvs2svn {
1421342caedSBrian Somers   if (t->rolling)
1431ae349f5Scvs2svn     StopTimer(&t->Timer);
1441ae349f5Scvs2svn }
1451ae349f5Scvs2svn 
1461ae349f5Scvs2svn void
1471ae349f5Scvs2svn throughput_addin(struct pppThroughput *t, int n)
1481ae349f5Scvs2svn {
1491ae349f5Scvs2svn   t->OctetsIn += n;
1501ae349f5Scvs2svn }
1511ae349f5Scvs2svn 
1521ae349f5Scvs2svn void
1531ae349f5Scvs2svn throughput_addout(struct pppThroughput *t, int n)
1541ae349f5Scvs2svn {
1551ae349f5Scvs2svn   t->OctetsOut += n;
1561ae349f5Scvs2svn }
157