networksensor.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2003 by Hans Karlsson                                   *
00003  *   karlsson.h@home.se                                                      *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 #ifdef __FreeBSD__
00011 #include <sys/param.h>
00012 #include <sys/sysctl.h>
00013 #include <sys/socket.h>
00014 #include <net/route.h>
00015 #endif
00016 
00017 #include "networksensor.h"
00018 
00019 NetworkSensor::NetworkSensor( QString dev, int interval ):Sensor( interval )
00020 {
00021    device = dev.lower();
00022 
00023 #ifdef __FreeBSD__
00024    /* Determine number of interfaces */
00025    u_int   n    = 0;
00026    size_t  nlen = 0;
00027    nlen = sizeof(n);
00028    sysctlbyname("net.link.generic.system.ifcount", &n, &nlen, NULL, 0);
00029 
00030    size_t  if_miblen = 0;
00031    if_miblen = sizeof(if_mib);
00032    static  int name[] = { CTL_NET,
00033                           PF_LINK,
00034                           NETLINK_GENERIC,
00035                           IFMIB_IFDATA,
00036                           0,
00037                           IFDATA_GENERAL };
00038 
00039    /*
00040       If the device was defined by the theme, find the right devicenumber.
00041       If not, use the device that holds the default route.
00042     */
00043 
00044    if_number = -1;
00045    int if_gw = -1;
00046 
00047    for (int i = 1; i <= n; ++i) {
00048       name[4] = i;
00049       /* Get data for iface-number i */
00050       sysctl(name, 6, (void*)&if_mib, (size_t*)&if_miblen, (void*)NULL, (size_t)0);
00051 
00052       /* We found the right interface? */
00053       if (QString(if_mib.ifmd_name) == device) {
00054          if_number = i;
00055          break;
00056       }
00057 
00058       /* Does the interface hold the default route? */
00059       if ( if_mib.ifmd_flags & RTF_GATEWAY )
00060          if_gw = i;
00061    }
00062 
00063    if ((if_number == -1) && (if_gw != -1))
00064       if_number = if_gw;
00065 #else
00066    if( device.isEmpty() )
00067     device = "eth0";
00068 #endif
00069      getInOutBytes(receivedBytes,transmittedBytes);
00070     netTimer.start();
00071 
00072 }
00073 NetworkSensor::~NetworkSensor()
00074 {
00075 }
00076 void NetworkSensor::getInOutBytes ( unsigned long &in,unsigned long &out) const
00077 {
00078 #ifdef __FreeBSD__
00079     if (if_number != -1) {
00080        size_t  if_miblen = 0;
00081        if_miblen = sizeof(if_mib);
00082        int name[] = { CTL_NET,
00083                       PF_LINK,
00084                       NETLINK_GENERIC,
00085                       IFMIB_IFDATA,
00086                       if_number,
00087                       IFDATA_GENERAL };
00088 
00089        sysctl(name, 6, (void*)&if_mib, (size_t*)&if_miblen, (void*)NULL, (size_t)0);
00090 
00091        in = if_mib.ifmd_data.ifi_ibytes;
00092        out = if_mib.ifmd_data.ifi_obytes;
00093    }
00094    else {
00095       in = 0;
00096       out = 0;
00097    }
00098 #else
00099     QFile file("/proc/net/dev");
00100     QString line;
00101     if ( file.open(IO_ReadOnly | IO_Translate) )
00102     {
00103         QTextStream t( &file );        // use a text stream
00104         line = t.readLine();
00105         while(line !=0 && !line.contains(device))
00106         {
00107             line = t.readLine();
00108         }
00109         if ( line.contains( device ) )
00110         {
00111             QRegExp rx( "\\W+"+device+":\\D*(\\d+)(?:\\D+\\d+){7}\\D+(\\d+)", false);
00112             rx.search(line);
00113             in = rx.cap(1).toULong();
00114             out = rx.cap(2).toULong();
00115        }
00116         else
00117         {
00118             qDebug("Network sensor: can not find %s", device.ascii());
00119             in = 0;
00120             out = 0;
00121         }
00122     file.close();
00123     }
00124 #endif
00125 }
00126 
00127 void NetworkSensor::update()
00128 {
00129     SensorParams *sp;
00130     Meter *meter;
00131     QObjectListIt it( *objList );
00132     QString format;
00133     int decimals;
00134 
00135     unsigned long inB, outB;
00136     const double delay = (double) netTimer.elapsed(); // msec elapsed since last update
00137     getInOutBytes( inB, outB );
00138     netTimer.restart();
00139 
00140     while( it != 0 )
00141     {
00142         sp = (SensorParams*)(*it);
00143         meter = sp->getMeter();
00144         format = sp->getParam( "FORMAT" );
00145         decimals = ( sp->getParam( "DECIMALS" ) ).toInt();
00146         if (format.length() == 0 )
00147         {
00148             format = "%in";
00149         }
00150 
00151         format.replace( QRegExp("%inkb", false), QString::number( ((inB - receivedBytes)*8)/delay, 'f', decimals ) );
00152         format.replace( QRegExp("%in", false), QString::number( (inB - receivedBytes)/delay, 'f', decimals ) );
00153 
00154         format.replace( QRegExp("%outkb", false), QString::number( ((outB - transmittedBytes)*8)/delay, 'f', decimals ) );
00155         format.replace( QRegExp("%out", false), QString::number( (outB - transmittedBytes)/delay, 'f', decimals ) );
00156 
00157         meter->setValue( format );
00158         ++it;
00159     }
00160     receivedBytes = inB;
00161     transmittedBytes = outB;
00162 }
00163 
00164 #include "networksensor.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys