~ubuntu-branches/ubuntu/wily/lxpanel/wily-proposed

« back to all changes in this revision

Viewing changes to src/plugins/netstatus/netstatus-sysdeps.c

  • Committer: Package Import Robot
  • Author(s): Julien Lavergne
  • Date: 2015-01-31 15:30:45 UTC
  • mfrom: (1.3.3)
  • mto: This revision was merged to the branch mainline in revision 45.
  • Revision ID: package-import@ubuntu.com-20150131153045-1r9i4602vrplnx3i
ImportĀ upstreamĀ versionĀ 0.7.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2003 Sun Microsystems, Inc.
3
 
 * Copyright (C) 2004 Red Hat Inc.
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License as
7
 
 * published by the Free Software Foundation; either version 2 of the
8
 
 * License, or (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful, but
11
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
 * 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., 59 Temple Place - Suite 330, Boston, MA
18
 
 * 02111-1307, USA.
19
 
 *
20
 
 * Authors:
21
 
 *    Erwann Chenede  <erwann.chenede@sun.com>
22
 
 *    Mark McLoughlin  <mark@skynet.ie>  
23
 
 *    Joe Marcus Clarke  <marcus@freebsd.org>
24
 
 */
25
 
 
26
 
#include <config.h>
27
 
 
28
 
#include "netstatus-sysdeps.h"
29
 
 
30
 
#include <stdio.h>
31
 
#include <string.h>
32
 
#include <math.h>
33
 
#include <unistd.h>
34
 
#include <errno.h>
35
 
#include <glib.h>
36
 
#include <glib/gi18n.h>
37
 
 
38
 
#ifdef __FreeBSD__
39
 
#include <sys/types.h>
40
 
#include <sys/socket.h>
41
 
#include <sys/ioctl.h>
42
 
#include <net/if.h>
43
 
#include <net/if_var.h>
44
 
#include <dev/an/if_aironet_ieee.h>
45
 
#include <dev/wi/if_wavelan_ieee.h>
46
 
#endif
47
 
 
48
 
static inline gboolean
49
 
parse_stats (char    *buf,
50
 
             int      prx_idx,
51
 
             int      ptx_idx,
52
 
             gulong  *in_packets,
53
 
             gulong  *out_packets,
54
 
             int      brx_idx,
55
 
             int      btx_idx,
56
 
             gulong  *in_bytes,
57
 
             gulong  *out_bytes)
58
 
{
59
 
  char *p;
60
 
  int   i;
61
 
 
62
 
  p = strtok (buf, " \t\n");
63
 
  for (i = 0; p; i++, p = strtok (NULL, " \t\n"))
64
 
    {
65
 
      if (i == prx_idx)
66
 
        *in_packets = g_ascii_strtoull (p, NULL, 10);
67
 
      if (i == ptx_idx)
68
 
        *out_packets = g_ascii_strtoull (p, NULL, 10);
69
 
      if (i == brx_idx)
70
 
        *in_bytes = g_ascii_strtoull (p, NULL, 10);
71
 
      if (i == btx_idx)
72
 
        *out_bytes = g_ascii_strtoull (p, NULL, 10);
73
 
    }
74
 
 
75
 
  if (i <= prx_idx || i <= ptx_idx || i <= brx_idx || i <=btx_idx)
76
 
    return FALSE;
77
 
 
78
 
  return TRUE;
79
 
}
80
 
 
81
 
#if !defined (__FreeBSD__)
82
 
 
83
 
static inline char *
84
 
parse_iface_name (const char *buf)
85
 
{
86
 
  char *p1;
87
 
 
88
 
  if ((p1 = strchr (buf, ':')))
89
 
    {
90
 
      char *p2;
91
 
 
92
 
      p2 = strchr (p1, ':');
93
 
      if (p2)
94
 
        *p2++ = '\0';
95
 
      else
96
 
        *p1++ = '\0';
97
 
 
98
 
      return p2 ? p2 : p1;
99
 
    }
100
 
  else if ((p1 = strchr (buf, ' ')))
101
 
    {
102
 
      *p1++ = '\0';
103
 
      return p1;
104
 
    }
105
 
 
106
 
  return NULL;
107
 
}
108
 
 
109
 
static inline void
110
 
parse_stats_header (char *buf,
111
 
                    int  *prx_idx,
112
 
                    int  *ptx_idx,
113
 
                    int  *brx_idx,
114
 
                    int  *btx_idx)
115
 
{
116
 
  char *p;
117
 
  int   i;
118
 
 
119
 
  *prx_idx = *ptx_idx = -1;
120
 
  *brx_idx = *btx_idx = -1;
121
 
 
122
 
  p = strtok (buf, "| \t\n");
123
 
  p = strtok (NULL, "| \t\n"); /* Skip the first one */
124
 
  for (i = 0; p; i++, p = strtok (NULL, "| \t\n"))
125
 
    {
126
 
      if (!strcmp (p, "packets"))
127
 
        {
128
 
          if (*prx_idx == -1)
129
 
            *prx_idx = i;
130
 
          else
131
 
            *ptx_idx = i;
132
 
        }
133
 
      else if (!strcmp (p, "bytes"))
134
 
        {
135
 
          if (*brx_idx == -1)
136
 
            *brx_idx = i;
137
 
          else
138
 
            *btx_idx = i;
139
 
        }
140
 
    }
141
 
}
142
 
 
143
 
static inline FILE *
144
 
get_proc_net_dev_fh (void)
145
 
{
146
 
  static FILE *retval = NULL;
147
 
 
148
 
  if (retval != NULL)
149
 
    return retval;
150
 
 
151
 
  return retval = fopen ("/proc/net/dev", "r");
152
 
}
153
 
 
154
 
char *
155
 
netstatus_sysdeps_read_iface_statistics (const char  *iface,
156
 
                                         gulong      *in_packets,
157
 
                                         gulong      *out_packets,
158
 
                                         gulong      *in_bytes,
159
 
                                         gulong      *out_bytes)
160
 
{
161
 
  FILE *fh;
162
 
  char  buf [512];
163
 
  int   prx_idx, ptx_idx;
164
 
  int   brx_idx, btx_idx;
165
 
  char *error_message = NULL;
166
 
 
167
 
  g_return_val_if_fail (iface != NULL, NULL);
168
 
  g_return_val_if_fail (in_packets != NULL, NULL);
169
 
  g_return_val_if_fail (out_packets != NULL, NULL);
170
 
  g_return_val_if_fail (in_bytes != NULL, NULL);
171
 
  g_return_val_if_fail (out_bytes != NULL, NULL);
172
 
  
173
 
  *in_packets  = -1;
174
 
  *out_packets = -1;
175
 
  *in_bytes    = -1;
176
 
  *out_bytes   = -1;
177
 
 
178
 
  fh = get_proc_net_dev_fh ();
179
 
  if (!fh)
180
 
    return g_strdup_printf (_("Cannot open /proc/net/dev: %s"),
181
 
                            g_strerror (errno));
182
 
 
183
 
  fgets (buf, sizeof (buf), fh);
184
 
  fgets (buf, sizeof (buf), fh);
185
 
 
186
 
  parse_stats_header (buf, &prx_idx, &ptx_idx, &brx_idx, &btx_idx);
187
 
  if (prx_idx == -1 || ptx_idx == -1 ||
188
 
      brx_idx == -1 || btx_idx == -1)
189
 
    return g_strdup (_("Could not parse /proc/net/dev. Unknown format."));
190
 
 
191
 
  while (fgets (buf, sizeof (buf), fh))
192
 
    {
193
 
      char *stats;
194
 
      char *name;
195
 
 
196
 
      name = buf;
197
 
      while (g_ascii_isspace (name [0]))
198
 
        name++;
199
 
 
200
 
      stats = parse_iface_name (name);
201
 
      if (!stats)
202
 
        {
203
 
          if (!error_message)
204
 
            error_message = g_strdup_printf (_("Could not parse interface name from '%s'"), buf);
205
 
          continue;
206
 
        }
207
 
 
208
 
      if (strcmp (name, iface) != 0)
209
 
        continue;
210
 
 
211
 
      if (!parse_stats (stats,
212
 
                        prx_idx, ptx_idx, in_packets, out_packets,
213
 
                        brx_idx, btx_idx, in_bytes, out_bytes))
214
 
        {
215
 
          if (error_message)
216
 
            g_free (error_message);
217
 
          error_message = g_strdup_printf (_("Could not parse interface statistics from '%s'. "
218
 
                                             "prx_idx = %d; ptx_idx = %d; brx_idx = %d; btx_idx = %d;"),
219
 
                                           buf, prx_idx, ptx_idx, brx_idx, btx_idx);
220
 
          continue;
221
 
        }
222
 
 
223
 
      break;
224
 
    }
225
 
 
226
 
  if ((*in_packets == (gulong) -1 || *out_packets == (gulong) -1 || *in_bytes == (gulong) -1 || *out_bytes == (gulong) -1) && !error_message)
227
 
    error_message = g_strdup_printf ("Could not find information on interface '%s' in /proc/net/dev", iface);
228
 
 
229
 
  rewind (fh);
230
 
  fflush (fh);
231
 
 
232
 
  return error_message;
233
 
}
234
 
 
235
 
static inline gboolean
236
 
parse_wireless (char  *buf,
237
 
                int    link_idx,
238
 
                int   *link)
239
 
{
240
 
  char *p;
241
 
  int   i;
242
 
 
243
 
  p = strtok (buf, " \t\n");
244
 
  for (i = 0; p; i++, p = strtok (NULL, " \t\n"))
245
 
    {
246
 
      if (i == link_idx)
247
 
        *link = g_ascii_strtoull (p, NULL, 10);
248
 
    }
249
 
 
250
 
  if (i <= link_idx)
251
 
    return FALSE;
252
 
 
253
 
  return TRUE;
254
 
}
255
 
 
256
 
static inline int
257
 
parse_wireless_header (char *buf)
258
 
{
259
 
  char *p;
260
 
  int   i;
261
 
 
262
 
  p = strtok (buf, "| \t\n");
263
 
  p = strtok (NULL, "| \t\n"); /* Skip the first one */
264
 
  for (i = 0; p; i++, p = strtok (NULL, "| \t\n"))
265
 
    {
266
 
      if (!strcmp (p, "link"))
267
 
        {
268
 
          return i;
269
 
        }
270
 
    }
271
 
 
272
 
  return -1;
273
 
}
274
 
 
275
 
static inline FILE *
276
 
get_proc_net_wireless_fh (void)
277
 
{
278
 
  static FILE *retval = NULL;
279
 
 
280
 
  if (retval != NULL)
281
 
    return retval;
282
 
 
283
 
  return retval = fopen ("/proc/net/wireless", "r");
284
 
}
285
 
 
286
 
char *
287
 
netstatus_sysdeps_read_iface_wireless_details (const char *iface,
288
 
                                               gboolean   *is_wireless,
289
 
                                               int        *signal_strength)
290
 
{
291
 
  FILE *fh;
292
 
  char  buf [512];
293
 
  int   link_idx;
294
 
  char *error_message = NULL;
295
 
 
296
 
  g_return_val_if_fail (iface != NULL, NULL);
297
 
  g_return_val_if_fail (is_wireless != NULL, NULL);
298
 
  g_return_val_if_fail (signal_strength != NULL, NULL);
299
 
 
300
 
  if (is_wireless)
301
 
    *is_wireless = FALSE;
302
 
  if (signal_strength)
303
 
    *signal_strength = 0;
304
 
  
305
 
  fh = get_proc_net_wireless_fh ();
306
 
  if (!fh)
307
 
    return NULL;
308
 
 
309
 
  fgets (buf, sizeof (buf), fh);
310
 
  fgets (buf, sizeof (buf), fh);
311
 
 
312
 
  link_idx = parse_wireless_header (buf);
313
 
  if (link_idx == -1)
314
 
    return g_strdup (_("Could not parse /proc/net/wireless. Unknown format."));
315
 
 
316
 
  while (fgets (buf, sizeof (buf), fh))
317
 
    {
318
 
      char *details;
319
 
      char *name;
320
 
      int   link = 0;
321
 
 
322
 
      name = buf;
323
 
      while (g_ascii_isspace (name [0]))
324
 
        name++;
325
 
 
326
 
      details = parse_iface_name (name);
327
 
      if (!details)
328
 
        {
329
 
          if (!error_message)
330
 
            error_message = g_strdup_printf (_("Could not parse interface name from '%s'"), buf);
331
 
          continue;
332
 
        }
333
 
 
334
 
      if (strcmp (name, iface) != 0)
335
 
        continue;
336
 
 
337
 
      if (!parse_wireless (details, link_idx, &link))
338
 
        {
339
 
          if (error_message)
340
 
            g_free (error_message);
341
 
          error_message = g_strdup_printf (_("Could not parse wireless details from '%s'. link_idx = %d;"),
342
 
                                           buf, link_idx);
343
 
          continue;
344
 
        }
345
 
 
346
 
      /* Stolen from the wireless applet */
347
 
      *signal_strength = (int) rint ((log (link) / log (92)) * 100.0);
348
 
      *signal_strength = CLAMP (*signal_strength, 0, 100);
349
 
      *is_wireless = TRUE;
350
 
 
351
 
      break;
352
 
    }
353
 
 
354
 
  rewind (fh);
355
 
  fflush (fh);
356
 
 
357
 
  return error_message;
358
 
}
359
 
 
360
 
#else /* defined(__FreeBSD__) */
361
 
 
362
 
static inline void
363
 
parse_header (char *buf,
364
 
              int  *prx_idx,
365
 
              int  *ptx_idx,
366
 
              int  *brx_idx,
367
 
              int  *btx_idx)
368
 
{
369
 
   char *p;
370
 
   int   i;
371
 
 
372
 
   *prx_idx = *ptx_idx = -1;
373
 
   *brx_idx = *btx_idx = -1;
374
 
 
375
 
   p = strtok (buf, " \n\t");
376
 
   for (i = 0; p; i++, p = strtok (NULL, " \t\n"))
377
 
     {
378
 
        if (!strcmp (p, "Ipkts"))
379
 
          {
380
 
             *prx_idx = i;
381
 
          }
382
 
        else if (!strcmp (p, "Ibytes"))
383
 
          {
384
 
             *brx_idx = i;
385
 
          }
386
 
        else if (!strcmp (p, "Opkts"))
387
 
          {
388
 
             *ptx_idx = i;
389
 
          }
390
 
        else if (!strcmp (p, "Obytes"))
391
 
          {
392
 
             *btx_idx = i;
393
 
          }
394
 
     }
395
 
}
396
 
 
397
 
static inline gboolean
398
 
wireless_getval (const char      *iface,
399
 
                 gpointer         req,
400
 
                 unsigned long    req_type,
401
 
                 char           **error)
402
 
{
403
 
  struct ifreq ifr;
404
 
  int          s;
405
 
 
406
 
  memset (&ifr, 0, sizeof (ifr));
407
 
 
408
 
  strlcpy (ifr.ifr_name, iface, sizeof (ifr.ifr_name));
409
 
  ifr.ifr_data = (caddr_t) req;
410
 
 
411
 
  s = socket (AF_INET, SOCK_DGRAM, 0);
412
 
  if (s == -1)
413
 
    {
414
 
      *error = g_strdup_printf (_("Could not connect to interface, '%s'"), iface);
415
 
      return FALSE;
416
 
    }
417
 
 
418
 
  if (ioctl (s, req_type, &ifr) == -1)
419
 
    {
420
 
      *error = g_strdup_printf (_("Could not send ioctl to interface, '%s'"), iface);
421
 
      close (s);
422
 
      return FALSE;
423
 
    }
424
 
 
425
 
  close (s);
426
 
  return TRUE;
427
 
}
428
 
 
429
 
static inline char *
430
 
get_an_data (const char *iface,
431
 
             int        *signal_strength)
432
 
{
433
 
#ifdef AN_RID_RSSI_MAP
434
 
  struct an_ltv_rssi_map  an_rssimap;
435
 
#endif
436
 
  struct an_req         areq;
437
 
  struct an_ltv_status *sts;
438
 
  int                   level;
439
 
  char                 *error = NULL;
440
 
  gboolean              rssimap_valid = FALSE;
441
 
 
442
 
#ifdef AN_RID_RSSI_MAP
443
 
  an_rssimap.an_len = sizeof (an_rssimap);
444
 
  an_rssimap.an_type = AN_RID_RSSI_MAP;
445
 
  rssimap_valid = wireless_getval (iface, (gpointer) &an_rssimap, SIOCGAIRONET, &error);
446
 
#endif
447
 
 
448
 
  areq.an_len = sizeof (areq);
449
 
  areq.an_type = AN_RID_STATUS;
450
 
 
451
 
  if (!wireless_getval (iface, (gpointer) &areq, SIOCGAIRONET, &error))
452
 
    return error;
453
 
 
454
 
  sts = (struct an_ltv_status *) &areq;
455
 
 
456
 
#ifdef AN_RID_RSSI_MAP
457
 
  if (rssimap_valid)
458
 
    level = (int) (an_rssimap.an_entries[sts->an_normalized_strength].an_rss_pct);
459
 
  else
460
 
    level = (int) (sts->an_normalized_strength);
461
 
#else
462
 
  level = (int) (sts->an_normalized_rssi);
463
 
#endif
464
 
 
465
 
  memcpy (signal_strength, &level, sizeof (signal_strength));
466
 
 
467
 
  return error;
468
 
}
469
 
 
470
 
static inline char *
471
 
get_wi_data (const char *iface,
472
 
             int        *signal_strength)
473
 
{
474
 
  struct wi_req  wreq;
475
 
  int            level;
476
 
  char          *error = NULL;
477
 
 
478
 
  memset (&wreq, 0, sizeof (wreq));
479
 
 
480
 
  wreq.wi_len  = WI_MAX_DATALEN;
481
 
  wreq.wi_type = WI_RID_COMMS_QUALITY;
482
 
 
483
 
  if (!wireless_getval (iface, &wreq, SIOCGWAVELAN, &error))
484
 
    return error;
485
 
 
486
 
  level = (int) wreq.wi_val[1];
487
 
 
488
 
#ifdef WI_RID_READ_APS
489
 
  if (signal_strength <= 0)
490
 
    {
491
 
      /* we fail to get signal strength by usual means, try another way */
492
 
      static time_t   last_scan;
493
 
      static long int cached;
494
 
      time_t          now;
495
 
 
496
 
      now = time (NULL);
497
 
 
498
 
      /* XXX: this is long operation, and we will scan station not often then one in 5 secs */
499
 
      if (now > last_scan + 5)
500
 
        {
501
 
          struct wi_apinfo *w;
502
 
          int              nstations;
503
 
 
504
 
          bzero (&wreq, sizeof (wreq));
505
 
          wreq.wi_len  = WI_MAX_DATALEN;
506
 
          wreq.wi_type = WI_RID_READ_APS;
507
 
          if (!wireless_getval (iface, &wreq, SIOCGWAVELAN, &error))
508
 
            return error;
509
 
          nstations = *(int *) wreq.wi_val;
510
 
          if (nstations > 0)
511
 
            {
512
 
              w = (struct wi_apinfo *)(((char *) &wreq.wi_val) + sizeof (int));
513
 
              signal_strength = (long int) w->signal;
514
 
            }
515
 
 
516
 
            cached = signal_strength;
517
 
            last_scan = now;
518
 
          }
519
 
        else
520
 
          {
521
 
            signal_strength = cached;
522
 
          }
523
 
    }
524
 
#endif
525
 
 
526
 
  memcpy (signal_strength, &level, sizeof (signal_strength));
527
 
 
528
 
  return error;
529
 
}
530
 
 
531
 
char *
532
 
netstatus_sysdeps_read_iface_wireless_details (const char *iface,
533
 
                                               gboolean   *is_wireless,
534
 
                                               int        *signal_strength)
535
 
{
536
 
  char *error_message = NULL;
537
 
 
538
 
  g_return_val_if_fail (iface != NULL, NULL);
539
 
  g_return_val_if_fail (is_wireless != NULL, NULL);
540
 
  g_return_val_if_fail (signal_strength != NULL, NULL);
541
 
 
542
 
  if (is_wireless)
543
 
    *is_wireless = FALSE;
544
 
  if (signal_strength)
545
 
    *signal_strength = 0;
546
 
 
547
 
  if (g_strncasecmp (iface, "an",   2) &&
548
 
      g_strncasecmp (iface, "wi",   2) &&
549
 
      g_strncasecmp (iface, "ath",  3) &&
550
 
      g_strncasecmp (iface, "ndis", 4) &&
551
 
      g_strncasecmp (iface, "ipw",  3) &&
552
 
      g_strncasecmp (iface, "iwi",  3) &&
553
 
      g_strncasecmp (iface, "acx",  3))
554
 
    return error_message;
555
 
 
556
 
  if (g_strncasecmp (iface, "an", 2) == 0)
557
 
    {
558
 
      error_message = get_an_data (iface, signal_strength);
559
 
      *is_wireless = TRUE;
560
 
    }
561
 
  else
562
 
    {
563
 
      error_message = get_wi_data (iface, signal_strength);
564
 
      *is_wireless = TRUE;
565
 
    }
566
 
 
567
 
  return error_message;
568
 
}
569
 
 
570
 
char *
571
 
netstatus_sysdeps_read_iface_statistics (const char *iface,
572
 
                                         gulong     *in_packets,
573
 
                                         gulong     *out_packets,
574
 
                                         gulong     *in_bytes,
575
 
                                         gulong     *out_bytes)
576
 
{
577
 
  GError  *error;
578
 
  char    *command_line;
579
 
  char   **argv;
580
 
  char    *error_message = NULL;
581
 
  int      pipe_out;
582
 
 
583
 
  g_return_val_if_fail (iface != NULL, NULL);
584
 
  g_return_val_if_fail (in_packets != NULL, NULL);
585
 
  g_return_val_if_fail (out_packets != NULL, NULL);
586
 
  g_return_val_if_fail (in_bytes != NULL, NULL);
587
 
  g_return_val_if_fail (out_bytes != NULL, NULL);
588
 
 
589
 
  *in_packets  = -1;
590
 
  *out_packets = -1;
591
 
  *in_bytes    = -1;
592
 
  *out_bytes   = -1;
593
 
 
594
 
  error = NULL;
595
 
  command_line = g_strdup_printf ("/usr/bin/netstat -n -I %s -b -f inet", iface);
596
 
  if (!g_shell_parse_argv (command_line, NULL, &argv, &error))
597
 
    {
598
 
      error_message = g_strdup_printf (_("Could not parse command line '%s': %s"),
599
 
                                       command_line,
600
 
                                       error->message);
601
 
      g_error_free (error);
602
 
      g_free (command_line);
603
 
      
604
 
      return error_message;
605
 
    }
606
 
  g_free (command_line);
607
 
 
608
 
  error = NULL;
609
 
  if (g_spawn_async_with_pipes (NULL,
610
 
                                argv,
611
 
                                NULL,
612
 
                                0,
613
 
                                NULL,
614
 
                                NULL,
615
 
                                NULL,
616
 
                                NULL,
617
 
                                &pipe_out,
618
 
                                NULL,
619
 
                                &error))
620
 
    {
621
 
      GIOChannel *channel;
622
 
      char       *buf;
623
 
      int         prx_idx, ptx_idx;
624
 
      int         brx_idx, btx_idx;
625
 
 
626
 
      channel = g_io_channel_unix_new (pipe_out);
627
 
 
628
 
      g_io_channel_read_line (channel, &buf, NULL, NULL, NULL);
629
 
      parse_header (buf, &prx_idx, &ptx_idx, &brx_idx, &btx_idx);
630
 
      g_free (buf);
631
 
 
632
 
      if (prx_idx == -1 || ptx_idx == -1 ||
633
 
          brx_idx == -1 || btx_idx == -1)
634
 
        {
635
 
          error_message = g_strdup (_("Could not parse 'netstat' output. Unknown format"));
636
 
          goto error_shutdown;
637
 
        }
638
 
 
639
 
      g_io_channel_read_line (channel, &buf, NULL, NULL, NULL);
640
 
 
641
 
      if (!parse_stats (buf,
642
 
                        prx_idx, ptx_idx, in_packets, out_packets,
643
 
                        brx_idx, btx_idx, in_bytes, out_bytes))
644
 
        {
645
 
          error_message = g_strdup_printf (_("Could not parse interface statistics from '%s'. "
646
 
                                             "prx_idx = %d; ptx_idx = %d; brx_idx = %d; btx_idx = %d;"),
647
 
                                           buf, prx_idx, ptx_idx, brx_idx, btx_idx);
648
 
        }
649
 
      else if (*in_packets == -1 || *out_packets == -1 || *in_bytes == -1 || *out_bytes == -1)
650
 
        {
651
 
          error_message = g_strdup_printf ("Could not obtain information on interface '%s' from netstat",
652
 
                                           iface);
653
 
        }
654
 
 
655
 
      g_free (buf);
656
 
 
657
 
    error_shutdown:
658
 
      g_io_channel_unref (channel);
659
 
      close (pipe_out);
660
 
    }
661
 
  else
662
 
    {
663
 
      error_message = g_strdup_printf ("Error running /usr/bin/netstat for '%s': %s", 
664
 
                                       iface, error->message);
665
 
      g_error_free (error);
666
 
    }
667
 
 
668
 
  g_strfreev (argv);
669
 
 
670
 
  return error_message;
671
 
}
672
 
 
673
 
#endif /* !defined(__FreeBSD__) */