blob: 43fbe6153a7e541b61527c860f6116facf7a5070 [file] [log] [blame]
Copybara botca5ce642024-11-08 17:38:08 +01001#!/usr/bin/env bash
2# Copyright (C) 2012 Stefan Breunig <stefan+measure-net-speed@mathphys.fsk.uni-heidelberg.de>
3# Copyright (C) 2014 kaueraal
4# Copyright (C) 2015 Thiago Perrotta <perrotta dot thiago at poli dot ufrj dot br>
5
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19# Get custom IN and OUT labels if provided by command line arguments
20while [[ $# -gt 1 ]]; do
21 key="$1"
22 case "$key" in
23 -i|--inlabel)
24 INLABEL="$2"
25 shift;;
26 -o|--outlabel)
27 OUTLABEL="$2"
28 shift;;
29 esac
30 shift
31done
32
33[[ -z "$INLABEL" ]] && INLABEL="IN "
34[[ -z "$OUTLABEL" ]] && OUTLABEL="OUT "
35
36# Use the provided interface, otherwise the device used for the default route.
37if [[ -z $INTERFACE ]] && [[ -n $BLOCK_INSTANCE ]]; then
38 INTERFACE=$BLOCK_INSTANCE
39elif [[ -z $INTERFACE ]]; then
40 INTERFACE=$(ip route | awk '/^default/ { print $5 ; exit }')
41fi
42
43# Exit if there is no default route
44[[ -z "$INTERFACE" ]] && exit
45
46# Issue #36 compliant.
47if ! [ -e "/sys/class/net/${INTERFACE}/operstate" ] || \
48 (! [ "$TREAT_UNKNOWN_AS_UP" = "1" ] &&
49 ! [ "`cat /sys/class/net/${INTERFACE}/operstate`" = "up" ])
50then
51 echo "$INTERFACE down"
52 echo "$INTERFACE down"
53 echo "#FF0000"
54 exit 0
55fi
56
57# path to store the old results in
58path="/tmp/$(basename $0)-${INTERFACE}"
59
60# grabbing data for each adapter.
61read rx < "/sys/class/net/${INTERFACE}/statistics/rx_bytes"
62read tx < "/sys/class/net/${INTERFACE}/statistics/tx_bytes"
63
64# get time
65time="$(date +%s)"
66
67# write current data if file does not exist. Do not exit, this will cause
68# problems if this file is sourced instead of executed as another process.
69if ! [[ -f "${path}" ]]; then
70 echo "${time} ${rx} ${tx}" > "${path}"
71 chmod 0666 "${path}"
72fi
73
74
75# read previous state and update data storage
76read old < "${path}"
77echo "${time} ${rx} ${tx}" > "${path}"
78
79# parse old data and calc time passed
80old=(${old//;/ })
81time_diff=$(( $time - ${old[0]} ))
82
83# sanity check: has a positive amount of time passed
84[[ "${time_diff}" -gt 0 ]] || exit
85
86# calc bytes transferred, and their rate in byte/s
87rx_diff=$(( $rx - ${old[1]} ))
88tx_diff=$(( $tx - ${old[2]} ))
89rx_rate=$(( $rx_diff / $time_diff ))
90tx_rate=$(( $tx_diff / $time_diff ))
91
92# shift by 10 bytes to get KiB/s. If the value is larger than
93# 1024^2 = 1048576, then display MiB/s instead
94
95# incoming
96echo -n "$INLABEL"
97rx_kib=$(( $rx_rate >> 10 ))
98if hash bc 2>/dev/null && [[ "$rx_rate" -gt 1048576 ]]; then
99 printf '%sM' "`echo "scale=1; $rx_kib / 1024" | bc`"
100else
101 echo -n "${rx_kib}K"
102fi
103
104echo -n " "
105
106# outgoing
107echo -n "$OUTLABEL"
108tx_kib=$(( $tx_rate >> 10 ))
109if hash bc 2>/dev/null && [[ "$tx_rate" -gt 1048576 ]]; then
110 printf '%sM\n' "`echo "scale=1; $tx_kib / 1024" | bc`"
111else
112 echo "${tx_kib}K"
113fi