xref: /freebsd/usr.sbin/ppp/throughput.c (revision dd7e261079699ca066fd8acaaf3ed460e5de61a1)
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  *
26dd7e2610SBrian Somers  *	$Id: throughput.c,v 1.4.4.8 1998/04/19 15:24:50 brian Exp $
271ae349f5Scvs2svn  */
281ae349f5Scvs2svn 
292764b86aSBrian Somers #include <sys/types.h>
301ae349f5Scvs2svn 
311ae349f5Scvs2svn #include <stdio.h>
32e3c70ce9SBrian Somers #include <string.h>
3385b542cfSBrian Somers #include <termios.h>
341ae349f5Scvs2svn #include <time.h>
351ae349f5Scvs2svn 
361ae349f5Scvs2svn #include "log.h"
371ae349f5Scvs2svn #include "timer.h"
381ae349f5Scvs2svn #include "throughput.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;
51e3c70ce9SBrian Somers   memset(&t->Timer, '\0', sizeof t->Timer);
523b0f8d2eSBrian Somers   t->Timer.name = "throughput";
53565e35e5SBrian Somers   t->uptime = 0;
541342caedSBrian Somers   t->rolling = 0;
551ae349f5Scvs2svn   throughput_stop(t);
561ae349f5Scvs2svn }
571ae349f5Scvs2svn 
581ae349f5Scvs2svn void
59b6217683SBrian Somers throughput_disp(struct pppThroughput *t, struct prompt *prompt)
601ae349f5Scvs2svn {
611ae349f5Scvs2svn   int secs_up;
621ae349f5Scvs2svn 
631ae349f5Scvs2svn   secs_up = t->uptime ? time(NULL) - t->uptime : 0;
64b6217683SBrian Somers   prompt_Printf(prompt, "Connect time: %d secs\n", secs_up);
651ae349f5Scvs2svn   if (secs_up == 0)
661ae349f5Scvs2svn     secs_up = 1;
67b6217683SBrian Somers   prompt_Printf(prompt, "%ld octets in, %ld octets out\n",
6885b542cfSBrian Somers                 t->OctetsIn, t->OctetsOut);
691342caedSBrian Somers   if (t->rolling) {
70b6217683SBrian Somers     prompt_Printf(prompt, "  overall   %5ld bytes/sec\n",
711ae349f5Scvs2svn                   (t->OctetsIn+t->OctetsOut)/secs_up);
72b6217683SBrian Somers     prompt_Printf(prompt, "  currently %5d bytes/sec\n", t->OctetsPerSecond);
73b6217683SBrian Somers     prompt_Printf(prompt, "  peak      %5d bytes/sec\n",
7485b542cfSBrian Somers                   t->BestOctetsPerSecond);
751ae349f5Scvs2svn   } else
76b6217683SBrian Somers     prompt_Printf(prompt, "Overall %ld bytes/sec\n",
7785b542cfSBrian Somers                   (t->OctetsIn+t->OctetsOut)/secs_up);
781ae349f5Scvs2svn }
791ae349f5Scvs2svn 
801ae349f5Scvs2svn 
811ae349f5Scvs2svn void
821ae349f5Scvs2svn throughput_log(struct pppThroughput *t, int level, const char *title)
831ae349f5Scvs2svn {
841ae349f5Scvs2svn   if (t->uptime) {
851ae349f5Scvs2svn     int secs_up;
861ae349f5Scvs2svn 
871ae349f5Scvs2svn     secs_up = t->uptime ? time(NULL) - t->uptime : 0;
881ae349f5Scvs2svn     if (title)
89dd7e2610SBrian Somers       log_Printf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
901ae349f5Scvs2svn                 " out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
911ae349f5Scvs2svn     else
92dd7e2610SBrian Somers       log_Printf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
931ae349f5Scvs2svn                 secs_up, t->OctetsIn, t->OctetsOut);
941ae349f5Scvs2svn     if (secs_up == 0)
951ae349f5Scvs2svn       secs_up = 1;
961342caedSBrian Somers     if (t->rolling)
97dd7e2610SBrian Somers       log_Printf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
981ae349f5Scvs2svn                 (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond);
991ae349f5Scvs2svn     else
100dd7e2610SBrian Somers       log_Printf(level, " total %ld bytes/sec\n",
1011ae349f5Scvs2svn                 (t->OctetsIn+t->OctetsOut)/secs_up);
1021ae349f5Scvs2svn   }
1031ae349f5Scvs2svn }
1041ae349f5Scvs2svn 
1051ae349f5Scvs2svn static void
1061ae349f5Scvs2svn throughput_sampler(void *v)
1071ae349f5Scvs2svn {
1081ae349f5Scvs2svn   struct pppThroughput *t = (struct pppThroughput *)v;
1091ae349f5Scvs2svn   u_long old;
1101ae349f5Scvs2svn 
111dd7e2610SBrian Somers   timer_Stop(&t->Timer);
1121ae349f5Scvs2svn 
1131ae349f5Scvs2svn   old = t->SampleOctets[t->nSample];
1141ae349f5Scvs2svn   t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut;
1151ae349f5Scvs2svn   t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD;
1161ae349f5Scvs2svn   if (t->BestOctetsPerSecond < t->OctetsPerSecond)
1171ae349f5Scvs2svn     t->BestOctetsPerSecond = t->OctetsPerSecond;
1181ae349f5Scvs2svn   if (++t->nSample == SAMPLE_PERIOD)
1191ae349f5Scvs2svn     t->nSample = 0;
1201ae349f5Scvs2svn 
121dd7e2610SBrian Somers   timer_Start(&t->Timer);
1221ae349f5Scvs2svn }
1231ae349f5Scvs2svn 
1241ae349f5Scvs2svn void
1251342caedSBrian Somers throughput_start(struct pppThroughput *t, const char *name, int rolling)
1261ae349f5Scvs2svn {
127dd7e2610SBrian Somers   timer_Stop(&t->Timer);
1281ae349f5Scvs2svn   throughput_init(t);
1291342caedSBrian Somers   t->rolling = rolling ? 1 : 0;
1301ae349f5Scvs2svn   time(&t->uptime);
1311342caedSBrian Somers   if (t->rolling) {
1321ae349f5Scvs2svn     t->Timer.load = SECTICKS;
1331ae349f5Scvs2svn     t->Timer.func = throughput_sampler;
1343b0f8d2eSBrian Somers     t->Timer.name = name;
1351ae349f5Scvs2svn     t->Timer.arg = t;
136dd7e2610SBrian Somers     timer_Start(&t->Timer);
1371ae349f5Scvs2svn   }
1381ae349f5Scvs2svn }
1391ae349f5Scvs2svn 
1401ae349f5Scvs2svn void
1411ae349f5Scvs2svn throughput_stop(struct pppThroughput *t)
1421ae349f5Scvs2svn {
143dd7e2610SBrian Somers   timer_Stop(&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