diff --git a/README.md b/README.md index cceeb64..01930ca 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,10 @@ An example report file, generated by `dsnet report` to "DNS": "", "PeersOnline": 4, "PeersTotal": 13, + "ReceiveBytes": 32517164, + "TransmitBytes": 85384984, + "ReceiveBytesSI": "32.5 MB", + "TransmitBytesSI": "85.4 MB", "Peers": [ { "Hostname": "test", diff --git a/reporttypes.go b/reporttypes.go index df8a4d6..8a72fd2 100644 --- a/reporttypes.go +++ b/reporttypes.go @@ -8,6 +8,7 @@ import ( "time" "github.com/go-playground/validator/v10" + "github.com/vishvananda/netlink" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) @@ -21,11 +22,15 @@ type DsnetReport struct { IP net.IP // IP network from which to allocate automatic sequential addresses // Network is chosen randomly when not specified - Network JSONIPNet - DNS net.IP - PeersOnline int - PeersTotal int - Peers []PeerReport + Network JSONIPNet + DNS net.IP + PeersOnline int + PeersTotal int + Peers []PeerReport + ReceiveBytes uint64 + TransmitBytes uint64 + ReceiveBytesSI string + TransmitBytesSI string } func GenerateReport(dev *wgtypes.Device, conf *DsnetConfig, oldReport *DsnetReport) DsnetReport { @@ -34,6 +39,11 @@ func GenerateReport(dev *wgtypes.Device, conf *DsnetConfig, oldReport *DsnetRepo oldPeerReportIndex := make(map[string]PeerReport) peersOnline := 0 + linkDev, err := netlink.LinkByName(conf.InterfaceName) + check(err) + + stats := linkDev.Attrs().Statistics + for _, peer := range dev.Peers { wgPeerIndex[peer.PublicKey] = peer } @@ -57,7 +67,7 @@ func GenerateReport(dev *wgtypes.Device, conf *DsnetConfig, oldReport *DsnetRepo dormant := !wgPeer.LastHandshakeTime.IsZero() && time.Since(wgPeer.LastHandshakeTime) > EXPIRY if online { - peersOnline += 1 + peersOnline++ } externalIP := net.IP{} @@ -65,6 +75,9 @@ func GenerateReport(dev *wgtypes.Device, conf *DsnetConfig, oldReport *DsnetRepo externalIP = wgPeer.Endpoint.IP } + uReceiveBytes := uint64(wgPeer.ReceiveBytes) + uTransmitBytes := uint64(wgPeer.TransmitBytes) + peerReports[i] = PeerReport{ Hostname: peer.Hostname, Online: online, @@ -76,24 +89,28 @@ func GenerateReport(dev *wgtypes.Device, conf *DsnetConfig, oldReport *DsnetRepo ExternalIP: externalIP, Networks: peer.Networks, LastHandshakeTime: wgPeer.LastHandshakeTime, - ReceiveBytes: wgPeer.ReceiveBytes, - TransmitBytes: wgPeer.TransmitBytes, - ReceiveBytesSI: BytesToSI(wgPeer.ReceiveBytes), - TransmitBytesSI: BytesToSI(wgPeer.TransmitBytes), + ReceiveBytes: uReceiveBytes, + TransmitBytes: uTransmitBytes, + ReceiveBytesSI: BytesToSI(uReceiveBytes), + TransmitBytesSI: BytesToSI(uTransmitBytes), } } return DsnetReport{ - ExternalIP: conf.ExternalIP, - InterfaceName: conf.InterfaceName, - ListenPort: conf.ListenPort, - Domain: conf.Domain, - IP: conf.IP, - Network: conf.Network, - DNS: conf.DNS, - Peers: peerReports, - PeersOnline: peersOnline, - PeersTotal: len(peerReports), + ExternalIP: conf.ExternalIP, + InterfaceName: conf.InterfaceName, + ListenPort: conf.ListenPort, + Domain: conf.Domain, + IP: conf.IP, + Network: conf.Network, + DNS: conf.DNS, + Peers: peerReports, + PeersOnline: peersOnline, + PeersTotal: len(peerReports), + ReceiveBytes: stats.RxBytes, + TransmitBytes: stats.TxBytes, + ReceiveBytesSI: BytesToSI(stats.RxBytes), + TransmitBytesSI: BytesToSI(stats.TxBytes), } } @@ -146,8 +163,8 @@ type PeerReport struct { // TODO support routing additional networks (AllowedIPs) Networks []JSONIPNet LastHandshakeTime time.Time - ReceiveBytes int64 - TransmitBytes int64 + ReceiveBytes uint64 + TransmitBytes uint64 ReceiveBytesSI string TransmitBytesSI string } diff --git a/util.go b/util.go index 64fda9f..b5cda5e 100644 --- a/util.go +++ b/util.go @@ -49,7 +49,7 @@ func ConfirmOrAbort(format string, a ...interface{}) { } } -func BytesToSI(b int64) string { +func BytesToSI(b uint64) string { const unit = 1000 if b < unit { return fmt.Sprintf("%d B", b)