"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 }