#!/bin/bash
# ======================================================================
#
# Check NETIO to show traffic over all network cards
# data besed on /proc/net/dev 
#
# ----------------------------------------------------------------------
# 2020-07-08  v1.0  <axel.hahn@iml.unibe.ch>
# 2023-08-21  v1.1  <axel.hahn@unibe.ch>      add help; add param -i
# 2023-08-22  v1.2  <axel.hahn@unibe.ch>      send perf data on single interface too; interfaces in alphabetic order; no more tmp file
# 2023-08-22  v1.3  <axel.hahn@unibe.ch>      show status line with 2 digits after "."
# 2023-09-22  v1.4  <axel.hahn@unibe.ch>      fix syntax error -eq: unary operator expected
# 2024-01-10  v1.5  <axel.hahn@unibe.ch>      added regex filter for include and exclude
# ======================================================================


. $( dirname $0 )/inc_pluginfunctions

export self_APPVERSION=1.5


# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------

# show help text
function showHelp(){
    local _self; _self=$(basename $0)
cat <<EOF
$( ph.showImlHelpHeader )

Show network io for all or selected interfaces.
It shows the current counter value from /proc/net/dev and the speed 
in byte per sec since last execution.

This plugin sends performancedata.

SYNTAX:
  $_self [-h] [-i INTERFACE(S)]

OPTIONS:
  -h               this help

PARAMETERS:

  -f  REGEX        filter interfaces by given regex.
  -r  REGEX        remove interfaces by given regex

  -i  INTERFACE    show this interface only. Quote multiple interfaces.
                   The check returns unknown if an interface does not
                   exist.

EXAMPLES:

  $_self      show netio of all network interfaces
  $_self -i "eth0 eth1" 
                   show netio of given interfaces.

  $_self -f "^eth" 
                   show netio of interfaces beginning with "eth"

  $_self -f "^eth" -r "eth2"
                   show netio of interfaces matching "^eth" but not "eth2"

  $_self -f "^(enp|wlp)"
                   Example to include multiple interface names: use brackets
                   and divide expressions with pipe sign.

EOF
}

# ----------------------------------------------------------------------
# MAIN
# ----------------------------------------------------------------------

ph.hasParamoption "h" "$@"; bOptHelp=$?

if [ $bOptHelp -eq 0 ]; then
    showHelp
    exit 0
fi

typeset -i iCountInterfaces

typeset -i iRead=0
typeset -i iTrans=0
typeset -i iSpeedRead=0
typeset -i iSpeedTrans=0
typeset -i iTotalRead=0
typeset -i iTotalTrans=0

data=$( cat /proc/net/dev | grep ":" | grep -vE "(lo|bond.*|ppp.*):")

sFilter=$( ph.getValueWithParam "." "f" "$@" )
sRemove=$( ph.getValueWithParam "SOMETHING_INVALID" "r" "$@" )

allInterfaces=$( cut -f 1 -d ":" <<< "$data" | tr -d " " | grep -E "$sFilter" | grep -vE "$sRemove" )

sInterface=$(   ph.getValueWithParam "$allInterfaces" "i" "$@" | sort )

out="---------- Interfaces:"

# ----- loop over all interfaces
iCountInterfaces=$( wc -w <<< "$sInterface" )
if [ $iCountInterfaces -eq 0 ]; then
    ph.abort "ERROR: No interface was found."
fi

for myinterface in $sInterface
do

    line=$( grep "${myinterface}:" <<< "$data" )
    if [ -n "$line" ] ; then

        # echo "SOURCE: $line"

        # total value of byte
        iRead=$( echo "$line" | awk '{ print $2 }')
        iTrans=$(echo "$line" | awk '{ print $10 }')

        # speed in byte per sec based on last stored value and its age
        iSpeedRead=$( ph.perfdeltaspeed "netio-${myinterface}-rx" $iRead)
        iSpeedTrans=$(ph.perfdeltaspeed "netio-${myinterface}-tx" $iTrans)

        out+=$(
            printf "\n>>> %s\n"                 "${myinterface}"
            printf "%15s %15s %10s %-10s \n"  "receive:"   $iRead  $iSpeedRead  "byte/s"
            printf "%15s %15s %10s %-10s \n"  "transmit:"  $iTrans $iSpeedTrans "byte/s"
            echo " "
        )
        ph.perfadd "rx-${myinterface}"   "$iSpeedRead"
        ph.perfadd "tx-${myinterface}"   "$iSpeedTrans"

        iTotalRead=$iTotalRead+$iSpeedRead
        iTotalTrans=$iTotalTrans+$iSpeedTrans
    else
        # ph.setStatus "unknown"
        # out+=$( printf "\nERROR: The interface [${myinterface}] does not exist." )
        ph.abort "ERROR: The interface [${myinterface}] does not exist."
    fi

done

# ----- total
if [ $iCountInterfaces -gt 1 ]; then

    out+=$(
        echo
        echo "---------- total:"
        printf "%15s %10s %-10s \n"  "receive:"   $iTotalRead  "byte/s"
        printf "%15s %10s %-10s \n"  "transmit:"  $iTotalTrans "byte/s"
        echo " "
    )
   
fi
ph.perfadd "rx"   "$iTotalRead"
ph.perfadd "tx"   "$iTotalTrans"

# ----- output
ph.status "Network IO ... IN $(ph.toUnit $iTotalRead M 2 ) MB/s >> [host] >> $(ph.toUnit $iTotalTrans M 2 ) MB/s OUT"

echo "$out"

ph.exit