xref: /freebsd/usr.sbin/ppp/throughput.c (revision 33b77e2decd50e53798014b70bf7ca3bdc4c0c7e)
1 /*-
2  * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	$Id$
27  */
28 
29 #include <sys/param.h>
30 
31 #include <stdio.h>
32 #include <time.h>
33 #include <netinet/in.h>
34 
35 #include "command.h"
36 #include "mbuf.h"
37 #include "log.h"
38 #include "timer.h"
39 #include "throughput.h"
40 #include "defs.h"
41 #include "loadalias.h"
42 #include "vars.h"
43 
44 void
45 throughput_init(struct pppThroughput *t)
46 {
47   int f;
48 
49   t->OctetsIn = t->OctetsOut = 0;
50   for (f = 0; f < SAMPLE_PERIOD; f++)
51     t->SampleOctets[f] = 0;
52   t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0;
53   throughput_stop(t);
54 }
55 
56 void
57 throughput_disp(struct pppThroughput *t, FILE *f)
58 {
59   int secs_up;
60 
61   secs_up = t->uptime ? time(NULL) - t->uptime : 0;
62   fprintf(f, "Connect time: %d secs\n", secs_up);
63   if (secs_up == 0)
64     secs_up = 1;
65   fprintf(f, "%ld octets in, %ld octets out\n", t->OctetsIn, t->OctetsOut);
66   if (Enabled(ConfThroughput)) {
67     fprintf(f, "  overall   %5ld bytes/sec\n",
68             (t->OctetsIn+t->OctetsOut)/secs_up);
69     fprintf(f, "  currently %5d bytes/sec\n", t->OctetsPerSecond);
70     fprintf(f, "  peak      %5d bytes/sec\n", t->BestOctetsPerSecond);
71   } else
72     fprintf(f, "Overall %ld bytes/sec\n", (t->OctetsIn+t->OctetsOut)/secs_up);
73 }
74 
75 
76 void
77 throughput_log(struct pppThroughput *t, int level, const char *title)
78 {
79   if (t->uptime) {
80     int secs_up;
81 
82     secs_up = t->uptime ? time(NULL) - t->uptime : 0;
83     if (title)
84       LogPrintf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
85                 " out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
86     else
87       LogPrintf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
88                 secs_up, t->OctetsIn, t->OctetsOut);
89     if (secs_up == 0)
90       secs_up = 1;
91     if (Enabled(ConfThroughput))
92       LogPrintf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
93                 (t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond);
94     else
95       LogPrintf(level, " total %ld bytes/sec\n",
96                 (t->OctetsIn+t->OctetsOut)/secs_up);
97   }
98 }
99 
100 static void
101 throughput_sampler(void *v)
102 {
103   struct pppThroughput *t = (struct pppThroughput *)v;
104   u_long old;
105 
106   StopTimer(&t->Timer);
107   t->Timer.state = TIMER_STOPPED;
108 
109   old = t->SampleOctets[t->nSample];
110   t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut;
111   t->OctetsPerSecond = (t->SampleOctets[t->nSample] - old) / SAMPLE_PERIOD;
112   if (t->BestOctetsPerSecond < t->OctetsPerSecond)
113     t->BestOctetsPerSecond = t->OctetsPerSecond;
114   if (++t->nSample == SAMPLE_PERIOD)
115     t->nSample = 0;
116 
117   StartTimer(&t->Timer);
118 }
119 
120 void
121 throughput_start(struct pppThroughput *t)
122 {
123   throughput_init(t);
124   time(&t->uptime);
125   if (Enabled(ConfThroughput)) {
126     t->Timer.state = TIMER_STOPPED;
127     t->Timer.load = SECTICKS;
128     t->Timer.func = throughput_sampler;
129     t->Timer.arg = t;
130     StartTimer(&t->Timer);
131   }
132 }
133 
134 void
135 throughput_stop(struct pppThroughput *t)
136 {
137   if (Enabled(ConfThroughput))
138     StopTimer(&t->Timer);
139 }
140 
141 void
142 throughput_addin(struct pppThroughput *t, int n)
143 {
144   t->OctetsIn += n;
145 }
146 
147 void
148 throughput_addout(struct pppThroughput *t, int n)
149 {
150   t->OctetsOut += n;
151 }
152