~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to ksysguard/ksysguardd/NetBSD/netdev.c

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  KSysGuard, the KDE System Guard
 
3
   
 
4
  Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
 
5
    
 
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.
 
9
 
 
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.
 
14
 
 
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.
 
18
 
 
19
*/
 
20
 
 
21
#include <sys/types.h>
 
22
#include <sys/param.h>
 
23
#include <sys/sysctl.h>
 
24
#include <sys/socket.h>
 
25
 
 
26
#include <net/route.h>
 
27
#include <net/if.h>
 
28
#include <net/if_dl.h>
 
29
 
 
30
#include <ifaddrs.h>
 
31
#include <stdlib.h>
 
32
#include <string.h>
 
33
 
 
34
#include "Command.h"
 
35
#include "ksysguardd.h"
 
36
#include "netdev.h"
 
37
 
 
38
 
 
39
#define I_bytes         0
 
40
#define I_packs         1
 
41
#define I_errs          2
 
42
#define I_mcasts        3
 
43
#define I_lost          4
 
44
 
 
45
typedef struct {
 
46
  char name[32];
 
47
  u_long recv[5], Drecv[5], sent[5], Dsent[5];
 
48
} NetDevInfo;
 
49
 
 
50
#define LEN(X) (sizeof(X)/sizeof(X[0]))
 
51
 
 
52
#define MAXNETDEVS 64
 
53
static NetDevInfo NetDevs[MAXNETDEVS], newval[MAXNETDEVS];
 
54
static int NetDevCnt = 0;
 
55
static struct SensorModul *NetDevSM;
 
56
 
 
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.)
 
63
 */
 
64
static int readSys(int countp) 
 
65
{
 
66
  size_t len;
 
67
  char *bfr, *ptr;
 
68
  struct rt_msghdr *rtm;
 
69
  NetDevInfo *nv;
 
70
  static int mib[] = {
 
71
    /* see sysctl(3): */
 
72
    CTL_NET,
 
73
    PF_ROUTE,
 
74
    0, /* `currently always 0' */
 
75
    0, /* `may be set to 0 to select all address families' */
 
76
    NET_RT_IFLIST,
 
77
    0 /* ignored but six levels are needed */
 
78
  };
 
79
     
 
80
  if (-1==sysctl(mib, LEN(mib), NULL, &len, NULL, 0))
 
81
    return -1;
 
82
  if (!(bfr = malloc(len)))
 
83
    return -1;
 
84
  if (-1==sysctl(mib, LEN(mib), bfr, &len, NULL, 0)) {
 
85
    free(bfr);
 
86
    return -1;
 
87
  }
 
88
  nv = newval;
 
89
  for (ptr=bfr; ptr<bfr+len; ptr+=rtm->rtm_msglen) {
 
90
    struct if_msghdr *ifm;
 
91
       
 
92
    rtm = (void*)ptr; /* chg ptr type to router msg */
 
93
 
 
94
    if (rtm->rtm_version != RTM_VERSION) {
 
95
      continue;
 
96
    }
 
97
 
 
98
    if (rtm->rtm_type != RTM_IFINFO) {
 
99
      continue;
 
100
    }
 
101
 
 
102
    ifm = (void*)rtm; /* chg ptr type to interface msg */
 
103
    if (!(ifm->ifm_flags & IFF_UP)) {
 
104
      continue;
 
105
    }
 
106
       
 
107
    if (!countp) {
 
108
      /* a sdl is concat'd to the if msg */
 
109
      struct sockaddr_dl *sdl = (void*)(ifm+1);
 
110
         
 
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;
 
115
         
 
116
      /* copy the data */
 
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;
 
127
    }
 
128
       
 
129
    /*fixme: guard against buffer overrun */
 
130
    nv++;
 
131
  }
 
132
  free(bfr);
 
133
  return nv-newval;
 
134
}
 
135
 
 
136
 
 
137
/* ------------------------------ public part --------------------------- */
 
138
 
 
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); }
 
142
        
 
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); }
 
146
        
 
147
static struct {
 
148
  char *label;
 
149
  cmdExecutor read, inform;
 
150
  struct {
 
151
    char *label, *info;
 
152
    int index;
 
153
  } op[5];
 
154
} opTable[] = {
 
155
  {"receiver",
 
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}}},
 
162
  {"transmitter",
 
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}}}
 
169
};
 
170
 
 
171
 
 
172
static void prVal(const char *cmd, int N) {
 
173
  char *p, *q, *r;
 
174
  int i, d;
 
175
 
 
176
  if (!(p=rindex(cmd, '/')))
 
177
    return;
 
178
  *p=0;
 
179
  q=rindex(cmd, '/');
 
180
  *q=0;
 
181
  r=rindex(cmd, '/');
 
182
  r++;
 
183
  for (d=NetDevCnt; d--; )
 
184
    if (!strcmp(r, NetDevs[d].name))
 
185
      break;
 
186
  *q=*p='/';
 
187
  
 
188
  if (-1 == d) return;
 
189
  
 
190
  p++;
 
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");
 
197
}
 
198
 
 
199
 
 
200
static void prInfo(const char *cmd, int N) {
 
201
  char *p, *q;
 
202
  int i;
 
203
  
 
204
  if (!(p=rindex(cmd, '/'))) return;
 
205
  p++;
 
206
 
 
207
  q = p+strlen(p)-1;
 
208
  if ('?' != *q) return;
 
209
  *q=0;
 
210
 
 
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);
 
214
  *q='?';
 
215
}
 
216
 
 
217
 
 
218
 
 
219
static void NDreg (int setp)
 
220
{
 
221
  int i;
 
222
        
 
223
  for (i = 0; i<NetDevCnt; i++) {
 
224
    int j;
 
225
 
 
226
    for (j=0; j<LEN(opTable); j++) {
 
227
      int k;
 
228
 
 
229
      for (k=0; k<LEN(opTable[0].op); k++) {
 
230
        char buffer[1024];
 
231
 
 
232
        snprintf(buffer, sizeof(buffer),
 
233
                 "network/interfaces/%s/%s/%s",
 
234
                 NetDevs[i].name,
 
235
                 opTable[j].label,
 
236
                 opTable[j].op[k].label);
 
237
 
 
238
        /* printf("%d %d %d %s\n",i,j,k,buffer); */
 
239
 
 
240
        if (setp)
 
241
          registerMonitor(buffer,
 
242
                          "integer",
 
243
                          opTable[j].read,
 
244
                          opTable[j].inform, NetDevSM);
 
245
        else
 
246
          removeMonitor(buffer);
 
247
      }
 
248
 
 
249
    }
 
250
  }
 
251
}
 
252
 
 
253
void initNetDev(struct SensorModul* sm) {
 
254
  int i;
 
255
 
 
256
  NetDevSM = sm;
 
257
 
 
258
  updateNetDev();
 
259
 
 
260
  for (i=LEN(NetDevs); i--;) {
 
261
    strcpy(NetDevs[i].name, newval[i].name);
 
262
  }
 
263
 
 
264
  NDreg(!0);
 
265
}
 
266
 
 
267
 
 
268
void exitNetDev(void) {
 
269
  NDreg(0);
 
270
}
 
271
 
 
272
int updateNetDev(void) {
 
273
  NetDevInfo *p, *q;
 
274
  int n;
 
275
 
 
276
  if (-1==(n = readSys(0)))
 
277
    return (0);
 
278
 
 
279
  NetDevCnt = n;
 
280
  /*fixme: assumes the interfaces are in the same order each time */
 
281
  for (p=NetDevs, q=newval; n--; p++, q++) {
 
282
    int i;
 
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];
 
289
 
 
290
    }
 
291
  }
 
292
        return (0);
 
293
}
 
294
 
 
295
void checkNetDev(void) {
 
296
  if (readSys(!0) != NetDevCnt) {
 
297
    /* interface has been added or removed
 
298
       so we do a reset */
 
299
    exitNetDev();
 
300
    initNetDev(NetDevSM);
 
301
  }
 
302
}
 
303
 
 
304
 
 
305
/* eof */