1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
# copyright (C) 1997-2001 Jean-Luc Fontaine (mailto:jfontain@free.fr)
# this program is free software: please read the COPYRIGHT file enclosed in this package or use the Help Copyright menu
set rcsId {$Id: netdev.tcl,v 2.8 2001/02/04 10:46:20 jfontain Exp $}
package provide netdev [lindex {$Revision: 2.8 $} 1]
package require network 1
namespace eval netdev {
# documentation from net/core/dev.c and include/linux/netdevice.h kernel source files
array set data {
updates 0
0,label interface 0,type dictionary 0,message {network device name}
1,label <bytes 1,type integer 1,message {total bytes received}
2,label <packets 2,type integer 2,message {total packets received}
3,label <errors 3,type integer 3,message {bad packets received}
4,label <dropped 4,type integer
4,message "received packets dropped for lack of space in\nkernel buffers, plus receiver missed packets"
5,label <FIFO 5,type integer 5,message {receiver FIFO overruns}
6,label <frame 6,type integer
6,message "frame alignment errors received, including length,\nreceiver ring buff overflow and CRC errors"
7,label <compressed 7,type integer 7,message {compressed packets received}
8,label <multicast 8,type integer 8,message {multicast packets received}
9,label bytes> 9,type integer 9,message {total bytes transmitted}
10,label packets> 10,type integer 10,message {total packets transmitted}
11,label errors> 11,type integer 11,message {packet transmit problems}
12,label dropped> 12,type integer 12,message "packets not transmitted for\nlack of space in kernel buffers"
13,label FIFO> 13,type integer 13,message {transmitter FIFO overruns}
14,label collisions> 14,type integer 14,message {collisions while transmitting}
15,label carrier> 15,type integer 15,message "carriers errors, including aborted,\nwindow and heartbeat errors"
16,label compressed> 16,type integer 16,message {compressed packets transmitted}
17,label <bytes/s 17,type real 17,message "total bytes received\nper second during last poll period"
18,label <packets/s 18,type real 18,message "total packets received\nper second during last poll period"
19,label <errors/s 19,type real 19,message "bad packets received\nper second during last poll period"
20,label <dropped/s 20,type real
20,message "received packets dropped for lack of space in\nkernel buffers, plus receiver missed packets,\nper second during last poll period"
21,label <FIFO/s 21,type real 21,message "receiver FIFO overruns\nper second during last poll period"
22,label <frame/s 22,type real
22,message "frame alignment errors received, including length,\nreceiver ring buff overflow and CRC errors,\nper second during last poll period"
23,label <compressed/s 23,type real 23,message "compressed packets received\nper second during last poll period"
24,label <multicast/s 24,type real 24,message "multicast packets received\nper second during last poll period"
25,label bytes/s> 25,type real 25,message "total bytes transmitted\nper second during last poll period"
26,label packets/s> 26,type real 26,message "total packets transmitted\nper second during last poll period"
27,label errors/s> 27,type real 27,message "packet transmit problems\nper second during last poll period"
28,label dropped/s> 28,type real
28,message "packets not transmitted\nfor lack of space in kernel buffers,\nper second during last poll period"
29,label FIFO/s> 29,type real 29,message "transmitter FIFO overruns\nper second during last poll period"
30,label collisions/s> 30,type real 30,message "collisions while transmitting\nper second during last poll period"
31,label carrier/s> 31,type real
31,message "carriers errors, including aborted,\nwindow and heartbeat errors,\nper second during last poll period"
32,label compressed/s> 32,type real 32,message "compressed packets transmitted\nper second during last poll period"
indexColumns 0
views {
{visibleColumns {0 1 2 3 4 5 6 7 8} sort {0 increasing}}
{visibleColumns {0 9 10 11 12 13 14 15 16} sort {0 increasing}}
{visibleColumns {0 17 18 19 20 21 22 23 24} sort {0 increasing}}
{visibleColumns {0 25 26 27 28 29 30 31 32} sort {0 increasing}}
}
switches {-r 1 --remote 1}
}
set file [open netdev.htm]
set data(helpText) [read $file] ;# initialize HTML help data from file
close $file
proc initialize {optionsName} {
upvar $optionsName options
variable remote
variable data
variable devicesFile
if {![catch {set locator $options(--remote)}]||![catch {set locator $options(-r)}]} { ;# remote monitoring
set data(pollTimes) {20 10 30 60 120 300 600} ;# poll less often when remotely monitoring
foreach {remote(protocol) remote(user) remote(host)} [network::parseRemoteLocator $locator] {}
network::checkRemoteOutputEmptiness $remote(protocol) $remote(user) $remote(host)
set data(identifier) netdev($remote(host))
set file [open "| /usr/bin/$remote(protocol) -n -l $remote(user) $remote(host) cat /proc/net/dev"]
fileevent $file readable {set ::netdev::remote(busy) 0}
vwait ::netdev::remote(busy) ;# allow GUI interaction
# detect errors early (but avoid write on pipe with no readers errors by reading whole data)
if {[catch {read $file} message]||[catch {close $file} message]} {
error "on remote host $remote(host) as user $remote(user): $message"
}
} else {
set data(pollTimes) {10 5 20 30 60 120 300 600}
set devicesFile [open /proc/net/dev] ;# keep local file open for better performance
}
}
variable nextIndex 0
proc update {} { ;# gather cpu statistics (based on the proc man page information)
variable remote
variable devicesFile
variable index
variable nextIndex
variable data
variable last
if {[info exists remote]} {
if {![info exists devicesFile]} { ;# start data gathering process in a non blocking fashion
if {$remote(busy)} return ;# core invocation while waiting for remote data
set remote(busy) 1
set file [open "| /usr/bin/$remote(protocol) -n -l $remote(user) $remote(host) cat /proc/net/dev"]
# do not hang GUI, allow other modules updates
fileevent $file readable "set ::netdev::devicesFile $file; ::netdev::update"
return ;# wait for remote data
} ;# else continue below to process data
} else {
seek $devicesFile 0 ;# rewind before retrieving data
}
gets $devicesFile; gets $devicesFile ;# skip column titles lines
while {[gets $devicesFile line]>=0} {
lappend lines $line
}
set clock [expr {[clock clicks -milliseconds]/1000.0}] ;# immediately store current clock in seconds
if {[info exists remote]} { ;# closing is necessary since seek does not work
read $devicesFile ;# avoid write on pipe with no readers errors by reading remaining data
if {[catch {close $devicesFile} message]} {
flashMessage "netdev error: $message"
set lines {} ;# consider data corrupted as a whole
}
unset devicesFile
set remote(busy) 0
}
set row 0
foreach line $lines {
regsub : $line { } line ;# remove column after interface name to make sure of proper list structure
set interface [lindex $line 0]
if {[catch {set row $index($interface)}]} { ;# new interface
set row [set index($interface) $nextIndex]
incr nextIndex
}
set data($row,0) $interface
set column 1
foreach cell [lrange $line 1 end] {
set data($row,$column) $cell
if {[info exists last(clock)]} {
set data($row,[expr {$column+16}]) [format %.1f [expr {($cell-$last($row,$column))/($clock-$last(clock))}]]
} else { ;# first update
set data($row,[expr {$column+16}]) ?
}
set last($row,$column) $cell
incr column
}
set current($interface) {}
incr row
}
set last(clock) $clock
foreach {interface row} [array get index] { ;# cleanup disappeared entries
if {[info exists current($interface)]} continue
unset index($interface)
unset data($row,0)
for {set column 1} {$column<=16} {incr column} {
unset data($row,$column) last($row,$column)
}
for {} {$column<=32} {incr column} {
unset data($row,$column)
}
}
incr data(updates)
}
}
|