"Fossies" - the Fresh Open Source Software Archive

Member "xosview-1.23/linux/netmeter.cc" (11 Jul 2020, 5004 Bytes) of package /linux/misc/xosview-1.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "netmeter.cc" see the Fossies "Dox" file reference documentation.

    1 //
    2 //  Copyright (c) 1994, 1995, 2002, 2006 by Mike Romberg ( mike.romberg@noaa.gov )
    3 //
    4 //  Modifications to support dynamic addresses by:
    5 //    Michael N. Lipp (mnl@dtro.e-technik.th-darmstadt.de)
    6 //
    7 //  This file may be distributed under terms of the GPL
    8 //
    9 
   10 #include "netmeter.h"
   11 #include <sys/types.h>
   12 #include <sys/stat.h>
   13 #include <dirent.h>
   14 #include <string.h>
   15 #include <stdlib.h>
   16 #include <iostream>
   17 #include <fstream>
   18 #include <string>
   19 
   20 static const char PROCNETDEV[] = "/proc/net/dev";
   21 static const char SYSCLASSNET[] = "/sys/class/net";
   22 
   23 /*
   24  * Parse the integer count from the given filename
   25  *
   26  * This is quite relaxed about error conditions because the file may
   27  * have been removed before it was opened, or truncated, in which case
   28  * the count is zero.
   29  *
   30  * Return: 0 if not not avilable, otherwise count (which may be zero)
   31  */
   32 
   33 static unsigned long long getCount( const char *filename ){
   34   unsigned long long n, count = 0;
   35   FILE *f;
   36 
   37   f = fopen(filename, "r");
   38   if (!f)
   39     return 0;
   40 
   41   if (fscanf(f, "%llu", &n) == 1)
   42     count = n;
   43 
   44   if (fclose(f) != 0)
   45     abort();
   46 
   47   return count;
   48 }
   49 
   50 
   51 NetMeter::NetMeter( XOSView *parent, float max )
   52   : FieldMeterGraph( parent, 3, "NET", "IN/OUT/IDLE" ){
   53   _maxpackets = max;
   54   _lastBytesIn = _lastBytesOut = 0;
   55   _usesysfs = _ignored = false;
   56 
   57   struct stat buf;
   58   if ( stat(SYSCLASSNET, &buf) == 0 && S_ISDIR(buf.st_mode) )
   59     _usesysfs = true;
   60 }
   61 
   62 NetMeter::~NetMeter( void ){
   63 }
   64 
   65 void NetMeter::checkResources( void ){
   66   FieldMeterGraph::checkResources();
   67 
   68   setfieldcolor( 0, parent_->getResource( "netInColor" ) );
   69   setfieldcolor( 1, parent_->getResource( "netOutColor" ) );
   70   setfieldcolor( 2, parent_->getResource( "netBackground" ) );
   71   priority_ = atoi( parent_->getResource( "netPriority" ) );
   72   useGraph_ = parent_->isResourceTrue( "netGraph" );
   73   dodecay_ = parent_->isResourceTrue( "netDecay" );
   74   SetUsedFormat( parent_->getResource("netUsedFormat") );
   75   _netIface = parent_->getResource( "netIface" );
   76   if (_netIface[0] == '-') {
   77     _ignored = true;
   78     _netIface.erase(0, _netIface.find_first_not_of("- "));
   79   }
   80 }
   81 
   82 void NetMeter::checkevent( void ){
   83   unsigned long long totin = 0, totout = 0;
   84   fields_[2] = _maxpackets;     // assume no
   85   fields_[0] = fields_[1] = 0;  // network activity
   86 
   87   IntervalTimerStop();
   88   if (_usesysfs)
   89     getSysStats(totin, totout);
   90   else
   91     getProcStats(totin, totout);
   92 
   93   double t = IntervalTimeInSecs();
   94   IntervalTimerStart();
   95 
   96   if (_lastBytesIn == 0 && _lastBytesOut == 0) {  // first run
   97     _lastBytesIn = totin;
   98     _lastBytesOut = totout;
   99   }
  100 
  101   fields_[0] = (totin - _lastBytesIn) / t;
  102   fields_[1] = (totout - _lastBytesOut) / t;
  103 
  104   _lastBytesIn = totin;
  105   _lastBytesOut = totout;
  106 
  107   total_ = fields_[0] + fields_[1];
  108   if (total_ > _maxpackets)
  109     fields_[2] = 0;
  110   else {
  111     total_ = _maxpackets;
  112     fields_[2] = total_ - fields_[0] - fields_[1];
  113   }
  114 
  115   setUsed(fields_[0] + fields_[1], total_);
  116   drawfields();
  117 }
  118 
  119 void NetMeter::getSysStats( unsigned long long &totin, unsigned long long &totout ){
  120   DIR *dir;
  121   struct dirent *ent;
  122   char filename[128];
  123   std::ifstream ifs;
  124 
  125   if ( !(dir = opendir(SYSCLASSNET)) ) {
  126     std::cerr << "Can not open directory : " << SYSCLASSNET << std::endl;
  127     parent_->done(1);
  128     return;
  129   }
  130 
  131   // walk through /sys/class/net/*/statistics/{r,t}x_bytes
  132   while ( (ent = readdir(dir)) ) {
  133     if ( ent->d_type != DT_LNK )
  134       continue;
  135     if ( _netIface != "False" &&
  136          ( (!_ignored && ent->d_name != _netIface) ||
  137            ( _ignored && ent->d_name == _netIface) ) )
  138         continue;
  139 
  140     snprintf(filename, 128, "%s/%s/statistics/rx_bytes", SYSCLASSNET, ent->d_name);
  141     totin += getCount(filename);
  142 
  143     snprintf(filename, 128, "%s/%s/statistics/tx_bytes", SYSCLASSNET, ent->d_name);
  144     totout += getCount(filename);
  145   }
  146   closedir(dir);
  147 }
  148 
  149 void NetMeter::getProcStats( unsigned long long &totin, unsigned long long &totout ){
  150   std::ifstream ifs(PROCNETDEV);
  151   std::string line, ifname;
  152 
  153   if (!ifs) {
  154     std::cerr << "Can not open file : " << PROCNETDEV << std::endl;
  155     parent_->done(1);
  156     return;
  157   }
  158 
  159   ifs.ignore(1024, '\n');
  160   ifs.ignore(1024, '\n');
  161 
  162   while ( !ifs.eof() ) {
  163     unsigned long long vals[9];
  164     std::getline(ifs, line);
  165     if ( !ifs.good() )
  166       break;
  167 
  168     int colon = line.find_first_of(':');
  169     ifname = line.substr(0, colon);
  170     ifname.erase(0, ifname.find_first_not_of(' '));
  171     if (_netIface != "False") {
  172       if ( (!_ignored && ifname != _netIface) ||
  173            ( _ignored && ifname == _netIface) )
  174         continue;
  175     }
  176 
  177     std::string l = line.erase(0, colon + 1);
  178     const char *cur = l.c_str();
  179     if ( strncmp(cur, " No ", 4) == 0 )
  180       continue; // xxx: No statistics available.
  181 
  182     char *end = NULL;
  183     for (int i = 0; i < 9; i++) {
  184       vals[i] = strtoull(cur, &end, 10);
  185       cur = end;
  186     }
  187     totin += vals[0];
  188     totout += vals[8];
  189     XOSDEBUG("%s: %llu bytes received, %llu bytes sent.\n",
  190              ifname.c_str(), vals[0], vals[8]);
  191   }
  192 }