Рівень сигналу трансивера через SNMP в Cisco

Іноді потрібно дізнатися рівень сигналу в трансивері. Причини бувають різні: раптове падіння каналу зв'язку, підключення нових оптичних кроссировок, моніторинг. Інженер з необхідним рівнем доступу вирішує це питання менше ніж за одну хвилину за допомогою команди:

#show interfaces Te1/49 transceiver
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Optical Optical
Temperature Voltage Tx Power Rx Power
Port (Celsius) (Volts) (dBm) (dBm)
--------- ----------- ------- -------- --------
Te1/49 53.3 3.25 -4.3 -2.8

Кому (у кого немає відповідного доступу) доводиться чекати цієї хвилини цілу вічність. Наприклад, коли канал впав у пікові години і на резервному лінке якісь втрати, які виявилися тільки при завантаженні лінка трафіком. Або коли новий канал потрібно було здати вчора, а нічого не працює, тому що постачальник неправильно підписав оптику на CWDM-мультиплексорі, і потрібно методом тику відшукати «правильну хвилю». І все це відбувається в умовах дефіциту верховних мережевих інженерів і часу.

У статті розглядається варіант того, як перевірити сигнал, маючи лише read-only доступ по SNMP. Чекати при цьому доводиться не більше 10 хвилин (звичайний період оновлення соответвтующей змінної). Виділення такого доступу здається більш безопаным логічним для ряду співробітників, які з тих чи інших причин не мають CCNA або CCNP (інженери моніторингу, операціоністи, технічні менеджери). Так само інформація може бути корисна при налаштуванні систем моніторингу.

Дано

  • хост з IP-адресою, який має read-only доступ по SNMP до кількох Cisco (7604, 7609, 4948-10GE)
  • IP-адреса пристрою Cisco (наприклад, 10.0.7.35)
  • номер порту (наприклад, Te1/49)

Знайти

  • рівень сигналу трансивера, встановленого в заданий порт

Рішення

Для початку знайдемо потрібний OID. Він буде складатися з ID «entSensorValue» «індексу» самого сенсора. Останній можна знайти, виконавши наступний запит з хоста, який має доступ по snmp до мережного пристрою з IP management 10.0.7.35:

$ snmpwalk-2c v-c community 10.0.7.35 1.3.6.1.2.1.47.1.1.1.1.7 | grep Te1/49
SNMPv2-SMI::mib-2.47.1.1.1.1.7.1107 = STRING: "Te1/49 Module Temperature Sensor"
SNMPv2-SMI::mib-2.47.1.1.1.1.7.1157 = STRING: "Te1/49 Supply Voltage Sensor"
SNMPv2-SMI::mib-2.47.1.1.1.1.7.1207 = STRING: "Te1/49 Bias Current Sensor"
SNMPv2-SMI::mib-2.47.1.1.1.1.7.1257 = STRING: "Te1/49 Transmit Power Sensor"
SNMPv2-SMI::mib-2.47.1.1.1.1.7.1307 = STRING: "Te1/49 Receive Power Sensor"

Скористаємося останнім числом в OID для «Te1/49 Transmit Power Sensor» і «Te1/49 Receive Power Sensor». Це відповідно 1257 і 1307. Використовуючи ці числа, ми відразу можемо отримати рівень вихідного і вхідного оптичного сигналу (value):

$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.4.1257
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.4.1257 = INTEGER: -28
$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.4.1307
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.4.1307 = INTEGER: -35

Комбінуючи аналогічним чином «entSensorPrecision» «індекс» сенсора, знаходимо точність виміру (кількість знаків після коми):

$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.3.1257
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.3.1257 = INTEGER: 1
$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.3.1307
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.3.1307 = INTEGER: 1

Цифра «1» у цьому випадку означає, що потрібно поставити кому перед однією цифрою справа в значенні відповідного сенсора.
Te1/49 Transmit Power = -2,8
Te1/49 Receive Power = -3,5

Щоб визначити одиниці вимірювання, скористаємося «entSensorType» в комбінації з «індексом» сенсора:

$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.1.1257
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.1.1257 = INTEGER: 14
$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.1.1307
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.1.1307 = INTEGER: 14

Значення 14 відповідає одиницям «dBm». Список значень дається описі «entSensorType».
До одиниць вимірювання може бути додана десяткова приставка. Яка саме — покаже «entSensorScale»:

$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.2.1257
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.2.1257 = INTEGER: 9
$ snmpget-2c v-c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.2.1307
SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.2.1307 = INTEGER: 9

В даному випадку приставка «Units» (яка відповідає числу 9) фактично означає відсутність приставки.
Таким чином, ми отримали рівень сигналу трансивера, встановленого в порту Te1/49, на свічі з IP 10.0.7.35

Te1/49 Transmit Power = -2,8 dBm
Te1/49 Receive Power = -3,5 dBm

Складемо відповідь підручнику:

light.bash
#!/bin/bash
E_OPTERROR=65
verbose=0

get_type () {
if [ -z "$1" ] # Length of argument is 0?
then
exit $E_OPTERROR
elif [ "$1" -eq "1" ]
then truetype=other
elif [ "$1" -eq "2" ]
then truetype=unknown
elif [ "$1" -eq "3" ]
then truetype=voltsAC
elif [ "$1" -eq "4" ]
then truetype=voltsDC
elif [ "$1" -eq "5" ]
then truetype=amperes
elif [ "$1" -eq "6" ]
then truetype=watts
elif [ "$1" -eq "7" ]
then truetype=hertz
elif [ "$1" -eq "8" ]
then truetype=celsius
elif [ "$1" -eq "9" ]
then truetype=percentRH
elif [ "$1" -eq "10" ]
then truetype="rpm"
elif [ "$1" -eq "11" ]
then truetype=cmm
elif [ "$1" -eq "12" ]
then truetype=truthvalue
elif [ "$1" -eq "13" ]
then truetype=specialEnum
elif [ "$1" -eq "14" ]
then truetype=dBm
else echo type=$1,error; exit $E_OPTERROR
fi
return 0
}

get_scale () {
if [ -z "$1" ] # Length of argument is 0?
then
exit $E_OPTERROR
elif [ "$1" -eq "1" ]
then truescale=yocto
elif [ "$1" -eq "2" ]
then truescale=zepto
elif [ "$1" -eq "3" ]
then truescale=atto
elif [ "$1" -eq "4" ]
then truescale=femto
elif [ "$1" -eq "5" ]
then truescale=pico
elif [ "$1" -eq "6" ]
then truescale=nano
elif [ "$1" -eq "7" ]
then truescale=micro
elif [ "$1" -eq "8" ]
then truescale=milli
elif [ "$1" -eq "9" ]
then truescale=""
elif [ "$1" -eq "10" ]
then truescale=kilo
elif [ "$1" -eq "11" ]
then truescale=mega
elif [ "$1" -eq "12" ]
then truescale=giga
elif [ "$1" -eq "13" ]
then truescale=tera
elif [ "$1" -eq "14" ]
then truescale=exa
elif [ "$1" -eq "15" ]
then truescale=peta
elif [ "$1" -eq "16" ]
then truescale=zetta
elif [ "$1" -eq "17" ]
then truescale=yotta
else echo scale=$1,error; exit $E_OPTERROR
fi
return 0
}
#reading the options
while getopts ":c:h:i:v" Option
do
#echo $OPTIND
case $Option in
c ) community=$OPTARG;;
h ) host=$OPTARG;;
i ) interface=$OPTARG;;
v ) echo "Verbose mode is set";verbose=1;;
* ) echo "Usage: `basename $0` -c community-h host-i interface"; exit $E_OPTERROR;; # default options
esac
done
shift $(($OPTIND - 1)) #moving on to the next provided option
if [ -z "$community" ] || [ -z $host ] || [ -z $interface ] # if some of options is not submitted
then
echo "Usage: `basename $0` -c community-h host-i interface"
exit $E_OPTERROR 
fi
if [ $verbose-eq 1 ]
then
echo "community is \"$community\""
echo "host is \"$host\""
echo "interface is \"$interface\""
fi
#looking for the index of sensor
if [ $verbose-eq 1 ]
then
echo "executing snmpwalk"
fi
# step1: getiing information from device
walksnmp=`snmpwalk-2c v-c $community $host 1.3.6.1.2.1.47.1.1.1.1.7 | grep $interface`
# step2: parse received string
if [ $verbose-eq 1 ]
then
echo "parsing snmpwalk result"
fi
rx_string=`echo $walksnmp | grep-o-e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Receive[ 0-9\/a-zA-Z]*\""`
rx_sensor=`echo $walksnmp | grep-o-e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Receive[ 0-9\/a-zA-Z]*\"" | cut-f1-d " "`
tx_string=`echo $walksnmp | grep-o-e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Transmit[ 0-9\/a-zA-Z]*\""`
tx_sensor=`echo $walksnmp | grep-o-e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Transmit[ 0-9\/a-zA-Z]*\"" | cut-f1-d " "`
if [ $verbose-eq 1 ]
then
echo "index of rx_sensor parsed to $rx_sensor"
echo "index of tx_sensor parsed to $tx_sensor"
echo "$rx_string"
echo "$tx_string"
fi
#getting the sensor value
if [ $verbose-eq 1 ]
then
echo "getting the sensor value"
fi
rx_value=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.4.$rx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
rx_precision=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.3.$rx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
rx_type=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.1.$rx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
get_type $rx_type
rx_type=$truetype
rx_scale=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.2.$rx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
get_scale $rx_scale
rx_scale=$truescale
tx_value=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.4.$tx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
tx_precision=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.3.$tx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
tx_type=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.1.$tx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
get_type $tx_type
tx_type=$truetype
tx_scale=`snmpget-2c v-c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.2.$rx_sensor | grep-o-e "INTEGER: [-+0-9]*" | cut-f2-d" "`
get_scale $tx_scale
tx_scale=$truescale
let lengthrx=${#rx_value}-$rx_precision
let lengthtx=${#tx_value}-$tx_precision
echo RX=${rx_value:0:$lengthrx}.${rx_value:$lengthrx} $rx_scale$rx_type
echo TX=${tx_value:0:$lengthtx}.${tx_value:$lengthtx} $tx_scale$tx_type
exit 0



Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.