2018-12-03 04:39:13 +08:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Copyright (C) Microsoft. All rights reserved.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
// See LICENSE.txt file in the project root for full license information.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"net"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
2018-12-05 12:15:56 +08:00
|
|
|
|
|
|
|
tm "github.com/nsf/termbox-go"
|
2018-12-03 04:39:13 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type ethrNetDevInfo struct {
|
|
|
|
bytes uint64
|
|
|
|
packets uint64
|
|
|
|
drop uint64
|
|
|
|
errs uint64
|
|
|
|
fifo uint64
|
|
|
|
frame uint64
|
|
|
|
compressed uint64
|
|
|
|
multicast uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
func getNetDevStats(stats *ethrNetStat) {
|
|
|
|
ifs, err := net.Interfaces()
|
|
|
|
if err != nil {
|
|
|
|
ui.printErr("%v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
netStatsFile, err := os.Open("/proc/net/dev")
|
|
|
|
if err != nil {
|
|
|
|
ui.printErr("%v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer netStatsFile.Close()
|
|
|
|
|
|
|
|
reader := bufio.NewReader(netStatsFile)
|
|
|
|
|
|
|
|
// Pass the header
|
|
|
|
// Inter-| Receive | Transmit
|
|
|
|
// face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
|
|
|
|
reader.ReadString('\n')
|
|
|
|
reader.ReadString('\n')
|
|
|
|
|
|
|
|
var line string
|
|
|
|
for err == nil {
|
|
|
|
line, err = reader.ReadString('\n')
|
|
|
|
if line == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
netDevStat := buildNetDevStat(line)
|
|
|
|
if isIfUp(netDevStat.interfaceName, ifs) {
|
|
|
|
stats.netDevStats = append(stats.netDevStats, buildNetDevStat(line))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func buildNetDevStat(line string) ethrNetDevStat {
|
|
|
|
fields := strings.Fields(line)
|
|
|
|
interfaceName := strings.TrimSuffix(fields[0], ":")
|
|
|
|
rxInfo := toNetDevInfo(fields[1:9])
|
|
|
|
txInfo := toNetDevInfo(fields[9:17])
|
|
|
|
return ethrNetDevStat{
|
|
|
|
interfaceName: interfaceName,
|
|
|
|
rxBytes: rxInfo.bytes,
|
|
|
|
txBytes: txInfo.bytes,
|
|
|
|
rxPkts: rxInfo.packets,
|
|
|
|
txPkts: txInfo.packets,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func toNetDevInfo(fields []string) ethrNetDevInfo {
|
|
|
|
return ethrNetDevInfo{
|
2018-12-18 00:52:58 +08:00
|
|
|
bytes: toUInt64(fields[0]),
|
|
|
|
packets: toUInt64(fields[1]),
|
|
|
|
errs: toUInt64(fields[2]),
|
|
|
|
drop: toUInt64(fields[3]),
|
|
|
|
fifo: toUInt64(fields[4]),
|
|
|
|
frame: toUInt64(fields[5]),
|
|
|
|
compressed: toUInt64(fields[6]),
|
|
|
|
multicast: toUInt64(fields[7]),
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func isIfUp(ifName string, ifs []net.Interface) bool {
|
|
|
|
for _, ifi := range ifs {
|
|
|
|
if ifi.Name == ifName {
|
|
|
|
if (ifi.Flags & net.FlagUp) != 0 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-12-18 00:52:58 +08:00
|
|
|
func toUInt64(str string) uint64 {
|
2018-12-03 04:39:13 +08:00
|
|
|
res, err := strconv.ParseUint(str, 10, 64)
|
|
|
|
if err != nil {
|
2019-01-02 13:28:38 +08:00
|
|
|
ui.printDbg("Error in string conversion: %v", err)
|
2018-12-18 00:52:58 +08:00
|
|
|
return 0
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2018-12-11 23:28:33 +08:00
|
|
|
func getTCPStats(stats *ethrNetStat) {
|
2018-12-03 04:39:13 +08:00
|
|
|
snmpStatsFile, err := os.Open("/proc/net/snmp")
|
|
|
|
if err != nil {
|
2019-01-02 13:28:38 +08:00
|
|
|
ui.printDbg("%v", err)
|
2018-12-03 04:39:13 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
defer snmpStatsFile.Close()
|
|
|
|
|
|
|
|
reader := bufio.NewReader(snmpStatsFile)
|
|
|
|
|
|
|
|
var line string
|
|
|
|
for err == nil {
|
|
|
|
// Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets
|
|
|
|
// CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
|
|
|
|
line, err = reader.ReadString('\n')
|
|
|
|
if line == "" || !strings.HasPrefix(line, "Tcp") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// Skip the first line starting with Tcp
|
|
|
|
line, err = reader.ReadString('\n')
|
|
|
|
if !strings.HasPrefix(line, "Tcp") {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
fields := strings.Fields(line)
|
2018-12-18 00:52:58 +08:00
|
|
|
stats.tcpStats.segRetrans = toUInt64(fields[12])
|
2018-12-03 04:39:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func hideCursor() {
|
|
|
|
tm.SetCursor(0, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
func blockWindowResize() {
|
|
|
|
}
|