2
* Bubbling Load Monitoring Applet
3
* Copyright (C) 1999-2004 Johan Walles - walles@mailblocks.com
4
* http://www.nongnu.org/bubblemon/
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
22
* This is the platform independent network load refinery functions.
30
#include "bubblemon.h"
32
static int netload_percentage = 0;
33
static int receivingUpdates = 0;
34
static struct netload_interface *interfaces;
36
static struct netload_interface *netload_findInterface(const char *name)
38
struct netload_interface *iter;
42
for (iter = interfaces; iter != NULL; iter = iter->next)
44
if (strcmp(iter->name, name) == 0)
53
static struct netload_interface *netload_forcedFindInterface(const char *name)
55
struct netload_interface *interface;
57
interface = netload_findInterface(name);
58
if (interface == NULL)
60
interface = (struct netload_interface *)malloc(sizeof(struct netload_interface));
61
assert(interface != NULL);
63
interface->name = strdup(name);
65
interface->currentBytesIn = 0;
66
interface->previousBytesIn = 0;
67
interface->maxBytesInPerSecond = 0;
69
interface->currentBytesOut = 0;
70
interface->previousBytesOut = 0;
71
interface->maxBytesOutPerSecond = 0;
73
interface->isAlive = 0;
75
interface->next = interfaces;
76
interfaces = interface;
82
void netload_reportBack(const char *name, unsigned long bytesSent, unsigned long bytesReceived)
84
struct netload_interface *interface;
86
assert(receivingUpdates &&
87
"netload_reportBack() called from outside netload_reportNetworkLoad()");
89
// Grab a pointer to the struct holding this interface's data. If
90
// there is no such struct, construct and initialize a new one.
91
interface = netload_forcedFindInterface(name);
93
// Verify that the interface isn't marked live. If it is, it means
94
// we have received two reports about the same interface.
95
assert(!interface->isAlive &&
96
"netload_reportBack() called twice on the same interface");
98
// Store the incoming values.
99
interface->previousBytesIn = interface->currentBytesIn;
100
interface->currentBytesIn = bytesReceived;
101
// Newly added interfaces don't get credit for any bytes during the
103
if (interface->previousBytesIn == 0)
105
interface->previousBytesIn = interface->currentBytesIn;
109
// Verify that the counter isn't moving backwards
110
assert(((interface->currentBytesIn - interface->previousBytesIn) < (1 << 30)) &&
111
"Input byte counter is moving backwards");
114
interface->previousBytesOut = interface->currentBytesOut;
115
interface->currentBytesOut = bytesSent;
116
// Newly added interfaces don't get credit for any bytes during the
118
if (interface->previousBytesOut == 0)
120
interface->previousBytesOut = interface->currentBytesOut;
124
// Verify that the counter isn't moving backwards
125
assert(((interface->currentBytesOut - interface->previousBytesOut) < (1 << 30)) &&
126
"Output byte counter is moving backwards");
129
// Mark the interface live
130
interface->isAlive = 1;
133
static void netload_receiveUpdates()
135
struct netload_interface *iter;
137
// Mark all known interfaces as shut down
138
for (iter = interfaces;
145
// Ask the platform dependent function to report network loads to us
146
receivingUpdates = 1;
147
netload_reportNetworkLoad();
148
receivingUpdates = 0;
150
// Forget about all interfaces marked as shut down.
151
// Start with interfaces at the start of the list.
152
while (interfaces != NULL && !interfaces->isAlive)
154
struct netload_interface *nextInterface = interfaces->next;
155
free(interfaces->name);
157
interfaces = nextInterface;
159
// Clean out interfaces after the start of the list
160
if (interfaces != NULL)
162
struct netload_interface *prev;
164
for (prev = interfaces, iter = interfaces->next;
166
prev = iter, iter = iter->next)
168
while ((iter != NULL) && !iter->isAlive)
170
prev->next = iter->next;
184
static int netload_calculateLoad(int lastIntervalLength)
186
struct netload_interface *iter;
189
// For all interfaces
190
for (iter = interfaces; iter != NULL; iter = iter->next)
192
unsigned long bytesPerSec;
195
// Calculate incoming load
196
bytesPerSec = ((iter->currentBytesIn - iter->previousBytesIn) * 1000) / lastIntervalLength;
197
if (bytesPerSec > iter->maxBytesInPerSecond)
199
iter->maxBytesInPerSecond = bytesPerSec;
201
if (iter->maxBytesInPerSecond > 0)
203
load = (100 * bytesPerSec) / iter->maxBytesInPerSecond;
214
// Calculate outgoing load
215
bytesPerSec = ((iter->currentBytesOut - iter->previousBytesOut) * 1000) / lastIntervalLength;
216
if (bytesPerSec > iter->maxBytesOutPerSecond)
218
iter->maxBytesOutPerSecond = bytesPerSec;
220
if (iter->maxBytesOutPerSecond > 0)
222
load = (100 * bytesPerSec) / iter->maxBytesOutPerSecond;
234
// Return the largest percentage
238
void netload_updateLoadstats(int msecsSinceLastCall)
240
static int timeToNextMeasurement = 0;
242
// If enough time has elapsed since the last measurement...
243
timeToNextMeasurement -= msecsSinceLastCall;
244
if (timeToNextMeasurement <= 0)
246
int intervalLength = NETLOAD_INTERVAL - timeToNextMeasurement;
248
netload_receiveUpdates();
250
netload_percentage = netload_calculateLoad(intervalLength);
252
timeToNextMeasurement += NETLOAD_INTERVAL;
256
int netload_getLoadPercentage(void)
258
assert((netload_percentage >= 0) &&
259
(netload_percentage <= 100));
261
return netload_percentage;