2
KSysGuard, the KDE System Guard
4
Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of version 2 of the GNU General Public
8
License as published by the Free Software Foundation.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
#include <sys/types.h>
22
#include <sys/param.h>
23
#include <sys/sysctl.h>
24
#include <sys/socket.h>
26
#include <net/route.h>
28
#include <net/if_dl.h>
35
#include "ksysguardd.h"
47
u_long recv[5], Drecv[5], sent[5], Dsent[5];
50
#define LEN(X) (sizeof(X)/sizeof(X[0]))
53
static NetDevInfo NetDevs[MAXNETDEVS], newval[MAXNETDEVS];
54
static int NetDevCnt = 0;
55
static struct SensorModul *NetDevSM;
57
/* Read the system's traffic registers.
58
* Merely count the IFs if countp nonzero.
59
* Returns count of IFs read, or -1; the data are written into newval.
60
* Based on getifaddrs source; getifaddrs itself seems to
61
* compile incorrectly, omitting the traffic data. (It also
62
* does things this doesn't need, thus this is slightly more efficient.)
64
static int readSys(int countp)
68
struct rt_msghdr *rtm;
74
0, /* `currently always 0' */
75
0, /* `may be set to 0 to select all address families' */
77
0 /* ignored but six levels are needed */
80
if (-1==sysctl(mib, LEN(mib), NULL, &len, NULL, 0))
82
if (!(bfr = malloc(len)))
84
if (-1==sysctl(mib, LEN(mib), bfr, &len, NULL, 0)) {
89
for (ptr=bfr; ptr<bfr+len; ptr+=rtm->rtm_msglen) {
90
struct if_msghdr *ifm;
92
rtm = (void*)ptr; /* chg ptr type to router msg */
94
if (rtm->rtm_version != RTM_VERSION) {
98
if (rtm->rtm_type != RTM_IFINFO) {
102
ifm = (void*)rtm; /* chg ptr type to interface msg */
103
if (!(ifm->ifm_flags & IFF_UP)) {
108
/* a sdl is concat'd to the if msg */
109
struct sockaddr_dl *sdl = (void*)(ifm+1);
111
/* copy and terminate the name */
112
/*fixme: check for overruns */
113
memcpy(nv->name, sdl->sdl_data, sdl->sdl_nlen);
114
nv->name[sdl->sdl_nlen] = 0;
117
nv->recv[I_bytes] = ifm->ifm_data.ifi_ibytes;
118
nv->recv[I_packs] = ifm->ifm_data.ifi_ipackets;
119
nv->recv[I_errs] = ifm->ifm_data.ifi_ierrors;
120
nv->recv[I_mcasts] = ifm->ifm_data.ifi_imcasts;
121
nv->recv[I_lost] = ifm->ifm_data.ifi_iqdrops;
122
nv->sent[I_bytes] = ifm->ifm_data.ifi_obytes;
123
nv->sent[I_packs] = ifm->ifm_data.ifi_opackets;
124
nv->sent[I_errs] = ifm->ifm_data.ifi_oerrors;
125
nv->sent[I_mcasts] = ifm->ifm_data.ifi_omcasts;
126
nv->sent[I_lost] = ifm->ifm_data.ifi_collisions;
129
/*fixme: guard against buffer overrun */
137
/* ------------------------------ public part --------------------------- */
139
static void prVal(const char*, int);
140
void printNetDevRecv(const char *cmd) { prVal(cmd,0); }
141
void printNetDevSent(const char *cmd) { prVal(cmd,1); }
143
static void prInfo(const char*, int);
144
void printNetDevRecvInfo(const char *cmd) { prInfo(cmd,0); }
145
void printNetDevSentInfo(const char *cmd) { prInfo(cmd,1); }
149
cmdExecutor read, inform;
156
printNetDevRecv, printNetDevRecvInfo,
157
{{"data", "Received Data\t0\t0\tB/s\n", I_bytes},
158
{"packets", "Received Packets\t0\t0\tHz\n", I_packs},
159
{"errors", "Receiver Errors\t0\t0\tHz\n", I_errs},
160
{"multicast", "Received Multicast Packets\t0\t0\tHz\n", I_mcasts},
161
{"drops", "Receiver Drops\t0\t0\tHz\n", I_lost}}},
163
printNetDevSent, printNetDevSentInfo,
164
{{"data", "Sent Data\t0\t0\tB/s\n", I_bytes},
165
{"packets", "Sent Packets\t0\t0\tHz\n", I_packs},
166
{"errors", "Transmitter Errors\t0\t0\tHz\n", I_errs},
167
{"multicast", "Sent Multicast Packets\t0\t0\tHz\n", I_mcasts},
168
{"collisions", "Transmitter Collisions\t0\t0\tHz\n", I_lost}}}
172
static void prVal(const char *cmd, int N) {
176
if (!(p=rindex(cmd, '/')))
183
for (d=NetDevCnt; d--; )
184
if (!strcmp(r, NetDevs[d].name))
191
for (i=0; i<LEN(opTable[0].op); i++)
192
if (!strcmp(p, opTable[N].op[i].label))
193
fprintf(CurrentClient, "%lu",
194
/*fixme: ugly and presumptuous */
195
(N?NetDevs[d].Dsent:NetDevs[d].Drecv)[opTable[N].op[i].index]);
196
fprintf(CurrentClient, "\n");
200
static void prInfo(const char *cmd, int N) {
204
if (!(p=rindex(cmd, '/'))) return;
208
if ('?' != *q) return;
211
for (i=0; i<LEN(opTable[0].op); i++)
212
if (!strcmp(p, opTable[N].op[i].label))
213
fputs(opTable[N].op[i].info, CurrentClient);
219
static void NDreg (int setp)
223
for (i = 0; i<NetDevCnt; i++) {
226
for (j=0; j<LEN(opTable); j++) {
229
for (k=0; k<LEN(opTable[0].op); k++) {
232
snprintf(buffer, sizeof(buffer),
233
"network/interfaces/%s/%s/%s",
236
opTable[j].op[k].label);
238
/* printf("%d %d %d %s\n",i,j,k,buffer); */
241
registerMonitor(buffer,
244
opTable[j].inform, NetDevSM);
246
removeMonitor(buffer);
253
void initNetDev(struct SensorModul* sm) {
260
for (i=LEN(NetDevs); i--;) {
261
strcpy(NetDevs[i].name, newval[i].name);
268
void exitNetDev(void) {
272
int updateNetDev(void) {
276
if (-1==(n = readSys(0)))
280
/*fixme: assumes the interfaces are in the same order each time */
281
for (p=NetDevs, q=newval; n--; p++, q++) {
283
/* calculate deltas */
284
for (i=0; i<5; i++) {
285
p->Drecv[i] = q->recv[i]-p->recv[i];
286
p->recv[i] = q->recv[i];
287
p->Dsent[i] = q->sent[i]-p->sent[i];
288
p->sent[i] = q->sent[i];
295
void checkNetDev(void) {
296
if (readSys(!0) != NetDevCnt) {
297
/* interface has been added or removed
300
initNetDev(NetDevSM);