I have played with snmp (Simple Network Management Protocol) in the past. Time to expand on that knowledge and put it to use. I started off with port utilization on our Ubiquiti Edge Switches.


The output from the script looks like this. I was doing an iperf3 test when I grabbed this screenshot.

I tend to over complicate things. Perhaps there is a simple and better way to do this. I see a port utilization value in the switches MIB file but it seems to be slow and keeps incrementing. After the time I have put into this script I’m thinking I should have looked more into what that value is and what I could have done with it. It mostly works and I learned a lot so I guess it turned out well.

#!/bin/bash
# Experimental script to monitor my Ubiquitu 24 + 2 port EdgeSwitch
# If it seems like I may not know what I am doing its because I don't.
# Seemed to also work on my home pfsense box that has 4 ports.
# Known issues:
# --Full port utilization seems to show as closer to 125%. Will update if I figure out why.
# --Could improve by reading port link speeds via snmp
# --I could not figure out how to make the {1..26} to be variables. HELP!
#
# Corrections / improvements appreciated adamd at sdf.org
#
#10,000,000 = 10**7 10Mb
#100,000,000 = 10**8 100Mb
#1,000,000,000 = 10**9 1G
#10,000,000,000 = 10**10 10G
port_speed=$((10**9))
upd_rate=5 #seconds
ip="192.168.0.2"

main () {
        while true;
        do
                InOct=($(snmpget -v1 -Oqv -c public $ip IF-MIB::ifInOctets.{1..26}))
                OutOct=($(snmpget -v1 -Oqv -c public $ip IF-MIB::ifOutOctets.{1..26}))
                InPkts=($(snmpget -v1 -Oqv -c public $ip IF-MIB::ifInUcastPkts.{1..26}))
                OutPkts=($(snmpget -v1 -Oqv -c public $ip IF-MIB::ifOutUcastPkts.{1..26}))
                x="0"
                clear
                echo "Port Utilization ***************************"
                for p in ${OldInOct[@]}; do
                        #TotInOct=$((${InOct[$x]} - ${OldInOct[$x]}))
                        #TotOutOct=$((${OutOct[$x]} - ${OldOutOct[$x]}))
                        #TotInPkts=$((${InPkts[$x]} - ${OldInPkts[$x]}))
                        #TotOutPkts=$((${OutPkts[$x]} - ${OldOutPkts[$x]}))
                        get_difference "${InOct[$x]}" "${OldInOct[$x]}"; TotInOct=$itemp
                        get_difference "${OutOct[$x]}" "${OldOutOct[$x]}"; TotOutOct=$itemp
                        get_difference "${InPkts[$x]}" "${OldInPkts[$x]}"; TotInPkts=$itemp
                        get_difference "${OutPkts[$x]}" "${OldOutPkts[$x]}"; TotOutPkts=$itemp
                        ((y=x+1)) #Arrays are zero based, ports start at 1
                        #The Incoming utilization
                        i=$(echo "((($TotInPkts * (96+64)) + ($TotInOct * 8)) / ($port_speed * $upd_rate)) * 100" | bc -l)
                        #The outgoing utilization       
                        j=$(echo "((($TotOutPkts * (96+64)) + ($TotOutOct * 8)) / ($port_speed * $upd_rate)) * 100" | bc -l)
                        #Colors the upload and or download number if it sees above requested percent
                        echo "P:$y"
                        if (( $(echo "$i > 1" | bc -l) )); then
                                printf "\e[31m%2.4f\e[0m, " $i
                        else
                                printf "%2.4f, " $i
                        fi
                        if (( $(echo "$j > 1" | bc -l) )); then
                                printf "\e[31m%2.4f\e[0m\n" $j
                        else
                                printf "%2.4f\n" $j
                        fi
                        #printf "%2.4f, %2.4f\n" $i $j
                        ((x=x+1))
                done
                OldInOct=(${InOct[*]})
                OldOutOct=(${OutOct[*]})
                OldInPkts=(${InPkts[*]})
                OldOutPkts=(${OutPkts[*]})
                sleep $upd_rate
        done
}
#Created to deal with packet and octet counter rollovers
get_difference () {
        if (( "$1" >= "$2" )); then
                itemp=$(($1 - $2))
        else
                #we must have rolled over the register
                #How far was it from the old value to the rollover point?
                #4294967296 = 2^32
                itemp=$((4294967295-$2))
                #add that to the new value
                itemp=$(($itemp+$1))
        fi
}
main "$@"; exit